Coverage Report

Created: 2026-08-13 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/resolve.c
Line
Count
Source
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
0
  int cname_chain_depth = 0;
403
0
  char *query_name;
404
0
  static char cname_chain_name[DNS_MAX_NAME];
405
406
0
  switch (af) {
407
0
    case AF_INET:
408
0
      size=4;
409
0
      type=T_A;
410
0
      break;
411
0
    case AF_INET6:
412
0
      size=16;
413
0
      type=T_AAAA;
414
0
      break;
415
0
    default:
416
0
      LM_ERR("Only A and AAAA queries\n");
417
0
      return NULL;
418
0
  }
419
420
0
  cached_he = (struct hostent *)dnscache_fetch_func(name,af==AF_INET?T_A:T_AAAA,0);
421
0
  if (cached_he == NULL) {
422
0
    LM_DBG("not found in cache or other internal error\n");
423
0
    goto query;
424
0
  } else if (cached_he == (void *)-1) {
425
0
    LM_DBG("previously failed query\n");
426
0
    return NULL;
427
0
  } else {
428
0
    LM_DBG("cache hit for %s - %d\n",name,af);
429
0
    return cached_he;
430
0
  }
431
432
0
query:
433
0
  global_he.h_addrtype=af;
434
0
  global_he.h_length=size;
435
436
0
  query_name = name;
437
438
  /* Follow CNAME chain - RFC 1034 recommends max depth of ~8-16 */
439
0
  #define MAX_CNAME_CHAIN_DEPTH 10
440
441
0
  while (cname_chain_depth < MAX_CNAME_CHAIN_DEPTH) {
442
0
    size=res_search(query_name, C_IN, type, buff.buff, sizeof(buff));
443
0
    if (size < 0) {
444
0
      LM_DBG("Domain name not found: %s\n", query_name);
445
0
      if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0)
446
0
        LM_ERR("Failed to store %s - %d in cache\n",name,af);
447
0
      return NULL;
448
0
    }
449
450
0
    if (get_dns_answer(&buff,size,query_name,type,&min_ttl) < 0) {
451
0
      LM_ERR("Failed to get dns answer for %s\n", query_name);
452
0
      return NULL;
453
0
    }
454
455
    /* Check if we got actual addresses or just a CNAME */
456
0
    if (global_he.h_addr_list && global_he.h_addr_list[0] != NULL) {
457
      /* We have addresses, done */
458
0
      LM_DBG("Resolved %s to addresses (CNAME chain depth: %d)\n",
459
0
        name, cname_chain_depth);
460
0
      break;
461
0
    }
462
463
    /* No addresses - check if we have a CNAME to follow */
464
0
    if (global_he.h_name && strcmp(global_he.h_name, query_name) != 0) {
465
      /* We have a CNAME, follow it */
466
0
      LM_DBG("Following CNAME: %s -> %s\n", query_name, global_he.h_name);
467
468
      /* Copy canonical name for next iteration */
469
0
      if (strlen(global_he.h_name) >= DNS_MAX_NAME) {
470
0
        LM_ERR("CNAME target too long: %s\n", global_he.h_name);
471
0
        return NULL;
472
0
      }
473
0
      strcpy(cname_chain_name, global_he.h_name);
474
0
      query_name = cname_chain_name;
475
0
      cname_chain_depth++;
476
0
    } else {
477
      /* No addresses and no CNAME to follow - this is an error */
478
0
      LM_WARN("No addresses and no CNAME for %s\n", query_name);
479
0
      if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,NULL,0,1,0) < 0)
480
0
        LM_ERR("Failed to store %s - %d in cache\n",name,af);
481
0
      return NULL;
482
0
    }
483
0
  }
484
485
0
  if (cname_chain_depth >= MAX_CNAME_CHAIN_DEPTH) {
486
0
    LM_ERR("CNAME chain too deep for %s (depth: %d)\n", name, cname_chain_depth);
487
0
    return NULL;
488
0
  }
489
490
0
  if (dnscache_put_func(name,af==AF_INET?T_A:T_AAAA,&global_he,-1,0,min_ttl) < 0)
491
0
    LM_ERR("Failed to store %s - %d in cache\n",name,af);
492
0
  return &global_he;
493
0
}
494
495
inline struct hostent* resolvehost_af(char* name, int no_ip_test, int af)
496
0
{
497
0
  static struct hostent *he = NULL;
498
#ifdef HAVE_GETIPNODEBYNAME
499
  int err;
500
  static struct hostent *he2 = NULL;
501
#endif
502
0
  struct timeval start;
503
0
  struct ip_addr *ip;
504
0
  str s;
505
506
0
  if (!no_ip_test) {
507
0
    s.s = (char *)name;
508
0
    s.len = strlen(name);
509
510
    /* check if it's an ip address */
511
0
    if (af != AF_INET6 && (ip = str2ip(&s)))
512
0
      return ip_addr2he(&s, ip);
513
0
    if (af != AF_INET && (ip = str2ip6(&s)))
514
0
      return ip_addr2he(&s, ip);
515
0
  }
516
517
0
  start_expire_timer(start, execdnsthreshold);
518
519
0
  if (af == AF_INET6 || (af == 0 && dns_try_ipv6)) {
520
    /* try ipv6 */
521
0
  #ifdef HAVE_GETHOSTBYNAME2
522
0
    if (dnscache_fetch_func)
523
0
          he = own_gethostbyname2(name,AF_INET6);
524
0
    else
525
0
      he = gethostbyname2(name, AF_INET6);
526
527
  #elif defined HAVE_GETIPNODEBYNAME
528
    /* on solaris 8 getipnodebyname has a memory leak,
529
     * after some time calls to it will fail with err=3
530
     * solution: patch your solaris 8 installation */
531
    if (he2) freehostent(he2);
532
    he = he2 = getipnodebyname(name, AF_INET6, 0, &err);
533
  #else
534
    #error "neither gethostbyname2 or getipnodebyname present"
535
  #endif
536
0
    if (he != 0)
537
      /* return the inet6 result if exists */
538
0
      goto out;
539
0
  }
540
541
0
  if (af != AF_INET6) {
542
0
    if (dnscache_fetch_func)
543
0
      he = own_gethostbyname2(name,AF_INET);
544
0
    else
545
0
      he = gethostbyname(name);
546
0
  }
547
548
0
out:
549
0
  _stop_expire_timer(start, execdnsthreshold, "dns",
550
0
              name, strlen(name), 0, dns_slow_queries, dns_total_queries);
551
0
  return he;
552
0
}
553
554
inline struct hostent* resolvehost(char* name, int no_ip_test)
555
0
{
556
0
  return resolvehost_af(name, no_ip_test, 0);
557
0
}
558
559
struct hostent * own_gethostbyaddr(void *addr, socklen_t len, int af)
560
0
{
561
0
  const unsigned char *uaddr = (const u_char *)addr;
562
0
  static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
563
0
  static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
564
0
  int n;
565
0
  int ret;
566
0
  static union dns_query ptr_buff;
567
0
  socklen_t size;
568
0
  char qbuf[DNS_MAX_NAME+1];
569
0
  char *qp=NULL;
570
0
  int min_ttl=INT_MAX;
571
0
  struct hostent *cached_he;
572
573
0
  if (af == AF_INET6 && len == 16 &&
574
0
  (!memcmp(uaddr, mapped, sizeof mapped) ||
575
0
  !memcmp(uaddr, tunnelled, sizeof tunnelled))) {
576
    /* Unmap. */
577
0
    addr += sizeof mapped;
578
0
    uaddr += sizeof mapped;
579
0
    af = AF_INET;
580
0
    len = 4;
581
0
  }
582
583
0
  switch (af) {
584
0
    case AF_INET:
585
0
      size = 4;
586
0
      break;
587
0
    case AF_INET6:
588
0
      size = 16;
589
0
      break;
590
0
    default:
591
0
      LM_ERR("unexpected af = %d\n",af);
592
0
      return NULL;
593
0
  }
594
595
0
  if (size != len) {
596
0
    LM_ERR("size = %d, len = %d\n",size,len);
597
0
    return NULL;
598
0
  }
599
600
0
  cached_he = (struct hostent *)dnscache_fetch_func(addr,T_PTR,af==AF_INET?4:16);
601
0
  if (cached_he == NULL) {
602
0
    LM_DBG("not found in cache or other internal error\n");
603
0
    goto query;
604
0
  } else if (cached_he == (void *)-1) {
605
0
    LM_DBG("previously failed query\n");
606
0
    return NULL;
607
0
  } else {
608
0
    LM_DBG("cache hit for PTR - %d\n",af);
609
0
    return cached_he;
610
0
  }
611
612
0
query:
613
0
  switch (af) {
614
0
    case AF_INET:
615
0
      sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
616
0
        (uaddr[3] & 0xff),
617
0
        (uaddr[2] & 0xff),
618
0
        (uaddr[1] & 0xff),
619
0
        (uaddr[0] & 0xff));
620
0
      break;
621
0
    case AF_INET6:
622
0
      qp = qbuf;
623
0
      for (n = 15; n >= 0; n--) {
624
0
        qp += sprintf(qp, "%x.%x.",
625
0
        uaddr[n] & 0xf,
626
0
        (uaddr[n] >> 4) & 0xf);
627
0
      }
628
0
      strcpy(qp, "ip6.arpa");
629
0
      break;
630
0
  }
631
632
0
  global_he.h_addrtype=af;
633
0
  global_he.h_length=len;
634
635
0
  ret=res_search(qbuf,C_IN,T_PTR,ptr_buff.buff,sizeof(ptr_buff.buff));
636
0
  if (ret < 0) {
637
0
    LM_DBG("ptr not found\n");
638
0
    if (dnscache_put_func(addr,T_PTR,NULL,len,1,0) < 0)
639
0
      LM_ERR("Failed to store PTR in cache\n");
640
0
    return NULL;
641
0
  }
642
643
0
  if (get_dns_answer(&ptr_buff,ret,qbuf,T_PTR,&min_ttl) < 0) {
644
0
    LM_ERR("Failed to get dns answer\n");
645
0
    return NULL;
646
0
  }
647
648
0
  if (dnscache_put_func(addr,T_PTR,&global_he,len,0,min_ttl) < 0)
649
0
    LM_ERR("Failed to store PTR in cache\n");
650
0
  return &global_he;
651
0
}
652
653
654
struct hostent* rev_resolvehost(struct ip_addr *ip)
655
0
{
656
0
  if (dnscache_fetch_func != NULL) {
657
0
    return own_gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af);
658
0
  } else
659
0
    return gethostbyaddr((char*)(ip)->u.addr, (ip)->len, (ip)->af);
660
0
}
661
662
/*! \brief checks if ip is in host(name) and ?host(ip)=name?
663
 * ip must be in network byte order!
664
 *  resolver = DO_DNS | DO_REV_DNS; if 0 no dns check is made
665
 * \return 0 if equal */
666
int check_ip_address(struct ip_addr* ip, str *name,
667
        unsigned short port, unsigned short proto, int resolver)
668
0
{
669
0
  struct ip_addr *ip2;
670
0
  struct hostent* he;
671
0
  int i;
672
673
  /* maybe we are lucky and host (name) is an IP */
674
0
  if ( (ip2=str2ip(name))!=NULL || (ip2=str2ip6(name))!=NULL ) {
675
    /* It's an IP :D */
676
0
    if (ip_addr_cmp(ip, ip2))
677
0
      return 0;
678
0
    return -1;
679
0
  }
680
681
  /* host is not an IP, do the DNS lookups on it :(*/
682
0
  if (port==0) port=SIP_PORT;
683
0
  if (resolver&DO_DNS){
684
0
    LM_DBG("doing dns lookup\n");
685
    /* try all names ips */
686
0
    he=sip_resolvehost(name, &port, &proto, 0, 0);
687
0
    if (he && (int)ip->af==he->h_addrtype){
688
0
      for(i=0;he && he->h_addr_list[i];i++){
689
0
        if ( memcmp(&he->h_addr_list[i], ip->u.addr, ip->len)==0)
690
0
          return 0;
691
0
      }
692
0
    }
693
0
  }
694
0
  if (resolver&DO_REV_DNS){
695
0
    LM_DBG("doing rev. dns lookup\n");
696
    /* try reverse dns */
697
0
    he=rev_resolvehost(ip);
698
0
    if (he && (strncmp(he->h_name, name->s, name->len)==0))
699
0
      return 0;
700
0
    for (i=0; he && he->h_aliases[i];i++){
701
0
      if (strncmp(he->h_aliases[i],name->s, name->len)==0)
702
0
        return 0;
703
0
    }
704
0
  }
705
0
  return -1;
706
0
}
707
708
709
710
/*! \brief Initialize the DNS resolver
711
 * retr_time  - time before retransmitting (must be >0)
712
 * retr_no    - retransmissions number
713
 * servers_no - how many dns servers will be used
714
 *                      (from the one listed in /etc/resolv.conf)
715
 * search     - if 0 the search list in /etc/resolv.conf will
716
 *                      be ignored (HINT: even if you don't have a
717
 *                      search list in resolv.conf, it's still better
718
 *                      to set search to 0, because an empty searchlist
719
 *                      means in fact search "" => it takes more time)
720
 * If any of the parameters <0, the default (system specific) value
721
 * will be used. See also resolv.conf(5).
722
 * \return 0 on success, -1 on error
723
 */
724
int resolv_init(void)
725
0
{
726
0
  res_init();
727
0
#ifdef HAVE_RESOLV_RES
728
0
  if (dns_retr_time>0)
729
0
    _res.retrans=dns_retr_time;
730
0
  if (dns_retr_no>0)
731
0
    _res.retry=dns_retr_no;
732
0
  if (dns_servers_no>=0)
733
0
    _res.nscount=dns_servers_no;
734
0
  if (dns_search_list==0)
735
0
    _res.options&=~(RES_DEFNAMES|RES_DNSRCH);
736
#else
737
#warning "no resolv timeout support"
738
  LM_WARN("no resolv options support - resolv options will be ignored\n");
739
#endif
740
741
0
  if (register_stat("dns", "dns_total_queries", &dns_total_queries, 0) ||
742
0
      register_stat("dns", "dns_slow_queries", &dns_slow_queries, 0)) {
743
0
    LM_ERR("failed to register DNS stats\n");
744
0
    return -1;
745
0
  }
746
747
0
  return 0;
748
0
}
749
750
751
752
/*! \brief Initialize blacklist */
753
int resolv_blacklist_init(void)
754
0
{
755
0
  str name = str_init(DNS_REVOLVER_BL_NAME);
756
757
0
  if (!disable_dns_blacklist) {
758
0
    failover_bl = create_bl_head(_str("dns"),
759
0
      BL_DO_EXPIRE|BL_BY_DEFAULT, 0, 0, &name);
760
0
    if (failover_bl==NULL) {
761
0
      LM_ERR("failed to create blacklist\n");
762
0
      return -1;
763
0
    }
764
0
  }
765
0
  return 0;
766
0
}
767
768
769
/*! \brief Skips over a domain name in a dns message
770
 *  (it can be  a sequence of labels ending in \\0, a pointer or
771
 *   a sequence of labels ending in a pointer -- see rfc1035
772
 *   returns pointer after the domain name or null on error
773
 */
774
unsigned char* dns_skipname(unsigned char* p, unsigned char* end)
775
0
{
776
0
  while(p<end) {
777
    /* check if \0 (root label length) */
778
0
    if (*p==0){
779
0
      p+=1;
780
0
      break;
781
0
    }
782
    /* check if we found a pointer */
783
0
    if (((*p)&0xc0)==0xc0){
784
      /* if pointer skip over it (2 bytes) & we found the end */
785
0
      p+=2;
786
0
      break;
787
0
    }
788
    /* normal label */
789
0
    p+=*p+1;
790
0
  }
791
0
  return (p>=end)?0:p;
792
0
}
793
794
795
796
/*! \brief parses the srv record into a srv_rdata structure
797
 *   \param msg   - pointer to the dns message
798
 *   \param end   - pointer to the end of the message
799
 *   \param rdata - pointer  to the rdata part of the srv answer
800
 *   \return 0 on error, or a dyn. alloc'ed srv_rdata structure
801
 *
802
 * SRV rdata format:
803
 *            111111
804
 *  0123456789012345
805
 * +----------------+
806
 * |     priority   |
807
 * |----------------|
808
 * |     weight     |
809
 * |----------------|
810
 * |   port number  |
811
 * |----------------|
812
 * |                |
813
 * ~      name      ~
814
 * |                |
815
 * +----------------+
816
 */
817
struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
818
                  unsigned char* rdata)
819
0
{
820
0
  struct srv_rdata* srv;
821
0
  int len;
822
823
0
  srv=0;
824
0
  if ((rdata+6)>=end) goto error;
825
0
  srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata));
826
0
  if (srv==0){
827
0
    LM_ERR("out of pkg memory\n");
828
0
    goto error;
829
0
  }
830
831
0
  memcpy((void*)&srv->priority, rdata, 2);
832
0
  memcpy((void*)&srv->weight,   rdata+2, 2);
833
0
  memcpy((void*)&srv->port,     rdata+4, 2);
834
0
  rdata+=6;
835
0
  srv->priority=ntohs(srv->priority);
836
0
  srv->weight=ntohs(srv->weight);
837
0
  srv->port=ntohs(srv->port);
838
0
  if ((len=dn_expand(msg, end, rdata, srv->name, MAX_DNS_NAME-1))==-1)
839
0
    goto error;
840
  /* add terminating 0 ? (warning: len=compressed name len) */
841
0
  srv->name_len=strlen(srv->name);
842
0
  return srv;
843
0
error:
844
0
  if (srv) local_free(srv);
845
0
  return 0;
846
0
}
847
848
849
/*! \brief parses the naptr record into a naptr_rdata structure
850
 *   \param msg   - pointer to the dns message
851
 *   \param end   - pointer to the end of the message
852
 *   \param rdata - pointer  to the rdata part of the naptr answer
853
 *   \return  0 on error, or a dyn. alloc'ed naptr_rdata structure
854
 *
855
 * NAPTR rdata format:
856
 *            111111
857
 *  0123456789012345
858
 * +----------------+
859
 * |      order     |
860
 * |----------------|
861
 * |   preference   |
862
 * |----------------|
863
 * ~     flags      ~
864
 * |   (string)     |
865
 * |----------------|
866
 * ~    services    ~
867
 * |   (string)     |
868
 * |----------------|
869
 * ~    regexp      ~
870
 * |   (string)     |
871
 * |----------------|
872
 * ~  replacement   ~
873
   |    (name)      |
874
 * +----------------+
875
 */
876
struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
877
                  unsigned char* rdata)
878
0
{
879
0
  struct naptr_rdata* naptr;
880
881
0
  naptr = 0;
882
0
  if ((rdata + 7) >= end)
883
0
    goto error;
884
0
  naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata));
885
0
  if (naptr == 0){
886
0
    LM_ERR("out of pkg memory\n");
887
0
    goto error;
888
0
  }
889
890
0
  memcpy((void*)&naptr->order, rdata, 2);
891
0
  naptr->order=ntohs(naptr->order);
892
0
  memcpy((void*)&naptr->pref, rdata + 2, 2);
893
0
  naptr->pref=ntohs(naptr->pref);
894
0
  naptr->flags_len = (int)rdata[4];
895
0
  if ((rdata + 7 +  naptr->flags_len) >= end)
896
0
    goto error;
897
0
  memcpy((void*)&naptr->flags, rdata + 5, naptr->flags_len);
898
0
  naptr->services_len = (int)rdata[5 + naptr->flags_len];
899
0
  if ((rdata + 7 + naptr->flags_len + naptr->services_len) >= end) goto error;
900
0
  memcpy((void*)&naptr->services, rdata + 6 + naptr->flags_len, naptr->services_len);
901
0
  naptr->regexp_len = (int)rdata[6 + naptr->flags_len + naptr->services_len];
902
0
  if ((rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len) >= end)
903
0
    goto error;
904
0
  memcpy((void*)&naptr->regexp, rdata + 7 + naptr->flags_len +
905
0
        naptr->services_len, naptr->regexp_len);
906
0
  rdata = rdata + 7 + naptr->flags_len + naptr->services_len + naptr->regexp_len;
907
0
  naptr->repl_len=dn_expand(msg, end, rdata, naptr->repl, MAX_DNS_NAME-1);
908
0
  if ( naptr->repl_len==(unsigned int)-1 )
909
0
    goto error;
910
  /* add terminating 0 ? (warning: len=compressed name len) */
911
0
  return naptr;
912
0
error:
913
0
  if (naptr)
914
0
    local_free(naptr);
915
0
  return 0;
916
0
}
917
918
919
920
/*! \brief Parses a CNAME record into a cname_rdata structure */
921
struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
922
                    unsigned char* rdata)
923
0
{
924
0
  struct cname_rdata* cname;
925
0
  int len;
926
927
0
  cname=0;
928
0
  cname=(struct cname_rdata*)local_malloc(sizeof(struct cname_rdata));
929
0
  if(cname==0){
930
0
    LM_ERR("out of pkg memory\n");
931
0
    goto error;
932
0
  }
933
0
  if ((len=dn_expand(msg, end, rdata, cname->name, MAX_DNS_NAME-1))==-1)
934
0
    goto error;
935
0
  return cname;
936
0
error:
937
0
  if (cname) local_free(cname);
938
0
  return 0;
939
0
}
940
941
942
943
/*! \brief Parses an A record rdata into an a_rdata structure
944
 * \return 0 on error or a dyn. alloc'ed a_rdata struct
945
 */
946
struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* end)
947
0
{
948
0
  struct a_rdata* a;
949
950
0
  if (rdata+4>=end) goto error;
951
0
  a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata));
952
0
  if (a==0){
953
0
    LM_ERR("out of pkg memory\n");
954
0
    goto error;
955
0
  }
956
0
  memcpy(a->ip, rdata, 4);
957
0
  return a;
958
0
error:
959
0
  return 0;
960
0
}
961
962
963
964
/*! \brief Parses an AAAA (ipv6) record rdata into an aaaa_rdata structure
965
 * \return 0 on error or a dyn. alloc'ed aaaa_rdata struct
966
 */
967
struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* end)
968
0
{
969
0
  struct aaaa_rdata* aaaa;
970
971
0
  if (rdata+16>=end) goto error;
972
0
  aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata));
973
0
  if (aaaa==0){
974
0
    LM_ERR("out of pkg memory\n");
975
0
    goto error;
976
0
  }
977
0
  memcpy(aaaa->ip6, rdata, 16);
978
0
  return aaaa;
979
0
error:
980
0
  return 0;
981
0
}
982
983
/*! \brief Parses a TXT record into a txt_rdata structure
984
 * \note RFC1035:
985
 * - <character-string> is a single length octet followed by that number of characters.
986
 * - TXT-DATA        One or more <character-string>s.
987
 *
988
 * We only take the first string here.
989
 */
990
struct txt_rdata* dns_txt_parser( unsigned char* msg, unsigned char* end,
991
                    unsigned char* rdata)
992
0
{
993
0
  struct txt_rdata* txt;
994
0
  unsigned int len;
995
996
0
  txt=0;
997
0
  txt=(struct txt_rdata*)local_malloc(sizeof(struct txt_rdata));
998
0
  if(txt==0){
999
0
    LM_ERR("out of pkg memory\n");
1000
0
    goto error;
1001
0
  }
1002
1003
0
  len = *rdata;
1004
0
  if (rdata + 1 + len >= end)
1005
0
    goto error; /*  something fishy in the record */
1006
1007
#if 0
1008
  /* Comparison is always false because len <= 255. */
1009
  if (len >= sizeof(txt->txt))
1010
    goto error; /* not enough space? */
1011
#endif
1012
0
  memcpy(txt->txt, rdata+1, len);
1013
0
  txt->txt[len] = 0;    /* 0-terminate string */
1014
0
  return txt;
1015
1016
0
error:
1017
0
  if (txt)
1018
0
    local_free(txt);
1019
0
  return 0;
1020
0
}
1021
1022
1023
/*! \brief parses a EBL record into a ebl_rdata structure
1024
 *
1025
 * EBL Record
1026
 *
1027
 *    0  1  2  3  4  5  6  7
1028
 *    +--+--+--+--+--+--+--+--+
1029
 *    |       POSITION        |
1030
 *    +--+--+--+--+--+--+--+--+
1031
 *    /       SEPARATOR       /
1032
 *    +--+--+--+--+--+--+--+--+
1033
 *    /         APEX          /
1034
 *    +--+--+--+--+--+--+--+--+
1035
 */
1036
struct ebl_rdata* dns_ebl_parser( unsigned char* msg, unsigned char* end,
1037
                    unsigned char* rdata)
1038
0
{
1039
0
  struct ebl_rdata* ebl;
1040
0
  int len;
1041
1042
0
  ebl=0;
1043
0
  ebl=(struct ebl_rdata*)local_malloc(sizeof(struct ebl_rdata));
1044
0
  if(ebl==0){
1045
0
    LM_ERR("out of pkg memory\n");
1046
0
    goto error;
1047
0
  }
1048
1049
0
  len = *rdata;
1050
0
  if (rdata + 1 + len >= end)
1051
0
    goto error; /*  something fishy in the record */
1052
1053
0
  ebl->position = *rdata;
1054
0
  if ( ebl->position > 15 )
1055
0
    goto error; /* doesn't make sense: E.164 numbers can't be longer */
1056
1057
0
  rdata++;
1058
1059
0
  ebl->separator_len = (int) *rdata;
1060
0
  rdata++;
1061
0
  if ((rdata + 1 +  ebl->separator_len) >= end)
1062
0
    goto error;
1063
0
  memcpy((void*)&ebl->separator, rdata, ebl->separator_len);
1064
0
  rdata += ebl->separator_len;
1065
1066
0
  ebl->apex_len=dn_expand(msg, end, rdata, ebl->apex, MAX_DNS_NAME-1);
1067
0
  if ( ebl->apex_len==(unsigned int)-1 )
1068
0
    goto error;
1069
0
  ebl->apex[ebl->apex_len] = 0; /* 0-terminate string */
1070
0
  return ebl;
1071
1072
0
error:
1073
0
  if (ebl)
1074
0
    local_free(ebl);
1075
0
  return 0;
1076
0
}
1077
1078
1079
1080
1081
/*! \brief frees completely a struct rdata list */
1082
void free_rdata_list(struct rdata* head)
1083
0
{
1084
0
  struct rdata* l;
1085
0
  struct rdata* next_l;
1086
1087
0
  for( l=head; l ; l=next_l) {
1088
0
    next_l = l->next;
1089
    /* free the parsed rdata*/
1090
0
    if (l->rdata)
1091
0
      local_free(l->rdata);
1092
0
    local_free(l);
1093
0
  }
1094
0
}
1095
1096
1097
1098
/*! \brief gets the DNS records for name:type
1099
 * \return A dyn. alloc'ed struct rdata linked list with the parsed responses
1100
 * or 0 on error
1101
 * \note see rfc1035 for the query/response format */
1102
struct rdata* get_record(char* name, int type)
1103
0
{
1104
0
  int size;
1105
0
  int qno, answers_no;
1106
0
  int r;
1107
0
  static union dns_query buff;
1108
0
  unsigned char* p;
1109
/*  unsigned char* t;
1110
  int ans_len;
1111
  static unsigned char answer[ANS_SIZE]; */
1112
0
  static int rdata_struct_len=sizeof(struct rdata)-sizeof(void *) -
1113
0
    sizeof(struct rdata *);
1114
0
  unsigned char* end;
1115
0
  unsigned short rtype, class, rdlength;
1116
0
  unsigned int ttl;
1117
0
  unsigned int min_ttl = UINT_MAX;
1118
0
  struct rdata* head;
1119
0
  struct rdata** crt;
1120
0
  struct rdata** last;
1121
0
  struct rdata* rd;
1122
0
  struct srv_rdata* srv_rd;
1123
0
  struct srv_rdata* crt_srv;
1124
0
  struct naptr_rdata* naptr_rd;
1125
0
  struct txt_rdata* txt_rd;
1126
0
  struct ebl_rdata* ebl_rd;
1127
0
  struct timeval start;
1128
0
  int rdata_buf_len=0;
1129
1130
0
  if (dnscache_fetch_func != NULL) {
1131
0
    head = (struct rdata *)dnscache_fetch_func(name,type,0);
1132
0
    if (head == NULL) {
1133
0
      LM_DBG("not found in cache or other internal error\n");
1134
0
      goto query;
1135
0
    } else if (head == (void *)-1) {
1136
0
      LM_DBG("previously failed query\n");
1137
0
      goto not_found;
1138
0
    } else {
1139
0
      LM_DBG("cache hit for %s - %d\n",name,type);
1140
0
      return head;
1141
0
    }
1142
0
  }
1143
1144
0
query:
1145
0
  start_expire_timer(start,execdnsthreshold);
1146
0
  size=res_search(name, C_IN, type, buff.buff, sizeof(buff));
1147
0
  _stop_expire_timer(start, execdnsthreshold, "dns",
1148
0
              name, strlen(name), 0, dns_slow_queries, dns_total_queries);
1149
1150
0
  if (size<0) {
1151
0
    LM_DBG("lookup(%s, %d) failed\n", name, type);
1152
0
    if (dnscache_put_func != NULL) {
1153
0
      if (dnscache_put_func(name,type,NULL,0,1,0) < 0)
1154
0
        LM_ERR("Failed to store %s - %d in cache\n",name,type);
1155
0
    }
1156
0
    goto not_found;
1157
0
  }
1158
0
  else if ((unsigned int)size > sizeof(buff)) size=sizeof(buff);
1159
0
  head=rd=0;
1160
0
  last=crt=&head;
1161
1162
0
  p=buff.buff+DNS_HDR_SIZE;
1163
0
  end=buff.buff+size;
1164
0
  if (p>=end) goto error_boundary;
1165
0
  qno=ntohs((unsigned short)buff.hdr.qdcount);
1166
1167
0
  for (r=0; r<qno; r++){
1168
    /* skip the name of the question */
1169
0
    if ((p=dns_skipname(p, end))==0) {
1170
0
      LM_ERR("skipname==0\n");
1171
0
      goto error;
1172
0
    }
1173
0
    p+=2+2; /* skip QCODE & QCLASS */
1174
  #if 0
1175
    for (;(p<end && (*p)); p++);
1176
    p+=1+2+2; /* skip the ending  '\0, QCODE and QCLASS */
1177
  #endif
1178
0
    if (p>=end) {
1179
0
      LM_ERR("p>=end\n");
1180
0
      goto error;
1181
0
    }
1182
0
  };
1183
0
  answers_no=ntohs((unsigned short)buff.hdr.ancount);
1184
  /*ans_len=ANS_SIZE;
1185
  t=answer;*/
1186
0
  for (r=0; (r<answers_no) && (p<end); r++){
1187
    /*  ignore it the default domain name */
1188
0
    if ((p=dns_skipname(p, end))==0) {
1189
0
      LM_ERR("skip_name=0 (#2)\n");
1190
0
      goto error;
1191
0
    }
1192
    /*
1193
    skip=dn_expand(buff.buff, end, p, t, ans_len);
1194
    p+=skip;
1195
    */
1196
    /* check if enough space is left for type, class, ttl & size */
1197
0
    if ((p+2+2+4+2)>=end) goto error_boundary;
1198
    /* get type */
1199
0
    memcpy((void*) &rtype, (void*)p, 2);
1200
0
    rtype=ntohs(rtype);
1201
0
    p+=2;
1202
    /* get  class */
1203
0
    memcpy((void*) &class, (void*)p, 2);
1204
0
    class=ntohs(class);
1205
0
    p+=2;
1206
    /* get ttl*/
1207
0
    memcpy((void*) &ttl, (void*)p, 4);
1208
0
    ttl=ntohl(ttl);
1209
0
    if (ttl < min_ttl)
1210
0
      min_ttl = ttl;
1211
0
    p+=4;
1212
    /* get size */
1213
0
    memcpy((void*)&rdlength, (void*)p, 2);
1214
0
    rdlength=ntohs(rdlength);
1215
0
    p+=2;
1216
    /* check for type */
1217
    /*
1218
    if (rtype!=type){
1219
      LM_WAR("wrong type in answer (%d!=%d)\n", rtype, type);
1220
      p+=rdlength;
1221
      continue;
1222
    }
1223
    */
1224
    /* expand the "type" record  (rdata)*/
1225
1226
0
    rd=(struct rdata*) local_malloc(sizeof(struct rdata));
1227
0
    if (rd==0){
1228
0
      LM_ERR("out of pkg memory\n");
1229
0
      goto error;
1230
0
    }
1231
0
    if (dnscache_put_func)
1232
0
      rdata_buf_len+=rdata_struct_len;
1233
0
    rd->type=rtype;
1234
0
    rd->class=class;
1235
0
    rd->ttl=ttl;
1236
0
    rd->next=0;
1237
0
    switch(rtype){
1238
0
      case T_SRV:
1239
0
        srv_rd= dns_srv_parser(buff.buff, end, p);
1240
0
        if (srv_rd==0) goto error_parse;
1241
0
        if (dnscache_put_func)
1242
0
          rdata_buf_len+=4*sizeof(unsigned short) +
1243
0
          sizeof(unsigned int ) + srv_rd->name_len+1;
1244
0
        rd->rdata=(void*)srv_rd;
1245
1246
        /* insert sorted into the list */
1247
0
        for (crt=&head; *crt; crt= &((*crt)->next)){
1248
0
          crt_srv=(struct srv_rdata*)(*crt)->rdata;
1249
0
          if ((srv_rd->priority <  crt_srv->priority) ||
1250
0
             ( (srv_rd->priority == crt_srv->priority) &&
1251
0
               ((srv_rd->weight==0) || (crt_srv->weight!=0)) ) ){
1252
            /* insert here */
1253
0
            goto skip;
1254
0
          }
1255
0
        }
1256
0
        last=&(rd->next); /*end of for => this will be the last elem*/
1257
0
      skip:
1258
        /* insert here */
1259
0
        rd->next=*crt;
1260
0
        *crt=rd;
1261
1262
0
        break;
1263
0
      case T_A:
1264
0
        rd->rdata=(void*) dns_a_parser(p,end);
1265
0
        if (rd->rdata==0) goto error_parse;
1266
0
        if (dnscache_put_func)
1267
0
          rdata_buf_len+=sizeof(struct a_rdata);
1268
0
        *last=rd; /* last points to the last "next" or the list head*/
1269
0
        last=&(rd->next);
1270
0
        break;
1271
0
      case T_AAAA:
1272
0
        rd->rdata=(void*) dns_aaaa_parser(p,end);
1273
0
        if (rd->rdata==0) goto error_parse;
1274
0
        if (dnscache_put_func)
1275
0
          rdata_buf_len+=sizeof(struct aaaa_rdata);
1276
0
        *last=rd;
1277
0
        last=&(rd->next);
1278
0
        break;
1279
0
      case T_CNAME:
1280
0
        rd->rdata=(void*) dns_cname_parser(buff.buff, end, p);
1281
0
        if(rd->rdata==0) goto error_parse;
1282
0
        if (dnscache_put_func)
1283
0
          rdata_buf_len+=
1284
0
          strlen(((struct cname_rdata *)rd->rdata)->name) +
1285
0
          1 + sizeof(int);
1286
0
        *last=rd;
1287
0
        last=&(rd->next);
1288
0
        break;
1289
0
      case T_NAPTR:
1290
0
        naptr_rd = dns_naptr_parser(buff.buff,end,p);
1291
0
        rd->rdata=(void*) naptr_rd;
1292
0
        if(rd->rdata==0) goto error_parse;
1293
0
        if (dnscache_put_func)
1294
0
          rdata_buf_len+=2*sizeof(unsigned short) +
1295
0
          4*sizeof(unsigned int) + naptr_rd->flags_len+1 +
1296
0
          + naptr_rd->services_len+1+naptr_rd->regexp_len +
1297
0
          + 1 + naptr_rd->repl_len + 1;
1298
0
        *last=rd;
1299
0
        last=&(rd->next);
1300
0
        break;
1301
0
      case T_TXT:
1302
0
        txt_rd = dns_txt_parser(buff.buff, end, p);
1303
0
        rd->rdata=(void*) txt_rd;
1304
0
        if(rd->rdata==0) goto error_parse;
1305
0
        if (dnscache_put_func)
1306
0
          rdata_buf_len+=sizeof(int)+strlen(txt_rd->txt)+1;
1307
0
        *last=rd;
1308
0
        last=&(rd->next);
1309
0
        break;
1310
0
      case T_EBL:
1311
0
        ebl_rd = dns_ebl_parser(buff.buff, end, p);
1312
0
        rd->rdata=(void*) ebl_rd;
1313
0
        if(rd->rdata==0) goto error_parse;
1314
0
        if (dnscache_put_func)
1315
0
          rdata_buf_len+=sizeof(unsigned char)+
1316
0
          2*sizeof(unsigned int)+ebl_rd->apex_len + 1 +
1317
0
          ebl_rd->separator_len + 1;
1318
0
        *last=rd;
1319
0
        last=&(rd->next);
1320
0
        break;
1321
0
      default:
1322
0
        LM_ERR("unknown type %d\n", rtype);
1323
0
        rd->rdata=0;
1324
0
        *last=rd;
1325
0
        last=&(rd->next);
1326
0
    }
1327
1328
0
    p+=rdlength;
1329
1330
0
  }
1331
1332
0
  if (dnscache_put_func != NULL) {
1333
0
    if (dnscache_put_func(name,type,head,rdata_buf_len,0,min_ttl) < 0)
1334
0
      LM_ERR("Failed to store %s - %d in cache\n",name,type);
1335
0
  }
1336
0
  return head;
1337
0
error_boundary:
1338
0
    LM_ERR("end of query buff reached\n");
1339
0
    if(head)
1340
0
      free_rdata_list(head);
1341
0
    return 0;
1342
0
error_parse:
1343
0
    LM_ERR("rdata parse error \n");
1344
0
    if (rd) local_free(rd); /* rd->rdata=0 & rd is not linked yet into
1345
                   the list */
1346
0
error:
1347
0
    LM_ERR("get_record \n");
1348
0
    if (head) free_rdata_list(head);
1349
0
not_found:
1350
0
  return 0;
1351
0
}
1352
1353
1354
1355
static inline int get_naptr_proto(struct naptr_rdata *n)
1356
0
{
1357
0
  if (n->services[3]=='s' || n->services[3]=='S' )
1358
0
    return PROTO_TLS;
1359
0
  switch (n->services[n->services_len-1]) {
1360
0
    case 'U':
1361
0
    case 'u':
1362
0
      return PROTO_UDP;
1363
0
      break;
1364
0
    case 'T':
1365
0
    case 't':
1366
0
      return PROTO_TCP;
1367
0
      break;
1368
0
    case 'S':
1369
0
    case 's':
1370
0
      return PROTO_SCTP;
1371
0
      break;
1372
0
  }
1373
0
  LM_CRIT("failed to detect proto\n");
1374
0
  return PROTO_NONE;
1375
0
}
1376
1377
1378
1379
static inline int srv2dns_node(struct rdata *head, struct dns_node **dn)
1380
0
{
1381
0
  unsigned int mem;
1382
0
  unsigned int l;
1383
0
  struct rdata *r;
1384
0
  struct dns_node *n;
1385
0
  char *p;
1386
1387
  /* calculate how much mem is required */
1388
0
  mem = sizeof(struct dns_node);
1389
0
  for( r=head,l=0 ; r ; r=r->next,l++ )
1390
0
    mem +=sizeof(struct dns_val) + get_naptr(r)->repl_len + 1;
1391
1392
0
  n = (struct dns_node*)shm_malloc(mem);
1393
0
  if (n==NULL) {
1394
0
    LM_ERR("no more shm mem (%d)\n", mem);
1395
0
    return -1;
1396
0
  }
1397
1398
0
  n->type = DNS_NODE_SRV;
1399
0
  n->size = mem;
1400
0
  n->idx = 0;
1401
0
  n->no = l;
1402
0
  n->kids = *dn;
1403
0
  *dn = n;
1404
1405
0
  n->vals = (struct dns_val*)(n+1);
1406
0
  p = (char*)(n->vals+l);
1407
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1408
0
    n->vals[l].ival = get_naptr_proto( get_naptr(r) );
1409
0
    n->vals[l].sval = p;
1410
0
    memcpy( p, get_naptr(r)->repl, get_naptr(r)->repl_len );
1411
0
    p += get_naptr(r)->repl_len;
1412
0
    *(p++) = 0;
1413
0
  }
1414
0
  return 0;
1415
0
}
1416
1417
1418
static inline int a2dns_node(struct rdata *head, struct dns_node **dn)
1419
0
{
1420
0
  unsigned int mem;
1421
0
  unsigned int l;
1422
0
  struct rdata *r;
1423
0
  struct dns_node *n;
1424
0
  char *p;
1425
1426
  /* calculate how much mem is required */
1427
0
  mem = sizeof(struct dns_node);
1428
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1429
0
    get_srv(r)->name_len = strlen(get_srv(r)->name);
1430
0
    mem +=sizeof(struct dns_val) + get_srv(r)->name_len + 1;
1431
0
    }
1432
1433
0
  n = (struct dns_node*)shm_malloc(mem);
1434
0
  if (n==NULL) {
1435
0
    LM_ERR("no more shm mem (%d)\n", mem);
1436
0
    return -1;
1437
0
  }
1438
1439
0
  n->type = DNS_NODE_A;
1440
0
  n->size = mem;
1441
0
  n->idx = 0;
1442
0
  n->no = l;
1443
0
  n->kids = 0;
1444
0
  *dn = n;
1445
1446
0
  n->vals = (struct dns_val*)(n+1);
1447
0
  p = (char*)(n->vals+l);
1448
0
  for( r=head,l=0 ; r ; r=r->next,l++ ) {
1449
0
    n->vals[l].ival = get_srv(r)->port;
1450
0
    n->vals[l].sval = p;
1451
0
    memcpy( p, get_srv(r)->name, get_srv(r)->name_len );
1452
0
    LM_DBG("storing %.*s:%d\n", get_srv(r)->name_len,p,n->vals[l].ival);
1453
0
    p += get_srv(r)->name_len;
1454
0
    *(p++) = 0;
1455
0
  }
1456
1457
0
  return 0;
1458
0
}
1459
1460
1461
static inline void sort_srvs(struct rdata **head)
1462
0
{
1463
0
#define rd2srv(_rd) ((struct srv_rdata*)_rd->rdata)
1464
0
  struct rdata *rd = *head;
1465
0
  struct rdata *tail = NULL;
1466
0
  struct rdata *rd_next;
1467
0
  struct rdata *crt;
1468
0
  struct rdata *crt2;
1469
0
  unsigned int weight_sum;
1470
0
  unsigned int rand_no;
1471
1472
1473
0
  *head = NULL;
1474
1475
0
  while( rd ) {
1476
0
    rd_next = rd->next;
1477
0
    if (rd->type!=T_SRV) {
1478
0
      rd->next = NULL;
1479
0
      free_rdata_list(rd);
1480
0
    } else {
1481
      /* only on element with same priority ? */
1482
0
      if (rd_next==NULL ||
1483
0
      rd2srv(rd)->priority!=rd2srv(rd_next)->priority) {
1484
0
        if (tail) {tail->next=rd;tail=rd;}
1485
0
        else {*head=tail=rd;}
1486
0
        rd->next = NULL;
1487
0
      } else {
1488
        /* multiple nodes with same priority */
1489
        /* -> calculate running sums (and detect the end) */
1490
0
        weight_sum = rd2srv(rd)->running_sum = rd2srv(rd)->weight;
1491
0
        crt = rd;
1492
0
        while( crt && crt->next &&
1493
0
        (rd2srv(rd)->priority==rd2srv(crt->next)->priority) ) {
1494
0
          crt = crt->next;
1495
0
          weight_sum += rd2srv(crt)->weight;
1496
0
          rd2srv(crt)->running_sum = weight_sum;
1497
0
        }
1498
        /* crt will point to last RR with same priority */
1499
0
        rd_next = crt->next;
1500
0
        crt->next = NULL;
1501
1502
        /* order the elements between rd and crt */
1503
0
        while (rd->next) {
1504
0
          rand_no = (unsigned int)
1505
0
            (weight_sum*((float)rand()/(float)RAND_MAX));
1506
0
          for( crt=rd,crt2=NULL ; crt ; crt2=crt,crt=crt->next) {
1507
0
            if (rd2srv(crt)->running_sum>=rand_no) break;
1508
0
          }
1509
0
          if (crt == NULL) {
1510
0
            LM_CRIT("bug in sorting SRVs - rand>sum\n");
1511
0
            crt = rd;
1512
0
            crt2 = NULL;
1513
0
          }
1514
          /* remove the element from the list ... */
1515
0
          if (crt2==NULL) { rd = rd->next;}
1516
0
          else {crt2->next = crt->next;}
1517
          /* .... and update the running sums */
1518
0
          for ( crt2=crt->next ; crt2 ; crt2=crt2->next)
1519
0
            rd2srv(crt2)->running_sum -= rd2srv(crt)->weight;
1520
0
          weight_sum -= rd2srv(crt)->weight;
1521
          /* link the crt in the new list */
1522
0
          crt->next = 0;
1523
0
          if (tail) {tail->next=crt;tail=crt;}
1524
0
          else {*head=tail=crt;}
1525
0
        }
1526
        /* just insert the last remaining element */
1527
0
        tail->next = rd; tail = rd ;
1528
0
      }
1529
0
    }
1530
1531
0
    rd = rd_next;
1532
0
  }
1533
0
}
1534
1535
1536
static inline struct hostent* do_srv_lookup(char *name, unsigned short* port, struct dns_node **dn)
1537
0
{
1538
0
  struct hostent *he;
1539
0
  struct srv_rdata *srv;
1540
0
  struct rdata *head;
1541
0
  struct rdata *rd;
1542
1543
  /* perform SRV lookup */
1544
0
  head = get_record( name, T_SRV);
1545
0
  sort_srvs(&head);
1546
0
  for( rd=head; rd ; rd=rd->next ) {
1547
0
    if (rd->type!=T_SRV)
1548
0
      continue; /*should never happen*/
1549
0
    srv = (struct srv_rdata*) rd->rdata;
1550
0
    if (srv==0) {
1551
0
      LM_CRIT("null rdata\n");
1552
0
      free_rdata_list(head);
1553
0
      return 0;
1554
0
    }
1555
0
    LM_DBG("resolving [%s]\n",srv->name);
1556
0
    he = resolvehost(srv->name, 1);
1557
0
    if ( he!=0 ) {
1558
0
      LM_DBG("SRV(%s) = %s:%d\n",     name, srv->name, srv->port);
1559
0
      if (port) *port=srv->port;
1560
0
      if (dn && rd->next && a2dns_node( rd->next, dn)==-1)
1561
0
          *dn = 0;
1562
0
      free_rdata_list(head);
1563
0
      return he;
1564
0
    }
1565
0
  }
1566
0
  if (head)
1567
0
    free_rdata_list(head);
1568
0
  return 0;
1569
0
}
1570
1571
1572
#define naptr_prio(_naptr) \
1573
0
  ((unsigned int)((((_naptr)->order) << 16) + ((_naptr)->pref)))
1574
1575
static inline void filter_and_sort_naptr( struct rdata** head_p, struct rdata** filtered_p, int is_sips)
1576
0
{
1577
0
  struct naptr_rdata *naptr;
1578
0
  struct rdata *head;
1579
0
  struct rdata *last;
1580
0
  struct rdata *out;
1581
0
  struct rdata *l, *ln, *it, *itp;
1582
0
  unsigned int prio;
1583
0
  char p;
1584
1585
0
  head = 0;
1586
0
  last = 0;
1587
0
  out = 0;
1588
1589
0
  for( l=*head_p ; l ; l=ln ) {
1590
0
    ln = l->next;
1591
1592
0
    if (l->type != T_NAPTR)
1593
0
      goto skip0; /*should never happen*/
1594
1595
0
    naptr = (struct naptr_rdata*)l->rdata;
1596
0
    if (naptr == 0) {
1597
0
      LM_CRIT("null rdata\n");
1598
0
      goto skip0;
1599
0
    }
1600
1601
    /* first filter out by flag and service */
1602
0
    if (naptr->flags_len!=1||(naptr->flags[0]!='s'&&naptr->flags[0]!='S'))
1603
0
      goto skip;
1604
0
    if (naptr->repl_len==0 || naptr->regexp_len!=0 )
1605
0
      goto skip;
1606
0
    if ( (is_sips || naptr->services_len!=7 ||
1607
0
      strncasecmp(naptr->services,"sip+d2",6) ) &&
1608
0
    (
1609
0
    naptr->services_len!=8 || strncasecmp(naptr->services,"sips+d2",7)))
1610
0
      goto skip;
1611
0
    p = naptr->services[naptr->services_len-1];
1612
    /* by default we do not support SCTP */
1613
0
    if ( p!='U' && p!='u'
1614
0
    && ((p!='T' && p!='t'))
1615
0
    && ((p!='S' && p!='s'))
1616
0
    )
1617
0
      goto skip;
1618
    /* is it valid? (SIPS+D2U is not!) */
1619
0
    if ( naptr->services_len==8 && (p=='U' || p=='u'))
1620
0
      goto skip;
1621
1622
0
    LM_DBG("found valid %.*s -> %s\n",
1623
0
      (int)naptr->services_len,naptr->services, naptr->repl);
1624
1625
    /* this is a supported service -> add it according to order to the
1626
     * new head list */
1627
0
    prio = naptr_prio(get_naptr(l));
1628
0
    if (head==0) {
1629
0
      head = last = l;
1630
0
      l->next = 0;
1631
0
    } else if ( naptr_prio(get_naptr(head)) >= prio ) {
1632
0
      l->next = head;
1633
0
      head = l;
1634
0
    } else if ( prio >= naptr_prio(get_naptr(last)) ) {
1635
0
      l->next = 0;
1636
0
      last->next = l;
1637
0
      last = l;
1638
0
    } else {
1639
0
      for( itp=head,it=head->next ; it && it->next ; itp=it,it=it->next ){
1640
0
        if ( prio <= naptr_prio(get_naptr(it)))
1641
0
          break;
1642
0
      }
1643
0
      l->next = itp->next;
1644
0
      itp->next = l;
1645
0
    }
1646
1647
0
    continue;
1648
0
skip:
1649
0
    LM_DBG("skipping %.*s -> %s\n",
1650
0
      (int)naptr->services_len, naptr->services, naptr->repl);
1651
0
skip0:
1652
0
    l->next = out;
1653
0
    out = l;
1654
0
  }
1655
1656
0
  *head_p = head;
1657
0
  *filtered_p = out;
1658
0
}
1659
1660
#if 0
1661
struct hostent* sip_resolvehost(str* name, unsigned short* port, int *proto,
1662
                                int is_sips)
1663
{
1664
  static char tmp[MAX_DNS_NAME];
1665
  struct ip_addr *ip;
1666
  struct rdata *head;
1667
  struct rdata *rd;
1668
  struct hostent* he;
1669
1670
  if ( (is_sips)
1671
  && (tls_disable)
1672
  ) {
1673
    LM_ERR("cannot resolve SIPS as no TLS support is configured\n");
1674
    return 0;
1675
  }
1676
1677
  /* check if it's an ip address */
1678
  if ( ((ip=str2ip(name))!=0)
1679
  || ((ip=str2ip6(name))!=0)
1680
  ){
1681
    /* we are lucky, this is an ip address */
1682
    if (proto && *proto==PROTO_NONE)
1683
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1684
    if (port && *port==0)
1685
      *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
1686
    return ip_addr2he(name,ip);
1687
  }
1688
1689
  /* do we have a port? */
1690
  if ( !port || (*port)!=0 ) {
1691
    /* have port -> no NAPTR, no SRV lookup, just A record lookup */
1692
    LM_DBG("has port -> do A record lookup!\n");
1693
    /* set default PROTO if not set */
1694
    if (proto && *proto==PROTO_NONE)
1695
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1696
    goto do_a;
1697
  }
1698
1699
  /* no port... what about proto? */
1700
  if ( !proto || (*proto)!=PROTO_NONE ) {
1701
    /* have proto, but no port -> do SRV lookup */
1702
    LM_DBG("no port, has proto -> do SRV lookup!\n");
1703
    if (is_sips && (*proto)!=PROTO_TLS) {
1704
      LM_ERR("forced proto %d not matching sips uri\n", *proto);
1705
      return 0;
1706
    }
1707
    goto do_srv;
1708
  }
1709
1710
  LM_DBG("no port, no proto -> do NAPTR lookup!\n");
1711
  /* no proto, no port -> do NAPTR lookup */
1712
  if (name->len >= MAX_DNS_NAME) {
1713
    LM_ERR("domain name too long\n");
1714
    return 0;
1715
  }
1716
  memcpy(tmp, name->s, name->len);
1717
  tmp[name->len] = '\0';
1718
  /* do NAPTR lookup */
1719
  head = get_record( tmp, T_NAPTR);
1720
  if (head) {
1721
    /* filter and sort the records */
1722
    filter_and_sort_naptr( &head, &rd, is_sips);
1723
    /* free what is useless */
1724
    free_rdata_list( rd );
1725
    /* process the NAPTR records */
1726
    for( rd=head ; rd ; rd=rd->next ) {
1727
      he = do_srv_lookup( get_naptr(rd)->repl, port );
1728
      if ( he ) {
1729
        *proto = get_naptr_proto( get_naptr(rd) );
1730
        LM_DBG("found!\n");
1731
        free_rdata_list(head);
1732
        return he;
1733
      }
1734
    }
1735
    if (head)
1736
      free_rdata_list(head);
1737
  }
1738
  LM_DBG("no valid NAPTR record found for %.*s,"
1739
    " trying direct SRV lookup...\n", name->len, name->s);
1740
  *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1741
1742
do_srv:
1743
  if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME) {
1744
    LM_WARN("domain name too long (%d),"
1745
      " unable to perform SRV lookup\n", name->len);
1746
    /* set defaults */
1747
    *port = (is_sips)?SIPS_PORT:SIP_PORT;
1748
    goto do_a;
1749
  }
1750
1751
  switch (*proto) {
1752
    case PROTO_UDP:
1753
      memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1754
      memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
1755
      tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1756
      break;
1757
    case PROTO_TCP:
1758
      memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1759
      memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
1760
      tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1761
      break;
1762
    case PROTO_TLS:
1763
      memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1764
      memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
1765
      tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1766
      break;
1767
    default:
1768
      goto err_proto;
1769
  }
1770
1771
  he = do_srv_lookup( tmp, port );
1772
  if (he)
1773
    return he;
1774
1775
  LM_DBG("no valid SRV record found for %s,"
1776
    " trying A record lookup...\n", tmp);
1777
  /* set default port */
1778
  *port = (is_sips||((*proto)==PROTO_TLS))?SIPS_PORT:SIP_PORT;
1779
1780
do_a:
1781
  /* do A record lookup */
1782
  if (name->len >= MAX_DNS_NAME) {
1783
    LM_ERR("domain name too long\n");
1784
    return 0;
1785
  }
1786
  memcpy(tmp, name->s, name->len);
1787
  tmp[name->len] = '\0';
1788
  he = resolvehost(tmp,1);
1789
  return he;
1790
err_proto:
1791
  LM_ERR("unsupported proto %d\n", *proto);
1792
  return 0;
1793
}
1794
#endif
1795
1796
1797
1798
struct hostent* sip_resolvehost( str* name, unsigned short* port,
1799
    unsigned short *proto, int is_sips, struct dns_node **dn)
1800
0
{
1801
0
  static char tmp[MAX_DNS_NAME];
1802
0
  struct ip_addr *ip;
1803
0
  struct rdata *head;
1804
0
  struct rdata *rd;
1805
0
  struct hostent* he;
1806
0
  unsigned short local_proto=PROTO_NONE;
1807
1808
0
  if (dn)
1809
0
    *dn = 0;
1810
1811
0
  if (proto==NULL)
1812
0
    proto = &local_proto;
1813
1814
  /* check if it's an ip address */
1815
0
  if ( ((ip=str2ip(name))!=0) || ((ip=str2ip6(name))!=0) ){
1816
    /* we are lucky, this is an ip address */
1817
0
    if (*proto==PROTO_NONE)
1818
0
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1819
0
    if (port && *port==0)
1820
0
      *port = protos[*proto].default_port;
1821
0
    return ip_addr2he(name,ip);
1822
0
  }
1823
1824
  /* do we have a port? */
1825
0
  if ( port && (*port)!=0 ) {
1826
    /* have port -> no NAPTR, no SRV lookup, just A record lookup */
1827
0
    LM_DBG("has port -> do A record lookup!\n");
1828
    /* set default PROTO if not set */
1829
0
    if (*proto==PROTO_NONE)
1830
0
      *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1831
0
    goto do_a;
1832
0
  }
1833
1834
  /* no port... what about proto? */
1835
0
  if ( (*proto)!=PROTO_NONE ) {
1836
    /* have proto, but no port -> do SRV lookup */
1837
0
    LM_DBG("no port, has proto -> do SRV lookup!\n");
1838
0
    if (is_sips && (*proto)!=PROTO_TLS) {
1839
0
      LM_ERR("forced proto %d not matching sips uri\n", *proto);
1840
0
      return 0;
1841
0
    }
1842
0
    goto do_srv;
1843
0
  }
1844
1845
0
  if ( dns_try_naptr==0 ) {
1846
0
    *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1847
0
    goto do_srv;
1848
0
  }
1849
0
  LM_DBG("no port, no proto -> do NAPTR lookup!\n");
1850
  /* no proto, no port -> do NAPTR lookup */
1851
0
  if (name->len >= MAX_DNS_NAME) {
1852
0
    LM_ERR("domain name too long\n");
1853
0
    return 0;
1854
0
  }
1855
0
  memcpy(tmp, name->s, name->len);
1856
0
  tmp[name->len] = '\0';
1857
  /* do NAPTR lookup */
1858
0
  head = get_record( tmp, T_NAPTR);
1859
0
  if (head) {
1860
    /* filter and sort the records */
1861
0
    filter_and_sort_naptr( &head, &rd, is_sips);
1862
    /* free what is useless */
1863
0
    free_rdata_list( rd );
1864
    /* process the NAPTR records */
1865
0
    for( rd=head ; rd ; rd=rd->next ) {
1866
0
      *proto = get_naptr_proto( get_naptr(rd) );
1867
0
      he = do_srv_lookup( get_naptr(rd)->repl, port, dn);
1868
0
      if ( he ) {
1869
0
        LM_DBG("valid SRV found!\n");
1870
0
        if (dn) {
1871
          /* save the state of the resolver for failure cases */
1872
0
          if (*dn==NULL)
1873
0
            rd = rd->next;
1874
0
          if (rd && srv2dns_node( rd, dn)!=0) {
1875
0
            shm_free(*dn);
1876
0
            *dn = 0;
1877
0
          }
1878
0
        }
1879
0
        free_rdata_list(head);
1880
0
        return he;
1881
0
      }
1882
0
    }
1883
0
    if (head)
1884
0
      free_rdata_list(head);
1885
0
  }
1886
0
  LM_DBG("no valid NAPTR record found for %.*s,"
1887
0
    " trying direct SRV lookup...\n", name->len, name->s);
1888
0
  *proto = (is_sips)?PROTO_TLS:PROTO_UDP;
1889
1890
0
do_srv:
1891
0
  if ((name->len+SRV_MAX_PREFIX_LEN+1)>MAX_DNS_NAME) {
1892
0
    LM_WARN("domain name too long (%d),"
1893
0
      " unable to perform SRV lookup\n", name->len);
1894
    /* set defaults */
1895
0
    if (port) *port = (is_sips)?SIPS_PORT:SIP_PORT;
1896
0
    goto do_a;
1897
0
  }
1898
1899
0
  switch (*proto) {
1900
0
    case PROTO_UDP:
1901
0
      memcpy(tmp, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1902
0
      memcpy(tmp+SRV_UDP_PREFIX_LEN, name->s, name->len);
1903
0
      tmp[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1904
0
      break;
1905
0
    case PROTO_TCP:
1906
0
      memcpy(tmp, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1907
0
      memcpy(tmp+SRV_TCP_PREFIX_LEN, name->s, name->len);
1908
0
      tmp[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1909
0
      break;
1910
0
    case PROTO_TLS:
1911
0
      memcpy(tmp, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1912
0
      memcpy(tmp+SRV_TLS_PREFIX_LEN, name->s, name->len);
1913
0
      tmp[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1914
0
      break;
1915
0
    case PROTO_SCTP:
1916
0
      memcpy(tmp, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
1917
0
      memcpy(tmp+SRV_SCTP_PREFIX_LEN, name->s, name->len);
1918
0
      tmp[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
1919
0
      break;
1920
0
    case PROTO_WS:
1921
0
      memcpy(tmp, SRV_WS_PREFIX, SRV_WS_PREFIX_LEN);
1922
0
      memcpy(tmp+SRV_WS_PREFIX_LEN, name->s, name->len);
1923
0
      tmp[SRV_WS_PREFIX_LEN + name->len] = '\0';
1924
0
      break;
1925
0
    case PROTO_WSS:
1926
0
      memcpy(tmp, SRV_WSS_PREFIX, SRV_WSS_PREFIX_LEN);
1927
0
      memcpy(tmp+SRV_WSS_PREFIX_LEN, name->s, name->len);
1928
0
      tmp[SRV_WSS_PREFIX_LEN + name->len] = '\0';
1929
0
      break;
1930
0
    default:
1931
0
      goto err_proto;
1932
0
  }
1933
1934
0
  he = do_srv_lookup( tmp, port, dn);
1935
0
  if (he)
1936
0
    return he;
1937
1938
0
  LM_DBG("no valid SRV record found for %s, trying A record lookup...\n",
1939
0
    tmp);
1940
  /* set default port */
1941
0
  if (port) *port = protos[*proto].default_port;
1942
1943
0
do_a:
1944
  /* do A record lookup */
1945
0
  if (name->len >= MAX_DNS_NAME) {
1946
0
    LM_ERR("domain name too long\n");
1947
0
    return 0;
1948
0
  }
1949
0
  memcpy(tmp, name->s, name->len);
1950
0
  tmp[name->len] = '\0';
1951
0
  he = resolvehost(tmp,1);
1952
0
  return he;
1953
0
err_proto:
1954
0
  LM_ERR("unsupported proto %d\n", *proto);
1955
0
  return 0;
1956
0
}
1957
1958
1959
1960
static inline struct hostent* get_next_he(struct dns_node **node,
1961
              unsigned short *proto, unsigned short *port)
1962
0
{
1963
0
  struct hostent  *he;
1964
0
  struct dns_node *n;
1965
0
  struct dns_node *last_srv;
1966
0
  struct dns_node *dn;
1967
1968
0
  if (node==NULL || *node==NULL)
1969
0
    return 0;
1970
1971
0
  n = *node;
1972
0
  last_srv = NULL;
1973
0
  he = 0;
1974
1975
0
  do {
1976
0
    switch (n->type) {
1977
0
      case DNS_NODE_SRV:
1978
0
        last_srv = n;
1979
0
        if (n->kids==NULL) {
1980
          /* need to resolve this SRV and get all the AAA records */
1981
0
          do {
1982
0
            dn = 0;
1983
0
            he = do_srv_lookup( n->vals[n->idx].sval, port, &dn);
1984
0
            if (he) {
1985
0
              *proto = n->vals[n->idx].ival;
1986
0
              n->idx++;
1987
0
              break;
1988
0
            }
1989
0
            n->idx++;
1990
0
          } while(n->idx<n->no);
1991
0
          if (he==NULL || (he && n->idx==n->no) ) {
1992
            /* colapse the SRV node */
1993
0
            shm_free(n);
1994
0
            *node = dn;
1995
0
            return he;
1996
0
          }
1997
0
          n->kids = dn;
1998
0
          return he;
1999
0
        }
2000
        /* go for the AAA records */
2001
0
        n = n->kids;
2002
0
        break;
2003
0
      case DNS_NODE_A:
2004
        /* do resolve until success */
2005
0
        do {
2006
0
          he = resolvehost(n->vals[n->idx].sval,1);
2007
0
          if (he) {
2008
0
            *port = n->vals[n->idx].ival;
2009
0
            n->idx++;
2010
0
            break;
2011
0
          }
2012
0
          n->idx++;
2013
0
        }while(n->idx<n->no);
2014
        /* found something? */
2015
0
        if (he==NULL || (he && n->idx==n->no)) {
2016
0
          shm_free(n);
2017
          /* any SRV level? */
2018
0
          if (last_srv==NULL) {
2019
            /* nothing left */
2020
0
            *node = 0;
2021
0
            return he;
2022
0
          }
2023
0
          last_srv->kids = 0;
2024
          /* increase the index on the SRV level */
2025
0
          if (++last_srv->idx<last_srv->no)
2026
0
            return he;
2027
          /* colapse the SRV node also */
2028
0
          shm_free(last_srv);
2029
0
          *node = 0;
2030
0
        }
2031
0
        return he;
2032
0
        break;
2033
0
      default:
2034
0
        LM_CRIT("unknown %d node type\n", n->type);
2035
0
        return 0;
2036
0
    }
2037
0
  } while(1);
2038
0
}
2039
2040
2041
2042
void free_dns_res( struct proxy_l *p )
2043
0
{
2044
0
  if (p==NULL || p->dn==NULL)
2045
0
    return;
2046
2047
0
  if (p->dn->kids)
2048
0
    shm_free(p->dn->kids);
2049
0
  shm_free(p->dn);
2050
0
  p->dn = 0;
2051
0
}
2052
2053
2054
2055
int get_next_su(struct proxy_l *p, union sockaddr_union* su, int add_to_bl)
2056
0
{
2057
0
  struct hostent *he;
2058
0
  struct bl_rule *list;
2059
0
  struct net  ip_net;
2060
0
  int n;
2061
2062
0
  if (failover_bl && add_to_bl) {
2063
0
    memset( &ip_net, 0xff , sizeof(struct net));
2064
0
    hostent2ip_addr( &ip_net.ip, &p->host, p->addr_idx);
2065
0
    ip_net.mask.af = ip_net.ip.af;
2066
0
    ip_net.mask.len = ip_net.ip.len;
2067
0
    list = 0;
2068
0
    n = add_rule_to_list( &list, &list, &ip_net, 0, p->port, p->proto, 0);
2069
0
    if (n!=0) {
2070
0
      LM_ERR("failed to build bl rule\n");
2071
0
    } else {
2072
0
      add_list_to_head( failover_bl, list, list, 0, DNS_BL_EXPIRE);
2073
0
    }
2074
0
  }
2075
2076
  /* any more available IPs in he ? */
2077
0
  if ( p->host.h_addr_list[++p->addr_idx] ) {
2078
    /* yes -> return the IP*/
2079
0
    hostent2su( su, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
2080
0
    return 0;
2081
0
  }
2082
2083
  /* get a new he from DNS */
2084
0
  he = get_next_he( &p->dn, &p->proto, &p->port);
2085
0
  if (he==NULL)
2086
0
    return -1;
2087
2088
  /* replace the current he */
2089
0
  if (p->flags&PROXY_SHM_FLAG) {
2090
0
    free_shm_hostent( &p->host );
2091
0
    n = hostent_shm_cpy(&(p->host), he);
2092
0
  } else {
2093
0
    free_hostent( &p->host );
2094
0
    n = hostent_cpy(&(p->host), he);
2095
0
  }
2096
0
  if (n!=0) {
2097
0
    free_dns_res( p );
2098
0
    return -1;
2099
0
  }
2100
2101
0
  hostent2su( su, &p->host, 0, (p->port)?p->port:SIP_PORT);
2102
0
  p->addr_idx = 0;
2103
0
  return 0;
2104
0
}
2105
2106
2107
2108
static inline struct dns_node *dns_node_copy(struct dns_node *s)
2109
0
{
2110
0
  struct dns_node *d;
2111
0
  unsigned int i;
2112
2113
0
  d = (struct dns_node*)shm_malloc(s->size);
2114
0
  if (d==NULL) {
2115
0
    LM_ERR("no more shm mem\n");
2116
0
    return 0;
2117
0
  }
2118
0
  memcpy( d, s, s->size);
2119
0
  d->vals = (struct dns_val*)(void *)((char*)d + ((char*)s->vals-(char*)s));
2120
0
  for( i=0 ; i<s->no ; i++ )
2121
0
    d->vals[i].sval = (char*)d + ((char*)s->vals[i].sval-(char*)s);
2122
0
  return d;
2123
0
}
2124
2125
2126
struct dns_node *dns_res_copy(struct dns_node *s)
2127
0
{
2128
0
  struct dns_node *d;
2129
2130
0
  d = dns_node_copy(s);
2131
0
  if (d==NULL)
2132
0
    return 0;
2133
0
  if (s->kids) {
2134
0
    d->kids = dns_node_copy(s->kids);
2135
0
    if (d->kids==NULL) {
2136
0
      shm_free(d);
2137
0
      return 0;
2138
0
    }
2139
0
  }
2140
0
  return d;
2141
0
}