00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef __resolve_h
00042 #define __resolve_h
00043
00044 #include <sys/types.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <netdb.h>
00048 #include <arpa/nameser.h>
00049 #include <resolv.h>
00050 #include "counters.h"
00051
00052 #ifdef __OS_darwin
00053 #include <arpa/nameser_compat.h>
00054 #endif
00055
00056 #include "ip_addr.h"
00057 #ifdef USE_DNS_CACHE
00058 #include "dns_wrappers.h"
00059 #endif
00060
00061
00062 #define RESOLVE_DBG
00063
00064 #define NAPTR_DBG
00065
00066
00067 #define MAX_QUERY_SIZE 8192
00068 #define ANS_SIZE 8192
00069 #define DNS_HDR_SIZE 12
00070 #define MAX_DNS_NAME 256
00071 #define MAX_DNS_STRING 255
00072
00073 #ifndef T_EBL
00074
00075 #define T_EBL 65300
00076 #endif
00077
00078
00079 #define RES_ONLY_TYPE 1
00080 #define RES_AR 2
00081
00082
00083
00084 struct dns_counters_h {
00085 counter_handle_t failed_dns_req;
00086 };
00087
00088 extern struct dns_counters_h dns_cnts_h;
00089
00090
00091 union dns_query{
00092 HEADER hdr;
00093 unsigned char buff[MAX_QUERY_SIZE];
00094 };
00095
00096
00097
00098 struct rdata {
00099 unsigned short type;
00100 unsigned short pclass;
00101 unsigned int ttl;
00102 void* rdata;
00103 struct rdata* next;
00104 unsigned char name_len;
00105 char name[1];
00106 };
00107
00108 #define RDATA_SIZE(s) (sizeof(struct rdata)+(s).name_len)
00109
00110
00111
00112 struct srv_rdata {
00113 unsigned short priority;
00114 unsigned short weight;
00115 unsigned short port;
00116 unsigned char name_len;
00117 char name[1];
00118 };
00119
00120
00121
00122 #define SRV_RDATA_SIZE(s) (sizeof(struct srv_rdata)+(s).name_len)
00123
00124
00125 struct naptr_rdata {
00126 char* flags;
00127 char* services;
00128 char* regexp;
00129 char* repl;
00130
00131 unsigned short order;
00132 unsigned short pref;
00133
00134 unsigned char flags_len;
00135 unsigned char services_len;
00136 unsigned char regexp_len;
00137 unsigned char repl_len;
00138
00139 char str_table[1];
00140 };
00141
00142
00143 #define NAPTR_RDATA_SIZE(s) (sizeof(struct naptr_rdata) \
00144 + (s).flags_len \
00145 + (s).services_len \
00146 + (s).regexp_len \
00147 + (s).repl_len + 1 - 1)
00148
00149
00150
00151 struct a_rdata {
00152 unsigned char ip[4];
00153 };
00154
00155 struct aaaa_rdata {
00156 unsigned char ip6[16];
00157 };
00158
00159
00160 struct cname_rdata {
00161 unsigned char name_len;
00162 char name[1];
00163 };
00164
00165
00166 #define CNAME_RDATA_SIZE(s) (sizeof(struct cname_rdata)+(s).name_len)
00167
00168
00169 struct dns_cstr{
00170 char* cstr;
00171 unsigned char cstr_len;
00172 };
00173
00174
00175 struct txt_rdata {
00176 unsigned short cstr_no;
00177 unsigned short tslen;
00178 struct dns_cstr txt[1];
00179
00180 };
00181
00182 #define TXT_RDATA_SIZE(s) \
00183 (sizeof(struct txt_rdata)+((s).cstr_no-1)*sizeof(struct dns_cstr)+\
00184 (s).tslen)
00185
00186
00187
00188 struct ebl_rdata {
00189 char* separator;
00190 char* apex;
00191 unsigned char separator_len;
00192 unsigned char apex_len;
00193 unsigned char position;
00194 char str_table[1];
00195 };
00196 #define EBL_RDATA_SIZE(s) \
00197 (sizeof(struct ebl_rdata)-1+(s).separator_len+1+(s).apex_len+1)
00198
00199
00200 struct ptr_rdata {
00201 unsigned char ptrdname_len;
00202 char ptrdname[1];
00203 };
00204
00205 #define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata)-1+(s).ptrdname_len+1)
00206
00207
00208 #ifdef HAVE_RESOLV_RES
00209 int match_search_list(const struct __res_state* res, char* name);
00210 #endif
00211 struct rdata* get_record(char* name, int type, int flags);
00212 void free_rdata_list(struct rdata* head);
00213
00214
00215
00216 #define rev_resolvehost(ip)\
00217 gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af)
00218
00219
00220
00221 #define HEX2I(c) \
00222 ( (((c)>='0') && ((c)<='9'))? (c)-'0' : \
00223 (((c)>='A') && ((c)<='F'))? ((c)-'A')+10 : \
00224 (((c)>='a') && ((c)<='f'))? ((c)-'a')+10 : -1 )
00225
00226
00227
00228
00229
00230
00231
00232 static inline struct ip_addr* str2ip(str* st)
00233 {
00234 int i;
00235 unsigned char *limit;
00236 static struct ip_addr ip;
00237 unsigned char* s;
00238
00239 s=(unsigned char*)st->s;
00240
00241
00242 ip.u.addr32[0]=0;
00243 i=0;
00244 limit=(unsigned char*)(st->s + st->len);
00245
00246 for(;s<limit ;s++){
00247 if (*s=='.'){
00248 i++;
00249 if (i>3) goto error_dots;
00250 }else if ( (*s <= '9' ) && (*s >= '0') ){
00251 ip.u.addr[i]=ip.u.addr[i]*10+*s-'0';
00252 }else{
00253
00254 goto error_char;
00255 }
00256 }
00257 if (i<3) goto error_dots;
00258 ip.af=AF_INET;
00259 ip.len=4;
00260
00261 return &ip;
00262 error_dots:
00263 #ifdef RESOLVE_DBG
00264 DBG("str2ip: ERROR: too %s dots in [%.*s]\n", (i>3)?"many":"few",
00265 st->len, st->s);
00266 #endif
00267 return 0;
00268 error_char:
00269
00270
00271
00272 return 0;
00273 }
00274
00275
00276 #ifdef USE_IPV6
00277
00278
00279 static inline struct ip_addr* str2ip6(str* st)
00280 {
00281 int i, idx1, rest;
00282 int no_colons;
00283 int double_colon;
00284 int hex;
00285 static struct ip_addr ip;
00286 unsigned short* addr_start;
00287 unsigned short addr_end[8];
00288 unsigned short* addr;
00289 unsigned char* limit;
00290 unsigned char* s;
00291
00292
00293 if ((st->len) && (st->s[0]=='[')){
00294
00295 if (st->s[st->len-1]!=']') goto error_char;
00296 s=(unsigned char*)(st->s+1);
00297 limit=(unsigned char*)(st->s+st->len-1);
00298 }else{
00299 s=(unsigned char*)st->s;
00300 limit=(unsigned char*)(st->s+st->len);
00301 }
00302 i=idx1=rest=0;
00303 double_colon=0;
00304 no_colons=0;
00305 ip.af=AF_INET6;
00306 ip.len=16;
00307 addr_start=ip.u.addr16;
00308 addr=addr_start;
00309 memset(addr_start, 0 , 8*sizeof(unsigned short));
00310 memset(addr_end, 0 , 8*sizeof(unsigned short));
00311 for (; s<limit; s++){
00312 if (*s==':'){
00313 no_colons++;
00314 if (no_colons>7) goto error_too_many_colons;
00315 if (double_colon){
00316 idx1=i;
00317 i=0;
00318 if (addr==addr_end) goto error_colons;
00319 addr=addr_end;
00320 }else{
00321 double_colon=1;
00322 addr[i]=htons(addr[i]);
00323 i++;
00324 }
00325 }else if ((hex=HEX2I(*s))>=0){
00326 addr[i]=addr[i]*16+hex;
00327 double_colon=0;
00328 }else{
00329
00330 goto error_char;
00331 }
00332 }
00333 if (!double_colon){
00334 addr[i]=htons(addr[i]);
00335 i++;
00336 }
00337
00338 if (addr==addr_end){
00339 rest=8-i-idx1;
00340 memcpy(addr_start+idx1+rest, addr_end, i*sizeof(unsigned short));
00341 }else{
00342
00343 if (no_colons<7) goto error_too_few_colons;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353 return &ip;
00354
00355 error_too_many_colons:
00356 #ifdef RESOLVE_DBG
00357 DBG("str2ip6: ERROR: too many colons in [%.*s]\n", st->len, st->s);
00358 #endif
00359 return 0;
00360
00361 error_too_few_colons:
00362 #ifdef RESOLVE_DBG
00363 DBG("str2ip6: ERROR: too few colons in [%.*s]\n", st->len, st->s);
00364 #endif
00365 return 0;
00366
00367 error_colons:
00368 #ifdef RESOLVE_DBG
00369 DBG("str2ip6: ERROR: too many double colons in [%.*s]\n", st->len, st->s);
00370 #endif
00371 return 0;
00372
00373 error_char:
00374
00375
00376
00377 return 0;
00378 }
00379 #endif
00380
00381
00382
00383 struct hostent* _sip_resolvehost(str* name, unsigned short* port, char* proto);
00384
00385
00386
00387
00388 static inline struct hostent* _resolvehost(char* name)
00389 {
00390 static struct hostent* he=0;
00391 #ifdef HAVE_GETIPNODEBYNAME
00392 #ifdef USE_IPV6
00393 int err;
00394 static struct hostent* he2=0;
00395 #endif
00396 #endif
00397 #ifndef DNS_IP_HACK
00398 #ifdef USE_IPV6
00399 int len;
00400 #endif
00401 #endif
00402 #ifdef DNS_IP_HACK
00403 struct ip_addr* ip;
00404 str s;
00405
00406 s.s = (char*)name;
00407 s.len = strlen(name);
00408
00409
00410 if ( ((ip=str2ip(&s))!=0)
00411 #ifdef USE_IPV6
00412 || ((ip=str2ip6(&s))!=0)
00413 #endif
00414 ){
00415
00416 return ip_addr2he(&s, ip);
00417 }
00418
00419 #else
00420 #ifdef USE_IPV6
00421 len=0;
00422 if (*name=='['){
00423 len=strlen(name);
00424 if (len && (name[len-1]==']')){
00425 name[len-1]=0;
00426 name++;
00427 goto skip_ipv4;
00428 }
00429 }
00430 #endif
00431 #endif
00432
00433 he=gethostbyname(name);
00434 #ifdef USE_IPV6
00435 if(he==0 && cfg_get(core, core_cfg, dns_try_ipv6)){
00436 #ifndef DNS_IP_HACK
00437 skip_ipv4:
00438 #endif
00439
00440 #ifdef HAVE_GETHOSTBYNAME2
00441 he=gethostbyname2(name, AF_INET6);
00442 #elif defined HAVE_GETIPNODEBYNAME
00443
00444
00445
00446 if (he2) freehostent(he2);
00447 he=he2=getipnodebyname(name, AF_INET6, 0, &err);
00448 #else
00449 #error neither gethostbyname2 or getipnodebyname present
00450 #endif
00451 #ifndef DNS_IP_HACK
00452 if (len) name[len-2]=']';
00453 #endif
00454 }
00455 #endif
00456 return he;
00457 }
00458
00459
00460 int resolv_init(void);
00461
00462
00463 void resolv_reinit(str *gname, str *name);
00464 int dns_reinit_fixup(void *handle, str *gname, str *name, void **val);
00465 int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val);
00466 void reinit_naptr_proto_prefs(str *gname, str *name);
00467
00468 #ifdef DNS_WATCHDOG_SUPPORT
00469
00470
00471
00472
00473
00474
00475
00476 typedef void (*on_resolv_reinit)(str*);
00477 int register_resolv_reinit_cb(on_resolv_reinit cb);
00478 #endif
00479
00480
00481 int sip_hostport2su(union sockaddr_union* su, str* host, unsigned short port,
00482 char* proto);
00483
00484
00485
00486
00487 #ifdef USE_DNS_CACHE
00488 #define resolvehost dns_resolvehost
00489 #define sip_resolvehost dns_sip_resolvehost
00490 #else
00491 #define resolvehost _resolvehost
00492 #define sip_resolvehost _sip_resolvehost
00493 #endif
00494
00495
00496
00497 #ifdef USE_NAPTR
00498
00499 typedef unsigned int naptr_bmp_t;
00500
00501 #define MAX_NAPTR_RRS (sizeof(naptr_bmp_t)*8)
00502
00503
00504 #define naptr_iterate_init(bmp) \
00505 do{ \
00506 *(bmp)=0; \
00507 }while(0) \
00508
00509 struct rdata* naptr_sip_iterate(struct rdata* naptr_head,
00510 naptr_bmp_t* tried,
00511 str* srv_name, char* proto);
00512
00513 char naptr_get_sip_proto(struct naptr_rdata* n);
00514
00515 int naptr_proto_preferred(char new_proto, char old_proto);
00516
00517 int naptr_proto_supported(char proto);
00518
00519
00520
00521 int naptr_choose (struct naptr_rdata** crt, char* crt_proto,
00522 struct naptr_rdata* n , char n_proto);
00523
00524 #endif
00525
00526 #endif