Open In App

How to Implement Forward DNS Look Up Cache?

Last Updated : 24 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

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

reverse DNS look up cache

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

Hashing

. In this post, a

Trie

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++.

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




// 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;
}


Java




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");
    }
}


Python3




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")


C#




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");
    }
}


Javascript




// 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");


Output

Forward DNS lookup resolved in cache:
www.samsung.com --> 107.108.11.123




Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads