Coverage Report

Created: 2026-02-26 07:12

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