File: resolver.hh

package info (click to toggle)
srg 1.3.5-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 1,956 kB
  • ctags: 776
  • sloc: sh: 9,073; cpp: 3,383; ansic: 563; makefile: 74; php: 57; yacc: 35; lex: 30
file content (132 lines) | stat: -rw-r--r-- 3,080 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#ifndef RESOLVER_HH
#define RESOLVER_HH
#include <stdio.h>
#include <unistd.h>
#include <map>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

class Resolver {
	private:
		bool verbose;
		struct ltstr
		{
			bool operator()(const char* s1, const char* s2) const
			{
				return strcmp(s1, s2) < 0;
			}
		};
		struct ltip
		{
			bool operator()(const in_addr i1, 
					const in_addr i2) const
			{
				return i1.s_addr<i2.s_addr;
			}
		};

		/* Caches */
		typedef std::map<const in_addr, char *, ltip> reverse_cache_t;
		typedef std::map<const char *, in_addr, ltstr> forward_cache_t;
		reverse_cache_t reverse_cache;
		forward_cache_t forward_cache;
		

	public:
		Resolver(bool be_verbose) {
			verbose = be_verbose;
		}
		~Resolver() {
			reverse_cache.clear();
			forward_cache.clear();
		}

		/* Returns a pointer to a statically allocated string 
		 * containing the DNS name for the requested address, or
		 * NULL if no name is available. */
		char *get_name(const in_addr addr) {

			/* Use cached name if available */
			reverse_cache_t::iterator name;
			name = reverse_cache.find(addr);
			if (name != reverse_cache.end()) {
				if (verbose)
					fprintf(stderr, "Using cached name "
							"for %s\n", 
							inet_ntoa(addr));
				return reverse_cache[addr];
			}
	
			/* Otherwise look it up */
			struct hostent *h;
			if ((h=gethostbyaddr((char *)&addr, sizeof(in_addr), 
						AF_INET))==NULL) {
				if (verbose)
					fprintf(stderr, "Unable to resolve "
							"address: %s\n", 
							inet_ntoa(addr));
				return NULL;
			} else {
				/* Put it into our cache */
				reverse_cache[addr] = strdup(h->h_name);
				if (verbose)
					fprintf(stderr, "Cached hostname "
							"(%s) for %s\n", h->h_name, 
							inet_ntoa(addr));
			}		

			return reverse_cache[addr];
			
		}

		/* Retrieves the IP Address for the specified hostname and 
		 * returns it via the inp parameter. Returns 0 if an ip 
		 * address was successfully returned, returns non zero 
		 * otherwise */
		int get_ip(const char *name, in_addr *inp) {
			
			/* Used cached ip if available */
			forward_cache_t::iterator tmp;
			tmp = forward_cache.find(name);
			if (tmp != forward_cache.end()) {
				if (verbose)
					fprintf(stderr, "Using cached ip (%s) "
							"address for %s\n", 
							inet_ntoa(forward_cache[name]),
							name);
				memcpy(inp, &(*tmp).second, sizeof(in_addr));
				return 0;
			}
			
			char *tname = strdup(name);

			/* Otherwise look it up */
			struct hostent *h;
			if ((h=gethostbyname(tname))==NULL) {
				if (verbose)
					fprintf(stderr, "Unable to resolve "
							"name: %s\n", tname);
				inp = NULL;
				free(tname);
				return 1;
			} else {
				/* Put it into our cache */
				in_addr t_addr;				
				memcpy(&t_addr, h->h_addr, sizeof(in_addr));
				forward_cache[tname] = t_addr;
				if (verbose)
					fprintf(stderr, "Cached ip address "
							"(%s) for %s\n", 
							inet_ntoa(forward_cache[tname]),
							tname);
				memcpy(inp, &t_addr, sizeof(in_addr));
			}		
			
			return 0;
		}

};

#endif