📜  如何实现反向DNS查找缓存?

📅  最后修改于: 2021-04-17 10:02:47             🧑  作者: Mango

反向DNS查找是使用Internet IP地址来查找域名。例如,如果您在浏览器中键入74.125.200.106,它将自动重定向到google.in。
如何实现反向DNS查找缓存?以下是缓存中所需的操作:

  • 将IP地址添加到缓存中的“ URL映射”。
  • 查找给定IP地址的URL。

一种解决方案是使用哈希。
在本文中,将讨论基于Trie的解决方案。基于Trie的解决方案的一个优势是,对于Trie,最坏情况的上限是O(1),对于哈希,最好的平均情况下时间复杂度是O(1)。同样,使用Trie,我们可以实现前缀搜索(为IP地址的公共前缀查找所有url)。
Trie的一般缺点是需要大量内存,这在这里不是主要问题,因为此处的字母大小仅为11。从’0’到’9’的数字需要十个字符,而对于点(’。’)则需要一个字符。
这个想法是将IP地址存储在Trie节点中,而在最后一个节点中,我们存储相应的域名。以下是C++中的C样式实现。

CPP
// C based program to implement reverse DNS lookup
#include
#include
#include
 
// 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; ichild[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; levelchild[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; levelchild[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 %s",
                ip, res_url);
    else
        printf("Reverse DNS look up not resolved in cache ");
    return 0;
}


Java
/* http://www.geeksforgeeks.org/implement-reverse-dns-look-cache/ */
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 child;
    String url;
 
    TrieNode()
    {
        this.child = new HashMap<>();
    }
 
    public String toString()
    {
        return child.toString()+" : "+url;
    }
}
 
// This code is contributed by Akhilesh Singla


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


输出:
Reverse DNS look up resolved in cache:
107.108.11.123 --> www.samsung.com

输出:

Reverse DNS look up resolved in cache:
107.108.11.123 --> www.samsung.com

注意,上面的Trie实现假定给定IP地址不包含{‘0’,’1’,…..’9’,’。’}以外的字符。如果用户提供的无效IP地址包含其他一些字符怎么办?可以通过在将输入的IP地址插入到Trie中之前验证输入的IP地址来解决此问题。我们可以将此处讨论的方法用于IP地址验证。
Java实现如下:

Java

/* http://www.geeksforgeeks.org/implement-reverse-dns-look-cache/ */
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 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实现:

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