Coverage Report

Created: 2024-02-11 06:21

/src/opensips/resolve.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2003 FhG Fokus
3
 * Copyright (C) 2005-2009 Voice Sistem S.R.L.
4
 *
5
 * This file is part of opensips, a free SIP server.
6
 *
7
 * opensips is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 2 of the License, or
10
 * (at your option) any later version
11
 *
12
 * opensips is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
20
 *
21
 * History:
22
 * -------
23
 *  2003-02-13  added proto to sip_resolvehost, for SRV lookups (andrei)
24
 *  2003-07-03  default port value set according to proto (andrei)
25
 *  2007-01-25  support for DNS failover added (bogdan)
26
 *  2008-07-25  support for SRV load-balancing added (bogdan)
27
 */
28
29
30
/*!
31
 * \file
32
 * \brief DNS resolver for OpenSIPS
33
 */
34
35
#include <sys/types.h>
36
#include <netinet/in.h>
37
#include <arpa/nameser.h>
38
#include <resolv.h>
39
#include <string.h>
40
#include <stdlib.h>
41
#include <limits.h>
42
43
#include "mem/mem.h"
44
#include "mem/shm_mem.h"
45
#include "net/trans.h"
46
#include "resolve.h"
47
#include "dprint.h"
48
#include "ut.h"
49
#include "ip_addr.h"
50
#include "globals.h"
51
#include "blacklists.h"
52
53
fetch_dns_cache_f *dnscache_fetch_func=NULL;
54
put_dns_cache_f *dnscache_put_func=NULL;
55
56
/* stuff related to DNS failover */
57
0
#define DNS_NODE_SRV   1
58
0
#define DNS_NODE_A     2
59
60
struct dns_val {
61
  unsigned int ival;
62
  char *sval;
63
};
64
65
/* mallocs for local stuff */
66
0
#define local_malloc pkg_malloc
67
0
#define local_free   pkg_free
68
69
int dns_try_ipv6=0; /*!< default off */
70
int dns_try_naptr=1; /*!< default on */
71
/* declared in globals.h */
72
int dns_retr_time=-1;
73
int dns_retr_no=-1;
74
int dns_servers_no=-1;
75
int dns_search_list=-1;
76
int disable_dns_blacklist=1;
77
78
static struct bl_head *failover_bl=0;
79
#define DNS_REVOLVER_BL_ID    17
80
#define DNS_REVOLVER_BL_NAME  "dns"
81
0
#define DNS_BL_EXPIRE         4*60
82
83
#define MAX_BUFF_SIZE 8192
84
0
#define MAXALIASES  36
85
0
#define MAXADDRS  36
86
0
#define DNS_MAX_NAME  256
87
struct hostent global_he;
88
static char hostbuf[MAX_BUFF_SIZE];
89
static char *h_addr_ptrs[MAXADDRS];
90
static char *host_aliases[MAXALIASES];
91
92
stat_var *dns_total_queries;
93
stat_var *dns_slow_queries;
94
95
typedef union {
96
  int32_t al;
97
  char ac;
98
} align;
99
100
#define BOUNDED_INCR(x) \
101
0
  do { \
102
0
    cp += x; \
103
0
    if (cp > eom) { \
104
0
      LM_ERR("Bounded incr failed\n"); \
105
0
      return -1; \
106
0
      } \
107
0
    } while (0)
108
109
#define BOUNDS_CHECK(ptr, count) \
110
0
  do { \
111
0
    if ((ptr) + (count) > eom) { \
112
0
      LM_ERR("Bounded check failed\n"); \
113
0
      return -1; \
114
0
    } \
115
0
  } while (0)
116
117
# define DNS_GET16(s, cp) \
118
0
  do { \
119
0
    uint16_t t_cp; memcpy(&t_cp, cp, sizeof(uint16_t)); \
120
0
    (s) = ntohs (t_cp); \
121
0
  } while (0)
122
123
# define DNS_GET32(s, cp) \
124
0
  do { \
125
0
    uint32_t t_cp; memcpy(&t_cp, cp, sizeof(uint32_t)); \
126
0
    (s) = ntohl (t_cp); \
127
0
  } while (0)
128
129
0
static inline unsigned int dns_get16(const u_char *src) {
130
0
  unsigned int dst;
131
132
0
  DNS_GET16(dst, src);
133
0
  return dst;
134
0
}
135
136
0
static inline unsigned int dns_get32(const u_char *src) {
137
0
  unsigned int dst;
138
139
0
  DNS_GET32(dst, src);
140
0
  return dst;
141
0
}
142
143
int get_dns_answer(union dns_query *answer,int anslen,char *qname,int qtype,int *min_ttl)
144
0
{
145
0
  register const HEADER *hp;
146
0
  register int n;
147
0
  register const unsigned char *cp;
148
0
  const char* tname;
149
0
  const unsigned char *eom,*erdata;
150
0
  int type, class,ttl, buflen, ancount;
151
0
  int haveanswer, had_error;
152
0
  char *bp,**ap,**hap;
153
0
  char tbuf[DNS_MAX_NAME];
154
0
  int toobig=0;
155
156
0
  tname = qname;
157
0
  global_he.h_name = NULL;
158
0
  eom = answer->buff + anslen;
159
160
0
  hp = &answer->hdr;
161
0
  ancount = ntohs(hp->ancount);
162
0
  bp = hostbuf;
163
0
  buflen = sizeof hostbuf;
164
165
0
  cp = answer->buff;
166
0
  BOUNDED_INCR(DNS_HDR_SIZE);
167
168
0
  n = dn_expand(answer->buff, eom, cp, bp, buflen);
169
0
  if (n < 0) {
170
0
    LM_ERR("Error expanding name\n");
171
0
    return -1;
172
0
  }
173
0
  BOUNDED_INCR(n+4);
174
175
0
  if (qtype == T_A || qtype == T_AAAA) {
176
0
    n = strlen(bp) + 1;
177
0
    if (n >= DNS_MAX_NAME) {
178
0
      LM_ERR("Name too large\n");
179
0
      return -1;
180
0
    }
181
0
    global_he.h_name = bp;
182
0
    bp += n;
183
0
    buflen -= n;
184
    /* The qname can be abbreviated, but h_name is now absolute. */
185
0
    qname = global_he.h_name;
186
0
  }
187
188
0
  ap = host_aliases;
189
0
  *ap = NULL;
190
0
  global_he.h_aliases = host_aliases;
191
0
  hap = h_addr_ptrs;
192
0
  *hap = NULL;
193
0
  global_he.h_addr_list = h_addr_ptrs;
194
0
  haveanswer = 0;
195
0
  had_error = 0;
196
0
  while (ancount-- > 0 && cp < eom && !had_error) {
197
0
    n = dn_expand(answer->buff, eom, cp, bp, buflen);
198
0
    if (n < 0) {
199
0
      had_error++;
200
0
      continue;
201
0
    }
202
0
    cp += n;  /* name */
203
0
    BOUNDS_CHECK(cp,3*2+4);
204
0
    type = dns_get16(cp);
205
0
    cp += 2;  /* type */
206
0
    class = dns_get16(cp);
207
0
    cp += 2;  /* class*/
208
0
    ttl = dns_get32(cp);
209
0
    if (ttl<*min_ttl)
210
0
      *min_ttl=ttl;
211
0
    cp +=4;
212
0
    n = dns_get16(cp);
213
0
    cp += 2;  /* len */
214
0
    BOUNDS_CHECK(cp, n);
215
0
    erdata = cp + n;
216
217
0
    if (class != C_IN) {
218
0
      LM_ERR("Got response class != C_IN");
219
0
      had_error++;
220
0
      continue;
221
0
    }
222
223
0
    if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
224
0
      if (ap >= &host_aliases[MAXALIASES-1])
225
0
        continue;
226
0
      n = dn_expand(answer->buff, eom, cp, tbuf, sizeof tbuf);
227
0
      if (n < 0) {
228
0
        LM_ERR("failed to expand alias\n");
229
0
        had_error++;
230
0
        continue;
231
0
      }
232
0
      cp += n;
233
0
      if (cp != erdata)
234
0
        return -1;
235
      /* Store alias. */
236
0
      *ap++ = bp;
237
0
      n = strlen(bp) + 1;
238
0
      if (n >= DNS_MAX_NAME) {
239
0
        LM_ERR("alias too long\n");
240
0
        had_error++;
241
0
        continue;
242
0
      }
243
0
      bp += n;
244
0
      buflen -= n;
245
      /* Get canonical name. */
246
0
      n = strlen(tbuf) + 1;
247
0
      if (n > buflen || n >= DNS_MAX_NAME) {
248
0
        had_error++;
249
0
        continue;
250
0
      }
251
252
0
      strcpy(bp, tbuf);
253
0
      global_he.h_name = bp;
254
0
      bp += n;
255
0
      buflen -= n;
256
0
      continue;
257
0
    }
258
259
0
    if (qtype == T_PTR && type == T_CNAME) {
260
0
      n = dn_expand(answer->buff, eom, cp, tbuf, sizeof tbuf);
261
0
      if (n < 0) {
262
0
        LM_ERR("failed to expand for t_ptr\n");
263
0
        had_error++;
264
0
        continue;
265
0
      }
266
267
0
      cp += n;
268
0
      if (cp != erdata) {
269
0
        LM_ERR("failure\n");
270
0
        return -1;
271
0
      }
272
      /* Get canonical name. */
273
0
      n = strlen(tbuf) + 1;
274
0
      if (n > buflen || n >= DNS_MAX_NAME) {
275
0
        LM_ERR("ptr name too long\n");
276
0
        had_error++;
277
0
        continue;
278
0
      }
279
0
      strcpy(bp, tbuf);
280
0
      tname = bp;
281
0
      bp += n;
282
0
      buflen -= n;
283
0
      continue;
284
0
    }
285
286
0
    if (type != qtype) {
287
0
      LM_ERR("asked for %d, got %d\n",qtype,type);
288
0
      cp+=n;
289
0
      continue;
290
0
    }
291
292
0
    switch (type) {
293
0
      case T_PTR:
294
0
        if (strcasecmp(tname, bp) != 0) {
295
0
          LM_ERR("asked for %s, got %s\n",tname,bp);
296
0
          cp += n;
297
0
          continue; /* XXX - had_error++ ? */
298
0
        }
299
0
        n = dn_expand(answer->buff, eom, cp, bp, buflen);
300
0
        if (n < 0) {
301
0
          had_error++;
302
0
          break;
303
0
        }
304
0
        cp += n;
305
0
        if (cp != erdata) {
306
0
          LM_ERR("errdata err\n");
307
0
          return -1;
308
0
        }
309
0
        if (!haveanswer)
310
0
          global_he.h_name = bp;
311
0
        else if (ap < &host_aliases[MAXALIASES-1])
312
0
          *ap++ = bp;
313
0
        else
314
0
          n = -1;
315
0
        if (n != -1) {
316
0
          n = strlen(bp) + 1; /* for the \0 */
317
0
          if (n >= MAXHOSTNAMELEN) {
318
0
            had_error++;
319
0
            break;
320
0
          }
321
0
          bp += n;
322
0
          buflen -= n;
323
0
        }
324
0
        break;
325
0
      case T_A:
326
0
      case T_AAAA:
327
0
        if (strcasecmp(global_he.h_name, bp) != 0) {
328
0
          LM_ERR("asked for %s, got %s\n",global_he.h_name,bp);
329
0
          cp += n;
330
0
          continue; /* XXX - had_error++ ? */
331
0
        }
332
0
        if (n != global_he.h_length) {
333
0
          cp += n;
334
0
          continue;
335
0
        }
336
0
        if (!haveanswer) {
337
0
          register int nn;
338
339
0
          global_he.h_name = bp;
340
0
          nn = strlen(bp) + 1;
341
0
          bp += nn;
342
0
          buflen -= nn;
343
0
        }
344
345
0
        buflen -= sizeof(align) - ((u_long)bp % sizeof(align));
346
0
        bp += sizeof(align) - ((u_long)bp % sizeof(align));
347
348
0
        if (bp + n >= &hostbuf[sizeof hostbuf]) {
349
0
          LM_ERR("size (%d) too big\n", n);
350
0
          had_error++;
351
0
          continue;
352
0
        }
353
0
        if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
354
0
          if (!toobig++)
355
0
            LM_ERR("Too many addresses (%d)\n",MAXADDRS);
356
0
          cp += n;
357
0
          continue;
358
0
        }
359
360
0
        memmove(*hap++ = bp, cp, n);
361
0
        bp += n;
362
0
        buflen -= n;
363
0
        cp += n;
364
0
        if (cp != erdata) {
365
0
          LM_ERR("failure\n");
366
0
          return -1;
367
0
        }
368
0
        break;
369
0
      default:
370
0
        LM_ERR("should never get here\n");
371
0
        return -1;
372
0
    }
373
0
    if (!had_error)
374
0
      haveanswer++;
375
0
  }
376
377
0
  if (haveanswer) {
378
0
    *ap = NULL;
379
0
    *hap = NULL;
380
0
    if (!global_he.h_name) {
381
0
      n = strlen(qname) + 1;
382
0
      if (n > buflen || n >= DNS_MAX_NAME) {
383
0
        LM_ERR("name too long\n");
384
0
        return -1;
385
0
      }
386
0
        strcpy(bp, qname);
387
0
        global_he.h_name = bp;
388
0
        bp += n;
389
0
        buflen -= n;
390
0
    }
391
0
  }
392
393
0
  return 0;
394
0
}
395
396
struct hostent* own_gethostbyname2(char *name,int af)
397
0
{
398
0
  int size,type;
399
0
  struct hostent *cached_he;
400
0
  static union dns_query buff;
401
0
  int min_ttl = INT_MAX;
402
403
0
  switch (af) {
404
0
    case AF_INET:
405
0
      size=4;
406
0
      type=T_A;
407
0
      break;
408
0
    case AF_INET6:
409
0
      size=16;
410
0
      type=T_AAAA;
411
0
      break;
412
0
    default:
413
0
      LM_ERR("Only A and AAAA queries\n");
414
0
      return NULL;
415
0
  }
416
417
0
  cached_he = (struct hostent *)dnscache_fetch_func(name,af==AF_INET?T_A:T_AAAA,0);
418
0
  if (cached_he == NULL) {
419
0
    LM_DBG("not found in cache or other internal error\n");
420
0
    goto query;
421
0
  } else if (cached_he == (void *)-1) {
422
0
    LM_DBG("previously failed query\n");
423
0
    return NULL;
424
0
  } else {
425
0
    LM_DBG("cache hit for %s - %d\n",name,af);
426
0
    return cached_he;
427
0
  }
428
429
0
query:
430
0
  global_he.h_addrtype=af;
431
0
  global_he.h_length=size;
432
433
0
  size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
434
0
  if (size < 0) {
435
0
    LM_DBG("Domain name not found\n");
436
0
    if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0)
437
0
      LM_ERR("Failed to store %s - %d in cache\n",name,af);
438
0
    return NULL;
439
0
  }
440
441
0
  if (get_dns_answer(&buff,size,name,type,&min_ttl) < 0) {
442
0
    LM_ERR("Failed to get dns answer\n");
443
0
    return NULL;
444
0
  }
445
446
0
  if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,&global_he,-1,0,min_ttl) < 0)
447
0
    LM_ERR("Failed to store %s - %d in cache\n",name,af);
448
0
  return &global_he;
449
0
}
450
451
inline struct hostent* resolvehost(char* name, int no_ip_test)
452
0
{
453
0
  static struct hostent *he = NULL;
454
#ifdef HAVE_GETIPNODEBYNAME
455
  int err;
456
  static struct hostent *he2 = NULL;
457
#endif
458
0
  struct timeval start;
459
0
  struct ip_addr *ip;
460
0
  str s;
461
462
0
  if (!no_ip_test) {
463
0
    s.s = (char *)name;
464
0
    s.len = strlen(name);
465
466
    /* check if it's an ip address */
467
0
    if ((ip = str2ip(&s)) || (ip = str2ip6(&s))) {
468
      /* we are lucky, this is an ip address */
469
0
      return ip_addr2he(&s, ip);
470
0
    }
471
0
  }
472
473
0
  start_expire_timer(start, execdnsthreshold);
474
475
0
  if (dns_try_ipv6) {
476
    /* try ipv6 */
477
0
  #ifdef HAVE_GETHOSTBYNAME2
478
0
    if (dnscache_fetch_func)
479
0
          he = own_gethostbyname2(name,AF_INET6);
480
0
    else
481
0
      he = gethostbyname2(name, AF_INET6);
482
483
  #elif defined HAVE_GETIPNODEBYNAME
484
    /* on solaris 8 getipnodebyname has a memory leak,
485
     * after some time calls to it will fail with err=3
486
     * solution: patch your solaris 8 installation */
487
    if (he2) freehostent(he2);
488
    he = he2 = getipnodebyname(name, AF_INET6, 0, &err);
489
  #else
490
    #error "neither gethostbyname2 or getipnodebyname present"
491
  #endif
492
0
    if (he != 0)
493
      /* return the inet6 result if exists */
494
0
      goto out;
495
0
  }
496
497
0
  if (dnscache_fetch_func)
498
0
    he = own_gethostbyname2(name,AF_INET);
499
0
  else
500
0
    he = gethostbyname(name);
501
502
0
out:
503
0
  _stop_expire_timer(start, execdnsthreshold, "dns",
504
0
              name, strlen(name), 0, dns_slow_queries, dns_total_queries);
505
0
  return he;
506
0
}
507
508
struct hostent * own_gethostbyaddr(void *addr, socklen_t len, int af)
509
0
{
510
0
  const unsigned char *uaddr = (const u_char *)addr;
511
0
  static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
512
0
  static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
513
0
  int n;
514
0
  int ret;
515
0
  static union dns_query ptr_buff;
516
0
  socklen_t size;
517
0
  char qbuf[DNS_MAX_NAME+1];
518
0
  char *qp=NULL;
519
0
  int min_ttl=INT_MAX;
520
0
  struct hostent *cached_he;
521
522
0
  if (af == AF_INET6 && len == 16 &&
523
0
  (!memcmp(uaddr, mapped, sizeof mapped) ||
524
0
  !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
525
    /* Unmap. */
526
0
    addr += sizeof mapped;
527
0
    uaddr += sizeof mapped;
528
0
    af = AF_INET;
529
0
    len = 4;
530
0
  }
531
532
0
  switch (af) {
533
0
    case AF_INET:
534
0
      size = 4;
535
0
      break;
536
0
    case AF_INET6:
537
0
      size = 16;
538
0
      break;
539
0
    default:
540
0
      LM_ERR("unexpected af = %d\n",af);
541
0
      return NULL;
542
0
  }
543
544
0
  if (size != len) {
545
0
    LM_ERR("size = %d, len = %d\n",size,len);
546
0
    return NULL;
547
0
  }
548
549
0
  cached_he = (struct hostent *)dnscache_fetch_func(addr,T_PTR,af==AF_INET?4:16);
550
0
  if (cached_he == NULL) {
551
0
    LM_DBG("not found in cache or other internal error\n");
552
0
    goto query;
553
0
  } else if (cached_he == (void *)-1) {
554
0
    LM_DBG("previously failed query\n");
555
0
    return NULL;
556
0
  } else {
557
0
    LM_DBG("cache hit for PTR - %d\n",af);
558
0
    return cached_he;
559
0
  }
560
561
0
query:
562
0
  switch (af) {
563
0
    case AF_INET:
564
0
      sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
565
0
        (uaddr[3] & 0xff),
566
0
        (uaddr[2] & 0xff),
567
0
        (uaddr[1] & 0xff),
568
0
        (uaddr[0] & 0xff));
569
0
      break;
570
0
    case AF_INET6:
571
0
      qp = qbuf;
572
0
      for (n = 15; n >= 0; n--) {
573
0
        qp += sprintf(qp, "%x.%x.",
574
0
        uaddr[n] & 0xf,
575
0
        (uaddr[n] >> 4) & 0xf);
576
0
      }
577
0
      strcpy(qp, "ip6.arpa");
578
0
      break;
579
0
  }
580
581
0
  global_he.h_addrtype=af;
582
0
  global_he.h_length=len;
583
584
0
  ret=res_search(qbuf,C_IN,T_PTR,ptr_buff.buff,sizeof(ptr_buff.buff));
585
0
  if (ret < 0) {
586
0
    LM_DBG("ptr not found\n");
587
0
    if (dnscache_put_func(addr,T_PTR,NULL,len,1,0) < 0)
588
0
      LM_ERR("Failed to store PTR in cache\n");
589
0
    return NULL;
590
0
  }
591
592
0
  if (get_dns_answer(&ptr_buff,ret,qbuf,T_PTR,&min_ttl) < 0) {
593
0
    LM_ERR("Failed to get dns answer\n");
594
0
    return NULL;
595
0
  }
596
597
0
  if (dnscache_put_func(addr,T_PTR,&global_he,len,0,min_ttl) < 0)
598
0
    LM_ERR("Failed to store PTR in cache\n");
599
0
  return &global_he;
600
0
}
601
602
603
struct hostent* rev_resolvehost(struct ip_addr *ip)
604
0
{
605
0
  if (dnscache_fetch_func != NULL) {
606
0
    return own_gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af);
607
0
  } else
608
0
    return gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af);
609
0
}
610
611
/*! \brief checks if ip is in host(name) and ?host(ip)=name?
612
 * ip must be in network byte order!
613
 *  resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
614
 * \return 0 if equal */
615
int check_ip_address(struct ip_addr* ip, str *name,
616
        unsigned short port, unsigned short proto, int resolver)
617
4.05k
{
618
4.05k
  struct ip_addr *ip2;
619
4.05k
  struct hostent* he;
620
4.05k
  int i;
621
622
  /* maybe we are lucky and host (name) is an IP */
623
4.05k
  if ( (ip2=str2ip(name))!=NULL || (ip2=str2ip6(name))!=NULL ) {
624
    /* It's an IP :D */
625
10
    if (ip_addr_cmp(ip, ip2))
626
4
      return 0;
627
6
    return -1;
628
10
  }
629
630
  /* host is not an IP, do the DNS lookups on it :(*/
631
4.04k
  if (port==0) port=SIP_PORT;
632
4.04k
  if (resolver&DO_DNS){
633
0
    LM_DBG("doing dns lookup\n");
634
    /* try all names ips */
635
0
    he=sip_resolvehost(name, &port, &proto, 0, 0);
636
0
    if (he && (int)ip->af==he->h_addrtype){
637
0
      for(i=0;he && he->h_addr_list[i];i++){
638
0
        if ( memcmp(&he->h_addr_list[i], ip->u.addr, ip->len)==0)
639
0
          return 0;
640
0
      }
641
0
    }
642
0
  }
643
4.04k
  if (resolver&DO_REV_DNS){
644
0
    LM_DBG("doing rev. dns lookup\n");
645
    /* try reverse dns */
646
0
    he=rev_resolvehost(ip);
647
0
    if (he && (strncmp(he->h_name, name->s, name->len)==0))
648
0
      return 0;
649
0
    for (i=0; he && he->h_aliases[i];i++){
650
0
      if (strncmp(he->h_aliases[i],name->s, name->len)==0)
651
0
        return 0;
652
0
    }
653
0
  }
654
4.04k
  return -1;
655
4.04k
}
656
657
658
659
/*! \brief Initialize the DNS resolver
660
 * retr_time  - time before retransmitting (must be >0)
661
 * retr_no    - retransmissions number
662
 * servers_no - how many dns servers will be used
663
 *                      (from the one listed in /etc/resolv.conf)
664
 * search     - if 0 the search list in /etc/resolv.conf will
665
 *                      be ignored (HINT: even if you don't have a
666
 *                      search list in resolv.conf, it's still better
667
 *                      to set search to 0, because an empty searchlist
668
 *                      means in fact search "" => it takes more time)
669
 * If any of the parameters <0, the default (system specific) value
670
 * will be used. See also resolv.conf(5).
671
 * \return 0 on success, -1 on error
672
 */
673
int resolv_init(void)
674
0
{
675
0
  res_init();
676
0
#ifdef HAVE_RESOLV_RES
677
0
  if (dns_retr_time>0)
678
0
    _res.retrans=dns_retr_time;
679
0
  if (dns_retr_no>0)
680
0
    _res.retry=dns_retr_no;
681
0
  if (dns_servers_no>=0)
682
0
    _res.nscount=dns_servers_no;
683
0
  if (dns_search_list==0)
684
0
    _res.options&=~(RES_DEFNAMES|RES_DNSRCH);
685
#else
686
#warning "no resolv timeout support"
687
  LM_WARN("no resolv options support - resolv options will be ignored\n");
688
#endif
689
690
0
  if (register_stat("dns", "dns_total_queries", &dns_total_queries, 0) ||
691
0
      register_stat("dns", "dns_slow_queries", &dns_slow_queries, 0)) {
692
0
    LM_ERR("failed to register DNS stats\n");
693
0
    return -1;
694
0
  }
695
696
0
  return 0;
697
0
}
698
699
700
701
/*! \brief Initialize blacklist */
702
int resolv_blacklist_init(void)
703
0
{
704
0
  str name = str_init(DNS_REVOLVER_BL_NAME);
705
706
0
  if (!disable_dns_blacklist) {
707
0
    failover_bl = create_bl_head(_str("dns"),
708
0
      BL_DO_EXPIRE|BL_BY_DEFAULT, 0, 0, &name);
709
0
    if (failover_bl==NULL) {
710
0
      LM_ERR("failed to create blacklist\n");
711
0
      return -1;
712
0
    }
713
0
  }
714
0
  return 0;
715
0
}
716
717
718
/*! \brief Skips over a domain name in a dns message
719
 *  (it can be  a sequence of labels ending in \\0, a pointer or
720
 *   a sequence of labels ending in a pointer -- see rfc1035
721
 *   returns pointer after the domain name or null on error
722
 */
723
unsigned char* dns_skipname(unsigned char* p, unsigned char* end)
724
0
{
725
0
  while(p<end) {
726
    /* check if \0 (root label length) */
727
0
    if (*p==0){
728
0
      p+=1;
729
0
      break;
730
0
    }
731
    /* check if we found a pointer */
732
0
    if (((*p)&0xc0)==0xc0){
733
      /* if pointer skip over it (2 bytes) & we found the end */
734
0
      p+=2;
735
0
      break;
736
0
    }
737
    /* normal label */
738
0
    p+=*p+1;
739
0
  }
740
0
  return (p>=end)?0:p;
741
0
}
742
743
744
745
/*! \brief parses the srv record into a srv_rdata structure
746
 *   \param msg   - pointer to the dns message
747
 *   \param end   - pointer to the end of the message
748
 *   \param rdata - pointer  to the rdata part of the srv answer
749
 *   \return 0 on error, or a dyn. alloc'ed srv_rdata structure
750
 *
751
 * SRV rdata format:
752
 *            111111
753
 *  0123456789012345
754
 * +----------------+
755
 * |     priority   |
756
 * |----------------|
757
 * |     weight     |
758
 * |----------------|
759
 * |   port number  |
760
 * |----------------|
761
 * |                |
762
 * ~      name      ~
763
 * |                |
764
 * +----------------+
765
 */
766
struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
767
                  unsigned char* rdata)
768
0
{
769
0
  struct srv_rdata* srv;
770
0
  int len;
771
772
0
  srv=0;
773
0
  if ((rdata+6)>=end) goto error;
774
0
  srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata));
775
0
  if (srv==0){
776
0
    LM_ERR("out of pkg memory\n");
777
0
    goto error;
778
0
  }
779
780
0
  memcpy((void*)&srv->priority, rdata, 2);
781
0
  memcpy((void*)&srv->weight,   rdata+2, 2);
782
0
  memcpy((void*)&srv->port,     rdata+4, 2);
783
0
  rdata+=6;
784
0
  srv->priority=ntohs(srv->priority);
785
0
  srv->weight=ntohs(srv->weight);
786
0
  srv->port=ntohs(srv->port);
787
0
  if ((len=dn_expand(msg, end, rdata, srv->name, MAX_DNS_NAME-1))==-1)
788
0
    goto error;
789
  /* add terminating 0 ? (warning: len=compressed name len) */
790
0
  srv->name_len=strlen(srv->name);
791
0
  return srv;
792
0
error:
793
0
  if (srv) local_free(srv);
794
0
  return 0;
795
0
}
796
797
798
/*! \brief parses the naptr record into a naptr_rdata structure
799
 *   \param msg   - pointer to the dns message
800
 *   \param end   - pointer to the end of the message
801
 *   \param rdata - pointer  to the rdata part of the naptr answer
802
 *   \return  0 on error, or a dyn. alloc'ed naptr_rdata structure
803
 *
804
 * NAPTR rdata format:
805
 *            111111
806
 *  0123456789012345
807
 * +----------------+
808
 * |      order     |
809
 * |----------------|
810
 * |   preference   |
811
 * |----------------|
812
 * ~     flags      ~
813
 * |   (string)     |
814
 * |----------------|
815
 * ~    services    ~
816
 * |   (string)     |
817
 * |----------------|
818
 * ~    regexp      ~
819
 * |   (string)     |
820
 * |----------------|
821
 * ~  replacement   ~
822
   |    (name)      |
823
 * +----------------+
824
 */
825
struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
826
                  unsigned char* rdata)
827
0
{
828
0
  struct naptr_rdata* naptr;
829
830
0
  naptr = 0;
831
0
  if ((rdata + 7) >= end)
832
0
    goto error;
833
0
  naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata));
834
0
  if (naptr == 0){
835
0
    LM_ERR("out of pkg memory\n");
836
0
    goto error;
837
0
  }
838
839
0
  memcpy((void*)&naptr->order, rdata, 2);
840
0
  naptr->order=ntohs(naptr->order);
841
0
  memcpy((void*)&naptr->pref, rdata + 2, 2);
842
0
  naptr->pref=ntohs(naptr->pref);
843
0
  naptr->flags_len = (int)rdata[4];
844
0
  if ((rdata + 7 +  naptr->flags_len) >= end)
845
0
    goto error;
846
0
  memcpy((void*)&naptr->flags, rdata + 5, naptr->flags_len);
847
0
  naptr->services_len = (int)rdata[5 + naptr->flags_len];
848
0
  if ((rdata + 7 + naptr->flags_len + naptr->services_len) >= end) goto error;
849
0
  memcpy((void*)&naptr->services, rdata + 6 + naptr->flags_len, naptr->services_len);
850
0
  naptr->regexp_len = (int)rdata[6 + naptr->flags_len + naptr->services_len];
851
0
  if ((rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len) >= end)
852
0
    goto error;
853
0
  memcpy((void*)&naptr->regexp, rdata + 7 + naptr->flags_len +
854
0
        naptr->services_len, naptr->regexp_len);
855
0
  rdata = rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len;
856
0
  naptr->repl_len=dn_expand(msg, end, rdata, naptr->repl, MAX_DNS_NAME-1);
857
0
  if ( naptr->repl_len==(unsigned int)-1 )
858
0
    goto error;
859
  /* add terminating 0 ? (warning: len=compressed name len) */
860
0
  return naptr;
861
0
error:
862
0
  if (naptr)
863
0
    local_free(naptr);
864
0
  return 0;
865
0
}
866
867
868
869
/*! \brief Parses a CNAME record into a cname_rdata structure */
870
struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
871
                    unsigned char* rdata)
872
0
{
873
0
  struct cname_rdata* cname;
874
0
  int len;
875
876
0
  cname=0;
877
0
  cname=(struct cname_rdata*)local_malloc(sizeof(struct cname_rdata));
878
0
  if(cname==0){
879
0
    LM_ERR("out of pkg memory\n");
880
0
    goto error;
881
0
  }
882
0
  if ((len=dn_expand(msg, end, rdata, cname->name, MAX_DNS_NAME-1))==-1)
883
0
    goto error;
884
0
  return cname;
885
0
error:
886
0
  if (cname) local_free(cname);
887
0
  return 0;
888
0
}
889
890
891
892
/*! \brief Parses an A record rdata into an a_rdata structure
893
 * \return 0 on error or a dyn. alloc'ed a_rdata struct
894
 */
895
struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* end)
896
0
{
897
0
  struct a_rdata* a;
898
899
0
  if (rdata+4>=end) goto error;
900
0
  a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata));
901
0
  if (a==0){
902
0
    LM_ERR("out of pkg memory\n");
903
0
    goto error;
904
0
  }
905
0
  memcpy(a->ip, rdata, 4);
906
0
  return a;
907
0
error:
908
0
  return 0;
909
0
}
910
911
912
913
/*! \brief Parses an AAAA (ipv6) record rdata into an aaaa_rdata structure
914
 * \return 0 on error or a dyn. alloc'ed aaaa_rdata struct
915
 */
916
struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* end)
917
0
{
918
0
  struct aaaa_rdata* aaaa;
919
920
0
  if (rdata+16>=end) goto error;
921
0
  aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata));
922
0
  if (aaaa==0){
923
0
    LM_ERR("out of pkg memory\n");
924
0
    goto error;
925
0
  }
926
0
  memcpy(aaaa->ip6, rdata, 16);
927
0
  return aaaa;
928
0
error:
929
0
  return 0;
930
0
}
931
932
/*! \brief Parses a TXT record into a txt_rdata structure
933
 * \note RFC1035:
934
 * - <character-string> is a single length octet followed by that number of characters.
935
 * - TXT-DATA        One or more <character-string>s.
936
 *
937
 * We only take the first string here.
938
 */
939
struct txt_rdata* dns_txt_parser( unsigned char* msg, unsigned char* end,
940
                    unsigned char* rdata)
941
0
{
942
0
  struct txt_rdata* txt;
943
0
  unsigned int len;
944
945
0
  txt=0;
946
0
  txt=(struct txt_rdata*)local_malloc(sizeof(struct txt_rdata));
947
0
  if(txt==0){
948
0
    LM_ERR("out of pkg memory\n");
949
0
    goto error;
950
0
  }
951
952
0
  len = *rdata;
953
0
  if (rdata + 1 + len >= end)
954
0
    goto error; /*  something fishy in the record */
955
956
#if 0
957
  /* Comparison is always false because len <= 255. */
958
  if (len >= sizeof(txt->txt))
959
    goto error; /* not enough space? */
960
#endif
961
0
  memcpy(txt->txt, rdata+1, len);
962
0
  txt->txt[len] = 0;    /* 0-terminate string */
963
0
  return txt;
964
965
0
error:
966
0
  if (txt)
967
0
    local_free(txt);
968
0
  return 0;
969
0
}
970
971
972
/*! \brief parses a EBL record into a ebl_rdata structure
973
 *
974
 * EBL Record
975
 *
976
 *    0  1  2  3  4  5  6  7
977
 *    +--+--+--+--+--+--+--+--+
978
 *    |       POSITION        |
979
 *    +--+--+--+--+--+--+--+--+
980
 *    /       SEPARATOR       /
981
 *    +--+--+--+--+--+--+--+--+
982
 *    /         APEX          /
983
 *    +--+--+--+--+--+--+--+--+
984
 */
985
struct ebl_rdata* dns_ebl_parser( unsigned char* msg, unsigned char* end,
986
                    unsigned char* rdata)
987
0
{
988
0
  struct ebl_rdata* ebl;
989
0
  int len;
990
991
0
  ebl=0;
992
0
  ebl=(struct ebl_rdata*)local_malloc(sizeof(struct ebl_rdata));
993
0
  if(ebl==0){
994
0
    LM_ERR("out of pkg memory\n");
995
0
    goto error;
996
0
  }
997
998
0
  len = *rdata;
999
0
  if (rdata + 1 + len >= end)
1000
0
    goto error; /*  something fishy in the record */
1001
1002
0
  ebl->position = *rdata;
1003
0
  if ( ebl->position > 15 )
1004
0
    goto error; /* doesn't make sense: E.164 numbers can't be longer */
1005
1006
0
  rdata++;
1007
1008
0
  ebl->separator_len = (int) *rdata;
1009
0
  rdata++;
1010
0
  if ((rdata + 1 +  ebl->separator_len) >= end)
1011
0
    goto error;
1012
0
  memcpy((void*)&ebl->separator, rdata, ebl->separator_len);
1013
0
  rdata += ebl->separator_len;
1014
1015
0
  ebl->apex_len=dn_expand(msg, end, rdata, ebl->apex, MAX_DNS_NAME-1);
1016
0
  if ( ebl->apex_len==(unsigned int)-1 )
1017
0
    goto error;
1018
0
  ebl->apex[ebl->apex_len] = 0; /* 0-terminate string */
1019
0
  return ebl;
1020
1021
0
error:
1022
0
  if (ebl)
1023
0
    local_free(ebl);
1024
0
  return 0;
1025
0
}
1026
1027
1028
1029
1030
/*! \brief frees completely a struct rdata list */
1031
void free_rdata_list(struct rdata* head)
1032
0
{
1033
0
  struct rdata* l;
1034
0
  struct rdata* next_l;
1035
1036
0
  for( l=head; l ; l=next_l) {
1037
0
    next_l = l->next;
1038
    /* free the parsed rdata*/
1039
0
    if (l->rdata)
1040
0
      local_free(l->rdata);
1041
0
    local_free(l);
1042
0
  }
1043
0
}
1044
1045
1046
1047
/*! \brief gets the DNS records for name:type
1048
 * \return A dyn. alloc'ed struct rdata linked list with the parsed responses
1049
 * or 0 on error
1050
 * \note see rfc1035 for the query/response format */
1051
struct rdata* get_record(char* name, int type)
1052
0
{
1053
0
  int size;
1054
0
  int qno, answers_no;
1055
0
  int r;
1056
0
  static union dns_query buff;
1057
0
  unsigned char* p;
1058
/*  unsigned char* t;
1059
  int ans_len;
1060
  static unsigned char answer[ANS_SIZE]; */
1061
0
  static int rdata_struct_len=sizeof(struct rdata)-sizeof(void *) -
1062
0
    sizeof(struct rdata *);
1063
0
  unsigned char* end;
1064
0
  unsigned short rtype, class, rdlength;
1065
0
  unsigned int ttl;
1066
0
  unsigned int min_ttl = UINT_MAX;
1067
0
  struct rdata* head;
1068
0
  struct rdata** crt;
1069
0
  struct rdata** last;
1070
0
  struct rdata* rd;
1071
0
  struct srv_rdata* srv_rd;
1072
0
  struct srv_rdata* crt_srv;
1073
0
  struct naptr_rdata* naptr_rd;
1074
0
  struct txt_rdata* txt_rd;
1075
0
  struct ebl_rdata* ebl_rd;
1076
0
  struct timeval start;
1077
0
  int rdata_buf_len=0;
1078
1079
0
  if (dnscache_fetch_func != NULL) {
1080
0
    head = (struct rdata *)dnscache_fetch_func(name,type,0);
1081
0
    if (head == NULL) {
1082
0
      LM_DBG("not found in cache or other internal error\n");
1083
0
      goto query;
1084
0
    } else if (head == (void *)-1) {
1085
0
      LM_DBG("previously failed query\n");
1086
0
      goto not_found;
1087
0
    } else {
1088
0
      LM_DBG("cache hit for %s - %d\n",name,type);
1089
0
      return head;
1090
0
    }
1091
0
  }
1092
1093
0
query:
1094
0
  start_expire_timer(start,execdnsthreshold);
1095
0
  size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
1096
0
  _stop_expire_timer(start, execdnsthreshold, "dns",
1097
0
              name, strlen(name), 0, dns_slow_queries, dns_total_queries);
1098
1099
0
  if (size<0) {
1100
0
    LM_DBG("lookup(%s, %d) failed\n", name, type);
1101
0
    if (dnscache_put_func != NULL) {
1102
0
      if (dnscache_put_func(name,type,NULL,0,1,0) < 0)
1103
0
        LM_ERR("Failed to store %s - %d in cache\n",name,type);
1104
0
    }
1105
0
    goto not_found;
1106
0
  }
1107
0
  else if ((unsigned int)size > sizeof(buff)) size=sizeof(buff);
1108
0
  head=rd=0;
1109
0
  last=crt=&head;
1110
1111
0
  p=buff.buff+DNS_HDR_SIZE;
1112
0
  end=buff.buff+size;
1113
0
  if (p>=end) goto error_boundary;
1114
0
  qno=ntohs((unsigned short)buff.hdr.qdcount);
1115
1116
0
  for (r=0; r<qno; r++){
1117
    /* skip the name of the question */
1118
0
    if ((p=dns_skipname(p, end))==0) {
1119
0
      LM_ERR("skipname==0\n");
1120
0
      goto error;
1121
0
    }
1122
0
    p+=2+2; /* skip QCODE & QCLASS */
1123
  #if 0
1124
    for (;(p<end && (*p)); p++);
1125
    p+=1+2+2; /* skip the ending  '\0, QCODE and QCLASS */
1126
  #endif
1127
0
    if (p>=end) {
1128
0
      LM_ERR("p>=end\n");
1129
0
      goto error;
1130
0
    }
1131
0
  };
1132
0
  answers_no=ntohs((unsigned short)buff.hdr.ancount);
1133
  /*ans_len=ANS_SIZE;
1134
  t=answer;*/
1135
0
  for (r=0; (r<answers_no) && (p<end); r++){
1136
    /*  ignore it the default domain name */
1137
0
    if ((p=dns_skipname(p, end))==0) {
1138
0
      LM_ERR("skip_name=0 (#2)\n");
1139
0
      goto error;
1140
0
    }
1141
    /*
1142
    skip=dn_expand(buff.buff, end, p, t, ans_len);
1143
    p+=skip;
1144
    */
1145
    /* check if enough space is left for type, class, ttl & size */
1146
0
    if ((p+2+2+4+2)>=end) goto error_boundary;
1147
    /* get type */
1148
0
    memcpy((void*) &rtype, (void*)p, 2);
1149
0
    rtype=ntohs(rtype);
1150
0
    p+=2;
1151
    /* get  class */
1152
0
    memcpy((void*) &class, (void*)p, 2);
1153
0
    class=ntohs(class);
1154
0
    p+=2;
1155
    /* get ttl*/
1156
0
    memcpy((void*) &ttl, (void*)p, 4);
1157
0
    ttl=ntohl(ttl);
1158
0
    if (ttl < min_ttl)
1159
0
      min_ttl = ttl;
1160
0
    p+=4;
1161
    /* get size */
1162
0
    memcpy((void*)&rdlength, (void*)p, 2);
1163
0
    rdlength=ntohs(rdlength);
1164
0
    p+=2;
1165
    /* check for type */
1166
    /*
1167
    if (rtype!=type){
1168
      LM_WAR("wrong type in answer (%d!=%d)\n", rtype, type);
1169
      p+=rdlength;
1170
      continue;
1171
    }
1172
    */
1173
    /* expand the "type" record  (rdata)*/
1174
1175
0
    rd=(struct rdata*) local_malloc(sizeof(struct rdata));
1176
0
    if (rd==0){
1177
0
      LM_ERR("out of pkg memory\n");
1178
0
      goto error;
1179
0
    }
1180
0
    if (dnscache_put_func)
1181
0
      rdata_buf_len+=rdata_struct_len;
1182
0
    rd->type=rtype;
1183
0
    rd->class=class;
1184
0
    rd->ttl=ttl;
1185
0
    rd->next=0;
1186
0
    switch(rtype){
1187
0
      case T_SRV:
1188
0
        srv_rd= dns_srv_parser(buff.buff, end, p);
1189
0
        if (srv_rd==0) goto error_parse;
1190
0
        if (dnscache_put_func)
1191
0
          rdata_buf_len+=4*sizeof(unsigned short) +
1192
0
          sizeof(unsigned int ) + srv_rd->name_len+1;
1193
0
        rd->rdata=(void*)srv_rd;
1194
1195
        /* insert sorted into the list */
1196
0
        for (crt=&head; *crt; crt= &((*crt)->next)){
1197
0
          crt_srv=(struct srv_rdata*)(*crt)->rdata;
1198
0
          if ((srv_rd->priority <  crt_srv->priority) ||
1199
0
             ( (srv_rd->priority == crt_srv->priority) &&
1200
0
               ((srv_rd->weight==0) || (crt_srv->weight!=0)) ) ){
1201
            /* insert here */
1202
0
            goto skip;
1203
0
          }
1204
0
        }
1205
0
        last=&(rd->next); /*end of for => this will be the last elem*/
1206
0
      skip:
1207
        /* insert here */
1208
0
        rd->next=*crt;
1209
0
        *crt=rd;
1210
1211
0
        break;
1212
0
      case T_A:
1213
0
        rd->rdata=(void*) dns_a_parser(p,end);
1214
0
        if (rd->rdata==0) goto error_parse;
1215
0
        if (dnscache_put_func)
1216
0
          rdata_buf_len+=sizeof(struct a_rdata);
1217
0
        *last=rd; /* last points to the last "next" or the list head*/
1218
0
        last=&(rd->next);
1219
0
        break;
1220
0
      case T_AAAA:
1221
0
        rd->rdata=(void*) dns_aaaa_parser(p,end);
1222
0
        if (rd->rdata==0) goto error_parse;
1223
0
        if (dnscache_put_func)
1224
0
          rdata_buf_len+=sizeof(struct aaaa_rdata);
1225
0
        *last=rd;
1226
0
        last=&(rd->next);
1227
0
        break;
1228
0
      case T_CNAME:
1229
0
        rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
1230
0
        if(rd->rdata==0) goto error_parse;
1231
0
        if (dnscache_put_func)
1232
0
          rdata_buf_len+=
1233
0
          strlen(((struct cname_rdata *)rd->rdata)->name) +
1234
0
          1 + sizeof(int);
1235
0
        *last=rd;
1236
0
        last=&(rd->next);
1237
0
        break;
1238
0
      case T_NAPTR:
1239
0
        naptr_rd = dns_naptr_parser(buff.buff,end,p);
1240
0
        rd->rdata=(void*) naptr_rd;
1241
0
        if(rd->rdata==0) goto error_parse;
1242
0
        if (dnscache_put_func)
1243
0
          rdata_buf_len+=2*sizeof(unsigned short) +
1244
0
          4*sizeof(unsigned int) + naptr_rd->flags_len+1 +
1245
0
          + naptr_rd->services_len+1+naptr_rd->regexp_len +
1246
0
          + 1 + naptr_rd->repl_len + 1;
1247
0
        *last=rd;
1248
0
        last=&(rd->next);
1249
0
        break;
1250
0
      case T_TXT:
1251
0
        txt_rd = dns_txt_parser(buff.buff, end, p);
1252
0
        rd->rdata=(void*) txt_rd;
1253
0
        if(rd->rdata==0) goto error_parse;
1254
0
        if (dnscache_put_func)
1255
0
          rdata_buf_len+=sizeof(int)+strlen(txt_rd->txt)+1;
1256
0
        *last=rd;
1257
0
        last=&(rd->next);
1258
0
        break;
1259
0
      case T_EBL:
1260
0
        ebl_rd = dns_ebl_parser(buff.buff, end, p);
1261
0
        rd->rdata=(void*) ebl_rd;
1262
0
        if(rd->rdata==0) goto error_parse;
1263
0
        if (dnscache_put_func)
1264
0
          rdata_buf_len+=sizeof(unsigned char)+
1265
0
          2*sizeof(unsigned int)+ebl_rd->apex_len + 1 +
1266
0
          ebl_rd->separator_len + 1;
1267
0
        *last=rd;
1268
0
        last=&(rd->next);
1269
0
        break;
1270
0
      default:
1271
0
        LM_ERR("unknown type %d\n", rtype);
1272
0
        rd->rdata=0;
1273
0
        *last=rd;
1274
0
        last=&(rd->next);
1275
0
    }
1276
1277
0
    p+=rdlength;
1278
1279
0
  }
1280
1281
0
  if (dnscache_put_func != NULL) {
1282
0
    if (dnscache_put_func(name,type,head,rdata_buf_len,0,min_ttl) < 0)
1283
0
      LM_ERR("Failed to store %s - %d in cache\n",name,type);
1284
0
  }
1285
0
  return head;
1286
0
error_boundary:
1287
0
    LM_ERR("end of query buff reached\n");
1288
0
    if(head)
1289
0
      free_rdata_list(head);
1290
0
    return 0;
1291
0
error_parse:
1292
0
    LM_ERR("rdata parse error \n");
1293
0
    if (rd) local_free(rd); /* rd->rdata=0 & rd is not linked yet into
1294
                   the list */
1295
0
error:
1296
0
    LM_ERR("get_record \n");
1297
0
    if (head) free_rdata_list(head);
1298
0
not_found:
1299
0
  return 0;
1300
0
}
1301
1302
1303
1304
static inline int get_naptr_proto(struct naptr_rdata *n)
1305
0
{
1306
0
  if (n->services[3]=='s' || n->services[3]=='S' )
1307
0
    return PROTO_TLS;
1308
0
  switch (n->services[n->services_len-1]) {
1309
0
    case 'U':
1310
0
    case 'u':
1311
0
      return PROTO_UDP;
1312
0
      break;
1313
0
    case 'T':
1314
0
    case 't':
1315
0
      return PROTO_TCP;
1316
0
      break;
1317
0
    case 'S':
1318
0
    case 's':
1319
0
      return PROTO_SCTP;
1320
0
      break;
1321
0
  }
1322
0
  LM_CRIT("failed to detect proto\n");
1323
0
  return PROTO_NONE;
1324
0
}
1325
1326
1327
1328
static inline int srv2dns_node(struct rdata *head, struct dns_node **dn)
1329
0
{
1330
0
  unsigned int mem;
1331
0
  unsigned int l;
1332
0
  struct rdata *r;
1333
0
  struct dns_node *n;
1334
0
  char *p;
1335
1336
  /* calculate how much mem is required */
1337
0
  mem = sizeof(struct dns_node);
1338
0
  for( r=head,l=0 ; r ; r=r->next,l++ )
1339
0
    mem +=sizeof(struct dns_val) + get_naptr(r)->repl_len + 1;
1340
1341
0
  n = (struct dns_node*)shm_malloc(mem);
1342
0
  if (n==NULL) {
1343
0
    LM_ERR("no more shm mem (%d)\n", mem);
1344
0
    return -1;
1345
0
  }
1346
1347
0
  n->type = DNS_NODE_SRV;
1348
0
  n->size = mem;
1349
0
  n->idx = 0;
1350
0
  n->no = l;
1351
0
  n->kids = *dn;
1352
0
  *dn = n;
1353
1354
0
  n->vals = (struct dns_val*)(n+1);
1355
0
  p = (char*)(n->vals+l);
1356
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1357
0
    n->vals[l].ival = get_naptr_proto( get_naptr(r) );
1358
0
    n->vals[l].sval = p;
1359
0
    memcpy( p, get_naptr(r)->repl, get_naptr(r)->repl_len );
1360
0
    p += get_naptr(r)->repl_len;
1361
0
    *(p++) = 0;
1362
0
  }
1363
0
  return 0;
1364
0
}
1365
1366
1367
static inline int a2dns_node(struct rdata *head, struct dns_node **dn)
1368
0
{
1369
0
  unsigned int mem;
1370
0
  unsigned int l;
1371
0
  struct rdata *r;
1372
0
  struct dns_node *n;
1373
0
  char *p;
1374
1375
  /* calculate how much mem is required */
1376
0
  mem = sizeof(struct dns_node);
1377
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1378
0
    get_srv(r)->name_len = strlen(get_srv(r)->name);
1379
0
    mem +=sizeof(struct dns_val) + get_srv(r)->name_len + 1;
1380
0
    }
1381
1382
0
  n = (struct dns_node*)shm_malloc(mem);
1383
0
  if (n==NULL) {
1384
0
    LM_ERR("no more shm mem (%d)\n", mem);
1385
0
    return -1;
1386
0
  }
1387
1388
0
  n->type = DNS_NODE_A;
1389
0
  n->size = mem;
1390
0
  n->idx = 0;
1391
0
  n->no = l;
1392
0
  n->kids = 0;
1393
0
  *dn = n;
1394
1395
0
  n->vals = (struct dns_val*)(n+1);
1396
0
  p = (char*)(n->vals+l);
1397
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1398
0
    n->vals[l].ival = get_srv(r)->port;
1399
0
    n->vals[l].sval = p;
1400
0
    memcpy( p, get_srv(r)->name, get_srv(r)->name_len );
1401
0
    LM_DBG("storing %.*s:%d\n", get_srv(r)->name_len,p,n->vals[l].ival);
1402
0
    p += get_srv(r)->name_len;
1403
0
    *(p++) = 0;
1404
0
  }
1405
1406
0
  return 0;
1407
0
}
1408
1409
1410
static inline void sort_srvs(struct rdata **head)
1411
0
{
1412
0
#define rd2srv(_rd) ((struct srv_rdata*)_rd->rdata)
1413
0
  struct rdata *rd = *head;
1414
0
  struct rdata *tail = NULL;
1415
0
  struct rdata *rd_next;
1416
0
  struct rdata *crt;
1417
0
  struct rdata *crt2;
1418
0
  unsigned int weight_sum;
1419
0
  unsigned int rand_no;
1420
1421
1422
0
  *head = NULL;
1423
1424
0
  while( rd ) {
1425
0
    rd_next = rd->next;
1426
0
    if (rd->type!=T_SRV) {
1427
0
      rd->next = NULL;
1428
0
      free_rdata_list(rd);
1429
0
    } else {
1430
      /* only on element with same priority ? */
1431
0
      if (rd_next==NULL ||
1432
0
      rd2srv(rd)->priority!=rd2srv(rd_next)->priority) {
1433
0
        if (tail) {tail->next=rd;tail=rd;}
1434
0
        else {*head=tail=rd;}
1435
0
        rd->next = NULL;
1436
0
      } else {
1437
        /* multiple nodes with same priority */
1438
        /* -> calculate running sums (and detect the end) */
1439
0
        weight_sum = rd2srv(rd)->running_sum = rd2srv(rd)->weight;
1440
0
        crt = rd;
1441
0
        while( crt && crt->next &&
1442
0
        (rd2srv(rd)->priority==rd2srv(crt->next)->priority) ) {
1443
0
          crt = crt->next;
1444
0
          weight_sum += rd2srv(crt)->weight;
1445
0
          rd2srv(crt)->running_sum = weight_sum;
1446
0
        }
1447
        /* crt will point to last RR with same priority */
1448
0
        rd_next = crt->next;
1449
0
        crt->next = NULL;
1450
1451
        /* order the elements between rd and crt */
1452
0
        while (rd->next) {
1453
0
          rand_no = (unsigned int)
1454
0
            (weight_sum*((float)rand()/(float)RAND_MAX));
1455
0
          for( crt=rd,crt2=NULL ; crt ; crt2=crt,crt=crt->next) {
1456
0
            if (rd2srv(crt)->running_sum>=rand_no) break;
1457
0
          }
1458
0
          if (crt == NULL) {
1459
0
            LM_CRIT("bug in sorting SRVs - rand>sum\n");
1460
0
            crt = rd;
1461
0
            crt2 = NULL;
1462
0
          }
1463
          /* remove the element from the list ... */
1464
0
          if (crt2==NULL) { rd = rd->next;}
1465
0
          else {crt2->next = crt->next;}
1466
          /* .... and update the running sums */
1467
0
          for ( crt2=crt->next ; crt2 ; crt2=crt2->next)
1468
0
            rd2srv(crt2)->running_sum -= rd2srv(crt)->weight;
1469
0
          weight_sum -= rd2srv(crt)->weight;
1470
          /* link the crt in the new list */
1471
0
          crt->next = 0;
1472
0
          if (tail) {tail->next=crt;tail=crt;}
1473
0
          else {*head=tail=crt;}
1474
0
        }
1475
        /* just insert the last remaining element */
1476
0
        tail->next = rd; tail = rd ;
1477
0
      }
1478
0
    }
1479
1480
0
    rd = rd_next;
1481
0
  }
1482
0
}
1483
1484
1485
static inline struct hostent* do_srv_lookup(char *name, unsigned short* port, struct dns_node **dn)
1486
0
{
1487
0
  struct hostent *he;
1488
0
  struct srv_rdata *srv;
1489
0
  struct rdata *head;
1490
0
  struct rdata *rd;
1491
1492
  /* perform SRV lookup */
1493
0
  head = get_record( name, T_SRV);
1494
0
  sort_srvs(&head);
1495
0
  for( rd=head; rd ; rd=rd->next ) {
1496
0
    if (rd->type!=T_SRV)
1497
0
      continue; /*should never happen*/
1498
0
    srv = (struct srv_rdata*) rd->rdata;
1499
0
    if (srv==0) {
1500
0
      LM_CRIT("null rdata\n");
1501
0
      free_rdata_list(head);
1502
0
      return 0;
1503
0
    }
1504
0
    LM_DBG("resolving [%s]\n",srv->name);
1505
0
    he = resolvehost(srv->name, 1);
1506
0
    if ( he!=0 ) {
1507
0
      LM_DBG("SRV(%s) = %s:%d\n",     name, srv->name, srv->port);
1508
0
      if (port) *port=srv->port;
1509
0
      if (dn && rd->next && a2dns_node( rd->next, dn)==-1)
1510
0
          *dn = 0;
1511
0
      free_rdata_list(head);
1512
0
      return he;
1513
0
    }
1514
0
  }
1515
0
  if (head)
1516
0
    free_rdata_list(head);
1517
0
  return 0;
1518
0
}
1519
1520
1521
#define naptr_prio(_naptr) \
1522
0
  ((unsigned int)((((_naptr)->order) << 16) + ((_naptr)->pref)))
1523
1524
static inline void filter_and_sort_naptr( struct rdata** head_p, struct rdata** filtered_p, int is_sips)
1525
0
{
1526
0
  struct naptr_rdata *naptr;
1527
0
  struct rdata *head;
1528
0
  struct rdata *last;
1529
0
  struct rdata *out;
1530
0
  struct rdata *l, *ln, *it, *itp;
1531
0
  unsigned int prio;
1532
0
  char p;
1533
1534
0
  head = 0;
1535
0
  last = 0;
1536
0
  out = 0;
1537
1538
0
  for( l=*head_p ; l ; l=ln ) {
1539
0
    ln = l->next;
1540
1541
0
    if (l->type != T_NAPTR)
1542
0
      goto skip0; /*should never happen*/
1543
1544
0
    naptr = (struct naptr_rdata*)l->rdata;
1545
0
    if (naptr == 0) {
1546
0
      LM_CRIT("null rdata\n");
1547
0
      goto skip0;
1548
0
    }
1549
1550
    /* first filter out by flag and service */
1551
0
    if (naptr->flags_len!=1||(naptr->flags[0]!='s'&&naptr->flags[0]!='S'))
1552
0
      goto skip;
1553
0
    if (naptr->repl_len==0 || naptr->regexp_len!=0 )
1554
0
      goto skip;
1555
0
    if ( (is_sips || naptr->services_len!=7 ||
1556
0
      strncasecmp(naptr->services,"sip+d2",6) ) &&
1557
0
    (
1558
0
    naptr->services_len!=8 || strncasecmp(naptr->services,"sips+d2",7)))
1559
0
      goto skip;
1560
0
    p = naptr->services[naptr->services_len-1];
1561
    /* by default we do not support SCTP */
1562
0
    if ( p!='U' && p!='u'
1563
0
    && ((p!='T' && p!='t'))
1564
0
    && ((p!='S' && p!='s'))
1565
0
    )
1566
0
      goto skip;
1567
    /* is it valid? (SIPS+D2U is not!) */
1568
0
    if ( naptr->services_len==8 && (p=='U' || p=='u'))
1569
0
      goto skip;
1570
1571
0
    LM_DBG("found valid %.*s -> %s\n",
1572
0
      (int)naptr->services_len,naptr->services, naptr->repl);
1573
1574
    /* this is a supported service -> add it according to order to the
1575
     * new head list */
1576
0
    prio = naptr_prio(get_naptr(l));
1577
0
    if (head==0) {
1578
0
      head = last = l;
1579
0
      l->next = 0;
1580
0
    } else if ( naptr_prio(get_naptr(head)) >= prio ) {
1581
0
      l->next = head;
1582
0
      head = l;
1583
0
    } else if ( prio >= naptr_prio(get_naptr(last)) ) {
1584
0
      l->next = 0;
1585
0
      last->next = l;
1586
0
      last = l;
1587
0
    } else {
1588
0
      for( itp=head,it=head->next ; it && it->next ; itp=it,it=it->next ){
1589
0
        if ( prio <= naptr_prio(get_naptr(it)))
1590
0
          break;
1591
0
      }
1592
0
      l->next = itp->next;
1593
0
      itp->next = l;
1594
0
    }
1595
1596
0
    continue;
1597
0
skip:
1598
0
    LM_DBG("skipping %.*s -> %s\n",
1599
0
      (int)naptr->services_len, naptr->services, naptr->repl);
1600
0
skip0:
1601
0
    l->next = out;
1602
0
    out = l;
1603
0
  }
1604
1605
0
  *head_p = head;
1606
0
  *filtered_p = out;
1607
0
}
1608
1609
#if 0
1610
struct hostent* sip_resolvehost(str* name, unsigned short* port, int *proto,
1611
                                int is_sips)
1612
{
1613
  static char tmp[MAX_DNS_NAME];
1614
  struct ip_addr *ip;
1615
  struct rdata *head;
1616
  struct rdata *rd;
1617
  struct hostent* he;
1618
1619
  if ( (is_sips)
1620
  && (tls_disable)
1621
  ) {
1622
    LM_ERR("cannot resolve SIPS as no TLS support is configured\n");
1623
    return 0;
1624
  }
1625
1626
  /* check if it's an ip address */
1627
  if ( ((ip=str2ip(name))!=0)
1628
  || ((ip=str2ip6(name))!=0)
1629
  ){
1630
    /* we are lucky, this is an ip address */
1631
    if (proto && *proto==PROTO_NONE)
1632
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1633
    if (port && *port==0)
1634
      *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
1635
    return ip_addr2he(name,ip);
1636
  }
1637
1638
  /* do we have a port? */
1639
  if ( !port || (*port)!=0 ) {
1640
    /* have port -> no NAPTR, no SRV lookup, just A record lookup */
1641
    LM_DBG("has port -> do A record lookup!\n");
1642
    /* set default PROTO if not set */
1643
    if (proto && *proto==PROTO_NONE)
1644
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1645
    goto do_a;
1646
  }
1647
1648
  /* no port... what about proto? */
1649
  if ( !proto || (*proto)!=PROTO_NONE ) {
1650
    /* have proto, but no port -> do SRV lookup */
1651
    LM_DBG("no port, has proto -> do SRV lookup!\n");
1652
    if (is_sips && (*proto)!=PROTO_TLS) {
1653
      LM_ERR("forced proto %d not matching sips uri\n", *proto);
1654
      return 0;
1655
    }
1656
    goto do_srv;
1657
  }
1658
1659
  LM_DBG("no port, no proto -> do NAPTR lookup!\n");
1660
  /* no proto, no port -> do NAPTR lookup */
1661
  if (name->len >= MAX_DNS_NAME) {
1662
    LM_ERR("domain name too long\n");
1663
    return 0;
1664
  }
1665
  memcpy(tmp, name->s, name->len);
1666
  tmp[name->len] = '\0';
1667
  /* do NAPTR lookup */
1668
  head = get_record( tmp, T_NAPTR);
1669
  if (head) {
1670
    /* filter and sort the records */
1671
    filter_and_sort_naptr( &head, &rd, is_sips);
1672
    /* free what is useless */
1673
    free_rdata_list( rd );
1674
    /* process the NAPTR records */
1675
    for( rd=head ; rd ; rd=rd->next ) {
1676
      he = do_srv_lookup( get_naptr(rd)->repl, port );
1677
      if ( he ) {
1678
        *proto = get_naptr_proto( get_naptr(rd) );
1679
        LM_DBG("found!\n");
1680
        free_rdata_list(head);
1681
        return he;
1682
      }
1683
    }
1684
    if (head)
1685
      free_rdata_list(head);
1686
  }
1687
  LM_DBG("no valid NAPTR record found for %.*s,"
1688
    " trying direct SRV lookup...\n", name->len, name->s);
1689
  *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1690
1691
do_srv:
1692
  if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME) {
1693
    LM_WARN("domain name too long (%d),"
1694
      " unable to perform SRV lookup\n", name->len);
1695
    /* set defaults */
1696
    *port = (is_sips)?SIPS_PORT:SIP_PORT;
1697
    goto do_a;
1698
  }
1699
1700
  switch (*proto) {
1701
    case PROTO_UDP:
1702
      memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1703
      memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
1704
      tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1705
      break;
1706
    case PROTO_TCP:
1707
      memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1708
      memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
1709
      tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1710
      break;
1711
    case PROTO_TLS:
1712
      memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1713
      memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
1714
      tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1715
      break;
1716
    default:
1717
      goto err_proto;
1718
  }
1719
1720
  he = do_srv_lookup( tmp, port );
1721
  if (he)
1722
    return he;
1723
1724
  LM_DBG("no valid SRV record found for %s,"
1725
    " trying A record lookup...\n", tmp);
1726
  /* set default port */
1727
  *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
1728
1729
do_a:
1730
  /* do A record lookup */
1731
  if (name->len >= MAX_DNS_NAME) {
1732
    LM_ERR("domain name too long\n");
1733
    return 0;
1734
  }
1735
  memcpy(tmp, name->s, name->len);
1736
  tmp[name->len] = '\0';
1737
  he = resolvehost(tmp,1);
1738
  return he;
1739
err_proto:
1740
  LM_ERR("unsupported proto %d\n", *proto);
1741
  return 0;
1742
}
1743
#endif
1744
1745
1746
1747
struct hostent* sip_resolvehost( str* name, unsigned short* port,
1748
    unsigned short *proto, int is_sips, struct dns_node **dn)
1749
0
{
1750
0
  static char tmp[MAX_DNS_NAME];
1751
0
  struct ip_addr *ip;
1752
0
  struct rdata *head;
1753
0
  struct rdata *rd;
1754
0
  struct hostent* he;
1755
0
  unsigned short local_proto=PROTO_NONE;
1756
1757
0
  if (dn)
1758
0
    *dn = 0;
1759
1760
0
  if (proto==NULL)
1761
0
    proto = &local_proto;
1762
1763
  /* check if it's an ip address */
1764
0
  if ( ((ip=str2ip(name))!=0) || ((ip=str2ip6(name))!=0) ){
1765
    /* we are lucky, this is an ip address */
1766
0
    if (*proto==PROTO_NONE)
1767
0
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1768
0
    if (port && *port==0)
1769
0
      *port = protos[*proto].default_port;
1770
0
    return ip_addr2he(name,ip);
1771
0
  }
1772
1773
  /* do we have a port? */
1774
0
  if ( port && (*port)!=0 ) {
1775
    /* have port -> no NAPTR, no SRV lookup, just A record lookup */
1776
0
    LM_DBG("has port -> do A record lookup!\n");
1777
    /* set default PROTO if not set */
1778
0
    if (*proto==PROTO_NONE)
1779
0
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1780
0
    goto do_a;
1781
0
  }
1782
1783
  /* no port... what about proto? */
1784
0
  if ( (*proto)!=PROTO_NONE ) {
1785
    /* have proto, but no port -> do SRV lookup */
1786
0
    LM_DBG("no port, has proto -> do SRV lookup!\n");
1787
0
    if (is_sips && (*proto)!=PROTO_TLS) {
1788
0
      LM_ERR("forced proto %d not matching sips uri\n", *proto);
1789
0
      return 0;
1790
0
    }
1791
0
    goto do_srv;
1792
0
  }
1793
1794
0
  if ( dns_try_naptr==0 ) {
1795
0
    *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1796
0
    goto do_srv;
1797
0
  }
1798
0
  LM_DBG("no port, no proto -> do NAPTR lookup!\n");
1799
  /* no proto, no port -> do NAPTR lookup */
1800
0
  if (name->len >= MAX_DNS_NAME) {
1801
0
    LM_ERR("domain name too long\n");
1802
0
    return 0;
1803
0
  }
1804
0
  memcpy(tmp, name->s, name->len);
1805
0
  tmp[name->len] = '\0';
1806
  /* do NAPTR lookup */
1807
0
  head = get_record( tmp, T_NAPTR);
1808
0
  if (head) {
1809
    /* filter and sort the records */
1810
0
    filter_and_sort_naptr( &head, &rd, is_sips);
1811
    /* free what is useless */
1812
0
    free_rdata_list( rd );
1813
    /* process the NAPTR records */
1814
0
    for( rd=head ; rd ; rd=rd->next ) {
1815
0
      *proto = get_naptr_proto( get_naptr(rd) );
1816
0
      he = do_srv_lookup( get_naptr(rd)->repl, port, dn);
1817
0
      if ( he ) {
1818
0
        LM_DBG("valid SRV found!\n");
1819
0
        if (dn) {
1820
          /* save the state of the resolver for failure cases */
1821
0
          if (*dn==NULL)
1822
0
            rd = rd->next;
1823
0
          if (rd && srv2dns_node( rd, dn)!=0) {
1824
0
            shm_free(*dn);
1825
0
            *dn = 0;
1826
0
          }
1827
0
        }
1828
0
        free_rdata_list(head);
1829
0
        return he;
1830
0
      }
1831
0
    }
1832
0
    if (head)
1833
0
      free_rdata_list(head);
1834
0
  }
1835
0
  LM_DBG("no valid NAPTR record found for %.*s,"
1836
0
    " trying direct SRV lookup...\n", name->len, name->s);
1837
0
  *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1838
1839
0
do_srv:
1840
0
  if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME) {
1841
0
    LM_WARN("domain name too long (%d),"
1842
0
      " unable to perform SRV lookup\n", name->len);
1843
    /* set defaults */
1844
0
    if (port) *port = (is_sips)?SIPS_PORT:SIP_PORT;
1845
0
    goto do_a;
1846
0
  }
1847
1848
0
  switch (*proto) {
1849
0
    case PROTO_UDP:
1850
0
      memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1851
0
      memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
1852
0
      tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1853
0
      break;
1854
0
    case PROTO_TCP:
1855
0
      memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1856
0
      memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
1857
0
      tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1858
0
      break;
1859
0
    case PROTO_TLS:
1860
0
      memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1861
0
      memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
1862
0
      tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1863
0
      break;
1864
0
    case PROTO_SCTP:
1865
0
      memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
1866
0
      memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
1867
0
      tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
1868
0
      break;
1869
0
    case PROTO_WS:
1870
0
      memcpy(tmp, SRV_WS_PREFIX, SRV_WS_PREFIX_LEN);
1871
0
      memcpy(tmp+SRV_WS_PREFIX_LEN, name->s, name->len);
1872
0
      tmp[SRV_WS_PREFIX_LEN + name->len] = '\0';
1873
0
      break;
1874
0
    case PROTO_WSS:
1875
0
      memcpy(tmp, SRV_WSS_PREFIX, SRV_WSS_PREFIX_LEN);
1876
0
      memcpy(tmp+SRV_WSS_PREFIX_LEN, name->s, name->len);
1877
0
      tmp[SRV_WSS_PREFIX_LEN + name->len] = '\0';
1878
0
      break;
1879
0
    default:
1880
0
      goto err_proto;
1881
0
  }
1882
1883
0
  he = do_srv_lookup( tmp, port, dn);
1884
0
  if (he)
1885
0
    return he;
1886
1887
0
  LM_DBG("no valid SRV record found for %s, trying A record lookup...\n",
1888
0
    tmp);
1889
  /* set default port */
1890
0
  if (port) *port = protos[*proto].default_port;
1891
1892
0
do_a:
1893
  /* do A record lookup */
1894
0
  if (name->len >= MAX_DNS_NAME) {
1895
0
    LM_ERR("domain name too long\n");
1896
0
    return 0;
1897
0
  }
1898
0
  memcpy(tmp, name->s, name->len);
1899
0
  tmp[name->len] = '\0';
1900
0
  he = resolvehost(tmp,1);
1901
0
  return he;
1902
0
err_proto:
1903
0
  LM_ERR("unsupported proto %d\n", *proto);
1904
0
  return 0;
1905
0
}
1906
1907
1908
1909
static inline struct hostent* get_next_he(struct dns_node **node,
1910
              unsigned short *proto, unsigned short *port)
1911
0
{
1912
0
  struct hostent  *he;
1913
0
  struct dns_node *n;
1914
0
  struct dns_node *last_srv;
1915
0
  struct dns_node *dn;
1916
1917
0
  if (node==NULL || *node==NULL)
1918
0
    return 0;
1919
1920
0
  n = *node;
1921
0
  last_srv = NULL;
1922
0
  he = 0;
1923
1924
0
  do {
1925
0
    switch (n->type) {
1926
0
      case DNS_NODE_SRV:
1927
0
        last_srv = n;
1928
0
        if (n->kids==NULL) {
1929
          /* need to resolve this SRV and get all the AAA records */
1930
0
          do {
1931
0
            dn = 0;
1932
0
            he = do_srv_lookup( n->vals[n->idx].sval, port, &dn);
1933
0
            if (he) {
1934
0
              *proto = n->vals[n->idx].ival;
1935
0
              n->idx++;
1936
0
              break;
1937
0
            }
1938
0
            n->idx++;
1939
0
          } while(n->idx<n->no);
1940
0
          if (he==NULL || (he && n->idx==n->no) ) {
1941
            /* colapse the SRV node */
1942
0
            shm_free(n);
1943
0
            *node = dn;
1944
0
            return he;
1945
0
          }
1946
0
          n->kids = dn;
1947
0
          return he;
1948
0
        }
1949
        /* go for the AAA records */
1950
0
        n = n->kids;
1951
0
        break;
1952
0
      case DNS_NODE_A:
1953
        /* do resolve until success */
1954
0
        do {
1955
0
          he = resolvehost(n->vals[n->idx].sval,1);
1956
0
          if (he) {
1957
0
            *port = n->vals[n->idx].ival;
1958
0
            n->idx++;
1959
0
            break;
1960
0
          }
1961
0
          n->idx++;
1962
0
        }while(n->idx<n->no);
1963
        /* found something? */
1964
0
        if (he==NULL || (he && n->idx==n->no)) {
1965
0
          shm_free(n);
1966
          /* any SRV level? */
1967
0
          if (last_srv==NULL) {
1968
            /* nothing left */
1969
0
            *node = 0;
1970
0
            return he;
1971
0
          }
1972
0
          last_srv->kids = 0;
1973
          /* increase the index on the SRV level */
1974
0
          if (++last_srv->idx<last_srv->no)
1975
0
            return he;
1976
          /* colapse the SRV node also */
1977
0
          shm_free(last_srv);
1978
0
          *node = 0;
1979
0
        }
1980
0
        return he;
1981
0
        break;
1982
0
      default:
1983
0
        LM_CRIT("unknown %d node type\n", n->type);
1984
0
        return 0;
1985
0
    }
1986
0
  } while(1);
1987
0
}
1988
1989
1990
1991
void free_dns_res( struct proxy_l *p )
1992
0
{
1993
0
  if (p==NULL || p->dn==NULL)
1994
0
    return;
1995
1996
0
  if (p->dn->kids)
1997
0
    shm_free(p->dn->kids);
1998
0
  shm_free(p->dn);
1999
0
  p->dn = 0;
2000
0
}
2001
2002
2003
2004
int get_next_su(struct proxy_l *p, union sockaddr_union* su, int add_to_bl)
2005
0
{
2006
0
  struct hostent *he;
2007
0
  struct bl_rule *list;
2008
0
  struct net  ip_net;
2009
0
  int n;
2010
2011
0
  if (failover_bl && add_to_bl) {
2012
0
    memset( &ip_net, 0xff , sizeof(struct net));
2013
0
    hostent2ip_addr( &ip_net.ip, &p->host, p->addr_idx);
2014
0
    ip_net.mask.af = ip_net.ip.af;
2015
0
    ip_net.mask.len = ip_net.ip.len;
2016
0
    list = 0;
2017
0
    n = add_rule_to_list( &list, &list, &ip_net, 0, p->port, p->proto, 0);
2018
0
    if (n!=0) {
2019
0
      LM_ERR("failed to build bl rule\n");
2020
0
    } else {
2021
0
      add_list_to_head( failover_bl, list, list, 0, DNS_BL_EXPIRE);
2022
0
    }
2023
0
  }
2024
2025
  /* any more available IPs in he ? */
2026
0
  if ( p->host.h_addr_list[++p->addr_idx] ) {
2027
    /* yes -> return the IP*/
2028
0
    hostent2su( su, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
2029
0
    return 0;
2030
0
  }
2031
2032
  /* get a new he from DNS */
2033
0
  he = get_next_he( &p->dn, &p->proto, &p->port);
2034
0
  if (he==NULL)
2035
0
    return -1;
2036
2037
  /* replace the current he */
2038
0
  if (p->flags&PROXY_SHM_FLAG) {
2039
0
    free_shm_hostent( &p->host );
2040
0
    n = hostent_shm_cpy(&(p->host), he);
2041
0
  } else {
2042
0
    free_hostent( &p->host );
2043
0
    n = hostent_cpy(&(p->host), he);
2044
0
  }
2045
0
  if (n!=0) {
2046
0
    free_dns_res( p );
2047
0
    return -1;
2048
0
  }
2049
2050
0
  hostent2su( su, &p->host, 0, (p->port)?p->port:SIP_PORT);
2051
0
  p->addr_idx = 0;
2052
0
  return 0;
2053
0
}
2054
2055
2056
2057
static inline struct dns_node *dns_node_copy(struct dns_node *s)
2058
0
{
2059
0
  struct dns_node *d;
2060
0
  unsigned int i;
2061
2062
0
  d = (struct dns_node*)shm_malloc(s->size);
2063
0
  if (d==NULL) {
2064
0
    LM_ERR("no more shm mem\n");
2065
0
    return 0;
2066
0
  }
2067
0
  memcpy( d, s, s->size);
2068
0
  d->vals = (struct dns_val*)(void *)((char*)d + ((char*)s->vals-(char*)s));
2069
0
  for( i=0 ; i<s->no ; i++ )
2070
0
    d->vals[i].sval = (char*)d + ((char*)s->vals[i].sval-(char*)s);
2071
0
  return d;
2072
0
}
2073
2074
2075
struct dns_node *dns_res_copy(struct dns_node *s)
2076
0
{
2077
0
  struct dns_node *d;
2078
2079
0
  d = dns_node_copy(s);
2080
0
  if (d==NULL)
2081
0
    return 0;
2082
0
  if (s->kids) {
2083
0
    d->kids = dns_node_copy(s->kids);
2084
0
    if (d->kids==NULL) {
2085
0
      shm_free(d);
2086
0
      return 0;
2087
0
    }
2088
0
  }
2089
0
  return d;
2090
0
}