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 #include <sys/types.h>
00037 #include <netinet/in.h>
00038 #include <arpa/nameser.h>
00039 #include <resolv.h>
00040 #include <string.h>
00041 #include <stdlib.h>
00042
00043 #include "mem/mem.h"
00044 #include "mem/shm_mem.h"
00045 #include "resolve.h"
00046 #include "dprint.h"
00047 #include "ut.h"
00048 #include "ip_addr.h"
00049 #include "globals.h"
00050 #include "blacklists.h"
00051
00052
00053
00054 #define DNS_NODE_SRV 1
00055 #define DNS_NODE_A 2
00056
00057 struct dns_val {
00058 unsigned int ival;
00059 char *sval;
00060 };
00061
00062
00063 #define local_malloc pkg_malloc
00064 #define local_free pkg_free
00065
00066 int dns_try_ipv6=0;
00067
00068 int dns_retr_time=-1;
00069 int dns_retr_no=-1;
00070 int dns_servers_no=-1;
00071 int dns_search_list=-1;
00072 int disable_dns_blacklist=1;
00073
00074 static struct bl_head *failover_bl=0;
00075 #define DNS_REVOLVER_BL_ID 17
00076 #define DNS_REVOLVER_BL_NAME "dns"
00077 #define DNS_BL_EXPIRE 4*60
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 int resolv_init(void)
00094 {
00095 res_init();
00096 #ifdef HAVE_RESOLV_RES
00097 if (dns_retr_time>0)
00098 _res.retrans=dns_retr_time;
00099 if (dns_retr_no>0)
00100 _res.retry=dns_retr_no;
00101 if (dns_servers_no>=0)
00102 _res.nscount=dns_servers_no;
00103 if (dns_search_list==0)
00104 _res.options&=~(RES_DEFNAMES|RES_DNSRCH);
00105 #else
00106 #warning "no resolv timeout support"
00107 LM_WARN("no resolv options support - resolv options will be ignored\n");
00108 #endif
00109 return 0;
00110 }
00111
00112
00113
00114
00115 int resolv_blacklist_init(void)
00116 {
00117 str name = str_init(DNS_REVOLVER_BL_NAME);
00118
00119 if (!disable_dns_blacklist) {
00120 failover_bl = create_bl_head( DNS_REVOLVER_BL_ID,
00121 BL_DO_EXPIRE|BL_BY_DEFAULT, 0, 0, &name);
00122 if (failover_bl==NULL) {
00123 LM_ERR("failed to create blacklist\n");
00124 return -1;
00125 }
00126 }
00127 return 0;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136 unsigned char* dns_skipname(unsigned char* p, unsigned char* end)
00137 {
00138 while(p<end) {
00139
00140 if (*p==0){
00141 p+=1;
00142 break;
00143 }
00144
00145 if (((*p)&0xc0)==0xc0){
00146
00147 p+=2;
00148 break;
00149 }
00150
00151 p+=*p+1;
00152 }
00153 return (p>=end)?0:p;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
00180 unsigned char* rdata)
00181 {
00182 struct srv_rdata* srv;
00183 int len;
00184
00185 srv=0;
00186 if ((rdata+6)>=end) goto error;
00187 srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata));
00188 if (srv==0){
00189 LM_ERR("out of pkg memory\n");
00190 goto error;
00191 }
00192
00193 memcpy((void*)&srv->priority, rdata, 2);
00194 memcpy((void*)&srv->weight, rdata+2, 2);
00195 memcpy((void*)&srv->port, rdata+4, 2);
00196 rdata+=6;
00197 srv->priority=ntohs(srv->priority);
00198 srv->weight=ntohs(srv->weight);
00199 srv->port=ntohs(srv->port);
00200 if ((len=dn_expand(msg, end, rdata, srv->name, MAX_DNS_NAME-1))==-1)
00201 goto error;
00202
00203 return srv;
00204 error:
00205 if (srv) local_free(srv);
00206 return 0;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
00238 unsigned char* rdata)
00239 {
00240 struct naptr_rdata* naptr;
00241
00242 naptr = 0;
00243 if ((rdata + 7) >= end)
00244 goto error;
00245 naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata));
00246 if (naptr == 0){
00247 LM_ERR("out of pkg memory\n");
00248 goto error;
00249 }
00250
00251 memcpy((void*)&naptr->order, rdata, 2);
00252 naptr->order=ntohs(naptr->order);
00253 memcpy((void*)&naptr->pref, rdata + 2, 2);
00254 naptr->pref=ntohs(naptr->pref);
00255 naptr->flags_len = (int)rdata[4];
00256 if ((rdata + 7 + naptr->flags_len) >= end)
00257 goto error;
00258 memcpy((void*)&naptr->flags, rdata + 5, naptr->flags_len);
00259 naptr->services_len = (int)rdata[5 + naptr->flags_len];
00260 if ((rdata + 7 + naptr->flags_len + naptr->services_len) >= end) goto error;
00261 memcpy((void*)&naptr->services, rdata + 6 + naptr->flags_len, naptr->services_len);
00262 naptr->regexp_len = (int)rdata[6 + naptr->flags_len + naptr->services_len];
00263 if ((rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len) >= end)
00264 goto error;
00265 memcpy((void*)&naptr->regexp, rdata + 7 + naptr->flags_len +
00266 naptr->services_len, naptr->regexp_len);
00267 rdata = rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len;
00268 naptr->repl_len=dn_expand(msg, end, rdata, naptr->repl, MAX_DNS_NAME-1);
00269 if ( naptr->repl_len==(unsigned int)-1 )
00270 goto error;
00271
00272 return naptr;
00273 error:
00274 if (naptr)
00275 local_free(naptr);
00276 return 0;
00277 }
00278
00279
00280
00281
00282 struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
00283 unsigned char* rdata)
00284 {
00285 struct cname_rdata* cname;
00286 int len;
00287
00288 cname=0;
00289 cname=(struct cname_rdata*)local_malloc(sizeof(struct cname_rdata));
00290 if(cname==0){
00291 LM_ERR("out of pkg memory\n");
00292 goto error;
00293 }
00294 if ((len=dn_expand(msg, end, rdata, cname->name, MAX_DNS_NAME-1))==-1)
00295 goto error;
00296 return cname;
00297 error:
00298 if (cname) local_free(cname);
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307 struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* end)
00308 {
00309 struct a_rdata* a;
00310
00311 if (rdata+4>=end) goto error;
00312 a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata));
00313 if (a==0){
00314 LM_ERR("out of pkg memory\n");
00315 goto error;
00316 }
00317 memcpy(a->ip, rdata, 4);
00318 return a;
00319 error:
00320 return 0;
00321 }
00322
00323
00324
00325
00326
00327
00328 struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* end)
00329 {
00330 struct aaaa_rdata* aaaa;
00331
00332 if (rdata+16>=end) goto error;
00333 aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata));
00334 if (aaaa==0){
00335 LM_ERR("out of pkg memory\n");
00336 goto error;
00337 }
00338 memcpy(aaaa->ip6, rdata, 16);
00339 return aaaa;
00340 error:
00341 return 0;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351 struct txt_rdata* dns_txt_parser( unsigned char* msg, unsigned char* end,
00352 unsigned char* rdata)
00353 {
00354 struct txt_rdata* txt;
00355 unsigned int len;
00356
00357 txt=0;
00358 txt=(struct txt_rdata*)local_malloc(sizeof(struct txt_rdata));
00359 if(txt==0){
00360 LM_ERR("out of pkg memory\n");
00361 goto error;
00362 }
00363
00364 len = *rdata;
00365 if (rdata + 1 + len >= end)
00366 goto error;
00367 if (len >= sizeof(txt->txt))
00368 goto error;
00369 memcpy(txt->txt, rdata+1, len);
00370 txt->txt[len] = 0;
00371 return txt;
00372
00373 error:
00374 if (txt)
00375 local_free(txt);
00376 return 0;
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 struct ebl_rdata* dns_ebl_parser( unsigned char* msg, unsigned char* end,
00394 unsigned char* rdata)
00395 {
00396 struct ebl_rdata* ebl;
00397 int len;
00398
00399 ebl=0;
00400 ebl=(struct ebl_rdata*)local_malloc(sizeof(struct ebl_rdata));
00401 if(ebl==0){
00402 LM_ERR("out of pkg memory\n");
00403 goto error;
00404 }
00405
00406 len = *rdata;
00407 if (rdata + 1 + len >= end)
00408 goto error;
00409
00410 ebl->position = *rdata;
00411 if ( ebl->position > 15 )
00412 goto error;
00413
00414 rdata++;
00415
00416 ebl->separator_len = (int) *rdata;
00417 rdata++;
00418 if ((rdata + 1 + ebl->separator_len) >= end)
00419 goto error;
00420 memcpy((void*)&ebl->separator, rdata, ebl->separator_len);
00421 rdata += ebl->separator_len;
00422
00423 ebl->apex_len=dn_expand(msg, end, rdata, ebl->apex, MAX_DNS_NAME-1);
00424 if ( ebl->apex_len==(unsigned int)-1 )
00425 goto error;
00426 ebl->apex[ebl->apex_len] = 0;
00427 return ebl;
00428
00429 error:
00430 if (ebl)
00431 local_free(ebl);
00432 return 0;
00433 }
00434
00435
00436
00437
00438
00439 void free_rdata_list(struct rdata* head)
00440 {
00441 struct rdata *l, *next_l;
00442
00443 for( l=head; l ; l=next_l) {
00444 next_l = l->next;
00445
00446 if (l->rdata)
00447 local_free(l->rdata);
00448 local_free(l);
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 struct rdata* get_record(char* name, int type)
00461 {
00462 int size, qno, answers_no, r, ans_len;
00463 static union dns_query buff;
00464 unsigned char *p, *t, *end;
00465 static unsigned char answer[ANS_SIZE];
00466 unsigned short rtype, class, rdlength;
00467 unsigned int ttl;
00468 struct rdata *head, *rd;
00469 struct rdata **crt, **last;
00470 struct srv_rdata *srv_rd, *crt_srv;
00471
00472 size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
00473 if (size<0) {
00474 LM_DBG("lookup(%s, %d) failed\n", name, type);
00475 goto not_found;
00476 }
00477 else if ((unsigned int)size > sizeof(buff)) size=sizeof(buff);
00478 head=rd=0;
00479 last=crt=&head;
00480
00481 p=buff.buff+DNS_HDR_SIZE;
00482 end=buff.buff+size;
00483 if (p>=end) goto error_boundary;
00484 qno=ntohs((unsigned short)buff.hdr.qdcount);
00485
00486 for (r=0; r<qno; r++){
00487
00488 if ((p=dns_skipname(p, end))==0) {
00489 LM_ERR("skipname==0\n");
00490 goto error;
00491 }
00492 p+=2+2;
00493 #if 0
00494 for (;(p<end && (*p)); p++);
00495 p+=1+2+2;
00496 #endif
00497 if (p>=end) {
00498 LM_ERR("p>=end\n");
00499 goto error;
00500 }
00501 };
00502 answers_no=ntohs((unsigned short)buff.hdr.ancount);
00503 ans_len=ANS_SIZE;
00504 t=answer;
00505 for (r=0; (r<answers_no) && (p<end); r++){
00506
00507 if ((p=dns_skipname(p, end))==0) {
00508 LM_ERR("skip_name=0 (#2)\n");
00509 goto error;
00510 }
00511
00512
00513
00514
00515
00516 if ((p+2+2+4+2)>=end) goto error_boundary;
00517
00518 memcpy((void*) &rtype, (void*)p, 2);
00519 rtype=ntohs(rtype);
00520 p+=2;
00521
00522 memcpy((void*) &class, (void*)p, 2);
00523 class=ntohs(class);
00524 p+=2;
00525
00526 memcpy((void*) &ttl, (void*)p, 4);
00527 ttl=ntohl(ttl);
00528 p+=4;
00529
00530 memcpy((void*)&rdlength, (void*)p, 2);
00531 rdlength=ntohs(rdlength);
00532 p+=2;
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 rd=(struct rdata*) local_malloc(sizeof(struct rdata));
00544 if (rd==0){
00545 LM_ERR("out of pkg memory\n");
00546 goto error;
00547 }
00548 rd->type=rtype;
00549 rd->class=class;
00550 rd->ttl=ttl;
00551 rd->next=0;
00552 switch(rtype){
00553 case T_SRV:
00554 srv_rd= dns_srv_parser(buff.buff, end, p);
00555 rd->rdata=(void*)srv_rd;
00556 if (srv_rd==0) goto error_parse;
00557
00558
00559 for (crt=&head; *crt; crt= &((*crt)->next)){
00560 crt_srv=(struct srv_rdata*)(*crt)->rdata;
00561 if ((srv_rd->priority < crt_srv->priority) ||
00562 ( (srv_rd->priority == crt_srv->priority) &&
00563 ((srv_rd->weight==0) || (crt_srv->weight!=0)) ) ){
00564
00565 goto skip;
00566 }
00567 }
00568 last=&(rd->next);
00569 skip:
00570
00571 rd->next=*crt;
00572 *crt=rd;
00573
00574 break;
00575 case T_A:
00576 rd->rdata=(void*) dns_a_parser(p,end);
00577 if (rd->rdata==0) goto error_parse;
00578 *last=rd;
00579 last=&(rd->next);
00580 break;
00581 case T_AAAA:
00582 rd->rdata=(void*) dns_aaaa_parser(p,end);
00583 if (rd->rdata==0) goto error_parse;
00584 *last=rd;
00585 last=&(rd->next);
00586 break;
00587 case T_CNAME:
00588 rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
00589 if(rd->rdata==0) goto error_parse;
00590 *last=rd;
00591 last=&(rd->next);
00592 break;
00593 case T_NAPTR:
00594 rd->rdata=(void*) dns_naptr_parser(buff.buff, end, p);
00595 if(rd->rdata==0) goto error_parse;
00596 *last=rd;
00597 last=&(rd->next);
00598 break;
00599 case T_TXT:
00600 rd->rdata=(void*) dns_txt_parser(buff.buff, end, p);
00601 if(rd->rdata==0) goto error_parse;
00602 *last=rd;
00603 last=&(rd->next);
00604 break;
00605 case T_EBL:
00606 rd->rdata=(void*) dns_ebl_parser(buff.buff, end, p);
00607 if(rd->rdata==0) goto error_parse;
00608 *last=rd;
00609 last=&(rd->next);
00610 break;
00611 default:
00612 LM_ERR("unknown type %d\n", rtype);
00613 rd->rdata=0;
00614 *last=rd;
00615 last=&(rd->next);
00616 }
00617
00618 p+=rdlength;
00619
00620 }
00621 return head;
00622 error_boundary:
00623 LM_ERR("end of query buff reached\n");
00624 if(head)
00625 free_rdata_list(head);
00626 return 0;
00627 error_parse:
00628 LM_ERR("rdata parse error \n");
00629 if (rd) local_free(rd);
00630
00631 error:
00632 LM_ERR("get_record \n");
00633 if (head) free_rdata_list(head);
00634 not_found:
00635 return 0;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645 static inline int get_naptr_proto(struct naptr_rdata *n)
00646 {
00647 #ifdef USE_TLS
00648 if (n->services[3]=='s' || n->services[3]=='S' )
00649 return PROTO_TLS;
00650 #endif
00651 switch (n->services[n->services_len-1]) {
00652 case 'U':
00653 case 'u':
00654 return PROTO_UDP;
00655 break;
00656 #ifdef USE_TCP
00657 case 'T':
00658 case 't':
00659 return PROTO_TCP;
00660 break;
00661 #endif
00662 #ifdef USE_SCTP
00663 case 'S':
00664 case 's':
00665 return PROTO_SCTP;
00666 break;
00667 #endif
00668
00669 }
00670 LM_CRIT("failed to detect proto\n");
00671 return PROTO_NONE;
00672 }
00673
00674
00675
00676 static inline int srv2dns_node(struct rdata *head, struct dns_node **dn)
00677 {
00678 unsigned int mem, l;
00679 struct rdata *r;
00680 struct dns_node *n;
00681 char *p;
00682
00683
00684 mem = sizeof(struct dns_node);
00685 for( r=head,l=0 ; r ; r=r->next,l++ )
00686 mem +=sizeof(struct dns_val) + get_naptr(r)->repl_len + 1;
00687
00688 n = (struct dns_node*)shm_malloc(mem);
00689 if (n==NULL) {
00690 LM_ERR("no more shm mem (%d)\n", mem);
00691 return -1;
00692 }
00693
00694 n->type = DNS_NODE_SRV;
00695 n->size = mem;
00696 n->idx = 0;
00697 n->no = l;
00698 n->kids = *dn;
00699 *dn = n;
00700
00701 n->vals = (struct dns_val*)(n+1);
00702 p = (char*)(n->vals+l);
00703 for( r=head,l=0 ; r ; r=r->next,l++ ) {
00704 n->vals[l].ival = get_naptr_proto( get_naptr(r) );
00705 n->vals[l].sval = p;
00706 memcpy( p, get_naptr(r)->repl, get_naptr(r)->repl_len );
00707 p += get_naptr(r)->repl_len;
00708 *(p++) = 0;
00709 }
00710 return 0;
00711 }
00712
00713
00714 static inline int a2dns_node(struct rdata *head, struct dns_node **dn)
00715 {
00716 unsigned int mem, l;
00717 struct rdata *r;
00718 struct dns_node *n;
00719 char *p;
00720
00721
00722 mem = sizeof(struct dns_node);
00723 for( r=head,l=0 ; r ; r=r->next,l++ ) {
00724 get_srv(r)->name_len = strlen(get_srv(r)->name);
00725 mem +=sizeof(struct dns_val) + get_srv(r)->name_len + 1;
00726 }
00727
00728 n = (struct dns_node*)shm_malloc(mem);
00729 if (n==NULL) {
00730 LM_ERR("no more shm mem (%d)\n", mem);
00731 return -1;
00732 }
00733
00734 n->type = DNS_NODE_A;
00735 n->size = mem;
00736 n->idx = 0;
00737 n->no = l;
00738 n->kids = 0;
00739 *dn = n;
00740
00741 n->vals = (struct dns_val*)(n+1);
00742 p = (char*)(n->vals+l);
00743 for( r=head,l=0 ; r ; r=r->next,l++ ) {
00744 n->vals[l].ival = get_srv(r)->port;
00745 n->vals[l].sval = p;
00746 memcpy( p, get_srv(r)->name, get_srv(r)->name_len );
00747 LM_DBG("storing %.*s:%d\n", get_srv(r)->name_len,p,n->vals[l].ival);
00748 p += get_srv(r)->name_len;
00749 *(p++) = 0;
00750 }
00751
00752 return 0;
00753 }
00754
00755
00756 static inline void sort_srvs(struct rdata **head)
00757 {
00758 #define rd2srv(_rd) ((struct srv_rdata*)_rd->rdata)
00759 struct rdata *rd = *head;
00760 struct rdata *tail = NULL;
00761 struct rdata *rd_next, *crt, *crt2;
00762 unsigned int weight_sum, rand_no;
00763
00764 *head = NULL;
00765
00766 while( rd ) {
00767 rd_next = rd->next;
00768 if (rd->type!=T_SRV) {
00769 rd->next = NULL;
00770 free_rdata_list(rd);
00771 } else {
00772
00773 if (rd_next==NULL ||
00774 rd2srv(rd)->priority!=rd2srv(rd_next)->priority) {
00775 if (tail) {tail->next=rd;tail=rd;}
00776 else {*head=tail=rd;}
00777 } else {
00778
00779
00780 weight_sum = rd2srv(rd)->running_sum = rd2srv(rd)->weight;
00781 crt = rd;
00782 while( crt && crt->next &&
00783 (rd2srv(rd)->priority==rd2srv(crt->next)->priority) ) {
00784 crt = crt->next;
00785 weight_sum += rd2srv(crt)->weight;
00786 rd2srv(crt)->running_sum = weight_sum;
00787 }
00788
00789 rd_next = crt->next;
00790 crt->next = NULL;
00791
00792
00793 while (rd->next) {
00794 rand_no = (unsigned int)
00795 (weight_sum*((float)rand()/RAND_MAX));
00796 for( crt=rd,crt2=NULL ; crt ; crt2=crt,crt=crt->next) {
00797 if (rd2srv(crt)->running_sum>=rand_no) break;
00798 }
00799 if (crt == NULL) {
00800 LM_CRIT("bug in sorting SRVs - rand>sum\n");
00801 crt = rd;
00802 crt2 = NULL;
00803 }
00804
00805 if (crt2==NULL) { rd = rd->next;}
00806 else {crt2->next = crt->next;}
00807
00808 for ( crt2=crt->next ; crt2 ; crt2=crt2->next)
00809 rd2srv(crt2)->running_sum -= rd2srv(crt)->weight;
00810 weight_sum -= rd2srv(crt)->weight;
00811
00812 crt->next = 0;
00813 if (tail) {tail->next=crt;tail=crt;}
00814 else {*head=tail=crt;}
00815 }
00816
00817 tail->next = rd; tail = rd ;
00818 }
00819 }
00820
00821 rd = rd_next;
00822 }
00823 }
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 static inline struct hostent* do_srv_lookup(char *name, unsigned short* port, struct dns_node **dn)
00834 {
00835 struct hostent *he;
00836 struct srv_rdata *srv;
00837 struct rdata *head, *rd;
00838
00839
00840 head = get_record( name, T_SRV);
00841 sort_srvs(&head);
00842 for( rd=head; rd ; rd=rd->next ) {
00843 if (rd->type!=T_SRV)
00844 continue;
00845 srv = (struct srv_rdata*) rd->rdata;
00846 if (srv==0) {
00847 LM_CRIT("null rdata\n");
00848 free_rdata_list(head);
00849 return 0;
00850 }
00851 he = resolvehost(srv->name, 1);
00852 if ( he!=0 ) {
00853 LM_DBG("SRV(%s) = %s:%d\n", name, srv->name, srv->port);
00854 *port=srv->port;
00855 if (dn && rd->next && a2dns_node( rd->next, dn)==-1)
00856 *dn = 0;
00857 free_rdata_list(head);
00858 return he;
00859 }
00860 }
00861 if (head)
00862 free_rdata_list(head);
00863 return 0;
00864 }
00865
00866
00867 #define naptr_prio(_naptr) \
00868 ((unsigned int)((((_naptr)->order) << 16) + ((_naptr)->pref)))
00869
00870 static inline void filter_and_sort_naptr( struct rdata** head_p, struct rdata** filtered_p, int is_sips)
00871 {
00872 struct naptr_rdata *naptr;
00873 struct rdata *head, *last, *out, *l, *ln, *it, *itp;
00874 unsigned int prio;
00875 char p;
00876
00877 head = 0;
00878 last = 0;
00879 out = 0;
00880
00881 for( l=*head_p ; l ; l=ln ) {
00882 ln = l->next;
00883
00884 if (l->type != T_NAPTR)
00885 goto skip0;
00886
00887 naptr = (struct naptr_rdata*)l->rdata;
00888 if (naptr == 0) {
00889 LM_CRIT("null rdata\n");
00890 goto skip0;
00891 }
00892
00893
00894 if (naptr->flags_len!=1||(naptr->flags[0]!='s'&&naptr->flags[0]!='S'))
00895 goto skip;
00896 if (naptr->repl_len==0 || naptr->regexp_len!=0 )
00897 goto skip;
00898 if ( (is_sips || naptr->services_len!=7 ||
00899 strncasecmp(naptr->services,"sip+d2",6) ) &&
00900 (
00901 #ifdef USE_TLS
00902 tls_disable ||
00903 #endif
00904 naptr->services_len!=8 || strncasecmp(naptr->services,"sips+d2",7)))
00905 goto skip;
00906 p = naptr->services[naptr->services_len-1];
00907
00908 if ( p!='U' && p!='u'
00909 #ifdef USE_TCP
00910 && (tcp_disable || (p!='T' && p!='t'))
00911 #endif
00912 #ifdef USE_SCTP
00913 && (sctp_disable || (p!='S' && p!='s'))
00914 #endif
00915 )
00916 goto skip;
00917
00918 if ( naptr->services_len==8 && (p=='U' || p=='u'))
00919 goto skip;
00920
00921 LM_DBG("found valid %.*s -> %s\n",
00922 (int)naptr->services_len,naptr->services, naptr->repl);
00923
00924
00925
00926 prio = naptr_prio(get_naptr(l));
00927 if (head==0) {
00928 head = last = l;
00929 l->next = 0;
00930 } else if ( naptr_prio(get_naptr(head)) >= prio ) {
00931 l->next = head;
00932 head = l;
00933 } else if ( prio >= naptr_prio(get_naptr(last)) ) {
00934 l->next = 0;
00935 last->next = l;
00936 last = l;
00937 } else {
00938 for( itp=head,it=head->next ; it && it->next ; itp=it,it=it->next ){
00939 if ( prio <= naptr_prio(get_naptr(it)))
00940 break;
00941 }
00942 l->next = itp->next;
00943 itp->next = l;
00944 }
00945
00946 continue;
00947 skip:
00948 LM_DBG("skipping %.*s -> %s\n",
00949 (int)naptr->services_len, naptr->services, naptr->repl);
00950 skip0:
00951 l->next = out;
00952 out = l;
00953 }
00954
00955 *head_p = head;
00956 *filtered_p = out;
00957 }
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 struct hostent* sip_resolvehost( str* name, unsigned short* port,
00979 unsigned short *proto, int is_sips, struct dns_node **dn)
00980 {
00981 static char tmp[MAX_DNS_NAME];
00982 struct ip_addr *ip;
00983 struct rdata *head, *rd;
00984 struct hostent* he;
00985
00986 if ( (is_sips)
00987 #ifdef USE_TLS
00988 && (tls_disable)
00989 #endif
00990 ) {
00991 LM_ERR("cannot resolve SIPS as no TLS support is configured\n");
00992 return 0;
00993 }
00994
00995 if (dn)
00996 *dn = 0;
00997
00998
00999 if ( ((ip=str2ip(name))!=0)
01000 #ifdef USE_IPV6
01001 || ((ip=str2ip6(name))!=0)
01002 #endif
01003 ){
01004
01005 if (proto && *proto==PROTO_NONE)
01006 *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
01007 if (port && *port==0)
01008 *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
01009 return ip_addr2he(name,ip);
01010 }
01011
01012
01013 if ( !port || (*port)!=0 ) {
01014
01015 LM_DBG("has port -> do A record lookup!\n");
01016
01017 if (proto && *proto==PROTO_NONE)
01018 *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
01019 goto do_a;
01020 }
01021
01022
01023 if ( !proto || (*proto)!=PROTO_NONE ) {
01024
01025 LM_DBG("no port, has proto -> do SRV lookup!\n");
01026 if (is_sips && (*proto)!=PROTO_TLS) {
01027 LM_ERR("forced proto %d not matching sips uri\n", *proto);
01028 return 0;
01029 }
01030 goto do_srv;
01031 }
01032
01033 LM_DBG("no port, no proto -> do NAPTR lookup!\n");
01034
01035 if (name->len >= MAX_DNS_NAME) {
01036 LM_ERR("domain name too long\n");
01037 return 0;
01038 }
01039 memcpy(tmp, name->s, name->len);
01040 tmp[name->len] = '\0';
01041
01042 head = get_record( tmp, T_NAPTR);
01043 if (head) {
01044
01045 filter_and_sort_naptr( &head, &rd, is_sips);
01046
01047 free_rdata_list( rd );
01048
01049 for( rd=head ; rd ; rd=rd->next ) {
01050 *proto = get_naptr_proto( get_naptr(rd) );
01051 he = do_srv_lookup( get_naptr(rd)->repl, port, dn);
01052 if ( he ) {
01053 LM_DBG("valid SRV found!\n");
01054 if (dn) {
01055
01056 if (*dn==NULL)
01057 rd = rd->next;
01058 if (rd && srv2dns_node( rd, dn)!=0) {
01059 shm_free(*dn);
01060 *dn = 0;
01061 }
01062 }
01063 free_rdata_list(head);
01064 return he;
01065 }
01066 }
01067 if (head)
01068 free_rdata_list(head);
01069 }
01070 if(errno==ETIMEDOUT) {
01071 LM_ERR("NATPR query timed out, no server could be reached, stop resolving (%s)\n", strerror(errno));
01072 return 0;
01073 }
01074
01075 LM_DBG("no valid NAPTR record found for %.*s,"
01076 " trying direct SRV lookup...\n", name->len, name->s);
01077 *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
01078
01079 do_srv:
01080 if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME) {
01081 LM_WARN("domain name too long (%d),"
01082 " unable to perform SRV lookup\n", name->len);
01083
01084 *port = (is_sips)?SIPS_PORT:SIP_PORT;
01085 goto do_a;
01086 }
01087
01088 switch (*proto) {
01089 case PROTO_UDP:
01090 memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
01091 memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
01092 tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
01093 break;
01094 #ifdef USE_TCP
01095 case PROTO_TCP:
01096 if (tcp_disable) goto err_proto;
01097 memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
01098 memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
01099 tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
01100 break;
01101 #endif
01102 #ifdef USE_TLS
01103 case PROTO_TLS:
01104 if (tls_disable) goto err_proto;
01105 memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
01106 memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
01107 tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
01108 break;
01109 #endif
01110 #ifdef USE_SCTP
01111 case PROTO_SCTP:
01112 if (sctp_disable) goto err_proto;
01113 memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
01114 memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
01115 tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
01116 break;
01117 #endif
01118 default:
01119 goto err_proto;
01120 }
01121
01122 he = do_srv_lookup( tmp, port, dn);
01123 if (he)
01124 return he;
01125
01126 LM_DBG("no valid SRV record found for %s, trying A record lookup...\n",
01127 tmp);
01128
01129 *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
01130
01131 do_a:
01132
01133 if (name->len >= MAX_DNS_NAME) {
01134 LM_ERR("domain name too long\n");
01135 return 0;
01136 }
01137 memcpy(tmp, name->s, name->len);
01138 tmp[name->len] = '\0';
01139 he = resolvehost(tmp,1);
01140 return he;
01141 err_proto:
01142 LM_ERR("unsupported proto %d\n", *proto);
01143 return 0;
01144 }
01145
01146
01147
01148 static inline struct hostent* get_next_he(struct dns_node **node,
01149 unsigned short *proto, unsigned short *port)
01150 {
01151 struct hostent *he;
01152 struct dns_node *n, *last_srv, *dn;
01153
01154 if (node==NULL || *node==NULL)
01155 return 0;
01156
01157 n = *node;
01158 last_srv = NULL;
01159 he = 0;
01160
01161 do {
01162 switch (n->type) {
01163 case DNS_NODE_SRV:
01164 last_srv = n;
01165 if (n->kids==NULL) {
01166
01167 do {
01168 dn = 0;
01169 he = do_srv_lookup( n->vals[n->idx].sval, port, &dn);
01170 if (he) {
01171 *proto = n->vals[n->idx].ival;
01172 break;
01173 }
01174 n->idx++;
01175 } while(n->idx<n->no);
01176 if (he==NULL || (he && n->idx+1==n->no) ) {
01177
01178 shm_free(n);
01179 *node = dn;
01180 return he;
01181 }
01182 n->kids = dn;
01183 return he;
01184 }
01185
01186 n = n->kids;
01187 break;
01188 case DNS_NODE_A:
01189
01190 do {
01191 he = resolvehost(n->vals[n->idx].sval,1);
01192 if (he) {
01193 *port = n->vals[n->idx].ival;
01194 break;
01195 }
01196 n->idx++;
01197 }while(n->idx<n->no);
01198
01199 if (he==NULL || (he && n->idx+1==n->no)) {
01200 shm_free(n);
01201
01202 if (last_srv==NULL) {
01203
01204 *node = 0;
01205 return he;
01206 }
01207 last_srv->kids = 0;
01208
01209 if (++last_srv->idx<last_srv->no)
01210 return he;
01211
01212 shm_free(last_srv);
01213 *node = 0;
01214 }
01215 return he;
01216 break;
01217 default:
01218 LM_CRIT("unknown %d node type\n", n->type);
01219 return 0;
01220 }
01221 } while(1);
01222 }
01223
01224
01225
01226 void free_dns_res( struct proxy_l *p )
01227 {
01228 if (p==NULL || p->dn==NULL)
01229 return;
01230
01231 if (p->dn->kids)
01232 shm_free(p->dn->kids);
01233 shm_free(p->dn);
01234 p->dn = 0;
01235 }
01236
01237
01238
01239 int get_next_su(struct proxy_l *p, union sockaddr_union* su, int add_to_bl)
01240 {
01241 struct hostent *he;
01242 struct bl_rule *list;
01243 struct net ip_net;
01244 int n;
01245
01246 if (failover_bl && add_to_bl) {
01247 memset( &ip_net, 0xff , sizeof(struct net));
01248 hostent2ip_addr( &ip_net.ip, &p->host, p->addr_idx);
01249 ip_net.mask.af = ip_net.ip.af;
01250 ip_net.mask.len = ip_net.ip.len;
01251 list = 0;
01252 n = add_rule_to_list( &list, &list, &ip_net, 0, p->port, p->proto, 0);
01253 if (n!=0) {
01254 LM_ERR("failed to build bl rule\n");
01255 } else {
01256 add_list_to_head( failover_bl, list, list, 0, DNS_BL_EXPIRE);
01257 }
01258 }
01259
01260
01261 if ( p->host.h_addr_list[++p->addr_idx] ) {
01262
01263 hostent2su( su, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
01264 return 0;
01265 }
01266
01267
01268 he = get_next_he( &p->dn, &p->proto, &p->port);
01269 if (he==NULL)
01270 return -1;
01271
01272
01273 if (p->flags&PROXY_SHM_FLAG) {
01274 free_shm_hostent( &p->host );
01275 n = hostent_shm_cpy(&(p->host), he);
01276 } else {
01277 free_hostent( &p->host );
01278 n = hostent_cpy(&(p->host), he);
01279 }
01280 if (n!=0) {
01281 free_dns_res( p );
01282 return -1;
01283 }
01284
01285 hostent2su( su, &p->host, 0, (p->port)?p->port:SIP_PORT);
01286 p->addr_idx = 0;
01287 return 0;
01288 }
01289
01290
01291
01292 static inline struct dns_node *dns_node_copy(struct dns_node *s)
01293 {
01294 struct dns_node *d;
01295 unsigned int i;
01296
01297 d = (struct dns_node*)shm_malloc(s->size);
01298 if (d==NULL) {
01299 LM_ERR("no more shm mem\n");
01300 return 0;
01301 }
01302 memcpy( d, s, s->size);
01303 d->vals = (struct dns_val*)((char*)d + ((char*)s->vals-(char*)s));
01304 for( i=0 ; i<s->no ; i++ )
01305 d->vals[i].sval = (char*)d + ((char*)s->vals[i].sval-(char*)s);
01306 return d;
01307 }
01308
01309
01310 struct dns_node *dns_res_copy(struct dns_node *s)
01311 {
01312 struct dns_node *d;
01313
01314 d = dns_node_copy(s);
01315 if (d==NULL)
01316 return 0;
01317 if (s->kids) {
01318 d->kids = dns_node_copy(s->kids);
01319 if (d->kids==NULL) {
01320 shm_free(d);
01321 return 0;
01322 }
01323 }
01324 return d;
01325 }