Coverage Report

Created: 2026-03-30 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kamailio/src/core/resolve.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2001-2003 FhG Fokus
3
 *
4
 * This file is part of Kamailio, a free SIP server.
5
 *
6
 * SPDX-License-Identifier: GPL-2.0-or-later
7
 *
8
 * Kamailio is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version
12
 *
13
 * Kamailio is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
 */
22
23
/*!
24
 * \file
25
 * \brief Kamailio core :: DNS resolver
26
 * \ingroup core
27
 * Module: \ref core
28
 */
29
30
31
#include <sys/types.h>
32
#include <netinet/in.h>
33
#include <arpa/nameser.h>
34
#include <resolv.h>
35
#include <string.h>
36
37
/*
38
 * Older glibc < 2.25 does not include T_OPT in nameser_compat.h yet.
39
 * On alpine linux musl library it is also not defined. There is no
40
 * musl feature test macro, so we look for glibc instead.
41
 */
42
#if(defined __GLIBC__ && __GLIBC__ == 2 && __GLIBC_MINOR__ < 25) \
43
    || !defined __GLIBC__
44
#ifndef T_OPT
45
#define T_OPT ns_t_opt
46
#endif
47
#endif
48
49
#include "resolve.h"
50
#include "compiler_opt.h"
51
#include "dprint.h"
52
#include "mem/mem.h"
53
#include "ip_addr.h"
54
#include "ut.h"
55
#include "error.h"
56
#include "globals.h" /* tcp_disable, tls_disable a.s.o */
57
#include "cfg_core.h"
58
#include "socket_info.h"
59
60
#ifdef USE_DNS_CACHE
61
#include "dns_cache.h"
62
#endif
63
64
0
#define KSR_IPADDR_LIST_SIZE 6
65
static ip_addr_t _ksr_ipaddr_list[KSR_IPADDR_LIST_SIZE];
66
static int _ksr_ipaddr_list_idx = 0;
67
68
static ip_addr_t *get_next_ipaddr_buf(void)
69
0
{
70
0
  ip_addr_t *ipb;
71
72
0
  ipb = &_ksr_ipaddr_list[_ksr_ipaddr_list_idx];
73
0
  _ksr_ipaddr_list_idx = (_ksr_ipaddr_list_idx + 1) % KSR_IPADDR_LIST_SIZE;
74
75
0
  return ipb;
76
0
}
77
78
/* counters framework */
79
struct dns_counters_h dns_cnts_h;
80
counter_def_t dns_cnt_defs[] = {
81
    {&dns_cnts_h.failed_dns_req, "failed_dns_request", 0, 0, 0,
82
        "incremented each time a DNS request has failed."},
83
    {&dns_cnts_h.slow_dns_req, "slow_dns_request", 0, 0, 0,
84
        "incremented each time a DNS request took longer than "
85
        "dns_slow_query_ms."},
86
    {0, 0, 0, 0, 0, 0}};
87
88
89
#ifdef USE_NAPTR
90
static int naptr_proto_pref[PROTO_LAST + 1];
91
#endif
92
static int srv_proto_pref[PROTO_LAST + 1];
93
94
#ifdef USE_NAPTR
95
static void init_naptr_proto_prefs()
96
0
{
97
0
  int ignore_rfc, udp, tcp, tls, sctp;
98
99
0
  if((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST)
100
0
      || (PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)) {
101
0
    BUG("init_naptr_proto_prefs: array too small \n");
102
0
    return;
103
0
  }
104
105
0
  ignore_rfc = cfg_get(core, core_cfg, dns_naptr_ignore_rfc);
106
0
  udp = cfg_get(core, core_cfg, dns_udp_pref);
107
0
  tcp = cfg_get(core, core_cfg, dns_tcp_pref);
108
0
  tls = cfg_get(core, core_cfg, dns_tls_pref);
109
0
  sctp = cfg_get(core, core_cfg, dns_sctp_pref);
110
111
  /* Old implementation ignored the Order field in the NAPTR RR and
112
   * thus violated a MUST in RFC 2915. Currently still the default. */
113
0
  if(ignore_rfc) {
114
0
    naptr_proto_pref[PROTO_UDP] = udp;
115
0
    naptr_proto_pref[PROTO_TCP] = tcp;
116
0
    naptr_proto_pref[PROTO_TLS] = tls;
117
0
    naptr_proto_pref[PROTO_SCTP] = sctp;
118
0
  } else {
119
    /* If value is less than 0, proto is disabled, otherwise
120
     * ignored. */
121
0
    naptr_proto_pref[PROTO_UDP] = udp < 0 ? udp : 1;
122
0
    naptr_proto_pref[PROTO_TCP] = tcp < 0 ? tcp : 1;
123
0
    naptr_proto_pref[PROTO_TLS] = tls < 0 ? tls : 1;
124
0
    naptr_proto_pref[PROTO_SCTP] = sctp < 0 ? sctp : 1;
125
0
  }
126
0
}
127
128
#endif /* USE_NAPTR */
129
130
static void init_srv_proto_prefs()
131
0
{
132
0
  if((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST)
133
0
      || (PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)) {
134
0
    BUG("init_srv_proto_prefs: array too small \n");
135
0
    return;
136
0
  }
137
138
0
  srv_proto_pref[PROTO_UDP] = cfg_get(core, core_cfg, dns_udp_pref);
139
0
  srv_proto_pref[PROTO_TCP] = cfg_get(core, core_cfg, dns_tcp_pref);
140
0
  srv_proto_pref[PROTO_TLS] = cfg_get(core, core_cfg, dns_tls_pref);
141
0
  srv_proto_pref[PROTO_SCTP] = cfg_get(core, core_cfg, dns_sctp_pref);
142
0
}
143
144
#ifdef DNS_WATCHDOG_SUPPORT
145
static on_resolv_reinit on_resolv_reinit_cb = NULL;
146
147
/* register the callback function */
148
int register_resolv_reinit_cb(on_resolv_reinit cb)
149
{
150
  if(on_resolv_reinit_cb) {
151
    LM_ERR("callback function has been already registered\n");
152
    return -1;
153
  }
154
  on_resolv_reinit_cb = cb;
155
  return 0;
156
}
157
#endif
158
159
/* counter init function
160
  must be called before fork
161
*/
162
static int stat_init(void)
163
0
{
164
0
  if(counter_register_array("dns", dns_cnt_defs) < 0)
165
0
    goto error;
166
0
  return 0;
167
0
error:
168
0
  return -1;
169
0
}
170
171
/** init. the resolver
172
 * params: retr_time  - time before retransmitting (must be >0)
173
 *         retr_no    - retransmissions number
174
 *         servers_no - how many dns servers will be used
175
 *                      (from the one listed in /etc/resolv.conf)
176
 *         search     - if 0 the search list in /etc/resolv.conf will
177
 *                      be ignored (HINT: even if you don't have a
178
 *                      search list in resolv.conf, it's still better
179
 *                      to set search to 0, because an empty seachlist
180
 *                      means in fact search "" => it takes more time)
181
 * If any of the parameters <0, the default (system specific) value
182
 * will be used. See also resolv.conf(5).
183
 * returns: 0 on success, -1 on error
184
 */
185
static int _resolv_init(void)
186
0
{
187
0
  dns_func.sr_res_init();
188
0
#ifdef HAVE_RESOLV_RES
189
0
  if(cfg_get(core, core_cfg, dns_retr_time) > 0)
190
0
    _res.retrans = cfg_get(core, core_cfg, dns_retr_time);
191
0
  if(cfg_get(core, core_cfg, dns_retr_no) > 0)
192
0
    _res.retry = cfg_get(core, core_cfg, dns_retr_no);
193
0
  if((cfg_get(core, core_cfg, dns_servers_no) >= 0)
194
0
      && (cfg_get(core, core_cfg, dns_servers_no) < _res.nscount))
195
0
    _res.nscount = cfg_get(core, core_cfg, dns_servers_no);
196
0
  if(cfg_get(core, core_cfg, dns_search_list) == 0)
197
0
    _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);
198
#else
199
#warning "no resolv timeout support"
200
  LM_WARN("no resolv options support - resolv options will be ignored\n");
201
#endif
202
0
  return 0;
203
0
}
204
205
/** wrapper function to initialize the resolver at startup */
206
int resolv_init(void)
207
0
{
208
0
  int res = -1;
209
0
  _resolv_init();
210
211
0
  reinit_proto_prefs(NULL, NULL);
212
  /* init counter API only at startup
213
   * This function must be called before DNS cache init method (if available)
214
   */
215
0
  res = stat_init();
216
0
  return res;
217
0
}
218
219
/** wrapper function to reinitialize the resolver
220
 * This function must be called by each child process whenever
221
 * a resolver option changes
222
 */
223
void resolv_reinit(str *gname, str *name)
224
0
{
225
0
  _resolv_init();
226
227
#ifdef DNS_WATCHDOG_SUPPORT
228
  if(on_resolv_reinit_cb)
229
    on_resolv_reinit_cb(name);
230
#endif
231
0
  LM_DBG("DNS resolver has been reinitialized\n");
232
0
}
233
234
/** fixup function for dns_reinit variable
235
 * (resets the variable to 0)
236
 */
237
int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
238
0
{
239
0
  *val = (void *)(long)0;
240
0
  return 0;
241
0
}
242
243
/** wrapper function to recalculate the naptr and srv protocol preferences */
244
void reinit_proto_prefs(str *gname, str *name)
245
0
{
246
0
#ifdef USE_NAPTR
247
0
  init_naptr_proto_prefs();
248
0
#endif
249
0
  init_srv_proto_prefs();
250
0
}
251
252
/** fixup function for dns_try_ipv6
253
 * verifies that Kamailio really listens on an ipv6 interface
254
 */
255
int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val)
256
0
{
257
0
  if((int)(long)(*val) && !(socket_types & SOCKET_T_IPV6)) {
258
0
    LM_ERR("SER does not listen on any ipv6 interface, "
259
0
         "there is no point in resolving ipv6 addresses\n");
260
0
    return -1;
261
0
  }
262
0
  return 0;
263
0
}
264
265
/**  skips over a domain name in a dns message
266
 *  (it can be  a sequence of labels ending in \0, a pointer or
267
 *   a sequence of labels ending in a pointer -- see rfc1035
268
 *   returns pointer after the domain name or null on error*/
269
unsigned char *dns_skipname(unsigned char *p, unsigned char *end)
270
0
{
271
0
  while(p < end) {
272
    /* check if \0 (root label length) */
273
0
    if(*p == 0) {
274
0
      p += 1;
275
0
      break;
276
0
    }
277
    /* check if we found a pointer */
278
0
    if(((*p) & 0xc0) == 0xc0) {
279
      /* if pointer skip over it (2 bytes) & we found the end */
280
0
      p += 2;
281
0
      break;
282
0
    }
283
    /* normal label */
284
0
    p += *p + 1;
285
0
  }
286
0
  return (p > end) ? 0 : p;
287
0
}
288
289
290
/** parses the srv record into a srv_rdata structure
291
 *   msg   - pointer to the dns message
292
 *   end   - pointer to the end of the message
293
 *   eor   - pointer to the end of the record/rdata
294
 *   rdata - pointer  to the rdata part of the srv answer
295
 * returns 0 on error, or a dyn. alloc'ed srv_rdata structure
296
 *
297
 * SRV rdata format:
298
 *            111111
299
 *  0123456789012345
300
 * +----------------+
301
 * |     priority   |
302
 * |----------------|
303
 * |     weight     |
304
 * |----------------|
305
 * |   port number  |
306
 * |----------------|
307
 * |                |
308
 * ~      name      ~
309
 * |                |
310
 * +----------------+
311
 */
312
struct srv_rdata *dns_srv_parser(unsigned char *msg, unsigned char *end,
313
    unsigned char *eor, unsigned char *rdata)
314
0
{
315
0
  struct srv_rdata *srv;
316
0
  unsigned short priority;
317
0
  unsigned short weight;
318
0
  unsigned short port;
319
0
  int len;
320
0
  char name[MAX_DNS_NAME];
321
322
0
  srv = 0;
323
0
  if((rdata + 6 + 1) > eor)
324
0
    goto error;
325
326
0
  memcpy((void *)&priority, rdata, 2);
327
0
  memcpy((void *)&weight, rdata + 2, 2);
328
0
  memcpy((void *)&port, rdata + 4, 2);
329
0
  rdata += 6;
330
0
  if(dn_expand(msg, end, rdata, name, MAX_DNS_NAME - 1) < 0)
331
0
    goto error;
332
0
  len = strlen(name);
333
0
  if(len > 255)
334
0
    goto error;
335
  /* alloc enought space for the struct + null terminated name */
336
0
  srv = pkg_malloc(sizeof(struct srv_rdata) - 1 + len + 1);
337
0
  if(srv == 0) {
338
0
    PKG_MEM_ERROR;
339
0
    goto error;
340
0
  }
341
0
  srv->priority = ntohs(priority);
342
0
  srv->weight = ntohs(weight);
343
0
  srv->port = ntohs(port);
344
0
  srv->name_len = len;
345
0
  memcpy(srv->name, name, srv->name_len);
346
0
  srv->name[srv->name_len] = 0;
347
348
0
  return srv;
349
0
error:
350
0
  if(srv)
351
0
    pkg_free(srv);
352
0
  return 0;
353
0
}
354
355
356
/** parses the naptr record into a naptr_rdata structure
357
 *   msg   - pointer to the dns message
358
 *   end   - pointer to the end of the message
359
 *   eor   - pointer to the end of the record/rdata
360
 *   rdata - pointer  to the rdata part of the naptr answer
361
 * returns 0 on error, or a dyn. alloc'ed naptr_rdata structure */
362
363
/* NAPTR rdata format:
364
 *            111111
365
 *  0123456789012345
366
 * +----------------+
367
 * |      order     |
368
 * |----------------|
369
 * |   preference   |
370
 * |----------------|
371
 * ~     flags      ~
372
 * |   (string)     |
373
 * |----------------|
374
 * ~    services    ~
375
 * |   (string)     |
376
 * |----------------|
377
 * ~    regexp      ~
378
 * |   (string)     |
379
 * |----------------|
380
 * ~  replacement   ~
381
   |    (name)      |
382
 * +----------------+
383
 */
384
struct naptr_rdata *dns_naptr_parser(unsigned char *msg, unsigned char *end,
385
    unsigned char *eor, unsigned char *rdata)
386
0
{
387
0
  struct naptr_rdata *naptr;
388
0
  unsigned char *flags;
389
0
  unsigned char *services;
390
0
  unsigned char *regexp;
391
0
  unsigned short order;
392
0
  unsigned short pref;
393
0
  unsigned char flags_len;
394
0
  unsigned char services_len;
395
0
  unsigned char regexp_len;
396
0
  int len;
397
0
  char repl[MAX_DNS_NAME];
398
399
0
  naptr = 0;
400
0
  if((rdata + 7 + 1) > eor)
401
0
    goto error;
402
403
0
  memcpy((void *)&order, rdata, 2);
404
0
  memcpy((void *)&pref, rdata + 2, 2);
405
0
  flags_len = rdata[4];
406
0
  if((rdata + 7 + 1 + flags_len) > eor)
407
0
    goto error;
408
0
  flags = rdata + 5;
409
0
  services_len = rdata[5 + flags_len];
410
0
  if((rdata + 7 + 1 + flags_len + services_len) > eor)
411
0
    goto error;
412
0
  services = rdata + 6 + flags_len;
413
0
  regexp_len = rdata[6 + flags_len + services_len];
414
0
  if((rdata + 7 + 1 + flags_len + services_len + regexp_len) > eor)
415
0
    goto error;
416
0
  regexp = rdata + 7 + flags_len + services_len;
417
0
  rdata = rdata + 7 + flags_len + services_len + regexp_len;
418
0
  if(dn_expand(msg, end, rdata, repl, MAX_DNS_NAME - 1) == -1)
419
0
    goto error;
420
0
  len = strlen(repl);
421
0
  if(len > 255)
422
0
    goto error;
423
0
  naptr = pkg_malloc(sizeof(struct naptr_rdata) + flags_len + services_len
424
0
             + regexp_len + len + 1 - 1);
425
0
  if(naptr == 0) {
426
0
    PKG_MEM_ERROR;
427
0
    goto error;
428
0
  }
429
0
  naptr->skip_record = 0;
430
0
  naptr->order = ntohs(order);
431
0
  naptr->pref = ntohs(pref);
432
433
0
  naptr->flags = &naptr->str_table[0];
434
0
  naptr->flags_len = flags_len;
435
0
  memcpy(naptr->flags, flags, naptr->flags_len);
436
0
  naptr->services = &naptr->str_table[flags_len];
437
0
  naptr->services_len = services_len;
438
0
  memcpy(naptr->services, services, naptr->services_len);
439
0
  naptr->regexp = &naptr->str_table[flags_len + services_len];
440
0
  naptr->regexp_len = regexp_len;
441
0
  memcpy(naptr->regexp, regexp, naptr->regexp_len);
442
0
  naptr->repl = &naptr->str_table[flags_len + services_len + regexp_len];
443
0
  naptr->repl_len = len;
444
0
  memcpy(naptr->repl, repl, len);
445
0
  naptr->repl[len] = 0; /* null term. */
446
447
0
  return naptr;
448
0
error:
449
0
  if(naptr)
450
0
    pkg_free(naptr);
451
0
  return 0;
452
0
}
453
454
455
/** parses a CNAME record into a cname_rdata structure */
456
struct cname_rdata *dns_cname_parser(
457
    unsigned char *msg, unsigned char *end, unsigned char *rdata)
458
0
{
459
0
  struct cname_rdata *cname;
460
0
  int len;
461
0
  char name[MAX_DNS_NAME];
462
463
0
  cname = 0;
464
0
  if(dn_expand(msg, end, rdata, name, MAX_DNS_NAME - 1) == -1)
465
0
    goto error;
466
0
  len = strlen(name);
467
0
  if(len > 255)
468
0
    goto error;
469
  /* alloc sizeof struct + space for the null terminated name */
470
0
  cname = pkg_malloc(sizeof(struct cname_rdata) - 1 + len + 1);
471
0
  if(cname == 0) {
472
0
    PKG_MEM_ERROR;
473
0
    goto error;
474
0
  }
475
0
  cname->name_len = len;
476
0
  memcpy(cname->name, name, cname->name_len);
477
0
  cname->name[cname->name_len] = 0;
478
0
  return cname;
479
0
error:
480
0
  if(cname)
481
0
    pkg_free(cname);
482
0
  return 0;
483
0
}
484
485
486
/** parses an A record rdata into an a_rdata structure
487
 * returns 0 on error or a dyn. alloc'ed a_rdata struct
488
 */
489
struct a_rdata *dns_a_parser(unsigned char *rdata, unsigned char *eor)
490
0
{
491
0
  struct a_rdata *a;
492
493
0
  if(rdata + 4 > eor)
494
0
    goto error;
495
0
  a = (struct a_rdata *)pkg_malloc(sizeof(struct a_rdata));
496
0
  if(a == 0) {
497
0
    PKG_MEM_ERROR;
498
0
    goto error;
499
0
  }
500
0
  memcpy(a->ip, rdata, 4);
501
0
  return a;
502
0
error:
503
0
  return 0;
504
0
}
505
506
507
/** parses an AAAA (ipv6) record rdata into an aaaa_rdata structure
508
 * returns 0 on error or a dyn. alloc'ed aaaa_rdata struct */
509
struct aaaa_rdata *dns_aaaa_parser(unsigned char *rdata, unsigned char *eor)
510
0
{
511
0
  struct aaaa_rdata *aaaa;
512
513
0
  if(rdata + 16 > eor)
514
0
    goto error;
515
0
  aaaa = (struct aaaa_rdata *)pkg_malloc(sizeof(struct aaaa_rdata));
516
0
  if(aaaa == 0) {
517
0
    PKG_MEM_ERROR;
518
0
    goto error;
519
0
  }
520
0
  memcpy(aaaa->ip6, rdata, 16);
521
0
  return aaaa;
522
0
error:
523
0
  return 0;
524
0
}
525
526
527
/** parses a TXT record into a txt_rdata structure.
528
 *   @param msg   - pointer to the dns message
529
 *   @param end   - pointer to the end of the record (rdata end)
530
 *   @param rdata - pointer  to the rdata part of the txt answer
531
 * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
532
/*  TXT rdata format:
533
 *
534
 * one or several character strings:
535
 *  01234567
536
 * +--------------------+
537
 * | len    | string   / ...
538
 * |------------------+
539
 */
540
static struct txt_rdata *dns_txt_parser(
541
    unsigned char *msg, unsigned char *end, unsigned char *rdata)
542
0
{
543
0
  struct txt_rdata *txt;
544
0
  int len, n, i;
545
0
  int str_size;
546
0
  unsigned char *p;
547
0
  unsigned char *st;
548
549
0
  txt = 0;
550
0
  if(unlikely((rdata + 1) > end))
551
0
    goto error;
552
0
  n = 0;
553
0
  str_size = 0;
554
  /* count the number of strings */
555
0
  p = rdata;
556
0
  do {
557
0
    len = *p;
558
0
    p += len + 1;
559
0
    str_size += len + 1; /* 1 for the term. 0 */
560
0
    if(unlikely(p > end))
561
0
      goto error;
562
0
    n++;
563
0
  } while(p < end);
564
  /* alloc sizeof struct + space for the dns_cstr array + space for
565
     the strings */
566
0
  txt = pkg_malloc(sizeof(struct txt_rdata)
567
0
           + (n - 1) * sizeof(struct dns_cstr) + str_size);
568
0
  if(unlikely(txt == 0)) {
569
0
    PKG_MEM_ERROR;
570
0
    goto error;
571
0
  }
572
  /* string table */
573
0
  st = (unsigned char *)txt + sizeof(struct txt_rdata)
574
0
     + (n - 1) * sizeof(struct dns_cstr);
575
0
  txt->cstr_no = n;
576
0
  txt->tslen = str_size;
577
  /* fill the structure */
578
0
  p = rdata;
579
0
  for(i = 0; i < n; i++) {
580
0
    len = *p;
581
0
    memcpy(st, p + 1, len);
582
0
    st[len] = 0;
583
0
    txt->txt[i].cstr_len = len;
584
0
    txt->txt[i].cstr = (char *)st;
585
0
    st += len + 1;
586
0
    p += len + 1;
587
0
  }
588
0
  return txt;
589
0
error:
590
0
  if(txt)
591
0
    pkg_free(txt);
592
0
  return 0;
593
0
}
594
595
596
/** parses an EBL record into a txt_rdata structure.
597
 *   @param msg   - pointer to the dns message
598
 *   @param end   - pointer to the end of the dns message
599
 *   @param eor   - pointer to the end of the record (rdata end)
600
 *   @param rdata - pointer  to the rdata part of the txt answer
601
 * returns 0 on error, or a dyn. alloc'ed txt_rdata structure */
602
/*  EBL rdata format:
603
 *  (see http://tools.ietf.org/html/draft-ietf-enum-branch-location-record-03)
604
 * one or several character strings:
605
 *  01234567
606
 * +---------+
607
 * | position|
608
 * +-----------+
609
 * / separator /
610
 * +-----------+
611
 * /   apex    /
612
 * +----------+
613
 *
614
 * where separator is a character string ( 8 bit len, followed by len chars)
615
 * and apex is a domain-name.
616
 */
617
static struct ebl_rdata *dns_ebl_parser(unsigned char *msg, unsigned char *end,
618
    unsigned char *eor, unsigned char *rdata)
619
0
{
620
0
  struct ebl_rdata *ebl;
621
0
  int sep_len;
622
0
  int apex_len;
623
0
  char apex[MAX_DNS_NAME];
624
625
0
  ebl = 0;
626
  /* check if len is at least 4 chars (minimum possible):
627
       pos (1 byte) +  sep. (min 1 byte) + apex (min. 2 bytes)
628
     and also check if rdata+1 (pos) + 1 (sep. len) + sep_len + 1 is ok*/
629
0
  if(unlikely(((rdata + 4) > eor) || ((rdata + 1 + 1 + rdata[1] + 2) > eor)))
630
0
    goto error;
631
0
  sep_len = rdata[1];
632
0
  if(unlikely(dn_expand(msg, end, rdata + 1 + 1 + sep_len, apex,
633
0
            MAX_DNS_NAME - 1)
634
0
        == -1))
635
0
    goto error;
636
0
  apex_len = strlen(apex);
637
  /* alloc sizeof struct + space for the 2 null-terminated strings */
638
0
  ebl = pkg_malloc(sizeof(struct ebl_rdata) - 1 + sep_len + 1 + apex_len + 1);
639
0
  if(ebl == 0) {
640
0
    PKG_MEM_ERROR;
641
0
    goto error;
642
0
  }
643
0
  ebl->position = rdata[0];
644
0
  ebl->separator = &ebl->str_table[0];
645
0
  ebl->apex = ebl->separator + sep_len + 1;
646
0
  ebl->separator_len = sep_len;
647
0
  ebl->apex_len = apex_len;
648
0
  memcpy(ebl->separator, rdata + 2, sep_len);
649
0
  ebl->separator[sep_len] = 0;
650
0
  memcpy(ebl->apex, apex, apex_len);
651
0
  ebl->apex[apex_len] = 0;
652
653
0
  return ebl;
654
0
error:
655
0
  if(ebl)
656
0
    pkg_free(ebl);
657
0
  return 0;
658
0
}
659
660
661
/** parses a PTR record into a ptr_rdata structure */
662
struct ptr_rdata *dns_ptr_parser(
663
    unsigned char *msg, unsigned char *end, unsigned char *rdata)
664
0
{
665
0
  struct ptr_rdata *pname;
666
0
  int len;
667
0
  char name[MAX_DNS_NAME];
668
669
0
  pname = 0;
670
0
  if(dn_expand(msg, end, rdata, name, MAX_DNS_NAME - 1) == -1)
671
0
    goto error;
672
0
  len = strlen(name);
673
0
  if(len > 255)
674
0
    goto error;
675
  /* alloc sizeof struct + space for the null terminated name */
676
0
  pname = pkg_malloc(sizeof(struct ptr_rdata) - 1 + len + 1);
677
0
  if(pname == 0) {
678
0
    PKG_MEM_ERROR;
679
0
    goto error;
680
0
  }
681
0
  pname->ptrdname_len = len;
682
0
  memcpy(pname->ptrdname, name, pname->ptrdname_len);
683
0
  pname->ptrdname[pname->ptrdname_len] = 0;
684
0
  return pname;
685
0
error:
686
0
  if(pname)
687
0
    pkg_free(pname);
688
0
  return 0;
689
0
}
690
691
692
/** frees completely a struct rdata list */
693
void free_rdata_list(struct rdata *head)
694
0
{
695
0
  struct rdata *l;
696
0
  struct rdata *next_l;
697
0
  l = head;
698
0
  while(l != 0) {
699
0
    next_l = l->next;
700
    /* free the parsed rdata*/
701
0
    if(l->rdata)
702
0
      pkg_free(l->rdata);
703
0
    pkg_free(l);
704
0
    l = next_l;
705
0
  }
706
0
}
707
708
#ifdef HAVE_RESOLV_RES
709
/** checks whether supplied name exists in the resolver search list
710
 * returns 1 if found
711
 *         0 if not found
712
 */
713
int match_search_list(const struct __res_state *res, char *name)
714
0
{
715
0
  int i;
716
0
  for(i = 0; (i < MAXDNSRCH) && (res->dnsrch[i]); i++) {
717
0
    if(strcasecmp(name, res->dnsrch[i]) == 0)
718
0
      return 1;
719
0
  }
720
0
  return 0;
721
0
}
722
#endif
723
724
#ifndef SR_DNS_MAX_QNO
725
0
#define SR_DNS_MAX_QNO 10
726
#endif
727
#ifndef SR_DNS_MAX_ANO
728
0
#define SR_DNS_MAX_ANO 100
729
#endif
730
731
/** gets the DNS records for name:type
732
 * returns a dyn. alloc'ed struct rdata linked list with the parsed responses
733
 * or 0 on error
734
 * see rfc1035 for the query/response format */
735
struct rdata *get_record(char *name, int type, int flags)
736
0
{
737
0
  int size;
738
0
  int skip;
739
0
  unsigned short qno, answers_no, r;
740
0
  int i;
741
0
  static union dns_query buff;
742
0
  unsigned char *p;
743
0
  unsigned char *end;
744
0
  unsigned char *rd_end;
745
0
  static char rec_name[MAX_DNS_NAME]; /* placeholder for the record name */
746
0
  int rec_name_len;
747
0
  unsigned short rtype, class, rdlength;
748
0
  unsigned int ttl;
749
0
  struct rdata *head;
750
0
  struct rdata **crt;
751
0
  struct rdata **last;
752
0
  struct rdata *rd;
753
0
  struct srv_rdata *srv_rd;
754
0
  struct srv_rdata *crt_srv;
755
0
  int search_list_used;
756
0
  int name_len;
757
0
  struct rdata *fullname_rd;
758
0
  char c;
759
0
  struct timeval start, stop;
760
0
  int slow_query_ms = cfg_get(core, core_cfg, dns_slow_query_ms);
761
762
0
  name_len = strlen(name);
763
764
0
  for(i = 0; i < name_len; i++) {
765
0
    c = name[i];
766
0
    if(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
767
0
        || ((c >= '0') && (c <= '9')) || (name[i] == '.')
768
0
        || (name[i] == '-') || (name[i] == '_'))
769
0
      continue;
770
0
    LM_DBG("'%s' is not domain name\n", name);
771
0
    return 0;
772
0
  }
773
774
0
  if(cfg_get(core, core_cfg, dns_search_list) == 0) {
775
0
    search_list_used = 0;
776
0
    name_len = 0;
777
0
  } else {
778
0
    search_list_used = 1;
779
0
  }
780
0
  fullname_rd = 0;
781
782
0
  if(slow_query_ms > 0)
783
0
    gettimeofday(&start, NULL);
784
785
0
  size = dns_func.sr_res_search(name, C_IN, type, buff.buff, sizeof(buff));
786
787
0
  if(slow_query_ms > 0) {
788
0
    gettimeofday(&stop, NULL);
789
0
    int latency_ms = (stop.tv_sec - start.tv_sec) * 1000
790
0
             + (stop.tv_usec - start.tv_usec) / 1000;
791
0
    if(slow_query_ms < latency_ms) {
792
0
      LOG(cfg_get(core, core_cfg, latency_log),
793
0
          "res_search[%d][%s]elapsed[%dms]\n", type, name,
794
0
          latency_ms);
795
0
      counter_inc(dns_cnts_h.slow_dns_req);
796
0
    }
797
0
  }
798
799
0
  if(unlikely(size < 0)) {
800
0
    LM_DBG("lookup(%s, %d) failed\n", name, type);
801
0
    goto not_found;
802
0
  } else if(unlikely(size > sizeof(buff)))
803
0
    size = sizeof(buff);
804
0
  head = rd = 0;
805
0
  last = crt = &head;
806
807
0
  p = buff.buff + DNS_HDR_SIZE;
808
0
  end = buff.buff + size;
809
0
  if(unlikely(p >= end))
810
0
    goto error_boundary;
811
0
  qno = ntohs((unsigned short)buff.hdr.qdcount);
812
813
0
  if(qno != 1) {
814
    /* usually the query is with a single domain name */
815
0
    LM_INFO("dns questions number is: %u\n", (uint32_t)qno);
816
0
    if(qno > SR_DNS_MAX_QNO) {
817
      /* early safe check against broken results */
818
0
      LM_ERR("dns questions number is too high: %u\n", (uint32_t)qno);
819
0
      goto error;
820
0
    }
821
0
  }
822
0
  for(r = 0; r < qno; r++) {
823
    /* skip the name of the question */
824
0
    if(unlikely((p = dns_skipname(p, end)) == 0)) {
825
0
      LM_ERR("skipname==0\n");
826
0
      goto error;
827
0
    }
828
0
    p += 2 + 2; /* skip QCODE & QCLASS */
829
#if 0
830
    for (;(p<end && (*p)); p++);
831
    p+=1+2+2; /* skip the ending  '\0, QCODE and QCLASS */
832
#endif
833
0
    if(unlikely(p > end)) {
834
0
      LM_ERR("p>=end\n");
835
0
      goto error;
836
0
    }
837
0
  }
838
0
  answers_no = ntohs((unsigned short)buff.hdr.ancount);
839
0
  if(answers_no > SR_DNS_MAX_ANO) {
840
    /* early safety check on answers number */
841
0
    LM_ERR("dns answers number is too high: %u\n", (uint32_t)answers_no);
842
0
    goto error;
843
0
  }
844
0
again:
845
0
  for(r = 0; (r < answers_no) && (p < end); r++) {
846
#if 0
847
    /*  ignore it the default domain name */
848
    if ((p=dns_skipname(p, end))==0) {
849
      LM_ERR("get_record: skip_name=0 (#2)\n");
850
      goto error;
851
    }
852
#else
853
0
    if(unlikely((skip = dn_expand(
854
0
               buff.buff, end, p, rec_name, MAX_DNS_NAME - 1))
855
0
          == -1)) {
856
0
      LM_ERR("dn_expand(rec_name) failed\n");
857
0
      goto error;
858
0
    }
859
0
#endif
860
0
    p += skip;
861
0
    rec_name_len = strlen(rec_name);
862
0
    if(unlikely(rec_name_len > MAX_DNS_NAME - 2)) {
863
0
      LM_ERR("dn_expand(rec_name): name too long (%d)\n", rec_name_len);
864
0
      goto error;
865
0
    }
866
    /* check if enough space is left for type, class, ttl & size */
867
0
    if(unlikely((p + 2 + 2 + 4 + 2) > end))
868
0
      goto error_boundary;
869
    /* get type */
870
0
    memcpy((void *)&rtype, (void *)p, 2);
871
0
    rtype = ntohs(rtype);
872
0
    p += 2;
873
    /* get  class */
874
0
    memcpy((void *)&class, (void *)p, 2);
875
0
    class = ntohs(class);
876
0
    p += 2;
877
    /* get ttl*/
878
0
    memcpy((void *)&ttl, (void *)p, 4);
879
0
    ttl = ntohl(ttl);
880
0
    p += 4;
881
    /* get size */
882
0
    memcpy((void *)&rdlength, (void *)p, 2);
883
0
    rdlength = ntohs(rdlength);
884
0
    p += 2;
885
0
    rd_end = p + rdlength;
886
0
    if(unlikely((rd_end) > end))
887
0
      goto error_boundary;
888
0
    if((flags & RES_ONLY_TYPE) && (rtype != type)) {
889
      /* skip */
890
0
      p = rd_end;
891
0
      continue;
892
0
    }
893
    /* expand the "type" record  (rdata)*/
894
895
0
    rd = (struct rdata *)pkg_malloc(
896
0
        sizeof(struct rdata) + rec_name_len + 1 - 1);
897
0
    if(rd == 0) {
898
0
      PKG_MEM_ERROR;
899
0
      goto error;
900
0
    }
901
0
    rd->type = rtype;
902
0
    rd->pclass = class;
903
0
    rd->ttl = ttl;
904
0
    rd->next = 0;
905
0
    memcpy(rd->name, rec_name, rec_name_len);
906
0
    rd->name[rec_name_len] = 0;
907
0
    rd->name_len = rec_name_len;
908
    /* check if full name matches */
909
0
    if((search_list_used == 1) && (fullname_rd == 0)
910
0
        && (rec_name_len >= name_len)
911
0
        && (strncasecmp(rec_name, name, name_len) == 0)) {
912
      /* now we have record whose name is the same (up-to the
913
       * name_len with the searched one):
914
       * if the length is the same - we found full match, no fake
915
       *  cname needed, just clear the flag
916
       * if the length of the name differs - it has matched using
917
       *  search list remember the rd, so we can create fake CNAME
918
       *  record when all answers are used and no better match found
919
       */
920
0
      if(rec_name_len == name_len)
921
0
        search_list_used = 0;
922
      /* this is safe.... here was rec_name_len > name_len */
923
0
      else if(rec_name[name_len] == '.') {
924
0
#ifdef HAVE_RESOLV_RES
925
0
        if((cfg_get(core, core_cfg, dns_search_fmatch) == 0)
926
0
            || (match_search_list(&_res, rec_name + name_len + 1)
927
0
                != 0))
928
0
#endif
929
0
          fullname_rd = rd;
930
0
      }
931
0
    }
932
0
    switch(rtype) {
933
0
      case T_SRV:
934
0
        srv_rd = dns_srv_parser(buff.buff, end, rd_end, p);
935
0
        rd->rdata = (void *)srv_rd;
936
0
        if(unlikely(srv_rd == 0))
937
0
          goto error_parse;
938
939
        /* insert sorted into the list */
940
0
        for(crt = &head; *crt; crt = &((*crt)->next)) {
941
0
          if((*crt)->type != T_SRV)
942
0
            continue;
943
0
          crt_srv = (struct srv_rdata *)(*crt)->rdata;
944
0
          if((srv_rd->priority < crt_srv->priority)
945
0
              || ((srv_rd->priority == crt_srv->priority)
946
0
                  && (srv_rd->weight > crt_srv->weight))) {
947
            /* insert here */
948
0
            goto skip;
949
0
          }
950
0
        }
951
0
        last = &(rd->next); /*end of for => this will be the last
952
                  element*/
953
0
      skip:
954
        /* insert here */
955
0
        rd->next = *crt;
956
0
        *crt = rd;
957
0
        break;
958
0
      case T_A:
959
0
        rd->rdata = (void *)dns_a_parser(p, rd_end);
960
0
        if(unlikely(rd->rdata == 0))
961
0
          goto error_parse;
962
0
        *last = rd; /* last points to the last "next" or the list
963
                head*/
964
0
        last = &(rd->next);
965
0
        break;
966
0
      case T_AAAA:
967
0
        rd->rdata = (void *)dns_aaaa_parser(p, rd_end);
968
0
        if(unlikely(rd->rdata == 0))
969
0
          goto error_parse;
970
0
        *last = rd;
971
0
        last = &(rd->next);
972
0
        break;
973
0
      case T_CNAME:
974
0
        rd->rdata = (void *)dns_cname_parser(buff.buff, end, p);
975
0
        if(unlikely(rd->rdata == 0))
976
0
          goto error_parse;
977
0
        *last = rd;
978
0
        last = &(rd->next);
979
0
        break;
980
0
      case T_NAPTR:
981
0
        rd->rdata = (void *)dns_naptr_parser(buff.buff, end, rd_end, p);
982
0
        if(unlikely(rd->rdata == 0))
983
0
          goto error_parse;
984
0
        *last = rd;
985
0
        last = &(rd->next);
986
0
        break;
987
0
      case T_TXT:
988
0
        rd->rdata = dns_txt_parser(buff.buff, rd_end, p);
989
0
        if(rd->rdata == 0)
990
0
          goto error_parse;
991
0
        *last = rd;
992
0
        last = &(rd->next);
993
0
        break;
994
0
      case T_EBL:
995
0
        rd->rdata = dns_ebl_parser(buff.buff, end, rd_end, p);
996
0
        if(rd->rdata == 0)
997
0
          goto error_parse;
998
0
        *last = rd;
999
0
        last = &(rd->next);
1000
0
        break;
1001
0
      case T_PTR:
1002
0
        rd->rdata = (void *)dns_ptr_parser(buff.buff, end, p);
1003
0
        if(unlikely(rd->rdata == 0))
1004
0
          goto error_parse;
1005
0
        *last = rd;
1006
0
        last = &(rd->next);
1007
0
        break;
1008
0
      case T_OPT:
1009
        /* skip DNS extensions, e.g. EDNS0 */
1010
0
        rd->rdata = 0;
1011
0
        *last = rd;
1012
0
        last = &(rd->next);
1013
0
        break;
1014
0
      default:
1015
0
        LM_ERR("unknown type %d\n", rtype);
1016
0
        rd->rdata = 0;
1017
0
        *last = rd;
1018
0
        last = &(rd->next);
1019
0
    }
1020
1021
0
    p += rdlength;
1022
0
  }
1023
0
  if(flags & RES_AR) {
1024
0
    flags &= ~RES_AR;
1025
0
    answers_no = ntohs((unsigned short)buff.hdr.nscount);
1026
0
    LM_DBG("skipping %d NS (p=%p, end=%p)\n", answers_no, p, end);
1027
0
    for(r = 0; (r < answers_no) && (p < end); r++) {
1028
      /* skip over the ns records */
1029
0
      if((p = dns_skipname(p, end)) == 0) {
1030
0
        LM_ERR("skip_name=0 (#3)\n");
1031
0
        goto error;
1032
0
      }
1033
      /* check if enough space is left for type, class, ttl & size */
1034
0
      if(unlikely((p + 2 + 2 + 4 + 2) > end))
1035
0
        goto error_boundary;
1036
0
      memcpy((void *)&rdlength, (void *)(p + 2 + 2 + 4), 2);
1037
0
      p += 2 + 2 + 4 + 2 + ntohs(rdlength);
1038
0
    }
1039
0
    answers_no = ntohs((unsigned short)buff.hdr.arcount);
1040
0
    LM_DBG("parsing %d ARs (p=%p, end=%p)\n", answers_no, p, end);
1041
0
    goto again; /* add also the additional records */
1042
0
  }
1043
1044
  /* if the name was expanded using DNS search list
1045
   * create fake CNAME record to convert the short name
1046
   * (queried) to long name (answered)
1047
   */
1048
0
  if((search_list_used == 1) && (fullname_rd != 0)) {
1049
0
    rd = (struct rdata *)pkg_malloc(
1050
0
        sizeof(struct rdata) + name_len + 1 - 1);
1051
0
    if(unlikely(rd == 0)) {
1052
0
      PKG_MEM_ERROR;
1053
0
      goto error;
1054
0
    }
1055
0
    rd->type = T_CNAME;
1056
0
    rd->pclass = fullname_rd->pclass;
1057
0
    rd->ttl = fullname_rd->ttl;
1058
0
    rd->next = head;
1059
0
    memcpy(rd->name, name, name_len);
1060
0
    rd->name[name_len] = 0;
1061
0
    rd->name_len = name_len;
1062
    /* alloc sizeof struct + space for the null terminated name */
1063
0
    rd->rdata = (void *)pkg_malloc(
1064
0
        sizeof(struct cname_rdata) - 1 + fullname_rd->name_len + 1);
1065
0
    if(unlikely(rd->rdata == 0)) {
1066
0
      PKG_MEM_ERROR;
1067
0
      goto error_rd;
1068
0
    }
1069
0
    ((struct cname_rdata *)(rd->rdata))->name_len = fullname_rd->name_len;
1070
0
    memcpy(((struct cname_rdata *)(rd->rdata))->name, fullname_rd->name,
1071
0
        fullname_rd->name_len);
1072
0
    ((struct cname_rdata *)(rd->rdata))->name[head->name_len] = 0;
1073
0
    head = rd;
1074
0
  }
1075
1076
0
  return head;
1077
0
error_boundary:
1078
0
  LM_ERR("end of query buff reached\n");
1079
0
  if(head)
1080
0
    free_rdata_list(head);
1081
0
  return 0;
1082
0
error_parse:
1083
0
  LM_ERR("rdata parse error (%s, %d), %p-%p"
1084
0
       " rtype=%d, class=%d, ttl=%d, rdlength=%d\n",
1085
0
      name, type, p, end, rtype, class, ttl, rdlength);
1086
0
error_rd:
1087
0
  if(rd)
1088
0
    pkg_free(rd); /* rd->rdata=0 & rd is not linked yet into
1089
                   the list */
1090
0
error:
1091
0
  LM_ERR("get_record\n");
1092
0
  if(head)
1093
0
    free_rdata_list(head);
1094
0
not_found:
1095
  /* increment error counter */
1096
0
  counter_inc(dns_cnts_h.failed_dns_req);
1097
0
  return 0;
1098
0
}
1099
1100
#ifdef USE_NAPTR
1101
1102
/* service matching constants, lowercase */
1103
0
#define SIP_SCH 0x2b706973
1104
0
#define SIPS_SCH 0x73706973
1105
0
#define SIP_D2U 0x00753264
1106
0
#define SIP_D2T 0x00743264
1107
0
#define SIP_D2S 0x00733264
1108
0
#define SIPS_D2T 0x7432642b
1109
1110
1111
/** get protocol from a naptr rdata and check for validity
1112
 * returns > 0 (PROTO_UDP, PROTO_TCP, PROTO_SCTP or PROTO_TLS)
1113
 *         <=0  on error
1114
 */
1115
char naptr_get_sip_proto(struct naptr_rdata *n)
1116
0
{
1117
0
  unsigned int s;
1118
0
  char proto;
1119
1120
0
  proto = -1;
1121
1122
0
  if((n->flags_len != 1) || ((*n->flags | 0x20) != 's'))
1123
0
    return -1;
1124
0
  if(n->regexp_len != 0)
1125
0
    return -1;
1126
  /* SIP+D2U, SIP+D2T, SIP+D2S, SIPS+D2T */
1127
0
  if(n->services_len == 7) { /* SIP+D2X */
1128
0
    s = n->services[0] + (n->services[1] << 8) + (n->services[2] << 16)
1129
0
      + (n->services[3] << 24);
1130
0
    s |= 0x20202020;
1131
0
    if(s == SIP_SCH) {
1132
0
      s = n->services[4] + (n->services[5] << 8) + (n->services[6] << 16);
1133
0
      s |= 0x00202020;
1134
0
      switch(s) {
1135
0
        case SIP_D2U:
1136
0
          proto = PROTO_UDP;
1137
0
          break;
1138
0
        case SIP_D2T:
1139
0
          proto = PROTO_TCP;
1140
0
          break;
1141
0
        case SIP_D2S:
1142
0
          proto = PROTO_SCTP;
1143
0
          break;
1144
0
        default:
1145
0
          return -1;
1146
0
      }
1147
0
    } else {
1148
0
      return -1;
1149
0
    }
1150
0
  } else if(n->services_len == 8) { /*SIPS+D2T */
1151
0
    s = n->services[0] + (n->services[1] << 8) + (n->services[2] << 16)
1152
0
      + (n->services[3] << 24);
1153
0
    s |= 0x20202020;
1154
0
    if(s == SIPS_SCH) {
1155
0
      s = n->services[4] + (n->services[5] << 8) + (n->services[6] << 16)
1156
0
        + (n->services[7] << 24);
1157
0
      s |= 0x20202020;
1158
0
      if(s == SIPS_D2T) {
1159
0
        proto = PROTO_TLS;
1160
0
      }
1161
0
    } else {
1162
0
      return -1;
1163
0
    }
1164
0
  } else {
1165
0
    return -1;
1166
0
  }
1167
0
  return proto;
1168
0
}
1169
1170
1171
inline static int naptr_proto_pref_score(char proto)
1172
0
{
1173
0
  if((proto >= PROTO_UDP) && (proto <= PROTO_LAST))
1174
0
    return naptr_proto_pref[(int)proto];
1175
0
  return 0;
1176
0
}
1177
1178
inline static int srv_proto_pref_score(char proto)
1179
0
{
1180
0
  if((proto >= PROTO_UDP) && (proto <= PROTO_LAST))
1181
0
    return srv_proto_pref[(int)proto];
1182
0
  return 0;
1183
0
}
1184
1185
1186
/** returns true if we support the protocol */
1187
int naptr_proto_supported(char proto)
1188
0
{
1189
0
  if(naptr_proto_pref_score(proto) < 0)
1190
0
    return 0;
1191
0
  switch(proto) {
1192
0
    case PROTO_UDP:
1193
0
      return 1;
1194
0
#ifdef USE_TCP
1195
0
    case PROTO_TCP:
1196
0
      return !tcp_disable;
1197
0
#ifdef USE_TLS
1198
0
    case PROTO_TLS:
1199
0
      return !tls_disable;
1200
0
#endif /* USE_TLS */
1201
0
#endif /* USE_TCP */
1202
0
#ifdef USE_SCTP
1203
0
    case PROTO_SCTP:
1204
0
      return !sctp_disable;
1205
0
#endif
1206
0
  }
1207
0
  return 0;
1208
0
}
1209
1210
1211
/** returns true if new_proto is preferred over old_proto */
1212
int naptr_proto_preferred(char new_proto, char old_proto)
1213
0
{
1214
0
  return naptr_proto_pref_score(new_proto)
1215
0
       > naptr_proto_pref_score(old_proto);
1216
0
}
1217
1218
1219
/** choose between 2 naptr records, should take into account local
1220
 * preferences too
1221
 * returns 1 if the new record was selected, 0 otherwise */
1222
int naptr_choose(struct naptr_rdata **crt, char *crt_proto,
1223
    struct naptr_rdata *n, char n_proto)
1224
0
{
1225
0
  LM_DBG("o:%d w:%d p:%d, o:%d w:%d p:%d\n", *crt ? (int)(*crt)->order : -1,
1226
0
      *crt ? (int)(*crt)->pref : -1, (int)*crt_proto, (int)n->order,
1227
0
      (int)n->pref, (int)n_proto);
1228
0
  if((*crt == 0)
1229
0
      || ((*crt_proto != n_proto)
1230
0
          && (naptr_proto_preferred(n_proto, *crt_proto))))
1231
0
    goto change;
1232
0
  if(!naptr_proto_preferred(*crt_proto, n_proto)
1233
0
      && ((n->order < (*crt)->order)
1234
0
          || ((n->order == (*crt)->order)
1235
0
              && (n->pref < (*crt)->pref)))) {
1236
0
    goto change;
1237
0
  }
1238
0
  LM_DBG("no change\n");
1239
0
  return 0;
1240
0
change:
1241
0
  LM_DBG("changed\n");
1242
0
  *crt_proto = n_proto;
1243
0
  *crt = n;
1244
0
  return 1;
1245
0
}
1246
#endif /* USE_NAPTR */
1247
1248
1249
/** internal sip srv resolver: resolves a host name trying:
1250
 * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1251
 *   query will be used for an A/AAAA lookup.
1252
 *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1253
 *   and *proto!=0 or port==0 && proto==0)
1254
 * when performing SRV lookup (*port==0) it will use *proto to look for
1255
 * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1256
 * If zt is set, name will be assumed to be 0 terminated and some copy
1257
 * operations will be avoided.
1258
 * If is_srv is set it will assume name has the srv prefixes for sip already
1259
 *  appended and it's already 0-term'ed; if not it will append them internally.
1260
 * If ars !=0, it will first try to look through them and only if the SRV
1261
 *   record is not found it will try doing a DNS query  (ars will not be
1262
 *   freed, the caller should take care of them)
1263
 * returns: hostent struct & *port filled with the port from the SRV record;
1264
 *  0 on error
1265
 */
1266
struct hostent *srv_sip_resolvehost(str *name, int zt, unsigned short *port,
1267
    char *proto, int is_srv, struct rdata *ars)
1268
0
{
1269
0
  struct hostent *he;
1270
0
  struct ip_addr *ip;
1271
0
  static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups and
1272
                                    null. term  strings */
1273
0
  struct rdata *l;
1274
0
  struct srv_rdata *srv;
1275
0
  struct rdata *srv_head;
1276
0
  char *srv_target;
1277
0
  char srv_proto;
1278
1279
  /* init */
1280
0
  srv_head = 0;
1281
0
  srv_target = 0;
1282
0
  if(name->len >= MAX_DNS_NAME) {
1283
0
    LM_ERR("domain name too long\n");
1284
0
    he = 0;
1285
0
    goto end;
1286
0
  }
1287
0
  LM_DBG("%.*s:%d proto=%d\n", name->len, name->s, port ? (int)*port : -1,
1288
0
      proto ? (int)*proto : -1);
1289
0
  if(is_srv) {
1290
    /* skip directly to srv resolving */
1291
0
    srv_proto = (proto) ? *proto : 0;
1292
0
    if(port)
1293
0
      *port = (srv_proto == PROTO_TLS) ? SIPS_PORT : SIP_PORT;
1294
0
    if(zt) {
1295
0
      srv_target = name->s; /* name.s must be 0 terminated in
1296
                  this case */
1297
0
    } else {
1298
0
      memcpy(tmp, name->s, name->len);
1299
0
      tmp[name->len] = '\0';
1300
0
      srv_target = tmp;
1301
0
    }
1302
0
    goto do_srv; /* skip to the actual srv query */
1303
0
  }
1304
0
  if(proto) { /* makes sure we have a protocol set*/
1305
0
    if(*proto == 0)
1306
0
      *proto = srv_proto = PROTO_UDP; /* default */
1307
0
    else
1308
0
      srv_proto = *proto;
1309
0
  } else {
1310
0
    srv_proto = PROTO_UDP;
1311
0
  }
1312
  /* try SRV if no port specified (draft-ietf-sip-srv-06) */
1313
0
  if((port) && (*port == 0)) {
1314
0
    *port = (srv_proto == PROTO_TLS) ? SIPS_PORT
1315
0
                     : SIP_PORT; /* just in case we
1316
                              don't find another */
1317
    /* check if it's an ip address */
1318
0
    if(((ip = str2ip(name)) != 0) || ((ip = str2ip6(name)) != 0)) {
1319
      /* we are lucky, this is an ip address */
1320
0
      he = ip_addr2he(name, ip);
1321
0
      goto end;
1322
0
    }
1323
0
    if((name->len + SRV_MAX_PREFIX_LEN + 1) > MAX_DNS_NAME) {
1324
0
      LM_WARN("domain name too long (%d), unable to perform SRV lookup\n",
1325
0
          name->len);
1326
0
    } else {
1327
1328
0
      switch(srv_proto) {
1329
0
        case PROTO_UDP:
1330
0
        case PROTO_TCP:
1331
0
        case PROTO_TLS:
1332
0
        case PROTO_SCTP:
1333
0
          create_srv_name(srv_proto, name, tmp);
1334
0
          break;
1335
0
        default:
1336
0
          LM_CRIT("unknown proto %d\n", srv_proto);
1337
0
          he = 0;
1338
0
          goto end;
1339
0
      }
1340
0
      srv_target = tmp;
1341
0
    do_srv:
1342
      /* try to find the SRV records inside previous ARs  first*/
1343
0
      for(l = ars; l; l = l->next) {
1344
0
        if(l->type != T_SRV)
1345
0
          continue;
1346
0
        srv = (struct srv_rdata *)l->rdata;
1347
0
        if(srv == 0) {
1348
0
          LM_CRIT("null rdata\n");
1349
          /* cleanup on exit only */
1350
0
          break;
1351
0
        }
1352
0
        he = resolvehost(srv->name);
1353
0
        if(he != 0) {
1354
          /* we found it*/
1355
0
          LM_DBG("found SRV(%s) = %s:%d in AR\n", srv_target,
1356
0
              srv->name, srv->port);
1357
0
          if(port)
1358
0
            *port = srv->port;
1359
          /* cleanup on exit */
1360
0
          goto end;
1361
0
        }
1362
0
      }
1363
0
      srv_head = get_record(srv_target, T_SRV, RES_ONLY_TYPE);
1364
0
      for(l = srv_head; l; l = l->next) {
1365
0
        if(l->type != T_SRV)
1366
0
          continue; /*should never happen*/
1367
0
        srv = (struct srv_rdata *)l->rdata;
1368
0
        if(srv == 0) {
1369
0
          LM_CRIT("null rdata\n");
1370
          /* cleanup on exit only */
1371
0
          break;
1372
0
        }
1373
0
        he = resolvehost(srv->name);
1374
0
        if(he != 0) {
1375
          /* we found it*/
1376
0
          LM_DBG("SRV(%s) = %s:%d\n", srv_target, srv->name,
1377
0
              srv->port);
1378
0
          if(port)
1379
0
            *port = srv->port;
1380
          /* cleanup on exit */
1381
0
          goto end;
1382
0
        }
1383
0
      }
1384
0
      if(is_srv) {
1385
        /* if the name was already into SRV format it doesn't make
1386
         * any sense to fall back to A/AAAA */
1387
0
        he = 0;
1388
0
        goto end;
1389
0
      }
1390
      /* cleanup on exit */
1391
0
      LM_DBG("no SRV record found for %.*s,"
1392
0
           " trying 'normal' lookup...\n",
1393
0
          name->len, name->s);
1394
0
    }
1395
0
  }
1396
0
  if(likely(!zt)) {
1397
0
    memcpy(tmp, name->s, name->len);
1398
0
    tmp[name->len] = '\0';
1399
0
    he = resolvehost(tmp);
1400
0
  } else {
1401
0
    he = resolvehost(name->s);
1402
0
  }
1403
0
end:
1404
0
  LM_DBG("returning %p (%.*s:%d proto=%d)\n", he, name->len, name->s,
1405
0
      port ? (int)*port : -1, proto ? (int)*proto : -1);
1406
0
  if(srv_head)
1407
0
    free_rdata_list(srv_head);
1408
0
  return he;
1409
0
}
1410
1411
1412
#ifdef USE_NAPTR
1413
1414
1415
/** iterates over a naptr rr list, returning each time a "good" naptr record
1416
 * is found.( srv type, no regex and a supported protocol)
1417
 * params:
1418
 *         naptr_head - naptr rr list head
1419
 *         tried      - bitmap used to keep track of the already tried records
1420
 *                      (no more than sizeof(tried)*8 valid records are
1421
 *                      ever walked
1422
 *         srv_name   - if successful, it will be set to the selected record
1423
 *                      srv name (naptr repl.)
1424
 *         proto      - if successful it will be set to the selected record
1425
 *                      protocol
1426
 * returns  0 if no more records found or a pointer to the selected record
1427
 *  and sets  protocol and srv_name
1428
 * WARNING: when calling first time make sure you run first
1429
 *           naptr_iterate_init(&tried)
1430
 */
1431
struct rdata *naptr_sip_iterate(struct rdata *naptr_head, naptr_bmp_t *tried,
1432
    str *srv_name, char *proto)
1433
0
{
1434
0
  int i, idx;
1435
0
  struct rdata *l;
1436
0
  struct rdata *l_saved;
1437
0
  struct naptr_rdata *naptr;
1438
0
  struct naptr_rdata *naptr_saved;
1439
0
  char saved_proto;
1440
0
  char naptr_proto;
1441
1442
0
  idx = 0;
1443
0
  naptr_proto = PROTO_NONE;
1444
0
  naptr_saved = 0;
1445
0
  l_saved = 0;
1446
0
  saved_proto = 0;
1447
0
  i = 0;
1448
0
  for(l = naptr_head; l && (i < MAX_NAPTR_RRS); l = l->next) {
1449
0
    if(l->type != T_NAPTR)
1450
0
      continue;
1451
0
    naptr = (struct naptr_rdata *)l->rdata;
1452
0
    if(naptr == 0) {
1453
0
      LM_CRIT("null rdata\n");
1454
0
      goto end;
1455
0
    }
1456
    /* check if valid and get proto */
1457
0
    if((naptr_proto = naptr_get_sip_proto(naptr)) <= 0)
1458
0
      continue;
1459
0
    if(*tried & (1 << i)) {
1460
0
      i++;
1461
0
      continue; /* already tried */
1462
0
    }
1463
0
    LM_DBG("found a valid sip NAPTR rr %.*s, proto %d\n", naptr->repl_len,
1464
0
        naptr->repl, (int)naptr_proto);
1465
0
    if((naptr_proto_supported(naptr_proto))) {
1466
0
      if(naptr_choose(&naptr_saved, &saved_proto, naptr, naptr_proto)) {
1467
0
        idx = i;
1468
0
        l_saved = l;
1469
0
      }
1470
0
    }
1471
0
    i++;
1472
0
  }
1473
0
  if(naptr_saved) {
1474
    /* found something */
1475
0
    LM_DBG("choosed NAPTR rr %.*s, proto %d tried: 0x%x\n",
1476
0
        naptr_saved->repl_len, naptr_saved->repl, (int)saved_proto,
1477
0
        *tried);
1478
0
    *tried |= 1 << idx;
1479
0
    *proto = saved_proto;
1480
0
    srv_name->s = naptr_saved->repl;
1481
0
    srv_name->len = naptr_saved->repl_len;
1482
0
    return l_saved;
1483
0
  }
1484
0
end:
1485
0
  return 0;
1486
0
}
1487
1488
/** Prepend srv prefix according to the proto. */
1489
void create_srv_name(char proto, str *name, char *srv)
1490
0
{
1491
0
  switch(proto) {
1492
0
    case PROTO_UDP:
1493
0
      memcpy(srv, SRV_UDP_PREFIX, SRV_UDP_PREFIX_LEN);
1494
0
      memcpy(srv + SRV_UDP_PREFIX_LEN, name->s, name->len);
1495
0
      srv[SRV_UDP_PREFIX_LEN + name->len] = '\0';
1496
0
      break;
1497
0
    case PROTO_TCP:
1498
0
      memcpy(srv, SRV_TCP_PREFIX, SRV_TCP_PREFIX_LEN);
1499
0
      memcpy(srv + SRV_TCP_PREFIX_LEN, name->s, name->len);
1500
0
      srv[SRV_TCP_PREFIX_LEN + name->len] = '\0';
1501
0
      break;
1502
0
    case PROTO_TLS:
1503
0
      memcpy(srv, SRV_TLS_PREFIX, SRV_TLS_PREFIX_LEN);
1504
0
      memcpy(srv + SRV_TLS_PREFIX_LEN, name->s, name->len);
1505
0
      srv[SRV_TLS_PREFIX_LEN + name->len] = '\0';
1506
0
      break;
1507
0
    case PROTO_SCTP:
1508
0
      memcpy(srv, SRV_SCTP_PREFIX, SRV_SCTP_PREFIX_LEN);
1509
0
      memcpy(srv + SRV_SCTP_PREFIX_LEN, name->s, name->len);
1510
0
      srv[SRV_SCTP_PREFIX_LEN + name->len] = '\0';
1511
0
      break;
1512
0
    default:
1513
0
      LM_CRIT("%s: unknown proto %d\n", __func__, proto);
1514
0
  }
1515
0
}
1516
1517
size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list)
1518
0
{
1519
0
  struct dns_srv_proto tmp;
1520
0
  size_t i, j, list_len;
1521
0
  int default_order = 1, max;
1522
1523
  /* if proto available, then add only the forced protocol to the list */
1524
0
  if(proto && *proto != PROTO_NONE) {
1525
0
    list[0].proto = *proto;
1526
0
    list_len = 1;
1527
0
  } else {
1528
0
    list_len = 0;
1529
    /*get protocols and preference scores, and add available protocol(s) and score(s) to the list*/
1530
0
    for(i = PROTO_UDP; i < PROTO_LAST; i++) {
1531
0
      tmp.proto_pref = srv_proto_pref_score(i);
1532
      /* if -1 so disabled continue with next protocol*/
1533
0
      if(naptr_proto_supported(i) == 0) {
1534
0
        continue;
1535
0
      } else {
1536
0
        list[list_len].proto_pref = tmp.proto_pref;
1537
0
        list[list_len].proto = i;
1538
0
        list_len++;
1539
0
      }
1540
0
    };
1541
1542
    /* if all protocol preference scores equal, then set the preference to default values: udp,tcp,tls,sctp */
1543
0
    for(i = 1; i < list_len; i++) {
1544
0
      if(list[0].proto_pref != list[i].proto_pref) {
1545
0
        default_order = 0;
1546
0
      }
1547
0
    }
1548
0
    if(default_order) {
1549
0
      for(i = 0; i < list_len; i++) {
1550
0
        list[i].proto_pref = srv_proto_pref_score(i);
1551
0
      }
1552
0
    }
1553
1554
    /* sorting the list */
1555
0
    for(i = 0; i < list_len - 1; i++) {
1556
0
      max = i;
1557
0
      for(j = i + 1; j < list_len; j++) {
1558
0
        if(list[j].proto_pref > list[max].proto_pref) {
1559
0
          max = j;
1560
0
        }
1561
0
      }
1562
0
      if(i != max) {
1563
0
        tmp = list[i];
1564
0
        list[i] = list[max];
1565
0
        list[max] = tmp;
1566
0
      }
1567
0
    }
1568
0
  }
1569
0
  return list_len;
1570
0
}
1571
1572
/** Resolves SRV if no naptr found.
1573
 * It reuse dns_pref values and according that resolves supported protocols.
1574
 * If dns_pref are equal then it use udp,tcp,tls,sctp order.
1575
 * returns: hostent struct & *port filled with the port from the SRV record;
1576
 *  0 on error
1577
 */
1578
struct hostent *no_naptr_srv_sip_resolvehost(
1579
    str *name, unsigned short *port, char *proto)
1580
0
{
1581
0
  struct dns_srv_proto srv_proto_list[PROTO_LAST];
1582
0
  struct hostent *he;
1583
0
  struct ip_addr *ip;
1584
0
  str srv_name;
1585
0
  static char tmp_srv[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups */
1586
0
  size_t i, list_len;
1587
  /* init variables */
1588
0
  he = 0;
1589
1590
  /* check if it's an ip address */
1591
0
  if(((ip = str2ip(name)) != 0) || ((ip = str2ip6(name)) != 0)) {
1592
    /* we are lucky, this is an ip address */
1593
    /* set proto if needed - default udp */
1594
0
    if((proto) && (*proto == PROTO_NONE))
1595
0
      *proto = PROTO_UDP;
1596
    /* set port if needed - default 5060/5061 */
1597
0
    if((port) && (*port == 0))
1598
0
      *port = ((proto) && (*proto == PROTO_TLS)) ? SIPS_PORT : SIP_PORT;
1599
0
    he = ip_addr2he(name, ip);
1600
0
    return he;
1601
0
  }
1602
1603
0
  if((name->len + SRV_MAX_PREFIX_LEN + 1) > MAX_DNS_NAME) {
1604
0
    LM_WARN("domain name too long (%d), unable to perform SRV lookup\n",
1605
0
        name->len);
1606
0
  } else {
1607
    /* looping on the ordered list until we found a protocol what has srv record */
1608
0
    list_len = create_srv_pref_list(proto, srv_proto_list);
1609
0
    for(i = 0; i < list_len; i++) {
1610
0
      switch(srv_proto_list[i].proto) {
1611
0
        case PROTO_UDP:
1612
0
        case PROTO_TCP:
1613
0
        case PROTO_TLS:
1614
0
        case PROTO_SCTP:
1615
0
          create_srv_name(srv_proto_list[i].proto, name, tmp_srv);
1616
0
          break;
1617
0
        default:
1618
0
          LM_CRIT("unknown proto %d\n", (int)srv_proto_list[i].proto);
1619
0
          return 0;
1620
0
      }
1621
      /* set default port */
1622
0
      if((port) && (*port == 0)) {
1623
0
        *port = (srv_proto_list[i].proto == PROTO_TLS)
1624
0
                ? SIPS_PORT
1625
0
                : SIP_PORT; /* just in case we don't find another */
1626
0
      }
1627
0
      if((proto) && (*proto == 0)) {
1628
0
        *proto = PROTO_UDP;
1629
0
      }
1630
0
      srv_name.s = tmp_srv;
1631
0
      srv_name.len = strlen(tmp_srv);
1632
0
#ifdef USE_DNS_CACHE
1633
0
      if(dns_cache_init) {
1634
0
        he = dns_srv_get_he(&srv_name, port, dns_flags);
1635
0
      } else {
1636
0
        he = srv_sip_resolvehost(&srv_name, 0, port, proto, 1, 0);
1637
0
      }
1638
#else
1639
      he = srv_sip_resolvehost(&srv_name, 0, port, proto, 1, 0);
1640
#endif
1641
0
      if(he != 0) {
1642
0
        if(proto)
1643
0
          *proto = srv_proto_list[i].proto;
1644
0
        return he;
1645
0
      }
1646
0
    }
1647
0
  }
1648
0
  return 0;
1649
0
}
1650
1651
/** internal sip naptr resolver function: resolves a host name trying:
1652
 * - NAPTR lookup if the address is not an ip and *proto==0 and *port==0.
1653
 *   The result of the NAPTR query will be used for a SRV lookup
1654
 * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1655
 *   query will be used for an A/AAAA lookup.
1656
 *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1657
 *   and *proto!=0 or port==0 && proto==0)
1658
 * when performing SRV lookup (*port==0) it will use proto to look for
1659
 * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1660
 * returns: hostent struct & *port filled with the port from the SRV record;
1661
 *  0 on error
1662
 */
1663
struct hostent *naptr_sip_resolvehost(
1664
    str *name, unsigned short *port, char *proto)
1665
0
{
1666
0
  struct hostent *he;
1667
0
  struct ip_addr *ip;
1668
0
  static char tmp[MAX_DNS_NAME]; /* tmp. buff. for SRV lookups and
1669
                                    null. term  strings */
1670
0
  struct rdata *l;
1671
0
  struct rdata *naptr_head;
1672
0
  char n_proto;
1673
0
  str srv_name;
1674
0
  str *name_copy = 0;
1675
0
  naptr_bmp_t tried_bmp; /* tried bitmap */
1676
0
  char origproto = PROTO_NONE;
1677
1678
0
  if(proto)
1679
0
    origproto = *proto;
1680
0
  naptr_head = 0;
1681
0
  he = 0;
1682
0
  if(name->len >= MAX_DNS_NAME) {
1683
0
    LM_ERR("domain name too long\n");
1684
0
    goto end;
1685
0
  }
1686
  /* try NAPTR if no port or protocol is specified and NAPTR lookup is
1687
   * enabled */
1688
0
  if(port && proto && (*proto == 0) && (*port == 0)) {
1689
0
    *proto = PROTO_UDP; /* just in case we don't find another */
1690
0
    if(((ip = str2ip(name)) != 0) || ((ip = str2ip6(name)) != 0)) {
1691
      /* we are lucky, this is an ip address */
1692
0
      he = ip_addr2he(name, ip);
1693
0
      *port = SIP_PORT;
1694
0
      goto end;
1695
0
    }
1696
0
    memcpy(tmp, name->s, name->len);
1697
0
    tmp[name->len] = '\0';
1698
0
    naptr_head = get_record(tmp, T_NAPTR, RES_AR);
1699
0
    naptr_iterate_init(&tried_bmp);
1700
0
    while((l = naptr_sip_iterate(
1701
0
             naptr_head, &tried_bmp, &srv_name, &n_proto))
1702
0
        != 0) {
1703
0
      if((he = srv_sip_resolvehost(&srv_name, 1, port, proto, 1, l))
1704
0
          != 0) {
1705
0
        *proto = n_proto;
1706
0
        return he;
1707
0
      }
1708
0
    }
1709
    /*clean up on exit*/
1710
0
    LM_DBG("no NAPTR record found for %.*s, trying SRV lookup...\n",
1711
0
        name->len, name->s);
1712
0
  }
1713
  /* fallback to srv lookup */
1714
0
  if(proto)
1715
0
    *proto = origproto;
1716
0
  he = no_naptr_srv_sip_resolvehost(name, port, proto);
1717
  /* fallback all the way down to A/AAAA */
1718
0
  if(he == 0) {
1719
0
    if(dns_cache_init) {
1720
0
      he = dns_get_he(name, dns_flags);
1721
0
    } else {
1722
      /* We need a zero terminated char* */
1723
0
      name_copy = shm_malloc(name->len + 1);
1724
0
      shm_str_dup(name_copy, name);
1725
0
      he = resolvehost(name_copy->s);
1726
0
      shm_free(name_copy);
1727
0
    }
1728
0
  }
1729
0
end:
1730
0
  if(naptr_head)
1731
0
    free_rdata_list(naptr_head);
1732
0
  return he;
1733
0
}
1734
#endif /* USE_NAPTR */
1735
1736
1737
/** resolves a host name trying:
1738
 * - NAPTR lookup if enabled, the address is not an ip and *proto==0 and
1739
 *   *port==0. The result of the NAPTR query will be used for a SRV lookup
1740
 * - SRV lookup if the address is not an ip *port==0. The result of the SRV
1741
 *   query will be used for an A/AAAA lookup.
1742
 *  - normal A/AAAA lookup (either fallback from the above or if *port!=0
1743
 *   and *proto!=0 or port==0 && proto==0)
1744
 * when performing SRV lookup (*port==0) it will use *proto to look for
1745
 * tcp or udp hosts, otherwise proto is unused; if proto==0 => no SRV lookup
1746
 *
1747
 * returns: hostent struct & *port filled with the port from the SRV record;
1748
 *  0 on error
1749
 */
1750
struct hostent *_sip_resolvehost(str *name, unsigned short *port, char *proto)
1751
0
{
1752
0
  struct hostent *res = NULL;
1753
0
#ifdef USE_NAPTR
1754
0
  if(cfg_get(core, core_cfg, dns_try_naptr))
1755
0
    res = naptr_sip_resolvehost(name, port, proto);
1756
0
  else
1757
0
#endif
1758
0
    res = srv_sip_resolvehost(name, 0, port, proto, 0, 0);
1759
0
  if(unlikely(!res)) {
1760
    /* failed DNS request */
1761
0
    counter_inc(dns_cnts_h.failed_dns_req);
1762
0
  }
1763
0
  return res;
1764
0
}
1765
1766
1767
/** resolve host, port, proto using sip rules (e.g. use SRV if port=0 a.s.o)
1768
 *  and write the result in the sockaddr_union to
1769
 *  returns -1 on error (resolve failed), 0 on success */
1770
int sip_hostport2su(
1771
    union sockaddr_union *su, str *name, unsigned short port, char *proto)
1772
0
{
1773
0
  struct hostent *he;
1774
1775
0
  he = sip_resolvehost(name, &port, proto);
1776
0
  if(he == 0) {
1777
0
    ser_error = E_BAD_ADDRESS;
1778
0
    LM_ERR("could not resolve hostname: \"%.*s\"\n", name->len, name->s);
1779
0
    goto error;
1780
0
  }
1781
  /* port filled by sip_resolvehost if empty*/
1782
0
  if(hostent2su(su, he, 0, port) < 0) {
1783
0
    ser_error = E_BAD_ADDRESS;
1784
0
    goto error;
1785
0
  }
1786
0
  return 0;
1787
0
error:
1788
0
  return -1;
1789
0
}
1790
1791
/* converts a str to an ipv4 address struct stored in ipb
1792
 * - ipb must be already allocated
1793
 * - return 0 on success; <0 on failure */
1794
int str2ipbuf(str *st, ip_addr_t *ipb)
1795
0
{
1796
0
  int i;
1797
0
  unsigned char *limit;
1798
0
  unsigned char *s;
1799
1800
  /* just in case that e.g. the VIA parser get confused */
1801
0
  if(unlikely(!st->s || st->len <= 0)) {
1802
0
    LM_ERR("invalid name (%p,%d), no conversion to IP address possible\n",
1803
0
        st->s, st->len);
1804
0
    return -1;
1805
0
  }
1806
0
  s = (unsigned char *)st->s;
1807
1808
  /*init*/
1809
0
  ipb->u.addr32[0] = 0;
1810
0
  i = 0;
1811
0
  limit = (unsigned char *)(st->s + st->len);
1812
1813
0
  for(; s < limit; s++) {
1814
0
    if(*s == '.') {
1815
0
      i++;
1816
0
      if(i > 3)
1817
0
        goto error_dots;
1818
0
    } else if((*s <= '9') && (*s >= '0')) {
1819
0
      ipb->u.addr[i] = ipb->u.addr[i] * 10 + *s - '0';
1820
0
    } else {
1821
      //error unknown char
1822
0
      goto error_char;
1823
0
    }
1824
0
  }
1825
0
  if(i < 3)
1826
0
    goto error_dots;
1827
0
  ipb->af = AF_INET;
1828
0
  ipb->len = 4;
1829
1830
0
  return 0;
1831
1832
0
error_dots:
1833
0
  DBG("error - too %s dots in [%.*s]\n", (i > 3) ? "many" : "few", st->len,
1834
0
      st->s);
1835
0
  return -1;
1836
0
error_char:
1837
  /*
1838
  DBG("warning - unexpected char %c in [%.*s]\n", *s, st->len, st->s);
1839
  */
1840
0
  return -2;
1841
0
}
1842
1843
/* converts a str to an ipv4 address, returns the address or 0 on error
1844
   Warning: the result is a pointer to a statically allocated structure */
1845
ip_addr_t *str2ip(str *st)
1846
0
{
1847
0
  ip_addr_t *ipb;
1848
1849
0
  ipb = get_next_ipaddr_buf();
1850
0
  if(str2ipbuf(st, ipb) < 0) {
1851
0
    return NULL;
1852
0
  }
1853
1854
0
  return ipb;
1855
0
}
1856
1857
/*
1858
* Resolve a host name to a hostent.
1859
* @param[in] name: the host name to resolve
1860
* @return the hostent structure or NULL on error
1861
*
1862
* @note
1863
* This function is a wrapper to choose between the DNS cache and the
1864
* system resolver. If the DNS cache is enabled, it will use the DNS cache
1865
* to resolve the host name. Otherwise, it will use the system resolver.
1866
*/
1867
struct hostent *__resolvehost(char *name)
1868
0
{
1869
0
#ifdef USE_DNS_CACHE
1870
0
  if(dns_cache_init) {
1871
0
    return dns_resolvehost(name);
1872
0
  } else {
1873
0
#endif
1874
0
    return _resolvehost(name);
1875
0
#ifdef USE_DNS_CACHE
1876
0
  }
1877
0
#endif
1878
0
}
1879
1880
/*
1881
* Resolve a host name to a hostent.
1882
* @param[in] name: the host name to resolve
1883
* @param[in] port: the port number
1884
* @param[in] proto: the protocol
1885
* @return the hostent structure or NULL on error
1886
*
1887
* @note
1888
* This function is a wrapper to choose between the DNS cache and the
1889
* system resolver. If the DNS cache is enabled, it will use the DNS cache
1890
* to resolve the host name. Otherwise, it will use the system resolver.
1891
*/
1892
struct hostent *__sip_resolvehost(str *name, unsigned short *port, char *proto)
1893
0
{
1894
0
#ifdef USE_DNS_CACHE
1895
0
  if(dns_cache_init) {
1896
0
    return dns_sip_resolvehost(name, port, proto);
1897
0
  } else {
1898
0
#endif
1899
0
    return _sip_resolvehost(name, port, proto);
1900
0
#ifdef USE_DNS_CACHE
1901
0
  }
1902
0
#endif
1903
0
}
1904
/* converts a str to an ipv6 address struct stored in ipb
1905
 * - ipb must be already allocated
1906
 * - return 0 on success; <0 on failure */
1907
int str2ip6buf(str *st, ip_addr_t *ipb)
1908
0
{
1909
0
  int i, idx1, rest;
1910
0
  int no_colons;
1911
0
  int double_colon;
1912
0
  int hex;
1913
0
  unsigned short *addr_start;
1914
0
  unsigned short addr_end[8];
1915
0
  unsigned short *addr;
1916
0
  unsigned char *limit;
1917
0
  unsigned char *s;
1918
1919
  /* just in case that e.g. the VIA parser get confused */
1920
0
  if(unlikely(!st->s || st->len <= 0)) {
1921
0
    LM_ERR("invalid name (%p,%d), no conversion to IP address possible\n",
1922
0
        st->s, st->len);
1923
0
    return -1;
1924
0
  }
1925
  /* init */
1926
0
  if((st->len) && (st->s[0] == '[')) {
1927
    /* skip over [ ] */
1928
0
    if(st->s[st->len - 1] != ']')
1929
0
      goto error_char;
1930
0
    s = (unsigned char *)(st->s + 1);
1931
0
    limit = (unsigned char *)(st->s + st->len - 1);
1932
0
  } else {
1933
0
    s = (unsigned char *)st->s;
1934
0
    limit = (unsigned char *)(st->s + st->len);
1935
0
  }
1936
0
  i = idx1 = rest = 0;
1937
0
  double_colon = 0;
1938
0
  no_colons = 0;
1939
0
  ipb->af = AF_INET6;
1940
0
  ipb->len = 16;
1941
0
  addr_start = ipb->u.addr16;
1942
0
  addr = addr_start;
1943
0
  memset(addr_start, 0, 8 * sizeof(unsigned short));
1944
0
  memset(addr_end, 0, 8 * sizeof(unsigned short));
1945
0
  for(; s < limit; s++) {
1946
0
    if(*s == ':') {
1947
0
      no_colons++;
1948
0
      if(no_colons > 7)
1949
0
        goto error_too_many_colons;
1950
0
      if(double_colon) {
1951
0
        idx1 = i;
1952
0
        i = 0;
1953
0
        if(addr == addr_end)
1954
0
          goto error_colons;
1955
0
        addr = addr_end;
1956
0
      } else {
1957
0
        double_colon = 1;
1958
0
        addr[i] = htons(addr[i]);
1959
0
        i++;
1960
0
      }
1961
0
    } else if((hex = HEX2I(*s)) >= 0) {
1962
0
      addr[i] = addr[i] * 16 + hex;
1963
0
      double_colon = 0;
1964
0
    } else {
1965
      /* error, unknown char */
1966
0
      goto error_char;
1967
0
    }
1968
0
  }
1969
0
  if(!double_colon) { /* not ending in ':' */
1970
0
    addr[i] = htons(addr[i]);
1971
0
    i++;
1972
0
  }
1973
  /* if address contained '::' fix it */
1974
0
  if(addr == addr_end) {
1975
0
    rest = 8 - i - idx1;
1976
0
    memcpy(addr_start + idx1 + rest, addr_end, i * sizeof(unsigned short));
1977
0
  } else {
1978
    /* no double colons inside */
1979
0
    if(no_colons < 7)
1980
0
      goto error_too_few_colons;
1981
0
  }
1982
  /*
1983
  DBG("idx1=%d, rest=%d, no_colons=%d, hex=%x\n",
1984
      idx1, rest, no_colons, hex);
1985
  DBG("address %x:%x:%x:%x:%x:%x:%x:%x\n",
1986
      addr_start[0], addr_start[1], addr_start[2],
1987
      addr_start[3], addr_start[4], addr_start[5],
1988
      addr_start[6], addr_start[7] );
1989
*/
1990
0
  return 0;
1991
1992
0
error_too_many_colons:
1993
0
  DBG("error - too many colons in [%.*s]\n", st->len, st->s);
1994
0
  return -1;
1995
1996
0
error_too_few_colons:
1997
0
  DBG("error - too few colons in [%.*s]\n", st->len, st->s);
1998
0
  return -2;
1999
2000
0
error_colons:
2001
0
  DBG("error - too many double colons in [%.*s]\n", st->len, st->s);
2002
0
  return -3;
2003
2004
0
error_char:
2005
  /*
2006
  DBG("warning - unexpected char %c in  [%.*s]\n", *s, st->len,
2007
      st->s);*/
2008
0
  return -4;
2009
0
}
2010
2011
/* returns an ip_addr struct.; on error returns 0
2012
 * the ip_addr struct is static, so subsequent calls will destroy its content*/
2013
ip_addr_t *str2ip6(str *st)
2014
0
{
2015
0
  ip_addr_t *ipb;
2016
2017
0
  ipb = get_next_ipaddr_buf();
2018
0
  if(str2ip6buf(st, ipb) < 0) {
2019
0
    return NULL;
2020
0
  }
2021
2022
0
  return ipb;
2023
0
}
2024
2025
/* converts a str to an ipvv/6 address struct stored in ipb
2026
 * - ipb must be already allocated
2027
 * - return 0 on success; <0 on failure */
2028
int str2ipxbuf(str *st, ip_addr_t *ipb)
2029
0
{
2030
0
  if(str2ipbuf(st, ipb) < 0) {
2031
0
    if(str2ip6buf(st, ipb) < 0) {
2032
0
      return -1;
2033
0
    }
2034
0
  }
2035
2036
0
  return 0;
2037
0
}
2038
2039
/* returns an ip_addr struct converted from ipv4/6 str; on error returns 0
2040
 * the ip_addr struct is static, so subsequent calls will destroy its content*/
2041
struct ip_addr *str2ipx(str *st)
2042
0
{
2043
0
  ip_addr_t *ipb;
2044
2045
0
  ipb = get_next_ipaddr_buf();
2046
0
  if(str2ipbuf(st, ipb) < 0) {
2047
0
    if(str2ip6buf(st, ipb) < 0) {
2048
0
      return NULL;
2049
0
    }
2050
0
  }
2051
2052
0
  return ipb;
2053
0
}