core: fix another bunch of 'no real prototype' warnings, add doxygen docs
[sip-router] / resolve.c
1 /* $Id$*/
2 /*
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * This file is part of ser, a free SIP server.
7  *
8  * ser 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  * For a license to use the ser software under conditions
14  * other than those described here, or to purchase support for this
15  * software, please contact iptel.org by e-mail at the following addresses:
16  *    info@iptel.org
17  *
18  * ser is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License 
24  * along with this program; if not, write to the Free Software 
25  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26  */
27 /*
28  * History:
29  * -------
30  *  2003-02-13  added proto to sip_resolvehost, for SRV lookups (andrei)
31  *  2003-07-03  default port value set according to proto (andrei)
32  *  2005-07-11  added resolv_init (timeouts a.s.o) (andrei)
33  *  2006-04-13  added sip_hostport2su()  (andrei)
34  *  2006-07-13  rdata structures put on diet (andrei)
35  *  2006-07-17  rdata contains now also the record name (andrei)
36  *  2006-08-18  get_record can append also the additional records to the
37  *               returned list (andrei)
38  *  2007-06-15  naptr support (andrei)
39  *  2007-10-10  short name resolution using search list supported (mma)
40  *              set dns_use_search_list=1 (default on)
41  *              new option dns_search_full_match (default on) controls
42  *              whether rest of the name is matched against search list
43  *              or blindly accepted (better performance but exploitable)
44  *  2008-01-31  resolver options use the configuration framework, and the
45  *               resolver is reinitialized when the options change (Miklos)
46  *  2008-08-12  sctp preference support for NAPTR queries (andrei)
47  *  2009-03-30  TXT record support (andrei)
48  *  2009-03-31  EBL record support (andrei)
49  *  2009-04-01  PTR record support (andrei)
50  */ 
51
52 /*!
53  * \file
54  * \brief SIP-router core :: 
55  * \ingroup core
56  * Module: \ref core
57  */
58
59
60 #include <sys/types.h>
61 #include <netinet/in.h>
62 #include <arpa/nameser.h>
63 #include <resolv.h>
64 #include <string.h>
65
66 #include "resolve.h"
67 #include "compiler_opt.h"
68 #include "dprint.h"
69 #include "mem/mem.h"
70 #include "ip_addr.h"
71 #include "error.h"
72 #include "globals.h" /* tcp_disable, tls_disable a.s.o */
73 #include "cfg_core.h"
74 #include "socket_info.h"
75
76 #ifdef USE_DNS_CACHE
77 #include "dns_cache.h"
78 #endif
79
80 /* counters framework */
81 struct dns_counters_h dns_cnts_h;
82 counter_def_t dns_cnt_defs[] =  {
83         {&dns_cnts_h.failed_dns_req, "failed_dns_request", 0, 0, 0,
84                 "incremented each time a DNS request has failed."},
85         {0, 0, 0, 0, 0, 0 }
86 };
87
88 /* mallocs for local stuff */
89 #define local_malloc pkg_malloc
90 #define local_free   pkg_free
91
92 #ifdef USE_NAPTR
93 static int naptr_proto_pref[PROTO_LAST+1];
94 #endif
95
96 #ifdef USE_NAPTR
97 void init_naptr_proto_prefs()
98 {
99         if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
100                 (PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
101                 BUG("init_naptr_proto_prefs: array too small \n");
102                 return;
103         }
104         naptr_proto_pref[PROTO_UDP]=cfg_get(core, core_cfg, dns_udp_pref);
105         naptr_proto_pref[PROTO_TCP]=cfg_get(core, core_cfg, dns_tcp_pref);
106         naptr_proto_pref[PROTO_TLS]=cfg_get(core, core_cfg, dns_tls_pref);
107         naptr_proto_pref[PROTO_SCTP]=cfg_get(core, core_cfg, dns_sctp_pref);
108 }
109
110 #endif /* USE_NAPTR */
111
112 #ifdef DNS_WATCHDOG_SUPPORT
113 static on_resolv_reinit on_resolv_reinit_cb = NULL;
114
115 /* register the callback function */
116 int register_resolv_reinit_cb(on_resolv_reinit cb)
117 {
118         if (on_resolv_reinit_cb) {
119                 LOG(L_ERR, "ERROR: register_resolv_reinit_cb(): "
120                         "callback function has been already registered\n");
121                 return -1;
122         }
123         on_resolv_reinit_cb = cb;
124         return 0;
125 }
126 #endif
127
128 /* counter init function
129   must be called before fork
130 */
131 static int stat_init()
132 {
133         if (counter_register_array("dns", dns_cnt_defs) < 0)
134                 goto error;
135         return 0;
136 error:
137         return -1;
138 }
139
140 /* init. the resolver
141  * params: retr_time  - time before retransmitting (must be >0)
142  *         retr_no    - retransmissions number
143  *         servers_no - how many dns servers will be used
144  *                      (from the one listed in /etc/resolv.conf)
145  *         search     - if 0 the search list in /etc/resolv.conf will
146  *                      be ignored (HINT: even if you don't have a
147  *                      search list in resolv.conf, it's still better
148  *                      to set search to 0, because an empty seachlist
149  *                      means in fact search "" => it takes more time)
150  * If any of the parameters <0, the default (system specific) value
151  * will be used. See also resolv.conf(5).
152  * returns: 0 on success, -1 on error
153  */
154 static int _resolv_init()
155 {
156         res_init();
157 #ifdef HAVE_RESOLV_RES
158         if (cfg_get(core, core_cfg, dns_retr_time)>0)
159                 _res.retrans=cfg_get(core, core_cfg, dns_retr_time);
160         if (cfg_get(core, core_cfg, dns_retr_no)>0)
161                 _res.retry=cfg_get(core, core_cfg, dns_retr_no);
162         if ((cfg_get(core, core_cfg, dns_servers_no)>=0)
163                 && (cfg_get(core, core_cfg, dns_servers_no)<_res.nscount))
164                         _res.nscount=cfg_get(core, core_cfg, dns_servers_no);
165         if (cfg_get(core, core_cfg, dns_search_list)==0)
166                 _res.options&=~(RES_DEFNAMES|RES_DNSRCH);
167 #else
168 #warning "no resolv timeout support"
169         LOG(L_WARN, "WARNING: _resolv_init: no resolv options support - resolv"
170                         " options will be ignored\n");
171 #endif
172         return 0;
173 }
174
175 /* wrapper function to initialize the resolver at startup */
176 int resolv_init()
177 {
178         int res = -1;
179         _resolv_init();
180
181 #ifdef USE_NAPTR
182         init_naptr_proto_prefs();
183 #endif
184         /* init counter API only at startup
185          * This function must be called before DNS cache init method (if available)
186          */
187         res = stat_init();
188         return res;
189 }
190
191 /* wrapper function to reinitialize the resolver
192  * This function must be called by each child process whenever
193  * a resolver option changes
194  */
195 void resolv_reinit(str *gname, str *name)
196 {
197         _resolv_init();
198
199 #ifdef DNS_WATCHDOG_SUPPORT
200         if (on_resolv_reinit_cb) on_resolv_reinit_cb(name);
201 #endif
202         LOG(L_DBG, "DEBUG: resolv_reinit(): "
203                 "DNS resolver has been reinitialized\n");
204 }
205
206 /* fixup function for dns_reinit variable
207  * (resets the variable to 0)
208  */
209 int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
210 {
211         *val = (void *)(long)0;
212         return 0;
213 }
214
215 /* wrapper function to recalculate the naptr protocol preferences */
216 void reinit_naptr_proto_prefs(str *gname, str *name)
217 {
218 #ifdef USE_NAPTR
219         init_naptr_proto_prefs();
220 #endif
221 }
222
223 /* fixup function for dns_try_ipv6
224  * verifies that SER really listens on an ipv6 interface
225  */
226 int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val)
227 {
228         if ((int)(long)(*val) && !(socket_types & SOCKET_T_IPV6)) {
229                 LOG(L_ERR, "ERROR: dns_try_ipv6_fixup(): "
230                         "SER does not listen on any ipv6 interface, "
231                         "there is no point in resolving ipv6 addresses\n");
232                 return -1;
233         }
234         return 0;
235 }
236
237  /*  skips over a domain name in a dns message
238  *  (it can be  a sequence of labels ending in \0, a pointer or
239  *   a sequence of labels ending in a pointer -- see rfc1035
240  *   returns pointer after the domain name or null on error*/
241 unsigned char* dns_skipname(unsigned char* p, unsigned char* end)
242 {
243         while(p<end){
244                 /* check if \0 (root label length) */
245                 if (*p==0){
246                         p+=1;
247                         break;
248                 }
249                 /* check if we found a pointer */
250                 if (((*p)&0xc0)==0xc0){
251                         /* if pointer skip over it (2 bytes) & we found the end */
252                         p+=2;
253                         break;
254                 }
255                 /* normal label */
256                 p+=*p+1;
257         }
258         return (p>end)?0:p;
259 }
260
261
262
263 /* parses the srv record into a srv_rdata structure
264  *   msg   - pointer to the dns message
265  *   end   - pointer to the end of the message
266  *   eor   - pointer to the end of the record/rdata
267  *   rdata - pointer  to the rdata part of the srv answer
268  * returns 0 on error, or a dyn. alloc'ed srv_rdata structure */
269 /* SRV rdata format:
270  *            111111
271  *  0123456789012345
272  * +----------------+
273  * |     priority   |
274  * |----------------|
275  * |     weight     |
276  * |----------------|
277  * |   port number  |
278  * |----------------|
279  * |                |
280  * ~      name      ~
281  * |                |
282  * +----------------+
283  */
284 struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
285                                                                   unsigned char* eor,
286                                                                   unsigned char* rdata)
287 {
288         struct srv_rdata* srv;
289         unsigned short priority;
290         unsigned short weight;
291         unsigned short port;
292         int len;
293         char name[MAX_DNS_NAME];
294         
295         srv=0;
296         if ((rdata+6+1)>eor) goto error;
297         
298         memcpy((void*)&priority, rdata, 2);
299         memcpy((void*)&weight,   rdata+2, 2);
300         memcpy((void*)&port,     rdata+4, 2);
301         rdata+=6;
302         if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)<0)
303                 goto error;
304         len=strlen(name);
305         if (len>255)
306                 goto error;
307         /* alloc enought space for the struct + null terminated name */
308         srv=local_malloc(sizeof(struct srv_rdata)-1+len+1);
309         if (srv==0){
310                 LOG(L_ERR, "ERROR: dns_srv_parser: out of memory\n");
311                 goto error;
312         }
313         srv->priority=ntohs(priority);
314         srv->weight=ntohs(weight);
315         srv->port=ntohs(port);
316         srv->name_len=len;
317         memcpy(srv->name, name, srv->name_len);
318         srv->name[srv->name_len]=0;
319         
320         return srv;
321 error:
322         if (srv) local_free(srv);
323         return 0;
324 }
325
326
327 /* parses the naptr record into a naptr_rdata structure
328  *   msg   - pointer to the dns message
329  *   end   - pointer to the end of the message
330  *   eor   - pointer to the end of the record/rdata
331  *   rdata - pointer  to the rdata part of the naptr answer
332  * returns 0 on error, or a dyn. alloc'ed naptr_rdata structure */
333 /* NAPTR rdata format:
334  *            111111
335  *  0123456789012345
336  * +----------------+
337  * |      order     |
338  * |----------------|
339  * |   preference   |
340  * |----------------|
341  * ~     flags      ~
342  * |   (string)     |
343  * |----------------|
344  * ~    services    ~
345  * |   (string)     |
346  * |----------------|
347  * ~    regexp      ~
348  * |   (string)     |
349  * |----------------|
350  * ~  replacement   ~
351    |    (name)      |
352  * +----------------+
353  */
354 struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
355                                                                                 unsigned char* eor,
356                                                                                 unsigned char* rdata)
357 {
358         struct naptr_rdata* naptr;
359         unsigned char* flags;
360         unsigned char* services;
361         unsigned char* regexp;
362         unsigned short order;
363         unsigned short pref;
364         unsigned char flags_len;
365         unsigned char services_len;
366         unsigned char regexp_len;
367         int len;
368         char repl[MAX_DNS_NAME];
369         
370         naptr = 0;
371         if ((rdata + 7 + 1)>eor) goto error;
372         
373         memcpy((void*)&order, rdata, 2);
374         memcpy((void*)&pref, rdata + 2, 2);
375         flags_len = rdata[4];
376         if ((rdata + 7 + 1 +  flags_len) > eor)
377                 goto error;
378         flags=rdata+5;
379         services_len = rdata[5 + flags_len];
380         if ((rdata + 7 + 1 + flags_len + services_len) > eor)
381                 goto error;
382         services=rdata + 6 + flags_len;
383         regexp_len = rdata[6 + flags_len + services_len];
384         if ((rdata + 7 +1 + flags_len + services_len + regexp_len) > eor)
385                 goto error;
386         regexp=rdata + 7 + flags_len + services_len;
387         rdata = rdata + 7 + flags_len + services_len + regexp_len;
388         if (dn_expand(msg, end, rdata, repl, MAX_DNS_NAME-1) == -1)
389                 goto error;
390         len=strlen(repl);
391         if (len>255)
392                 goto error;
393         naptr=local_malloc(sizeof(struct naptr_rdata)+flags_len+services_len+
394                                                 regexp_len+len+1-1);
395         if (naptr == 0){
396                 LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n");
397                 goto error;
398         }
399         naptr->order=ntohs(order);
400         naptr->pref=ntohs(pref);
401         
402         naptr->flags=&naptr->str_table[0];
403         naptr->flags_len=flags_len;
404         memcpy(naptr->flags, flags, naptr->flags_len);
405         naptr->services=&naptr->str_table[flags_len];
406         naptr->services_len=services_len;
407         memcpy(naptr->services, services, naptr->services_len);
408         naptr->regexp=&naptr->str_table[flags_len+services_len];
409         naptr->regexp_len=regexp_len;
410         memcpy(naptr->regexp, regexp, naptr->regexp_len);
411         naptr->repl=&naptr->str_table[flags_len+services_len+regexp_len];
412         naptr->repl_len=len;
413         memcpy(naptr->repl, repl, len);
414         naptr->repl[len]=0; /* null term. */
415         
416         return naptr;
417 error:
418         if (naptr) local_free(naptr);
419         return 0;
420 }
421
422
423
424 /* parses a CNAME record into a cname_rdata structure */
425 struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
426                                                                           unsigned char* rdata)
427 {
428         struct cname_rdata* cname;
429         int len;
430         char name[MAX_DNS_NAME];
431         
432         cname=0;
433         if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
434                 goto error;
435         len=strlen(name);
436         if (len>255)
437                 goto error;
438         /* alloc sizeof struct + space for the null terminated name */
439         cname=local_malloc(sizeof(struct cname_rdata)-1+len+1);
440         if(cname==0){
441                 LOG(L_ERR, "ERROR: dns_cname_parser: out of memory\n");
442                 goto error;
443         }
444         cname->name_len=len;
445         memcpy(cname->name, name, cname->name_len);
446         cname->name[cname->name_len]=0;
447         return cname;
448 error:
449         if (cname) local_free(cname);
450         return 0;
451 }
452
453
454
455 /* parses an A record rdata into an a_rdata structure
456  * returns 0 on error or a dyn. alloc'ed a_rdata struct
457  */
458 struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* eor)
459 {
460         struct a_rdata* a;
461         
462         if (rdata+4>eor) goto error;
463         a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata));
464         if (a==0){
465                 LOG(L_ERR, "ERROR: dns_a_parser: out of memory\n");
466                 goto error;
467         }
468         memcpy(a->ip, rdata, 4);
469         return a;
470 error:
471         return 0;
472 }
473
474
475
476 /* parses an AAAA (ipv6) record rdata into an aaaa_rdata structure
477  * returns 0 on error or a dyn. alloc'ed aaaa_rdata struct */
478 struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* eor)
479 {
480         struct aaaa_rdata* aaaa;
481         
482         if (rdata+16>eor) goto error;
483         aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata));
484         if (aaaa==0){
485                 LOG(L_ERR, "ERROR: dns_aaaa_parser: out of memory\n");
486                 goto error;
487         }
488         memcpy(aaaa->ip6, rdata, 16);
489         return aaaa;
490 error:
491         return 0;
492 }
493
494
495
496 /** parses a TXT record into a txt_rdata structure.
497  *   @param msg   - pointer to the dns message
498  *   @param end   - pointer to the end of the record (rdata end)
499  *   @param rdata - pointer  to the rdata part of the txt answer
500  * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
501 /*  TXT rdata format:
502  *
503  * one or several character strings:
504  *  01234567
505  * +--------------------+
506  * | len    | string   / ...
507  * |------------------+
508  */
509 static struct txt_rdata* dns_txt_parser(unsigned char* msg, unsigned char* end,
510                                                                                 unsigned char* rdata)
511 {
512         struct txt_rdata* txt;
513         int len, n, i;
514         int str_size;
515         unsigned char* p;
516         unsigned char* st;
517         
518         txt=0;
519         if (unlikely((rdata+1)>end)) goto error;
520         n=0;
521         str_size=0;
522         /* count the number of strings */
523         p=rdata;
524         do{
525                 len=*p;
526                 p+=len+1;
527                 str_size+=len+1; /* 1 for the term. 0 */
528                 if (unlikely(p>end)) goto error;
529                 n++;
530         }while(p<end);
531         /* alloc sizeof struct + space for the dns_cstr array + space for
532            the strings */
533         txt=local_malloc(sizeof(struct txt_rdata) +(n-1)*sizeof(struct dns_cstr)+
534                                                 str_size);
535         if(unlikely(txt==0)){
536                 LOG(L_ERR, "ERROR: dns_txt_parser: out of memory\n");
537                 goto error;
538         }
539         /* string table */
540         st=(unsigned char*)txt+sizeof(struct txt_rdata) +
541                 (n-1)*sizeof(struct dns_cstr);
542         txt->cstr_no=n;
543         txt->tslen=str_size;
544         /* fill the structure */
545         p=rdata;
546         for (i=0; i<n; i++){
547                 len=*p;
548                 memcpy(st, p+1, len);
549                 st[len]=0;
550                 txt->txt[i].cstr_len=len;
551                 txt->txt[i].cstr=(char*)st;
552                 st+=len+1;
553                 p+=len+1;
554         }
555         return txt;
556 error:
557         if (txt) local_free(txt);
558         return 0;
559 }
560
561
562
563 /** parses an EBL record into a txt_rdata structure.
564  *   @param msg   - pointer to the dns message
565  *   @param end   - pointer to the end of the dns message
566  *   @param eor   - pointer to the end of the record (rdata end)
567  *   @param rdata - pointer  to the rdata part of the txt answer
568  * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
569 /*  EBL rdata format:
570  *  (see http://tools.ietf.org/html/draft-ietf-enum-branch-location-record-03)
571  * one or several character strings:
572  *  01234567
573  * +--------+
574  * | postion|
575  * +-----------+
576  * / separator /
577  * +-----------+
578  * /   apex    /
579  * +----------+
580  *
581  * where separator is a character string ( 8 bit len, followed by len chars)
582  * and apex is a domain-name.
583  */
584 static struct ebl_rdata* dns_ebl_parser(unsigned char* msg, unsigned char* end,
585                                                                                 unsigned char* eor,
586                                                                                 unsigned char* rdata)
587 {
588         struct ebl_rdata* ebl;
589         int sep_len;
590         int apex_len;
591         char apex[MAX_DNS_NAME];
592         
593         ebl=0;
594         /* check if len is at least 4 chars (minimum possible):
595              pos (1 byte) +  sep. (min 1 byte) + apex (min. 2 bytes) 
596            and also check if rdata+1 (pos) + 1 (sep. len) + sep_len + 1 is ok*/
597         if (unlikely(((rdata+4)>eor)||((rdata+1+1+rdata[1]+2)>eor))) goto error;
598         sep_len=rdata[1];
599         if (unlikely(dn_expand(msg, end, rdata+1+1+sep_len,
600                                                         apex, MAX_DNS_NAME-1)==-1))
601                 goto error;
602         apex_len=strlen(apex);
603         /* alloc sizeof struct + space for the 2 null-terminated strings */
604         ebl=local_malloc(sizeof(struct ebl_rdata)-1+sep_len+1+apex_len+1);
605         if (ebl==0){
606                 LOG(L_ERR, "ERROR: dns_ebl_parser: out of memory\n");
607                 goto error;
608         }
609         ebl->position=rdata[0];
610         ebl->separator=&ebl->str_table[0];
611         ebl->apex=ebl->separator+sep_len+1;
612         ebl->separator_len=sep_len;
613         ebl->apex_len=apex_len;
614         memcpy(ebl->separator, rdata+2, sep_len);
615         ebl->separator[sep_len]=0;
616         memcpy(ebl->apex, apex, apex_len);
617         ebl->apex[apex_len]=0;
618         
619         return ebl;
620 error:
621         if (ebl) local_free(ebl);
622         return 0;
623 }
624
625
626
627 /* parses a PTR record into a ptr_rdata structure */
628 struct ptr_rdata* dns_ptr_parser( unsigned char* msg, unsigned char* end,
629                                                                           unsigned char* rdata)
630 {
631         struct ptr_rdata* pname;
632         int len;
633         char name[MAX_DNS_NAME];
634         
635         pname=0;
636         if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
637                 goto error;
638         len=strlen(name);
639         if (len>255)
640                 goto error;
641         /* alloc sizeof struct + space for the null terminated name */
642         pname=local_malloc(sizeof(struct ptr_rdata)-1+len+1);
643         if(pname==0){
644                 LOG(L_ERR, "ERROR: dns_ptr_parser: out of memory\n");
645                 goto error;
646         }
647         pname->ptrdname_len=len;
648         memcpy(pname->ptrdname, name, pname->ptrdname_len);
649         pname->ptrdname[pname->ptrdname_len]=0;
650         return pname;
651 error:
652         if (pname) local_free(pname);
653         return 0;
654 }
655
656
657
658 /* frees completely a struct rdata list */
659 void free_rdata_list(struct rdata* head)
660 {
661         struct rdata* l;
662         struct rdata* next_l;
663         l=head;
664         while (l != 0) {
665                 next_l = l->next;
666                 /* free the parsed rdata*/
667                 if (l->rdata) local_free(l->rdata);
668                 local_free(l);
669                 l = next_l;
670         }
671 }
672
673 #ifdef HAVE_RESOLV_RES
674 /* checks whether supplied name exists in the resolver search list
675  * returns 1 if found
676  *         0 if not found
677  */
678 int match_search_list(const struct __res_state* res, char* name) {
679         int i;
680         for (i=0; (i<MAXDNSRCH) && (res->dnsrch[i]); i++) {
681                 if (strcasecmp(name, res->dnsrch[i])==0) 
682                         return 1;
683         }
684         return 0;
685 }
686 #endif
687
688 /* gets the DNS records for name:type
689  * returns a dyn. alloc'ed struct rdata linked list with the parsed responses
690  * or 0 on error
691  * see rfc1035 for the query/response format */
692 struct rdata* get_record(char* name, int type, int flags)
693 {
694         int size;
695         int skip;
696         int qno, answers_no;
697         int r;
698         static union dns_query buff;
699         unsigned char* p;
700         unsigned char* end;
701         unsigned char* rd_end;
702         static char rec_name[MAX_DNS_NAME]; /* placeholder for the record name */
703         int rec_name_len;
704         unsigned short rtype, class, rdlength;
705         unsigned int ttl;
706         struct rdata* head;
707         struct rdata** crt;
708         struct rdata** last;
709         struct rdata* rd;
710         struct srv_rdata* srv_rd;
711         struct srv_rdata* crt_srv;
712         int search_list_used;
713         int name_len;
714         struct rdata* fullname_rd;
715         
716         if (cfg_get(core, core_cfg, dns_search_list)==0) {
717                 search_list_used=0;
718                 name_len=0;
719         } else {
720                 search_list_used=1;
721                 name_len=strlen(name);
722         }
723         fullname_rd=0;
724
725         size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
726         if (unlikely(size<0)) {
727                 DBG("get_record: lookup(%s, %d) failed\n", name, type);
728                 goto not_found;
729         }
730         else if (unlikely(size > sizeof(buff))) size=sizeof(buff);
731         head=rd=0;
732         last=crt=&head;
733         
734         p=buff.buff+DNS_HDR_SIZE;
735         end=buff.buff+size;
736         if (unlikely(p>=end)) goto error_boundary;
737         qno=ntohs((unsigned short)buff.hdr.qdcount);
738
739         for (r=0; r<qno; r++){
740                 /* skip the name of the question */
741                 if (unlikely((p=dns_skipname(p, end))==0)) {
742                         LOG(L_ERR, "ERROR: get_record: skipname==0\n");
743                         goto error;
744                 }
745                 p+=2+2; /* skip QCODE & QCLASS */
746         #if 0
747                 for (;(p<end && (*p)); p++);
748                 p+=1+2+2; /* skip the ending  '\0, QCODE and QCLASS */
749         #endif
750                 if (unlikely(p>end)) {
751                         LOG(L_ERR, "ERROR: get_record: p>=end\n");
752                         goto error;
753                 }
754         };
755         answers_no=ntohs((unsigned short)buff.hdr.ancount);
756 again:
757         for (r=0; (r<answers_no) && (p<end); r++){
758 #if 0
759                 /*  ignore it the default domain name */
760                 if ((p=dns_skipname(p, end))==0) {
761                         LOG(L_ERR, "ERROR: get_record: skip_name=0 (#2)\n");
762                         goto error;
763                 }
764 #else
765                 if (unlikely((skip=dn_expand(buff.buff, end, p, rec_name,
766                                                         MAX_DNS_NAME-1))==-1)){
767                         LOG(L_ERR, "ERROR: get_record: dn_expand(rec_name) failed\n");
768                         goto error;
769                 }
770 #endif
771                 p+=skip;
772                 rec_name_len=strlen(rec_name);
773                 if (unlikely(rec_name_len>255)){
774                         LOG(L_ERR, "ERROR: get_record: dn_expand(rec_name): name too"
775                                         " long  (%d)\n", rec_name_len);
776                         goto error;
777                 }
778                 /* check if enough space is left for type, class, ttl & size */
779                 if (unlikely((p+2+2+4+2)>end)) goto error_boundary;
780                 /* get type */
781                 memcpy((void*) &rtype, (void*)p, 2);
782                 rtype=ntohs(rtype);
783                 p+=2;
784                 /* get  class */
785                 memcpy((void*) &class, (void*)p, 2);
786                 class=ntohs(class);
787                 p+=2;
788                 /* get ttl*/
789                 memcpy((void*) &ttl, (void*)p, 4);
790                 ttl=ntohl(ttl);
791                 p+=4;
792                 /* get size */
793                 memcpy((void*)&rdlength, (void*)p, 2);
794                 rdlength=ntohs(rdlength);
795                 p+=2;
796                 rd_end=p+rdlength;
797                 if (unlikely((rd_end)>end)) goto error_boundary;
798                 if ((flags & RES_ONLY_TYPE) && (rtype!=type)){
799                         /* skip */
800                         p=rd_end;
801                         continue;
802                 }
803                 /* expand the "type" record  (rdata)*/
804                 
805                 rd=(struct rdata*) local_malloc(sizeof(struct rdata)+rec_name_len+
806                                                                                 1-1);
807                 if (rd==0){
808                         LOG(L_ERR, "ERROR: get_record: out of memory\n");
809                         goto error;
810                 }
811                 rd->type=rtype;
812                 rd->pclass=class;
813                 rd->ttl=ttl;
814                 rd->next=0;
815                 memcpy(rd->name, rec_name, rec_name_len);
816                 rd->name[rec_name_len]=0;
817                 rd->name_len=rec_name_len;
818                 /* check if full name matches */
819                 if ((search_list_used==1)&&(fullname_rd==0)&&
820                                 (rec_name_len>=name_len)&&
821                                 (strncasecmp(rec_name, name, name_len)==0)) {
822                         /* now we have record whose name is the same (up-to the
823                          * name_len with the searched one):
824                          * if the length is the same - we found full match, no fake
825                          *  cname needed, just clear the flag
826                          * if the length of the name differs - it has matched using
827                          *  search list remember the rd, so we can create fake CNAME
828                          *  record when all answers are used and no better match found
829                          */
830                         if (rec_name_len==name_len)
831                                 search_list_used=0;
832                         /* this is safe.... here was rec_name_len > name_len */
833                         else if (rec_name[name_len]=='.') {
834 #ifdef HAVE_RESOLV_RES
835                                 if ((cfg_get(core, core_cfg, dns_search_fmatch)==0) ||
836                                                 (match_search_list(&_res, rec_name+name_len+1)!=0))
837 #endif
838                                         fullname_rd=rd;
839                         }
840                 }
841                 switch(rtype){
842                         case T_SRV:
843                                 srv_rd= dns_srv_parser(buff.buff, end, rd_end, p);
844                                 rd->rdata=(void*)srv_rd;
845                                 if (unlikely(srv_rd==0)) goto error_parse;
846                                 
847                                 /* insert sorted into the list */
848                                 for (crt=&head; *crt; crt= &((*crt)->next)){
849                                         if ((*crt)->type!=T_SRV)
850                                                 continue;
851                                         crt_srv=(struct srv_rdata*)(*crt)->rdata;
852                                         if ((srv_rd->priority <  crt_srv->priority) ||
853                                            ( (srv_rd->priority == crt_srv->priority) && 
854                                                          (srv_rd->weight > crt_srv->weight) ) ){
855                                                 /* insert here */
856                                                 goto skip;
857                                         }
858                                 }
859                                 last=&(rd->next); /*end of for => this will be the last
860                                                                         element*/
861                         skip:
862                                 /* insert here */
863                                 rd->next=*crt;
864                                 *crt=rd;
865                                 break;
866                         case T_A:
867                                 rd->rdata=(void*) dns_a_parser(p, rd_end);
868                                 if (unlikely(rd->rdata==0)) goto error_parse;
869                                 *last=rd; /* last points to the last "next" or the list
870                                                                 head*/
871                                 last=&(rd->next);
872                                 break;
873                         case T_AAAA:
874                                 rd->rdata=(void*) dns_aaaa_parser(p, rd_end);
875                                 if (unlikely(rd->rdata==0)) goto error_parse;
876                                 *last=rd;
877                                 last=&(rd->next);
878                                 break;
879                         case T_CNAME:
880                                 rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
881                                 if(unlikely(rd->rdata==0)) goto error_parse;
882                                 *last=rd;
883                                 last=&(rd->next);
884                                 break;
885                         case T_NAPTR:
886                                 rd->rdata=(void*)dns_naptr_parser(buff.buff, end, rd_end, p);
887                                 if(unlikely(rd->rdata==0)) goto error_parse;
888                                 *last=rd;
889                                 last=&(rd->next);
890                                 break;
891                         case T_TXT:
892                                 rd->rdata= dns_txt_parser(buff.buff, rd_end, p);
893                                 if (rd->rdata==0) goto error_parse;
894                                 *last=rd;
895                                 last=&(rd->next);
896                                 break;
897                         case T_EBL:
898                                 rd->rdata= dns_ebl_parser(buff.buff, end, rd_end, p);
899                                 if (rd->rdata==0) goto error_parse;
900                                 *last=rd;
901                                 last=&(rd->next);
902                                 break;
903                         case T_PTR:
904                                 rd->rdata=(void*) dns_ptr_parser(buff.buff, end, p);
905                                 if(unlikely(rd->rdata==0)) goto error_parse;
906                                 *last=rd;
907                                 last=&(rd->next);
908                                 break;
909                         default:
910                                 LOG(L_ERR, "WARNING: get_record: unknown type %d\n", rtype);
911                                 rd->rdata=0;
912                                 *last=rd;
913                                 last=&(rd->next);
914                 }
915                 
916                 p+=rdlength;
917                 
918         }
919         if (flags & RES_AR){
920                 flags&=~RES_AR;
921                 answers_no=ntohs((unsigned short)buff.hdr.nscount);
922 #ifdef RESOLVE_DBG
923                 DBG("get_record: skipping %d NS (p=%p, end=%p)\n", answers_no, p,
924                                 end);
925 #endif
926                 for (r=0; (r<answers_no) && (p<end); r++){
927                         /* skip over the ns records */
928                         if ((p=dns_skipname(p, end))==0) {
929                                 LOG(L_ERR, "ERROR: get_record: skip_name=0 (#3)\n");
930                                 goto error;
931                         }
932                         /* check if enough space is left for type, class, ttl & size */
933                         if (unlikely((p+2+2+4+2)>end)) goto error_boundary;
934                         memcpy((void*)&rdlength, (void*)p+2+2+4, 2);
935                         p+=2+2+4+2+ntohs(rdlength);
936                 }
937                 answers_no=ntohs((unsigned short)buff.hdr.arcount);
938 #ifdef RESOLVE_DBG
939                 DBG("get_record: parsing %d ARs (p=%p, end=%p)\n", answers_no, p,
940                                 end);
941 #endif
942                 goto again; /* add also the additional records */
943         }
944
945         /* if the name was expanded using DNS search list
946          * create fake CNAME record to convert the short name
947          * (queried) to long name (answered)
948          */
949         if ((search_list_used==1)&&(fullname_rd!=0)) {
950                 rd=(struct rdata*) local_malloc(sizeof(struct rdata)+name_len+1-1);
951                 if (unlikely(rd==0)){
952                         LOG(L_ERR, "ERROR: get_record: out of memory\n");
953                         goto error;
954                 }
955                 rd->type=T_CNAME;
956                 rd->pclass=fullname_rd->pclass;
957                 rd->ttl=fullname_rd->ttl;
958                 rd->next=head;
959                 memcpy(rd->name, name, name_len);
960                 rd->name[name_len]=0;
961                 rd->name_len=name_len;
962                 /* alloc sizeof struct + space for the null terminated name */
963                 rd->rdata=(void*)local_malloc(sizeof(struct cname_rdata)-1+
964                                                                                 head->name_len+1);
965                 if(unlikely(rd->rdata==0)){
966                         LOG(L_ERR, "ERROR: get_record: out of memory\n");
967                         goto error_rd;
968                 }
969                 ((struct cname_rdata*)(rd->rdata))->name_len=fullname_rd->name_len;
970                 memcpy(((struct cname_rdata*)(rd->rdata))->name, fullname_rd->name,
971                                 fullname_rd->name_len);
972                 ((struct cname_rdata*)(rd->rdata))->name[head->name_len]=0;
973                 head=rd;
974         }
975
976         return head;
977 error_boundary:
978                 LOG(L_ERR, "ERROR: get_record: end of query buff reached\n");
979                 if (head) free_rdata_list(head);
980                 return 0;
981 error_parse:
982                 LOG(L_ERR, "ERROR: get_record: rdata parse error (%s, %d), %p-%p"
983                                                 " rtype=%d, class=%d, ttl=%d, rdlength=%d \n",
984                                 name, type,
985                                 p, end, rtype, class, ttl, rdlength);
986 error_rd:
987                 if (rd) local_free(rd); /* rd->rdata=0 & rd is not linked yet into
988                                                                    the list */
989 error:
990                 LOG(L_ERR, "ERROR: get_record \n");
991                 if (head) free_rdata_list(head);
992 not_found:
993         /* increment error counter */
994         counter_inc(dns_cnts_h.failed_dns_req);
995         return 0;
996 }
997
998 #ifdef USE_NAPTR
999
1000 /* service matching constants, lowercase */
1001 #define SIP_SCH         0x2b706973
1002 #define SIPS_SCH        0x73706973
1003 #define SIP_D2U         0x00753264
1004 #define SIP_D2T         0x00743264
1005 #define SIP_D2S         0x00733264
1006 #define SIPS_D2T        0x7432642b
1007
1008
1009 /* get protocol from a naptr rdata and check for validity
1010  * returns > 0 (PROTO_UDP, PROTO_TCP, PROTO_SCTP or PROTO_TLS)
1011  *         <=0  on error 
1012  */
1013 char naptr_get_sip_proto(struct naptr_rdata* n)
1014 {
1015         unsigned int s;
1016         char proto;
1017
1018         proto=-1;
1019         
1020         if ((n->flags_len!=1) || ((*n->flags | 0x20 )!='s'))
1021                 return -1;
1022         if (n->regexp_len!=0)
1023                 return -1;
1024         /* SIP+D2U, SIP+D2T, SIP+D2S, SIPS+D2T */
1025         if (n->services_len==7){ /* SIP+D2X */
1026                 s=n->services[0]+(n->services[1]<<8)+(n->services[2]<<16)+
1027                                 (n->services[3]<<24);
1028                 s|=0x20202020;
1029                 if (s==SIP_SCH){
1030                         s=n->services[4]+(n->services[5]<<8)+(n->services[6]<<16);
1031                         s|=0x00202020;
1032                         switch(s){
1033                                 case SIP_D2U:
1034                                         proto=PROTO_UDP;
1035                                         break;
1036                                 case SIP_D2T:
1037                                         proto=PROTO_TCP;
1038                                         break;
1039                                 case SIP_D2S:
1040                                         proto=PROTO_SCTP;
1041                                         break;
1042                                 default:
1043                                         return -1;
1044                         }
1045                 }else{
1046                         return -1;
1047                 }
1048         }else if  (n->services_len==8){ /*SIPS+D2T */
1049                 s=n->services[0]+(n->services[1]<<8)+(n->services[2]<<16)+
1050                                 (n->services[3]<<24);
1051                 s|=0x20202020;
1052                 if (s==SIPS_SCH){
1053                         s=n->services[4]+(n->services[5]<<8)+(n->services[6]<<16)+
1054                                         (n->services[7]<<24);
1055                         s|=0x20202020;
1056                         if (s==SIPS_D2T){
1057                                 proto=PROTO_TLS;
1058                         }
1059                 }else{
1060                         return -1;
1061                 }
1062         }else{
1063                 return -1;
1064         }
1065         return proto;
1066 }
1067
1068
1069
1070 inline static int proto_pref_score(char proto)
1071 {
1072         if ((proto>=PROTO_UDP) && (proto<= PROTO_LAST))
1073                 return naptr_proto_pref[(int)proto];
1074         return 0;
1075 }
1076
1077
1078
1079 /* returns true if we support the protocol */
1080 int naptr_proto_supported(char proto)
1081 {
1082         if (proto_pref_score(proto)<0)
1083                 return 0;
1084         switch(proto){
1085                 case PROTO_UDP:
1086                         return 1;
1087 #ifdef USE_TCP
1088                 case PROTO_TCP:
1089                         return !tcp_disable;
1090 #ifdef USE_TLS
1091                 case PROTO_TLS:
1092                         return !tls_disable;
1093 #endif /* USE_TLS */
1094 #endif /* USE_TCP */
1095 #ifdef USE_SCTP
1096                 case PROTO_SCTP:
1097                         return !sctp_disable;
1098 #endif
1099         }
1100         return 0;
1101 }
1102
1103
1104
1105
1106 /* returns true if new_proto is preferred over old_proto */
1107 int naptr_proto_preferred(char new_proto, char old_proto)
1108 {
1109         return proto_pref_score(new_proto)>proto_pref_score(old_proto);
1110 }
1111
1112
1113 /* choose between 2 naptr records, should take into account local
1114  * preferences too
1115  * returns 1 if the new record was selected, 0 otherwise */
1116 int naptr_choose (struct naptr_rdata** crt, char* crt_proto,
1117                                                                         struct naptr_rdata* n , char n_proto)
1118 {
1119 #ifdef NAPTR_DBG
1120         DBG("naptr_choose(o: %d w: %d p:%d , o: %d w:%d p:%d)\n",
1121                         *crt?(int)(*crt)->order:-1, *crt?(int)(*crt)->pref:-1,
1122                         (int)*crt_proto,
1123                         (int)n->order, (int)n->pref, (int)n_proto);
1124 #endif
1125         if ((*crt==0) || ((*crt_proto!=n_proto) && 
1126                                                 ( naptr_proto_preferred(n_proto, *crt_proto))) )
1127                         goto change;
1128         if (!naptr_proto_preferred(*crt_proto, n_proto) && 
1129                         ((n->order<(*crt)->order) || ((n->order== (*crt)->order) &&
1130                                                                 (n->pref < (*crt)->pref)))){
1131                         goto change;
1132         }
1133 #ifdef NAPTR_DBG
1134         DBG("naptr_choose: no change\n");
1135 #endif
1136         return 0;
1137 change:
1138 #ifdef NAPTR_DBG
1139         DBG("naptr_choose: changed\n");
1140 #endif
1141         *crt_proto=n_proto;
1142         *crt=n;
1143         return 1;
1144 }
1145 #endif /* USE_NAPTR */
1146
1147
1148
1149 /* internal sip srv resolver: resolves a host name trying:
1150  * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1151  *   query will be used for an A/AAAA lookup.
1152  *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1153  *   and *proto!=0 or port==0 && proto==0)
1154  * when performing SRV lookup (*port==0) it will use *proto to look for
1155  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1156  * If zt is set, name will be assumed to be 0 terminated and some copy 
1157  * operations will be avoided.
1158  * If is_srv is set it will assume name has the srv prefixes for sip already
1159  *  appended and it's already 0-term'ed; if not it will append them internally.
1160  * If ars !=0, it will first try to look through them and only if the SRV
1161  *   record is not found it will try doing a DNS query  (ars will not be
1162  *   freed, the caller should take care of them)
1163  * returns: hostent struct & *port filled with the port from the SRV record;
1164  *  0 on error
1165  */
1166 struct hostent* srv_sip_resolvehost(str* name, int zt, unsigned short* port,
1167                                                                         char* proto, int is_srv, struct rdata* ars)
1168 {
1169         struct hostent* he;
1170         struct ip_addr* ip;
1171         static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups and
1172                                           null. term  strings */
1173         struct rdata* l;
1174         struct srv_rdata* srv;
1175         struct rdata* srv_head;
1176         char* srv_target;
1177         char srv_proto;
1178
1179         /* init */
1180         srv_head=0;
1181         srv_target=0;
1182         if (name->len >= MAX_DNS_NAME) {
1183                 LOG(L_ERR, "sip_resolvehost: domain name too long\n");
1184                 he=0;
1185                 goto end;
1186         }
1187 #ifdef RESOLVE_DBG
1188         DBG("srv_sip_resolvehost: %.*s:%d proto=%d\n", name->len, name->s,
1189                         port?(int)*port:-1, proto?(int)*proto:-1);
1190 #endif
1191         if (is_srv){
1192                 /* skip directly to srv resolving */
1193                 srv_proto=(proto)?*proto:0;
1194                 *port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT;
1195                 if (zt){
1196                         srv_target=name->s; /* name.s must be 0 terminated in
1197                                                                   this case */
1198                 }else{
1199                         memcpy(tmp, name->s, name->len);
1200                         tmp[name->len] = '\0';
1201                         srv_target=tmp;
1202                 }
1203                 goto do_srv; /* skip to the actual srv query */
1204         }
1205         if (proto){ /* makes sure we have a protocol set*/
1206                 if (*proto==0)
1207                         *proto=srv_proto=PROTO_UDP; /* default */
1208                 else
1209                         srv_proto=*proto;
1210         }else{
1211                 srv_proto=PROTO_UDP;
1212         }
1213         /* try SRV if no port specified (draft-ietf-sip-srv-06) */
1214         if ((port)&&(*port==0)){
1215                 *port=(srv_proto==PROTO_TLS)?SIPS_PORT:SIP_PORT; /* just in case we
1216                                                                                                                   don't find another */
1217                 /* check if it's an ip address */
1218                 if (((ip=str2ip(name))!=0)
1219 #ifdef  USE_IPV6
1220                           || ((ip=str2ip6(name))!=0) 
1221 #endif
1222                          ){
1223                         /* we are lucky, this is an ip address */
1224                         he=ip_addr2he(name, ip);
1225                         goto end;
1226                 }
1227                 if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME){
1228                         LOG(L_WARN, "WARNING: sip_resolvehost: domain name too long (%d),"
1229                                                 " unable to perform SRV lookup\n", name->len);
1230                 }else{
1231                         
1232                         switch(srv_proto){
1233                                 case PROTO_NONE: /* no proto specified, use udp */
1234                                         if (proto)
1235                                                 *proto=PROTO_UDP;
1236                                         /* no break */
1237                                 case PROTO_UDP:
1238                                         memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1239                                         memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
1240                                         tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1241                                         break;
1242                                 case PROTO_TCP:
1243                                         memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1244                                         memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
1245                                         tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1246                                         break;
1247                                 case PROTO_TLS:
1248                                         memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1249                                         memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
1250                                         tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1251                                         break;
1252                                 case PROTO_SCTP:
1253                                         memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
1254                                         memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
1255                                         tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
1256                                         break;
1257                                 default:
1258                                         LOG(L_CRIT, "BUG: sip_resolvehost: unknown proto %d\n",
1259                                                         srv_proto);
1260                                         he=0;
1261                                         goto end;
1262                         }
1263                         srv_target=tmp;
1264 do_srv:
1265                         /* try to find the SRV records inside previous ARs  first*/
1266                         for (l=ars; l; l=l->next){
1267                                 if (l->type!=T_SRV) continue; 
1268                                 srv=(struct srv_rdata*) l->rdata;
1269                                 if (srv==0){
1270                                         LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
1271                                         /* cleanup on exit only */
1272                                         break;
1273                                 }
1274                                 he=resolvehost(srv->name);
1275                                 if (he!=0){
1276                                         /* we found it*/
1277 #ifdef RESOLVE_DBG
1278                                         DBG("sip_resolvehost: found SRV(%s) = %s:%d in AR\n",
1279                                                         srv_target, srv->name, srv->port);
1280 #endif
1281                                         *port=srv->port;
1282                                         /* cleanup on exit */
1283                                         goto end;
1284                                 }
1285                         }
1286                         srv_head=get_record(srv_target, T_SRV, RES_ONLY_TYPE);
1287                         for(l=srv_head; l; l=l->next){
1288                                 if (l->type!=T_SRV) continue; /*should never happen*/
1289                                 srv=(struct srv_rdata*) l->rdata;
1290                                 if (srv==0){
1291                                         LOG(L_CRIT, "sip_resolvehost: BUG: null rdata\n");
1292                                         /* cleanup on exit only */
1293                                         break;
1294                                 }
1295                                 he=resolvehost(srv->name);
1296                                 if (he!=0){
1297                                         /* we found it*/
1298 #ifdef RESOLVE_DBG
1299                                         DBG("sip_resolvehost: SRV(%s) = %s:%d\n",
1300                                                         srv_target, srv->name, srv->port);
1301 #endif
1302                                         *port=srv->port;
1303                                         /* cleanup on exit */
1304                                         goto end;
1305                                 }
1306                         }
1307                         if (is_srv){
1308                                 /* if the name was already into SRV format it doesn't make
1309                                  * any sense to fall back to A/AAAA */
1310                                 he=0;
1311                                 goto end;
1312                         }
1313                         /* cleanup on exit */
1314 #ifdef RESOLVE_DBG
1315                         DBG("sip_resolvehost: no SRV record found for %.*s," 
1316                                         " trying 'normal' lookup...\n", name->len, name->s);
1317 #endif
1318                 }
1319         }
1320 /*skip_srv:*/
1321         if (likely(!zt)){
1322                 memcpy(tmp, name->s, name->len);
1323                 tmp[name->len] = '\0';
1324                 he=resolvehost(tmp);
1325         }else{
1326                 he=resolvehost(name->s);
1327         }
1328 end:
1329 #ifdef RESOLVE_DBG
1330         DBG("srv_sip_resolvehost: returning %p (%.*s:%d proto=%d)\n",
1331                         he, name->len, name->s,
1332                         port?(int)*port:-1, proto?(int)*proto:-1);
1333 #endif
1334         if (srv_head)
1335                 free_rdata_list(srv_head);
1336         return he;
1337 }
1338
1339
1340
1341 #ifdef USE_NAPTR 
1342
1343
1344 /* iterates over a naptr rr list, returning each time a "good" naptr record
1345  * is found.( srv type, no regex and a supported protocol)
1346  * params:
1347  *         naptr_head - naptr rr list head
1348  *         tried      - bitmap used to keep track of the already tried records
1349  *                      (no more then sizeof(tried)*8 valid records are 
1350  *                      ever walked
1351  *         srv_name   - if succesfull, it will be set to the selected record
1352  *                      srv name (naptr repl.)
1353  *         proto      - if succesfull it will be set to the selected record
1354  *                      protocol
1355  * returns  0 if no more records found or a pointer to the selected record
1356  *  and sets  protocol and srv_name
1357  * WARNING: when calling first time make sure you run first 
1358  *           naptr_iterate_init(&tried)
1359  */
1360 struct rdata* naptr_sip_iterate(struct rdata* naptr_head, 
1361                                                                                 naptr_bmp_t* tried,
1362                                                                                 str* srv_name, char* proto)
1363 {
1364         int i, idx;
1365         struct rdata* l;
1366         struct rdata* l_saved;
1367         struct naptr_rdata* naptr;
1368         struct naptr_rdata* naptr_saved;
1369         char saved_proto;
1370         char naptr_proto;
1371
1372         idx=0;
1373         naptr_proto=PROTO_NONE;
1374         naptr_saved=0;
1375         l_saved=0;
1376         saved_proto=0;
1377         i=0;
1378         for(l=naptr_head; l && (i<MAX_NAPTR_RRS); l=l->next){
1379                 if (l->type!=T_NAPTR) continue; 
1380                 naptr=(struct naptr_rdata*) l->rdata;
1381                 if (naptr==0){
1382                                 LOG(L_CRIT, "naptr_iterate: BUG: null rdata\n");
1383                         goto end;
1384                 }
1385                 /* check if valid and get proto */
1386                 if ((naptr_proto=naptr_get_sip_proto(naptr))<=0) continue;
1387                 if (*tried& (1<<i)){
1388                         i++;
1389                         continue; /* already tried */
1390                 }
1391 #ifdef NAPTR_DBG
1392                 DBG("naptr_iterate: found a valid sip NAPTR rr %.*s,"
1393                                         " proto %d\n", naptr->repl_len, naptr->repl, 
1394                                         (int)naptr_proto);
1395 #endif
1396                 if ((naptr_proto_supported(naptr_proto))){
1397                         if (naptr_choose(&naptr_saved, &saved_proto,
1398                                                                 naptr, naptr_proto))
1399                                 idx=i;
1400                                 l_saved=l;
1401                         }
1402                 i++;
1403         }
1404         if (naptr_saved){
1405                 /* found something */
1406 #ifdef NAPTR_DBG
1407                 DBG("naptr_iterate: choosed NAPTR rr %.*s, proto %d"
1408                                         " tried: 0x%x\n", naptr_saved->repl_len, 
1409                                         naptr_saved->repl, (int)saved_proto, *tried);
1410 #endif
1411                 *tried|=1<<idx;
1412                 *proto=saved_proto;
1413                 srv_name->s=naptr_saved->repl;
1414                 srv_name->len=naptr_saved->repl_len;
1415                 return l_saved;
1416         }
1417 end:
1418         return 0;
1419 }
1420
1421
1422
1423
1424 /* internal sip naptr resolver function: resolves a host name trying:
1425  * - NAPTR lookup if the address is not an ip and *proto==0 and *port==0.
1426  *   The result of the NAPTR query will be used for a SRV lookup
1427  * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1428  *   query will be used for an A/AAAA lookup.
1429  *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1430  *   and *proto!=0 or port==0 && proto==0)
1431  * when performing SRV lookup (*port==0) it will use proto to look for
1432  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1433  * returns: hostent struct & *port filled with the port from the SRV record;
1434  *  0 on error
1435  */
1436 struct hostent* naptr_sip_resolvehost(str* name,  unsigned short* port,
1437                                                                                 char* proto)
1438 {
1439         struct hostent* he;
1440         struct ip_addr* ip;
1441         static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups and
1442                                           null. term  strings */
1443         struct rdata* l;
1444         struct rdata* naptr_head;
1445         char n_proto;
1446         str srv_name;
1447         naptr_bmp_t tried_bmp; /* tried bitmap */
1448
1449
1450
1451         naptr_head=0;
1452         he=0;
1453         if (name->len >= MAX_DNS_NAME) {
1454                 LOG(L_ERR, "naptr_sip_resolvehost: domain name too long\n");
1455                 goto end;
1456         }
1457         /* try NAPTR if no port or protocol is specified and NAPTR lookup is
1458          * enabled */
1459         if (port && proto && (*proto==0) && (*port==0)){
1460                 *proto=PROTO_UDP; /* just in case we don't find another */
1461                 if ( ((ip=str2ip(name))!=0)
1462 #ifdef  USE_IPV6
1463                           || ((ip=str2ip6(name))!=0)
1464 #endif
1465                 ){
1466                         /* we are lucky, this is an ip address */
1467                         he=ip_addr2he(name,ip);
1468                         *port=SIP_PORT;
1469                         goto end;
1470                 }
1471                 memcpy(tmp, name->s, name->len);
1472                 tmp[name->len] = '\0';
1473                 naptr_head=get_record(tmp, T_NAPTR, RES_AR);
1474                 naptr_iterate_init(&tried_bmp);
1475                 while((l=naptr_sip_iterate(naptr_head, &tried_bmp,
1476                                                                                 &srv_name, &n_proto))!=0){
1477                         if ((he=srv_sip_resolvehost(&srv_name, 1, port, proto, 1, l))!=0){
1478                                 *proto=n_proto;
1479                                 return he;
1480                         }
1481                 }
1482                 /*clean up on exit*/
1483 #ifdef RESOLVE_DBG
1484                 DBG("naptr_sip_resolvehost: no NAPTR record found for %.*s," 
1485                                 " trying SRV lookup...\n", name->len, name->s);
1486 #endif
1487         }
1488         /* fallback to normal srv lookup */
1489         he=srv_sip_resolvehost(name, 0, port, proto, 0, 0);
1490 end:
1491         if (naptr_head)
1492                 free_rdata_list(naptr_head);
1493         return he;
1494 }
1495 #endif /* USE_NAPTR */
1496
1497
1498
1499 /* resolves a host name trying:
1500  * - NAPTR lookup if enabled, the address is not an ip and *proto==0 and 
1501  *   *port==0. The result of the NAPTR query will be used for a SRV lookup
1502  * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1503  *   query will be used for an A/AAAA lookup.
1504  *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1505  *   and *proto!=0 or port==0 && proto==0)
1506  * when performing SRV lookup (*port==0) it will use *proto to look for
1507  * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1508  *
1509  * returns: hostent struct & *port filled with the port from the SRV record;
1510  *  0 on error
1511  */
1512 struct hostent* _sip_resolvehost(str* name, unsigned short* port, char* proto)
1513 {
1514         struct hostent* res = NULL;
1515 #ifdef USE_NAPTR
1516         if (cfg_get(core, core_cfg, dns_try_naptr))
1517                 res = naptr_sip_resolvehost(name, port, proto);
1518 #endif
1519         res = srv_sip_resolvehost(name, 0, port, proto, 0, 0);
1520         if( unlikely(!res) ){
1521                 /* failed DNS request */
1522                 counter_inc(dns_cnts_h.failed_dns_req);
1523         }
1524         return res;
1525 }
1526
1527
1528 /* resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
1529  *  and write the result in the sockaddr_union to
1530  *  returns -1 on error (resolve failed), 0 on success */
1531 int sip_hostport2su(union sockaddr_union* su, str* name, unsigned short port,
1532                                                 char* proto)
1533 {
1534         struct hostent* he;
1535         
1536         he=sip_resolvehost(name, &port, proto);
1537         if (he==0){
1538                 ser_error=E_BAD_ADDRESS;
1539                 LOG(L_ERR, "ERROR: sip_hostport2su: could not resolve hostname:"
1540                                         " \"%.*s\"\n", name->len, name->s);
1541                 goto error;
1542         }
1543         /* port filled by sip_resolvehost if empty*/
1544         if (hostent2su(su, he, 0, port)<0){
1545                 ser_error=E_BAD_ADDRESS;
1546                 goto error;
1547         }
1548         return 0;
1549 error:
1550         return -1;
1551 }