We have discussed
implementation of Reverse DNS Look Up Cache
. Forward DNS look up is getting IP address for a given domain name typed in the web browser.
The cache should do the following operations : 1. Add a mapping from URL to IP address 2. Find IP address for a given URL. There are a few changes from
that we need to incorporate. 1. Instead of [0-9] and (.) dot we need to take care of [A-Z], [a-z] and (.) dot. As most of the domain name contains only lowercase characters we can assume that there will be [a-z] and (.) 27 children for each trie node. 2. When we type www.google.in and google.in the browser takes us to the same page. So, we need to add a domain name into trie for the words after www(.). Similarly while searching for a domain name corresponding IP address remove the www(.) if the user has provided it. This is left as an exercise and for simplicity we have taken care of www. also. One solution is to use
. In this post, a
based solution is discussed. One advantage of Trie based solutions is, 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 IPs for a common prefix of URLs). The general disadvantage of Trie is large amount of memory requirement. The idea is to store URLs in Trie nodes and store the corresponding IP address in last or leaf node. Following is C style implementation in C++.
#include <iostream> #include <cstring> // Define constants for the number of characters and maximum length #define CHARS 27 #define MAX 100 // Function to get the index for a character in the trie node's child array int getIndex( char c) {
return (c == '.' ) ? 26 : (c - 'a' );
} // Function to get the character for a given index in the trie node's child array char getCharFromIndex( int i) {
return (i == 26) ? '.' : ( 'a' + i);
} // Trie Node structure struct TrieNode {
bool isLeaf;
char *ipAdd;
TrieNode *child[CHARS];
}; // Function to create a new trie node TrieNode *newTrieNode() { TrieNode *newNode = new TrieNode;
newNode->isLeaf = false ;
newNode->ipAdd = nullptr;
for ( int i = 0; i < CHARS; i++)
newNode->child[i] = nullptr;
return newNode;
} // Function to insert a URL and corresponding IP address into the trie void insert(TrieNode *root, char *URL, char *ipAdd) {
int len = strlen (URL);
TrieNode *pCrawl = root;
for ( int level = 0; level < len; level++) {
int index = getIndex(URL[level]);
if (!pCrawl->child[index])
pCrawl->child[index] = newTrieNode();
pCrawl = pCrawl->child[index];
}
pCrawl->isLeaf = true ;
pCrawl->ipAdd = new char [ strlen (ipAdd) + 1];
strcpy (pCrawl->ipAdd, ipAdd);
} // Function to search the DNS cache for a given URL and return the corresponding IP address char *searchDNSCache(TrieNode *root, char *URL) {
TrieNode *pCrawl = root;
int len = strlen (URL);
for ( int level = 0; level < len; level++) {
int index = getIndex(URL[level]);
if (!pCrawl->child[index])
return nullptr;
pCrawl = pCrawl->child[index];
}
if (pCrawl != nullptr && pCrawl->isLeaf)
return pCrawl->ipAdd;
return nullptr;
} int main() {
// Sample data for URLs and corresponding IP addresses
char URL[][50] = { "www.samsung.com" , "www.samsung.net" , "www.google.in" };
char ipAdd[][MAX] = { "107.108.11.123" , "107.109.123.255" , "74.125.200.106" };
int n = sizeof (URL) / sizeof (URL[0]);
// Create the root of the trie
TrieNode *root = newTrieNode();
// Insert all the domain names and their corresponding IP addresses into the trie
for ( int i = 0; i < n; i++)
insert(root, URL[i], ipAdd[i]);
// Perform forward DNS lookup and print the result
char url[] = "www.samsung.com" ;
char *res_ip = searchDNSCache(root, url);
if (res_ip != nullptr)
std::cout << "Forward DNS lookup resolved in cache:\n" << url << " --> " << res_ip << std::endl;
else
std::cout << "Forward DNS lookup not resolved in cache" << std::endl;
return 0;
} |
// C based program to implement reverse DNS lookup #include<stdio.h> #include<stdlib.h> #include<string.h> // There are atmost 27 different chars in a valid URL // assuming URL consists [a-z] and (.) #define CHARS 27 // Maximum length of a valid URL #define MAX 100 // A utility function to find index of child for a given character 'c' int getIndex( char c)
{ return (c == '.' ) ? 26 : (c - 'a' );
} // A utility function to find character for a given child index. char getCharFromIndex( int i)
{ return (i == 26) ? '.' : ( 'a' + i);
} // Trie Node. struct trieNode
{ bool isLeaf;
char *ipAdd;
struct trieNode *child[CHARS];
}; // Function to create a new trie node. struct trieNode *newTrieNode( void )
{ struct trieNode *newNode = new trieNode;
newNode->isLeaf = false ;
newNode->ipAdd = NULL;
for ( int i = 0; i<CHARS; i++)
newNode->child[i] = NULL;
return newNode;
} // This method inserts a URL and corresponding IP address // in the trie. The last node in Trie contains the ip address. void insert( struct trieNode *root, char *URL, char *ipAdd)
{ // Length of the URL
int len = strlen (URL);
struct trieNode *pCrawl = root;
// Traversing over the length of the URL.
for ( int level = 0; level<len; level++)
{
// Get index of child node from current character
// in URL[] Index must be from 0 to 26 where
// 0 to 25 is used for alphabets and 26 for dot
int index = getIndex(URL[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 ip address of the URL in the
//last node of trie.
pCrawl->isLeaf = true ;
pCrawl->ipAdd = new char [ strlen (ipAdd) + 1];
strcpy (pCrawl->ipAdd, ipAdd);
} // This function returns IP address if given URL is // present in DNS cache. Else returns NULL char *searchDNSCache( struct trieNode *root, char *URL)
{ // Root node of trie.
struct trieNode *pCrawl = root;
int len = strlen (URL);
// Traversal over the length of URL.
for ( int level = 0; level<len; level++)
{
int index = getIndex(URL[level]);
if (!pCrawl->child[index])
return NULL;
pCrawl = pCrawl->child[index];
}
// If we find the last node for a given ip address,
// print the ip address.
if (pCrawl != NULL && pCrawl->isLeaf)
return pCrawl->ipAdd;
return NULL;
} // Driver function. int main()
{ char URL[][50] = { "www.samsung.com", "www.samsung.net",
"www.google.in"
};
char ipAdd[][MAX] = { "107.108.11.123", "107.109.123.255",
"74.125.200.106"
};
int n = sizeof (URL) / sizeof (URL[0]);
struct trieNode *root = newTrieNode();
// Inserts all the domain name and their corresponding
// ip address
for ( int i = 0; i<n; i++)
insert(root, URL[i], ipAdd[i]);
// If forward DNS look up succeeds print the url along
// with the resolved ip address.
char url[] = "www.samsung.com";
char *res_ip = searchDNSCache(root, url);
if (res_ip != NULL)
printf ("Forward DNS look up resolved in cache:\n%s --> %s",
url, res_ip);
else
printf ("Forward DNS look up not resolved in cache ");
return 0;
} |
public class ReverseDNSLookup {
// Define constants for the number of characters and maximum length
private static final int CHARS = 27 ;
private static final int MAX = 100 ;
// Trie Node structure
static class TrieNode {
boolean isLeaf;
String ipAdd;
TrieNode[] child;
TrieNode() {
isLeaf = false ;
ipAdd = null ;
child = new TrieNode[CHARS];
}
}
// Function to get the index for a character in the trie node's child array
private static int getIndex( char c) {
return (c == '.' ) ? 26 : (c - 'a' );
}
// Function to get the character for a given index in the trie node's child array
private static char getCharFromIndex( int i) {
return (i == 26 ) ? '.' : ( char ) ( 'a' + i);
}
// Function to create a new trie node
private static TrieNode newTrieNode() {
return new TrieNode();
}
// Function to insert a URL and corresponding IP address into the trie
private static void insert(TrieNode root, String URL, String ipAdd) {
int len = URL.length();
TrieNode pCrawl = root;
for ( int level = 0 ; level < len; level++) {
int index = getIndex(URL.charAt(level));
if (pCrawl.child[index] == null )
pCrawl.child[index] = newTrieNode();
pCrawl = pCrawl.child[index];
}
pCrawl.isLeaf = true ;
pCrawl.ipAdd = ipAdd;
}
// Function to search the DNS cache for a given URL and return the corresponding IP address
private static String searchDNSCache(TrieNode root, String URL) {
TrieNode pCrawl = root;
int len = URL.length();
for ( int level = 0 ; level < len; level++) {
int index = getIndex(URL.charAt(level));
if (pCrawl.child[index] == null )
return null ;
pCrawl = pCrawl.child[index];
}
if (pCrawl != null && pCrawl.isLeaf)
return pCrawl.ipAdd;
return null ;
}
public static void main(String[] args) {
// Sample data for URLs and corresponding IP addresses
String[] URL = { "www.samsung.com" , "www.samsung.net" , "www.google.in" };
String[] ipAdd = { "107.108.11.123" , "107.109.123.255" , "74.125.200.106" };
int n = URL.length;
// Create the root of the trie
TrieNode root = newTrieNode();
// Insert all the domain names and their corresponding IP addresses into the trie
for ( int i = 0 ; i < n; i++)
insert(root, URL[i], ipAdd[i]);
// Perform forward DNS lookup and print the result
String url = "www.samsung.com" ;
String res_ip = searchDNSCache(root, url);
if (res_ip != null )
System.out.println( "Forward DNS lookup resolved in cache:\n" + url + " --> " + res_ip);
else
System.out.println( "Forward DNS lookup not resolved in cache" );
}
} |
class TrieNode:
def __init__( self ):
self .isLeaf = False
self .ipAdd = None
self .child = [ None ] * 27
def get_index(c):
return 26 if c = = '.' else ord (c) - ord ( 'a' )
def get_char_from_index(i):
return '.' if i = = 26 else chr ( ord ( 'a' ) + i)
def new_trie_node():
new_node = TrieNode()
new_node.isLeaf = False
new_node.ipAdd = None
new_node.child = [ None ] * 27
return new_node
def insert(root, URL, ipAdd):
pCrawl = root
for level in range ( len (URL)):
index = get_index(URL[level])
if not pCrawl.child[index]:
pCrawl.child[index] = new_trie_node()
pCrawl = pCrawl.child[index]
pCrawl.isLeaf = True
pCrawl.ipAdd = ipAdd
def search_dns_cache(root, URL):
pCrawl = root
for level in range ( len (URL)):
index = get_index(URL[level])
if not pCrawl.child[index]:
return None
pCrawl = pCrawl.child[index]
if pCrawl and pCrawl.isLeaf:
return pCrawl.ipAdd
return None
if __name__ = = "__main__" :
# Sample data for URLs and corresponding IP addresses
URL = [ "www.samsung.com" , "www.samsung.net" , "www.google.in" ]
ipAdd = [ "107.108.11.123" , "107.109.123.255" , "74.125.200.106" ]
n = len (URL)
# Create the root of the trie
root = new_trie_node()
# Insert all the domain names and their corresponding IP addresses into the trie
for i in range (n):
insert(root, URL[i], ipAdd[i])
# Perform forward DNS lookup and print the result
url = "www.samsung.com"
res_ip = search_dns_cache(root, url)
if res_ip is not None :
print ( "Forward DNS lookup resolved in cache:" )
print (f "{url} --> {res_ip}" )
else :
print ( "Forward DNS lookup not resolved in cache" )
|
using System;
using System.Collections.Generic;
public class Program
{ // Define constants for the number of characters and maximum length
const int CHARS = 27;
const int MAX = 100;
// Function to get the index for a character in the trie node's child array
static int GetIndex( char c) {
return (c == '.' ) ? 26 : (c - 'a' );
}
// Function to get the character for a given index in the trie node's child array
static char GetCharFromIndex( int i) {
return (i == 26) ? '.' : ( char )( 'a' + i);
}
// Trie Node structure
public class TrieNode {
public bool IsLeaf;
public string IpAdd;
public TrieNode[] Child;
public TrieNode() {
IsLeaf = false ;
IpAdd = null ;
Child = new TrieNode[CHARS];
}
}
// Function to insert a URL and corresponding IP address into the trie
static void Insert(TrieNode root, string URL, string ipAdd) {
int len = URL.Length;
TrieNode pCrawl = root;
for ( int level = 0; level < len; level++) {
int index = GetIndex(URL[level]);
if (pCrawl.Child[index] == null )
pCrawl.Child[index] = new TrieNode();
pCrawl = pCrawl.Child[index];
}
pCrawl.IsLeaf = true ;
pCrawl.IpAdd = ipAdd;
}
// Function to search the DNS cache for a given URL and return the corresponding IP address
static string SearchDNSCache(TrieNode root, string URL) {
TrieNode pCrawl = root;
int len = URL.Length;
for ( int level = 0; level < len; level++) {
int index = GetIndex(URL[level]);
if (pCrawl.Child[index] == null )
return null ;
pCrawl = pCrawl.Child[index];
}
if (pCrawl != null && pCrawl.IsLeaf)
return pCrawl.IpAdd;
return null ;
}
public static void Main( string [] args) {
// Sample data for URLs and corresponding IP addresses
string [] URL = { "www.samsung.com" , "www.samsung.net" , "www.google.in" };
string [] ipAdd = { "107.108.11.123" , "107.109.123.255" , "74.125.200.106" };
int n = URL.Length;
// Create the root of the trie
TrieNode root = new TrieNode();
// Insert all the domain names and their corresponding IP addresses into the trie
for ( int i = 0; i < n; i++)
Insert(root, URL[i], ipAdd[i]);
// Perform forward DNS lookup and print the result
string url = "www.samsung.com" ;
string res_ip = SearchDNSCache(root, url);
if (res_ip != null )
Console.WriteLine( "Forward DNS lookup resolved in cache:\n" + url + " --> " + res_ip);
else
Console.WriteLine( "Forward DNS lookup not resolved in cache" );
}
} |
// Define constants for the number of characters and maximum length const CHARS = 27; const MAX = 100; // Function to get the index for a character in the trie node's child array function getIndex(c) {
return (c === '. ') ? 26 : (c.charCodeAt(0) - ' a '.charCodeAt(0));
} // Function to get the character for a given index in the trie node' s child array
function getCharFromIndex(i) {
return (i === 26) ? '.' : String.fromCharCode( 'a' .charCodeAt(0) + i);
} // Trie Node structure class TrieNode { constructor() {
this .isLeaf = false ;
this .ipAdd = null ;
this .child = new Array(CHARS).fill( null );
}
} // Function to create a new trie node function newTrieNode() {
return new TrieNode();
} // Function to insert a URL and corresponding IP address into the trie function insert(root, URL, ipAdd) {
const len = URL.length;
let pCrawl = root;
for (let level = 0; level < len; level++) {
const index = getIndex(URL[level]);
if (!pCrawl.child[index])
pCrawl.child[index] = newTrieNode();
pCrawl = pCrawl.child[index];
}
pCrawl.isLeaf = true ;
pCrawl.ipAdd = ipAdd;
} // Function to search the DNS cache for a given URL and return the corresponding IP address function searchDNSCache(root, URL) {
let pCrawl = root;
const len = URL.length;
for (let level = 0; level < len; level++) {
const index = getIndex(URL[level]);
if (!pCrawl.child[index])
return null ;
pCrawl = pCrawl.child[index];
}
if (pCrawl !== null && pCrawl.isLeaf)
return pCrawl.ipAdd;
return null ;
} // Sample data for URLs and corresponding IP addresses const URL = [ "www.samsung.com" , "www.samsung.net" , "www.google.in" ];
const ipAdd = [ "107.108.11.123" , "107.109.123.255" , "74.125.200.106" ];
const n = URL.length; // Create the root of the trie const root = newTrieNode(); // Insert all the domain names and their corresponding IP addresses into the trie for (let i = 0; i < n; i++)
insert(root, URL[i], ipAdd[i]);
// Perform forward DNS lookup and print the result const url = "www.samsung.com" ;
const res_ip = searchDNSCache(root, url); if (res_ip !== null )
console.log( "Forward DNS lookup resolved in cache:\n" + url + " --> " + res_ip);
else console.log( "Forward DNS lookup not resolved in cache" );
|
Forward DNS lookup resolved in cache: www.samsung.com --> 107.108.11.123