Reverse DNS look up is using an internet IP address to find a domain name. For example, if you type 74.125.200.106 in browser, it automatically redirects to google.in.
How to implement Reverse DNS Look Up cache? Following are the operations needed from cache:
- Add an IP address to URL Mapping in cache.
- Find URL for a given IP address.
One solution is to use Hashing.
In this post, a Trie based solution is discussed. One advantage of Trie based solutions is, the worst case upper bound is O(1) for Trie, for hashing, the best possible average case time complexity is O(1). Also, with Trie we can implement prefix search (finding all urls for a common prefix of IP addresses).
The general disadvantage of Trie is large amount of memory requirement, this is not a major problem here as the alphabet size is only 11 here. Ten characters are needed for digits from ‘0’ to ‘9’ and one for dot (‘.’).
The idea is to store IP addresses in Trie nodes and in the last node we store the corresponding domain name. Following is C style implementation in C++.
CPP
// C based program to implement reverse DNS lookup #include<stdio.h> #include<stdlib.h> #include<string.h> // There are atmost 11 different chars in a valid IP address #define CHARS 11 // Maximum length of a valid IP address #define MAX 50 // A utility function to find index of child for a given character 'c' int getIndex( char c) { return (c == '.' )? 10: (c - '0' ); } // A utility function to find character for a given child index. char getCharFromIndex( int i) { return (i== 10)? '.' : ( '0' + i); } // Trie Node. struct trieNode { bool isLeaf; char *URL; struct trieNode *child[CHARS]; }; // Function to create a new trie node. struct trieNode *newTrieNode( void ) { struct trieNode *newNode = new trieNode; newNode->isLeaf = false ; newNode->URL = NULL; for ( int i=0; i<CHARS; i++) newNode->child[i] = NULL; return newNode; } // This method inserts an ip address and the corresponding // domain name in the trie. The last node in Trie contains the URL. void insert( struct trieNode *root, char *ipAdd, char *URL) { // Length of the ip address int len = strlen (ipAdd); struct trieNode *pCrawl = root; // Traversing over the length of the ip address. for ( int level=0; level<len; level++) { // Get index of child node from current character // in ipAdd[]. Index must be from 0 to 10 where // 0 to 9 is used for digits and 10 for dot int index = getIndex(ipAdd[level]); // Create a new child if not exist already if (!pCrawl->child[index]) pCrawl->child[index] = newTrieNode(); // Move to the child pCrawl = pCrawl->child[index]; } //Below needs to be carried out for the last node. //Save the corresponding URL of the ip address in the //last node of trie. pCrawl->isLeaf = true ; pCrawl->URL = new char [ strlen (URL) + 1]; strcpy (pCrawl->URL, URL); } // This function returns URL if given IP address is present in DNS cache. // Else returns NULL char *searchDNSCache( struct trieNode *root, char *ipAdd) { // Root node of trie. struct trieNode *pCrawl = root; int len = strlen (ipAdd); // Traversal over the length of ip address. for ( int level=0; level<len; level++) { int index = getIndex(ipAdd[level]); if (!pCrawl->child[index]) return NULL; pCrawl = pCrawl->child[index]; } // If we find the last node for a given ip address, print the URL. if (pCrawl!=NULL && pCrawl->isLeaf) return pCrawl->URL; return NULL; } //Driver function. int main() { /* Change third ipAddress for validation */ char ipAdd[][MAX] = { "107.108.11.123" , "107.109.123.255" , "74.125.200.106" }; char URL[][50] = { "www.samsung.com" , "www.samsung.net" , "www.google.in" }; int n = sizeof (ipAdd)/ sizeof (ipAdd[0]); struct trieNode *root = newTrieNode(); // Inserts all the ip address and their corresponding // domain name after ip address validation. for ( int i=0; i<n; i++) insert(root,ipAdd[i],URL[i]); // If reverse DNS look up succeeds print the domain // name along with DNS resolved. char ip[] = "107.108.11.123" ; char *res_url = searchDNSCache(root, ip); if (res_url != NULL) printf ( "Reverse DNS look up resolved in cache:\n%s --> %s" , ip, res_url); else printf ( "Reverse DNS look up not resolved in cache " ); return 0; } |
Reverse DNS look up resolved in cache: 107.108.11.123 --> www.samsung.com
Output:
Reverse DNS look up resolved in cache: 107.108.11.123 --> www.samsung.com
Note that the above implementation of Trie assumes that the given IP address does not contain characters other than {‘0’, ‘1’,….. ‘9’, ‘.’}. What if a user gives an invalid IP address that contains some other characters? This problem can be resolved by validating the input IP address before inserting it into Trie. We can use the approach discussed here for IP address validation.
Java implementation is given below:
Java
import java.util.HashMap; import java.util.Map; public class ReverseDNSLookup { public void insert(TrieNode node, String[] ipAdd, String[] urls) { for ( int i= 0 ;i<ipAdd.length;i++) this .insertUtil(node, ipAdd[i], urls[i], 0 ); } public void insertUtil(TrieNode node, String ipAddr, String url, int pos) { TrieNode temp = null ; if (node.child.containsKey(ipAddr.charAt(pos))) { temp = node.child.get(ipAddr.charAt(pos)); } else { temp = new TrieNode(); node.child.put(ipAddr.charAt(pos), temp); } if (pos==ipAddr.length()- 1 ) { temp.url = url; return ; } this .insertUtil(temp, ipAddr, url, pos+ 1 ); } public String search(TrieNode node, String ipAddr, int pos) { TrieNode temp = null ; if (pos==ipAddr.length()- 1 ) { temp = node.child.get(ipAddr.charAt(pos)); if (temp!= null ) return temp.url; } if (node.child.containsKey(ipAddr.charAt(pos))) { temp = node.child.get(ipAddr.charAt(pos)); return this .search(temp, ipAddr, pos+ 1 ); } return "No url associated/Invalid IP address" ; } public static void main(String []args) { ReverseDNSLookup r = new ReverseDNSLookup(); String[] ipAdd = { "107.108.11.123" , "107.109.123.255" , "74.125.200.106" }; String[] urls = { "www.samsung.com" , "www.samsung.net" , "www.google.in" }; TrieNode root = new TrieNode(); r.insert(root, ipAdd, urls); //System.out.println(root); System.out.println( "74.125.200.106 : " + r.search(root, "74.125.200.106" , 0 )); System.out.println( "107.109.123.245 : " + r.search(root, "107.109.123.245" , 0 )); } } class TrieNode { Map<Character, TrieNode> child; String url; TrieNode() { this .child = new HashMap<>(); } public String toString() { return child.toString()+ " : " +url; } } // This code is contributed by Akhilesh Singla |
74.125.200.106 : www.google.in 107.109.123.245 : No url associated/Invalid IP address
Python3 Implementation:
Python3
# Trie Node class TrieNode: def __init__( self ): self .child = [ None ] * 11 self .url = None self .is_end = False class Trie: def __init__( self ): self .root = TrieNode() def getIndex( self , c): # For the . (dot) in IP address, we'll use the 10th index in child list return 10 if c = = '.' else int (c) def insert( self , ip, domain): cur = self .root n = len (ip) for level in range (n): # We'll use the digits of IP address to form the trie structure idx = self .getIndex(ip[level]) if cur.child[idx] is None : # Create a new trie node if not available for a particular digit # and assign to the respective index cur.child[idx] = TrieNode() cur = cur.child[idx] # At the end, we'll map the domain name and mark the end node cur.url = domain cur.is_end = True def search_domain( self , ip): cur = self .root n = len (ip) # Traverse through the trie structure with all digits in ip address for level in range (n): idx = self .getIndex(ip[level]) if cur.child[idx] is None : return "Domain name not found" cur = cur.child[idx] # Returns the url when all the digits in ip found if cur and cur.url: return cur.url return "Domain name not found" # Driver Code ip = [ "107.108.11.123" , "107.109.123.255" , "74.125.200.106" ] domain = [ "www.samsung.com" , "www.samsung.net" , "www.google.co.in" ] trie = Trie() for idx in range ( len (ip)): trie.insert(ip[idx], domain[idx]) print (trie.search_domain( "107.109.123.255" )) print (trie.search_domain( "107.109.123.245" )) # This code is contributed by Abhilash Pujari |
www.samsung.net Domain name not found
This article is contributed by Kumar Gautam. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above