- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)
1 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,518 +0,0 @@ |
1 |
-/* |
|
2 |
- * resolver related functions |
|
3 |
- * |
|
4 |
- * Copyright (C) 2001-2003 FhG Fokus |
|
5 |
- * |
|
6 |
- * This file is part of Kamailio, a free SIP server. |
|
7 |
- * |
|
8 |
- * Kamailio is free software; you can redistribute it and/or modify |
|
9 |
- * it under the terms of the GNU General Public License as published by |
|
10 |
- * the Free Software Foundation; either version 2 of the License, or |
|
11 |
- * (at your option) any later version |
|
12 |
- * |
|
13 |
- * Kamailio is distributed in the hope that it will be useful, |
|
14 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 |
- * GNU General Public License for more details. |
|
17 |
- * |
|
18 |
- * You should have received a copy of the GNU General Public License |
|
19 |
- * along with this program; if not, write to the Free Software |
|
20 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
21 |
- */ |
|
22 |
- |
|
23 |
-/*! |
|
24 |
- * \file |
|
25 |
- * \brief Kamailio core :: DNS resolver |
|
26 |
- * \author andrei |
|
27 |
- * \ingroup core |
|
28 |
- * Module: \ref core |
|
29 |
- */ |
|
30 |
- |
|
31 |
-#ifndef __resolve_h |
|
32 |
-#define __resolve_h |
|
33 |
- |
|
34 |
-#include <sys/types.h> |
|
35 |
-#include <sys/socket.h> |
|
36 |
-#include <netinet/in.h> |
|
37 |
-#include <netdb.h> |
|
38 |
-#include <arpa/nameser.h> |
|
39 |
-#include <resolv.h> |
|
40 |
-#include "counters.h" |
|
41 |
-#include "dns_func.h" |
|
42 |
- |
|
43 |
-#ifdef __OS_darwin |
|
44 |
-#include <arpa/nameser_compat.h> |
|
45 |
-#endif |
|
46 |
- |
|
47 |
-#include "ip_addr.h" |
|
48 |
-#ifdef USE_DNS_CACHE |
|
49 |
-#include "dns_wrappers.h" |
|
50 |
-#endif |
|
51 |
- |
|
52 |
- |
|
53 |
-/* define RESOLVE_DBG for debugging info (very noisy) */ |
|
54 |
-#define RESOLVE_DBG |
|
55 |
-/* define NAPTR_DBG for naptr related debugging info (very noisy) */ |
|
56 |
-#define NAPTR_DBG |
|
57 |
- |
|
58 |
- |
|
59 |
-#define MAX_QUERY_SIZE 8192 |
|
60 |
-#define ANS_SIZE 8192 |
|
61 |
-#define DNS_HDR_SIZE 12 |
|
62 |
-#define MAX_DNS_NAME 256 |
|
63 |
-#define MAX_DNS_STRING 255 |
|
64 |
- |
|
65 |
-#ifndef T_EBL |
|
66 |
-/** not official yet - iEnum. */ |
|
67 |
-#define T_EBL 65300 |
|
68 |
-#endif |
|
69 |
- |
|
70 |
-/* get_record flags */ |
|
71 |
-#define RES_ONLY_TYPE 1 /* return only the specified type records */ |
|
72 |
-#define RES_AR 2 /* return also the additional records */ |
|
73 |
- |
|
74 |
-/* counter for failed DNS requests |
|
75 |
-*/ |
|
76 |
-struct dns_counters_h { |
|
77 |
- counter_handle_t failed_dns_req; |
|
78 |
-}; |
|
79 |
- |
|
80 |
-extern struct dns_counters_h dns_cnts_h; |
|
81 |
-extern struct dns_func_t dns_func; |
|
82 |
- |
|
83 |
-/* query union*/ |
|
84 |
-union dns_query{ |
|
85 |
- HEADER hdr; |
|
86 |
- unsigned char buff[MAX_QUERY_SIZE]; |
|
87 |
-}; |
|
88 |
- |
|
89 |
- |
|
90 |
-/* rdata struct*/ |
|
91 |
-struct rdata { |
|
92 |
- unsigned short type; |
|
93 |
- unsigned short pclass; |
|
94 |
- unsigned int ttl; |
|
95 |
- void* rdata; |
|
96 |
- struct rdata* next; |
|
97 |
- unsigned char name_len; /* name length w/o the terminating 0 */ |
|
98 |
- char name[1]; /* null terminated name (len=name_len+1) */ |
|
99 |
-}; |
|
100 |
-/* real size of the structure */ |
|
101 |
-#define RDATA_SIZE(s) (sizeof(struct rdata)+(s).name_len) /* +1-1 */ |
|
102 |
- |
|
103 |
- |
|
104 |
-/* srv rec. struct*/ |
|
105 |
-struct srv_rdata { |
|
106 |
- unsigned short priority; |
|
107 |
- unsigned short weight; |
|
108 |
- unsigned short port; |
|
109 |
- unsigned char name_len; /* name length w/o the terminating 0 */ |
|
110 |
- char name[1]; /* null terminated name (len=name_len+1) */ |
|
111 |
-}; |
|
112 |
- |
|
113 |
- |
|
114 |
-/* real size of the structure */ |
|
115 |
-#define SRV_RDATA_SIZE(s) (sizeof(struct srv_rdata)+(s).name_len) |
|
116 |
- |
|
117 |
-/* naptr rec. struct*/ |
|
118 |
-struct naptr_rdata { |
|
119 |
- char* flags; /* points inside str_table */ |
|
120 |
- char* services; /* points inside str_table */ |
|
121 |
- char* regexp; /* points inside str_table */ |
|
122 |
- char* repl; /* points inside str_table, null terminated */ |
|
123 |
- |
|
124 |
- unsigned short order; |
|
125 |
- unsigned short pref; |
|
126 |
- |
|
127 |
- unsigned char flags_len; |
|
128 |
- unsigned char services_len; |
|
129 |
- unsigned char regexp_len; |
|
130 |
- unsigned char repl_len; /* not currently used */ |
|
131 |
- |
|
132 |
- char str_table[1]; /* contains all the strings */ |
|
133 |
-}; |
|
134 |
- |
|
135 |
-/* real size of the structure */ |
|
136 |
-#define NAPTR_RDATA_SIZE(s) (sizeof(struct naptr_rdata) \ |
|
137 |
- + (s).flags_len \ |
|
138 |
- + (s).services_len \ |
|
139 |
- + (s).regexp_len \ |
|
140 |
- + (s).repl_len + 1 - 1) |
|
141 |
- |
|
142 |
- |
|
143 |
-/* A rec. struct */ |
|
144 |
-struct a_rdata { |
|
145 |
- unsigned char ip[4]; |
|
146 |
-}; |
|
147 |
- |
|
148 |
-struct aaaa_rdata { |
|
149 |
- unsigned char ip6[16]; |
|
150 |
-}; |
|
151 |
- |
|
152 |
-/* cname rec. struct*/ |
|
153 |
-struct cname_rdata { |
|
154 |
- unsigned char name_len; /* name length w/o the terminating 0 */ |
|
155 |
- char name[1]; /* null terminated name (len=name_len+1) */ |
|
156 |
-}; |
|
157 |
- |
|
158 |
-/* real size of the structure */ |
|
159 |
-#define CNAME_RDATA_SIZE(s) (sizeof(struct cname_rdata)+(s).name_len) |
|
160 |
- |
|
161 |
-/* dns character-string */ |
|
162 |
-struct dns_cstr{ |
|
163 |
- char* cstr; /* pointer to null term. string */ |
|
164 |
- unsigned char cstr_len; |
|
165 |
-}; |
|
166 |
- |
|
167 |
-/* txt rec. struct */ |
|
168 |
-struct txt_rdata { |
|
169 |
- unsigned short cstr_no; /* number of strings */ |
|
170 |
- unsigned short tslen; /* total strings table len */ |
|
171 |
- struct dns_cstr txt[1]; /* at least 1 */ |
|
172 |
- /* all txt[*].cstr point inside a string table at the end of the struct.*/ |
|
173 |
-}; |
|
174 |
- |
|
175 |
-#define TXT_RDATA_SIZE(s) \ |
|
176 |
- (sizeof(struct txt_rdata)+((s).cstr_no-1)*sizeof(struct dns_cstr)+\ |
|
177 |
- (s).tslen) |
|
178 |
- |
|
179 |
-/* ebl rec. struct, see |
|
180 |
- http://tools.ietf.org/html/draft-ietf-enum-branch-location-record-03 */ |
|
181 |
-struct ebl_rdata { |
|
182 |
- char* separator; /* points inside str_table */ |
|
183 |
- char* apex; /* point inside str_table */ |
|
184 |
- unsigned char separator_len; /* separator len w/o the terminating 0 */ |
|
185 |
- unsigned char apex_len; /* apex len w/p the terminating 0 */ |
|
186 |
- unsigned char position; |
|
187 |
- char str_table[1]; /* contains the 2 strings: separator and apex */ |
|
188 |
-}; |
|
189 |
-#define EBL_RDATA_SIZE(s) \ |
|
190 |
- (sizeof(struct ebl_rdata)-1+(s).separator_len+1+(s).apex_len+1) |
|
191 |
- |
|
192 |
- |
|
193 |
-struct ptr_rdata { |
|
194 |
- unsigned char ptrdname_len; /* name length w/o the terminating 0 */ |
|
195 |
- char ptrdname[1]; /* null terminated name (len=name_len+1) */ |
|
196 |
-}; |
|
197 |
-/* real size of the structure */ |
|
198 |
-#define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata)-1+(s).ptrdname_len+1) |
|
199 |
- |
|
200 |
- |
|
201 |
-#ifdef HAVE_RESOLV_RES |
|
202 |
-int match_search_list(const struct __res_state* res, char* name); |
|
203 |
-#endif |
|
204 |
-struct rdata* get_record(char* name, int type, int flags); |
|
205 |
-void free_rdata_list(struct rdata* head); |
|
206 |
- |
|
207 |
- |
|
208 |
- |
|
209 |
-#define rev_resolvehost(ip)\ |
|
210 |
- gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af) |
|
211 |
- |
|
212 |
- |
|
213 |
- |
|
214 |
-#define HEX2I(c) \ |
|
215 |
- ( (((c)>='0') && ((c)<='9'))? (c)-'0' : \ |
|
216 |
- (((c)>='A') && ((c)<='F'))? ((c)-'A')+10 : \ |
|
217 |
- (((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 ) |
|
218 |
- |
|
219 |
- |
|
220 |
- |
|
221 |
- |
|
222 |
- |
|
223 |
-/* converts a str to an ipv4 address, returns the address or 0 on error |
|
224 |
- Warning: the result is a pointer to a statically allocated structure */ |
|
225 |
-static inline struct ip_addr* str2ip(str* st) |
|
226 |
-{ |
|
227 |
- int i; |
|
228 |
- unsigned char *limit; |
|
229 |
- static struct ip_addr ip; |
|
230 |
- unsigned char* s; |
|
231 |
- |
|
232 |
- s=(unsigned char*)st->s; |
|
233 |
- |
|
234 |
- /*init*/ |
|
235 |
- ip.u.addr32[0]=0; |
|
236 |
- i=0; |
|
237 |
- limit=(unsigned char*)(st->s + st->len); |
|
238 |
- |
|
239 |
- for(;s<limit ;s++){ |
|
240 |
- if (*s=='.'){ |
|
241 |
- i++; |
|
242 |
- if (i>3) goto error_dots; |
|
243 |
- }else if ( (*s <= '9' ) && (*s >= '0') ){ |
|
244 |
- ip.u.addr[i]=ip.u.addr[i]*10+*s-'0'; |
|
245 |
- }else{ |
|
246 |
- //error unknown char |
|
247 |
- goto error_char; |
|
248 |
- } |
|
249 |
- } |
|
250 |
- if (i<3) goto error_dots; |
|
251 |
- ip.af=AF_INET; |
|
252 |
- ip.len=4; |
|
253 |
- |
|
254 |
- return &ip; |
|
255 |
-error_dots: |
|
256 |
-#ifdef RESOLVE_DBG |
|
257 |
- DBG("str2ip: ERROR: too %s dots in [%.*s]\n", (i>3)?"many":"few", |
|
258 |
- st->len, st->s); |
|
259 |
-#endif |
|
260 |
- return 0; |
|
261 |
- error_char: |
|
262 |
- /* |
|
263 |
- DBG("str2ip: WARNING: unexpected char %c in [%.*s]\n", *s, st->len, st->s); |
|
264 |
- */ |
|
265 |
- return 0; |
|
266 |
-} |
|
267 |
- |
|
268 |
- |
|
269 |
-/* returns an ip_addr struct.; on error returns 0 |
|
270 |
- * the ip_addr struct is static, so subsequent calls will destroy its content*/ |
|
271 |
-static inline struct ip_addr* str2ip6(str* st) |
|
272 |
-{ |
|
273 |
- int i, idx1, rest; |
|
274 |
- int no_colons; |
|
275 |
- int double_colon; |
|
276 |
- int hex; |
|
277 |
- static struct ip_addr ip; |
|
278 |
- unsigned short* addr_start; |
|
279 |
- unsigned short addr_end[8]; |
|
280 |
- unsigned short* addr; |
|
281 |
- unsigned char* limit; |
|
282 |
- unsigned char* s; |
|
283 |
- |
|
284 |
- /* init */ |
|
285 |
- if ((st->len) && (st->s[0]=='[')){ |
|
286 |
- /* skip over [ ] */ |
|
287 |
- if (st->s[st->len-1]!=']') goto error_char; |
|
288 |
- s=(unsigned char*)(st->s+1); |
|
289 |
- limit=(unsigned char*)(st->s+st->len-1); |
|
290 |
- }else{ |
|
291 |
- s=(unsigned char*)st->s; |
|
292 |
- limit=(unsigned char*)(st->s+st->len); |
|
293 |
- } |
|
294 |
- i=idx1=rest=0; |
|
295 |
- double_colon=0; |
|
296 |
- no_colons=0; |
|
297 |
- ip.af=AF_INET6; |
|
298 |
- ip.len=16; |
|
299 |
- addr_start=ip.u.addr16; |
|
300 |
- addr=addr_start; |
|
301 |
- memset(addr_start, 0 , 8*sizeof(unsigned short)); |
|
302 |
- memset(addr_end, 0 , 8*sizeof(unsigned short)); |
|
303 |
- for (; s<limit; s++){ |
|
304 |
- if (*s==':'){ |
|
305 |
- no_colons++; |
|
306 |
- if (no_colons>7) goto error_too_many_colons; |
|
307 |
- if (double_colon){ |
|
308 |
- idx1=i; |
|
309 |
- i=0; |
|
310 |
- if (addr==addr_end) goto error_colons; |
|
311 |
- addr=addr_end; |
|
312 |
- }else{ |
|
313 |
- double_colon=1; |
|
314 |
- addr[i]=htons(addr[i]); |
|
315 |
- i++; |
|
316 |
- } |
|
317 |
- }else if ((hex=HEX2I(*s))>=0){ |
|
318 |
- addr[i]=addr[i]*16+hex; |
|
319 |
- double_colon=0; |
|
320 |
- }else{ |
|
321 |
- /* error, unknown char */ |
|
322 |
- goto error_char; |
|
323 |
- } |
|
324 |
- } |
|
325 |
- if (!double_colon){ /* not ending in ':' */ |
|
326 |
- addr[i]=htons(addr[i]); |
|
327 |
- i++; |
|
328 |
- } |
|
329 |
- /* if address contained '::' fix it */ |
|
330 |
- if (addr==addr_end){ |
|
331 |
- rest=8-i-idx1; |
|
332 |
- memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short)); |
|
333 |
- }else{ |
|
334 |
- /* no double colons inside */ |
|
335 |
- if (no_colons<7) goto error_too_few_colons; |
|
336 |
- } |
|
337 |
-/* |
|
338 |
- DBG("str2ip6: idx1=%d, rest=%d, no_colons=%d, hex=%x\n", |
|
339 |
- idx1, rest, no_colons, hex); |
|
340 |
- DBG("str2ip6: address %x:%x:%x:%x:%x:%x:%x:%x\n", |
|
341 |
- addr_start[0], addr_start[1], addr_start[2], |
|
342 |
- addr_start[3], addr_start[4], addr_start[5], |
|
343 |
- addr_start[6], addr_start[7] ); |
|
344 |
-*/ |
|
345 |
- return &ip; |
|
346 |
- |
|
347 |
-error_too_many_colons: |
|
348 |
-#ifdef RESOLVE_DBG |
|
349 |
- DBG("str2ip6: ERROR: too many colons in [%.*s]\n", st->len, st->s); |
|
350 |
-#endif |
|
351 |
- return 0; |
|
352 |
- |
|
353 |
-error_too_few_colons: |
|
354 |
-#ifdef RESOLVE_DBG |
|
355 |
- DBG("str2ip6: ERROR: too few colons in [%.*s]\n", st->len, st->s); |
|
356 |
-#endif |
|
357 |
- return 0; |
|
358 |
- |
|
359 |
-error_colons: |
|
360 |
-#ifdef RESOLVE_DBG |
|
361 |
- DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", st->len, st->s); |
|
362 |
-#endif |
|
363 |
- return 0; |
|
364 |
- |
|
365 |
-error_char: |
|
366 |
- /* |
|
367 |
- DBG("str2ip6: WARNING: unexpected char %c in [%.*s]\n", *s, st->len, |
|
368 |
- st->s);*/ |
|
369 |
- return 0; |
|
370 |
-} |
|
371 |
- |
|
372 |
- |
|
373 |
- |
|
374 |
-struct hostent* _sip_resolvehost(str* name, unsigned short* port, char* proto); |
|
375 |
- |
|
376 |
- |
|
377 |
- |
|
378 |
-/* gethostbyname wrapper, handles ip/ipv6 automatically */ |
|
379 |
-static inline struct hostent* _resolvehost(char* name) |
|
380 |
-{ |
|
381 |
- static struct hostent* he=0; |
|
382 |
-#ifdef HAVE_GETIPNODEBYNAME |
|
383 |
- int err; |
|
384 |
- static struct hostent* he2=0; |
|
385 |
-#endif |
|
386 |
-#ifndef DNS_IP_HACK |
|
387 |
- int len; |
|
388 |
-#endif |
|
389 |
-#ifdef DNS_IP_HACK |
|
390 |
- struct ip_addr* ip; |
|
391 |
- str s; |
|
392 |
- |
|
393 |
- s.s = (char*)name; |
|
394 |
- s.len = strlen(name); |
|
395 |
- |
|
396 |
- /* check if it's an ip address */ |
|
397 |
- if ( ((ip=str2ip(&s))!=0) |
|
398 |
- || ((ip=str2ip6(&s))!=0) |
|
399 |
- ){ |
|
400 |
- /* we are lucky, this is an ip address */ |
|
401 |
- return ip_addr2he(&s, ip); |
|
402 |
- } |
|
403 |
- |
|
404 |
-#else /* DNS_IP_HACK */ |
|
405 |
- len=0; |
|
406 |
- if (*name=='['){ |
|
407 |
- len=strlen(name); |
|
408 |
- if (len && (name[len-1]==']')){ |
|
409 |
- name[len-1]=0; /* remove '[' */ |
|
410 |
- name++; /* skip '[' */ |
|
411 |
- goto skip_ipv4; |
|
412 |
- } |
|
413 |
- } |
|
414 |
-#endif |
|
415 |
- /* ipv4 */ |
|
416 |
- he=dns_func.sr_gethostbyname(name); |
|
417 |
- |
|
418 |
- if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
|
419 |
-#ifndef DNS_IP_HACK |
|
420 |
-skip_ipv4: |
|
421 |
-#endif |
|
422 |
- /*try ipv6*/ |
|
423 |
- #ifdef HAVE_GETHOSTBYNAME2 |
|
424 |
- he=dns_func.sr_gethostbyname2(name, AF_INET6); |
|
425 |
- #elif defined HAVE_GETIPNODEBYNAME |
|
426 |
- /* on solaris 8 getipnodebyname has a memory leak, |
|
427 |
- * after some time calls to it will fail with err=3 |
|
428 |
- * solution: patch your solaris 8 installation */ |
|
429 |
- if (he2) freehostent(he2); |
|
430 |
- he=he2=getipnodebyname(name, AF_INET6, 0, &err); |
|
431 |
- #else |
|
432 |
- #error neither gethostbyname2 or getipnodebyname present |
|
433 |
- #endif |
|
434 |
-#ifndef DNS_IP_HACK |
|
435 |
- if (len) name[len-2]=']'; /* restore */ |
|
436 |
-#endif |
|
437 |
- } |
|
438 |
- return he; |
|
439 |
-} |
|
440 |
- |
|
441 |
- |
|
442 |
-int resolv_init(void); |
|
443 |
- |
|
444 |
-/* callback/fixup functions executed by the configuration framework */ |
|
445 |
-void resolv_reinit(str *gname, str *name); |
|
446 |
-int dns_reinit_fixup(void *handle, str *gname, str *name, void **val); |
|
447 |
-int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val); |
|
448 |
-void reinit_proto_prefs(str *gname, str *name); |
|
449 |
- |
|
450 |
-struct dns_srv_proto { |
|
451 |
- char proto; |
|
452 |
- int proto_pref; |
|
453 |
-}; |
|
454 |
-void create_srv_name(char proto, str *name, char *srv); |
|
455 |
-size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list); |
|
456 |
- |
|
457 |
-#ifdef DNS_WATCHDOG_SUPPORT |
|
458 |
-/* callback function that is called by the child processes |
|
459 |
- * when they reinitialize the resolver |
|
460 |
- * |
|
461 |
- * Note, that this callback is called by each chiled process separately!!! |
|
462 |
- * If the callback is registered after forking, only the child process |
|
463 |
- * that installs the hook will call the callback. |
|
464 |
- */ |
|
465 |
-typedef void (*on_resolv_reinit)(str*); |
|
466 |
-int register_resolv_reinit_cb(on_resolv_reinit cb); |
|
467 |
-#endif |
|
468 |
- |
|
469 |
- |
|
470 |
-int sip_hostport2su(union sockaddr_union* su, str* host, unsigned short port, |
|
471 |
- char* proto); |
|
472 |
- |
|
473 |
- |
|
474 |
- |
|
475 |
-/* wrappers */ |
|
476 |
-#ifdef USE_DNS_CACHE |
|
477 |
-#define resolvehost dns_resolvehost |
|
478 |
-#define sip_resolvehost dns_sip_resolvehost |
|
479 |
-#else |
|
480 |
-#define resolvehost _resolvehost |
|
481 |
-#define sip_resolvehost _sip_resolvehost |
|
482 |
-#endif |
|
483 |
- |
|
484 |
- |
|
485 |
- |
|
486 |
-#ifdef USE_NAPTR |
|
487 |
-/* NAPTR helper functions */ |
|
488 |
-typedef unsigned int naptr_bmp_t; /* type used for keeping track of tried |
|
489 |
- naptr records*/ |
|
490 |
-#define MAX_NAPTR_RRS (sizeof(naptr_bmp_t)*8) |
|
491 |
- |
|
492 |
-/* use before first call to naptr_sip_iterate */ |
|
493 |
-#define naptr_iterate_init(bmp) \ |
|
494 |
- do{ \ |
|
495 |
- *(bmp)=0; \ |
|
496 |
- }while(0) \ |
|
497 |
- |
|
498 |
-struct rdata* naptr_sip_iterate(struct rdata* naptr_head, |
|
499 |
- naptr_bmp_t* tried, |
|
500 |
- str* srv_name, char* proto); |
|
501 |
-/* returns sip proto if valis sip naptr record, .-1 otherwise */ |
|
502 |
-char naptr_get_sip_proto(struct naptr_rdata* n); |
|
503 |
-/* returns true if new_proto is preferred over old_proto */ |
|
504 |
-int naptr_proto_preferred(char new_proto, char old_proto); |
|
505 |
-/* returns true if we support the protocol */ |
|
506 |
-int naptr_proto_supported(char proto); |
|
507 |
-/* choose between 2 naptr records, should take into account local |
|
508 |
- * preferences too |
|
509 |
- * returns 1 if the new record was selected, 0 otherwise */ |
|
510 |
-int naptr_choose (struct naptr_rdata** crt, char* crt_proto, |
|
511 |
- struct naptr_rdata* n , char n_proto); |
|
512 |
- |
|
513 |
-#endif/* USE_NAPTR */ |
|
514 |
- |
|
515 |
-struct hostent* no_naptr_srv_sip_resolvehost(str* name, unsigned short* port, |
|
516 |
- char* proto); |
|
517 |
- |
|
518 |
-#endif |
... | ... |
@@ -1,23 +1,16 @@ |
1 | 1 |
/* |
2 |
- * $Id$ |
|
3 |
- * |
|
4 | 2 |
* resolver related functions |
5 | 3 |
* |
6 | 4 |
* Copyright (C) 2001-2003 FhG Fokus |
7 | 5 |
* |
8 |
- * This file is part of ser, a free SIP server. |
|
6 |
+ * This file is part of Kamailio, a free SIP server. |
|
9 | 7 |
* |
10 |
- * ser is free software; you can redistribute it and/or modify |
|
8 |
+ * Kamailio is free software; you can redistribute it and/or modify |
|
11 | 9 |
* it under the terms of the GNU General Public License as published by |
12 | 10 |
* the Free Software Foundation; either version 2 of the License, or |
13 | 11 |
* (at your option) any later version |
14 | 12 |
* |
15 |
- * For a license to use the ser software under conditions |
|
16 |
- * other than those described here, or to purchase support for this |
|
17 |
- * software, please contact iptel.org by e-mail at the following addresses: |
|
18 |
- * info@iptel.org |
|
19 |
- * |
|
20 |
- * ser is distributed in the hope that it will be useful, |
|
13 |
+ * Kamailio is distributed in the hope that it will be useful, |
|
21 | 14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | 15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | 16 |
* GNU General Public License for more details. |
... | ... |
@@ -26,17 +19,14 @@ |
26 | 19 |
* along with this program; if not, write to the Free Software |
27 | 20 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
28 | 21 |
*/ |
29 |
-/* History: |
|
30 |
- * -------- |
|
31 |
- * 2003-04-12 support for resolving ipv6 address references added (andrei) |
|
32 |
- * 2004-07-28 darwin needs nameser_compat.h (andrei) |
|
33 |
- * 2006-07-13 rdata structures put on diet (andrei) |
|
34 |
- * 2006-07-17 rdata contains now also the record name (andrei) |
|
35 |
- * 2006-08-18 get_record uses flags (andrei) |
|
36 |
- * 2006-06-16 naptr support (andrei) |
|
37 |
- */ |
|
38 |
- |
|
39 | 22 |
|
23 |
+/*! |
|
24 |
+ * \file |
|
25 |
+ * \brief Kamailio core :: DNS resolver |
|
26 |
+ * \author andrei |
|
27 |
+ * \ingroup core |
|
28 |
+ * Module: \ref core |
|
29 |
+ */ |
|
40 | 30 |
|
41 | 31 |
#ifndef __resolve_h |
42 | 32 |
#define __resolve_h |
... | ... |
@@ -24,7 +24,7 @@ |
24 | 24 |
* |
25 | 25 |
* You should have received a copy of the GNU General Public License |
26 | 26 |
* along with this program; if not, write to the Free Software |
27 |
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
27 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
28 | 28 |
*/ |
29 | 29 |
/* History: |
30 | 30 |
* -------- |
- the beaviour is controlled by core parameter dns_naptr_ignore_rfc
- default is 1, preserving current behaviouf to ignore rfc requirements
(for backward compatibility)
... | ... |
@@ -455,7 +455,7 @@ int resolv_init(void); |
455 | 455 |
void resolv_reinit(str *gname, str *name); |
456 | 456 |
int dns_reinit_fixup(void *handle, str *gname, str *name, void **val); |
457 | 457 |
int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val); |
458 |
-void reinit_naptr_proto_prefs(str *gname, str *name); |
|
458 |
+void reinit_proto_prefs(str *gname, str *name); |
|
459 | 459 |
|
460 | 460 |
struct dns_srv_proto { |
461 | 461 |
char proto; |
- refactored code for srv lookup to have less code duplication
... | ... |
@@ -457,6 +457,13 @@ int dns_reinit_fixup(void *handle, str *gname, str *name, void **val); |
457 | 457 |
int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val); |
458 | 458 |
void reinit_naptr_proto_prefs(str *gname, str *name); |
459 | 459 |
|
460 |
+struct dns_srv_proto { |
|
461 |
+ char proto; |
|
462 |
+ int proto_pref; |
|
463 |
+}; |
|
464 |
+void create_srv_name(char proto, str *name, char *srv); |
|
465 |
+size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list); |
|
466 |
+ |
|
460 | 467 |
#ifdef DNS_WATCHDOG_SUPPORT |
461 | 468 |
/* callback function that is called by the child processes |
462 | 469 |
* when they reinitialize the resolver |
* Make IPv6 the default in the core and affected modules
* it has been default switched on since a long time, and was introduced in 2002
* even on embedded systems one probably want now proper IPv6 support
* there was an issue in cygwin in 2008, but IPv6 is there also available since v1.7
* remove over 160 #ifdefs, cleanup the code a lot and removes many of rarely
tested alternative code paths to ease support of the codebase
* note for gentoo maintainer: please review your packages, they will maybe not
work now correctly anymore if somebody specified -ipv6 in the use flags
... | ... |
@@ -276,7 +276,6 @@ error_dots: |
276 | 276 |
} |
277 | 277 |
|
278 | 278 |
|
279 |
-#ifdef USE_IPV6 |
|
280 | 279 |
/* returns an ip_addr struct.; on error returns 0 |
281 | 280 |
* the ip_addr struct is static, so subsequent calls will destroy its content*/ |
282 | 281 |
static inline struct ip_addr* str2ip6(str* st) |
... | ... |
@@ -379,7 +378,6 @@ error_char: |
379 | 378 |
st->s);*/ |
380 | 379 |
return 0; |
381 | 380 |
} |
382 |
-#endif /* USE_IPV6 */ |
|
383 | 381 |
|
384 | 382 |
|
385 | 383 |
|
... | ... |
@@ -392,16 +390,12 @@ static inline struct hostent* _resolvehost(char* name) |
392 | 390 |
{ |
393 | 391 |
static struct hostent* he=0; |
394 | 392 |
#ifdef HAVE_GETIPNODEBYNAME |
395 |
-#ifdef USE_IPV6 |
|
396 | 393 |
int err; |
397 | 394 |
static struct hostent* he2=0; |
398 | 395 |
#endif |
399 |
-#endif |
|
400 | 396 |
#ifndef DNS_IP_HACK |
401 |
-#ifdef USE_IPV6 |
|
402 | 397 |
int len; |
403 | 398 |
#endif |
404 |
-#endif |
|
405 | 399 |
#ifdef DNS_IP_HACK |
406 | 400 |
struct ip_addr* ip; |
407 | 401 |
str s; |
... | ... |
@@ -411,16 +405,13 @@ static inline struct hostent* _resolvehost(char* name) |
411 | 405 |
|
412 | 406 |
/* check if it's an ip address */ |
413 | 407 |
if ( ((ip=str2ip(&s))!=0) |
414 |
-#ifdef USE_IPV6 |
|
415 | 408 |
|| ((ip=str2ip6(&s))!=0) |
416 |
-#endif |
|
417 | 409 |
){ |
418 | 410 |
/* we are lucky, this is an ip address */ |
419 | 411 |
return ip_addr2he(&s, ip); |
420 | 412 |
} |
421 | 413 |
|
422 | 414 |
#else /* DNS_IP_HACK */ |
423 |
-#ifdef USE_IPV6 |
|
424 | 415 |
len=0; |
425 | 416 |
if (*name=='['){ |
426 | 417 |
len=strlen(name); |
... | ... |
@@ -430,12 +421,10 @@ static inline struct hostent* _resolvehost(char* name) |
430 | 421 |
goto skip_ipv4; |
431 | 422 |
} |
432 | 423 |
} |
433 |
-#endif |
|
434 | 424 |
#endif |
435 | 425 |
/* ipv4 */ |
436 | 426 |
he=dns_func.sr_gethostbyname(name); |
437 | 427 |
|
438 |
-#ifdef USE_IPV6 |
|
439 | 428 |
if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
440 | 429 |
#ifndef DNS_IP_HACK |
441 | 430 |
skip_ipv4: |
... | ... |
@@ -456,7 +445,6 @@ skip_ipv4: |
456 | 445 |
if (len) name[len-2]=']'; /* restore */ |
457 | 446 |
#endif |
458 | 447 |
} |
459 |
-#endif |
|
460 | 448 |
return he; |
461 | 449 |
} |
462 | 450 |
|
The library functions can now be easily overwritten by modules(dnssec) to allow enhanced resolving capabilities
... | ... |
@@ -48,6 +48,7 @@ |
48 | 48 |
#include <arpa/nameser.h> |
49 | 49 |
#include <resolv.h> |
50 | 50 |
#include "counters.h" |
51 |
+#include "dns_func.h" |
|
51 | 52 |
|
52 | 53 |
#ifdef __OS_darwin |
53 | 54 |
#include <arpa/nameser_compat.h> |
... | ... |
@@ -58,9 +59,6 @@ |
58 | 59 |
#include "dns_wrappers.h" |
59 | 60 |
#endif |
60 | 61 |
|
61 |
-#ifdef USE_DNSSEC |
|
62 |
-#include <validator/validator.h> |
|
63 |
-#endif |
|
64 | 62 |
|
65 | 63 |
/* define RESOLVE_DBG for debugging info (very noisy) */ |
66 | 64 |
#define RESOLVE_DBG |
... | ... |
@@ -90,6 +88,7 @@ struct dns_counters_h { |
90 | 88 |
}; |
91 | 89 |
|
92 | 90 |
extern struct dns_counters_h dns_cnts_h; |
91 |
+extern struct dns_func_t dns_func; |
|
93 | 92 |
|
94 | 93 |
/* query union*/ |
95 | 94 |
union dns_query{ |
... | ... |
@@ -404,9 +403,6 @@ static inline struct hostent* _resolvehost(char* name) |
404 | 403 |
#endif |
405 | 404 |
#endif |
406 | 405 |
#ifdef DNS_IP_HACK |
407 |
-#ifdef USE_DNSSEC |
|
408 |
- val_status_t val_status; |
|
409 |
-#endif |
|
410 | 406 |
struct ip_addr* ip; |
411 | 407 |
str s; |
412 | 408 |
|
... | ... |
@@ -437,14 +433,7 @@ static inline struct hostent* _resolvehost(char* name) |
437 | 433 |
#endif |
438 | 434 |
#endif |
439 | 435 |
/* ipv4 */ |
440 |
-#ifndef USE_DNSSEC |
|
441 |
- he=gethostbyname(name); |
|
442 |
-#else |
|
443 |
- he=val_gethostbyname( (val_context_t *) 0, name, &val_status); |
|
444 |
- if(!val_istrusted(val_status)){ |
|
445 |
- LOG(L_INFO, "INFO: got not trusted record when resolving %s\n",name); |
|
446 |
- } |
|
447 |
-#endif |
|
436 |
+ he=dns_func.sr_gethostbyname(name); |
|
448 | 437 |
|
449 | 438 |
#ifdef USE_IPV6 |
450 | 439 |
if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
... | ... |
@@ -453,14 +442,7 @@ skip_ipv4: |
453 | 442 |
#endif |
454 | 443 |
/*try ipv6*/ |
455 | 444 |
#ifdef HAVE_GETHOSTBYNAME2 |
456 |
- #ifndef USE_DNSSEC |
|
457 |
- he=gethostbyname2(name, AF_INET6); |
|
458 |
- #else |
|
459 |
- he=val_gethostbyname2((val_context_t*)0, name, AF_INET6, &val_status); |
|
460 |
- if(!val_istrusted(val_status)){ |
|
461 |
- LOG(L_INFO, "INFO: got not trusted record when resolving %s\n",name); |
|
462 |
- } |
|
463 |
- #endif //!USE_DNSSEC |
|
445 |
+ he=dns_func.sr_gethostbyname2(name, AF_INET6); |
|
464 | 446 |
#elif defined HAVE_GETIPNODEBYNAME |
465 | 447 |
/* on solaris 8 getipnodebyname has a memory leak, |
466 | 448 |
* after some time calls to it will fail with err=3 |
- fix compile warning, reported by Ovidiu Sas
This is available by setting the USE_DNSSEC compile flag. It requires libval-threads and libres (part of dnssec-tools dnssec-tools.org)
The custom resolvers were replaced by val_gethostbyname, val_gethostbyname and val_res_query (for SRV).
... | ... |
@@ -58,6 +58,10 @@ |
58 | 58 |
#include "dns_wrappers.h" |
59 | 59 |
#endif |
60 | 60 |
|
61 |
+#ifdef USE_DNSSEC |
|
62 |
+#include "validator/validator.h" |
|
63 |
+#endif |
|
64 |
+ |
|
61 | 65 |
/* define RESOLVE_DBG for debugging info (very noisy) */ |
62 | 66 |
#define RESOLVE_DBG |
63 | 67 |
/* define NAPTR_DBG for naptr related debugging info (very noisy) */ |
... | ... |
@@ -400,6 +404,9 @@ static inline struct hostent* _resolvehost(char* name) |
400 | 404 |
#endif |
401 | 405 |
#endif |
402 | 406 |
#ifdef DNS_IP_HACK |
407 |
+#ifdef USE_DNSSEC |
|
408 |
+ val_status_t val_status; |
|
409 |
+#endif |
|
403 | 410 |
struct ip_addr* ip; |
404 | 411 |
str s; |
405 | 412 |
|
... | ... |
@@ -430,7 +437,15 @@ static inline struct hostent* _resolvehost(char* name) |
430 | 437 |
#endif |
431 | 438 |
#endif |
432 | 439 |
/* ipv4 */ |
440 |
+#ifndef USE_DNSSEC |
|
433 | 441 |
he=gethostbyname(name); |
442 |
+#else |
|
443 |
+ he=val_gethostbyname( (val_context_t *) 0, name, &val_status); |
|
444 |
+ if(!val_istrusted(val_status)){ |
|
445 |
+ LOG(L_INFO, "INFO: got not trusted record when resolving %s\n",name); |
|
446 |
+ } |
|
447 |
+#endif |
|
448 |
+ |
|
434 | 449 |
#ifdef USE_IPV6 |
435 | 450 |
if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
436 | 451 |
#ifndef DNS_IP_HACK |
... | ... |
@@ -438,7 +453,14 @@ skip_ipv4: |
438 | 453 |
#endif |
439 | 454 |
/*try ipv6*/ |
440 | 455 |
#ifdef HAVE_GETHOSTBYNAME2 |
456 |
+ #ifndef USE_DNSSEC |
|
441 | 457 |
he=gethostbyname2(name, AF_INET6); |
458 |
+ #else |
|
459 |
+ he=val_gethostbyname2((val_context_t*)0, name, AF_INET6, &val_status); |
|
460 |
+ if(!val_istrusted(val_status)){ |
|
461 |
+ LOG(L_INFO, "INFO: got not trusted record when resolving %s\n",name); |
|
462 |
+ } |
|
463 |
+ #endif //!USE_DNSSEC |
|
442 | 464 |
#elif defined HAVE_GETIPNODEBYNAME |
443 | 465 |
/* on solaris 8 getipnodebyname has a memory leak, |
444 | 466 |
* after some time calls to it will fail with err=3 |
This reverts commit e1b3961b16b76b02ae7ad5f52b2e9db126f81ff9.
... | ... |
@@ -429,10 +429,8 @@ static inline struct hostent* _resolvehost(char* name) |
429 | 429 |
} |
430 | 430 |
#endif |
431 | 431 |
#endif |
432 |
- if (socket_types & SOCKET_T_IPV4) { |
|
433 |
- /* ipv4 */ |
|
434 |
- he=gethostbyname(name); |
|
435 |
- } |
|
432 |
+ /* ipv4 */ |
|
433 |
+ he=gethostbyname(name); |
|
436 | 434 |
#ifdef USE_IPV6 |
437 | 435 |
if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
438 | 436 |
#ifndef DNS_IP_HACK |
... | ... |
@@ -429,8 +429,10 @@ static inline struct hostent* _resolvehost(char* name) |
429 | 429 |
} |
430 | 430 |
#endif |
431 | 431 |
#endif |
432 |
- /* ipv4 */ |
|
433 |
- he=gethostbyname(name); |
|
432 |
+ if (socket_types & SOCKET_T_IPV4) { |
|
433 |
+ /* ipv4 */ |
|
434 |
+ he=gethostbyname(name); |
|
435 |
+ } |
|
434 | 436 |
#ifdef USE_IPV6 |
435 | 437 |
if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){ |
436 | 438 |
#ifndef DNS_IP_HACK |
In C language, a declaration in the form int f(); is equivalent to int f(...);, thus being able to accept an indefinit number of parameters. With the -Wstrict-prototypes GCC options, these declarations are reported as "function declaration isn’t a prototype".
On some cases, this may trick the compiler into generating unoptimized code (like preparing to handle variadic argument list).
In all cases having a declaration int f() and a definition inf f(int) is missleading, even if standard compliant.
This is still Work in Progress. (maybe adding the -Wstrict-prototypes option to default is desireable)
DNS statistics can be seen with:
sercmd> cnt.get dns failed_dns_request
Still TODO: failed statistics for DNS cache
... | ... |
@@ -47,6 +47,7 @@ |
47 | 47 |
#include <netdb.h> |
48 | 48 |
#include <arpa/nameser.h> |
49 | 49 |
#include <resolv.h> |
50 |
+#include "counters.h" |
|
50 | 51 |
|
51 | 52 |
#ifdef __OS_darwin |
52 | 53 |
#include <arpa/nameser_compat.h> |
... | ... |
@@ -78,6 +79,14 @@ |
78 | 79 |
#define RES_ONLY_TYPE 1 /* return only the specified type records */ |
79 | 80 |
#define RES_AR 2 /* return also the additional records */ |
80 | 81 |
|
82 |
+/* counter for failed DNS requests |
|
83 |
+*/ |
|
84 |
+struct dns_counters_h { |
|
85 |
+ counter_handle_t failed_dns_req; |
|
86 |
+}; |
|
87 |
+ |
|
88 |
+extern struct dns_counters_h dns_cnts_h; |
|
89 |
+ |
|
81 | 90 |
/* query union*/ |
82 | 91 |
union dns_query{ |
83 | 92 |
HEADER hdr; |
- PTR resolve support
- PTR dns cache support
- rpc dns.delete_ptr
(e.g. sercmd dns.delete_ptr 56.1.10.10.in-addr.arpa)
... | ... |
@@ -188,6 +188,14 @@ struct ebl_rdata { |
188 | 188 |
(sizeof(struct ebl_rdata)-1+(s).separator_len+1+(s).apex_len+1) |
189 | 189 |
|
190 | 190 |
|
191 |
+struct ptr_rdata { |
|
192 |
+ unsigned char ptrdname_len; /* name length w/o the terminating 0 */ |
|
193 |
+ char ptrdname[1]; /* null terminated name (len=name_len+1) */ |
|
194 |
+}; |
|
195 |
+/* real size of the structure */ |
|
196 |
+#define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata)-1+(s).ptrdname_len+1) |
|
197 |
+ |
|
198 |
+ |
|
191 | 199 |
#ifdef HAVE_RESOLV_RES |
192 | 200 |
int match_search_list(const struct __res_state* res, char* name); |
193 | 201 |
#endif |
- support for EBL records
- dns cache support for EBLs
- dns.delete_ebl rpc added