Coverage Report

Created: 2025-06-09 06:27

/src/kamailio/src/core/resolve.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * resolver related functions
3
 *
4
 * Copyright (C) 2001-2003 FhG Fokus
5
 *
6
 * This file is part of Kamailio, a free SIP server.
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 *
10
 * Kamailio is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version
14
 *
15
 * Kamailio is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23
 */
24
25
/*!
26
 * \file
27
 * \brief Kamailio core :: DNS resolver
28
 * \author andrei
29
 * \ingroup core
30
 * Module: \ref core
31
 */
32
33
#ifndef __resolve_h
34
#define __resolve_h
35
36
#include <sys/types.h>
37
#include <sys/socket.h>
38
#include <netinet/in.h>
39
#include <netdb.h>
40
#include <arpa/nameser.h>
41
#include <resolv.h>
42
#include "counters.h"
43
#include "dns_func.h"
44
45
#ifdef __OS_darwin
46
#include <arpa/nameser_compat.h>
47
#endif
48
49
#include "ip_addr.h"
50
#ifdef USE_DNS_CACHE
51
#include "dns_wrappers.h"
52
#endif
53
54
55
#define MAX_QUERY_SIZE 8192
56
#define ANS_SIZE 8192
57
0
#define DNS_HDR_SIZE 12
58
0
#define MAX_DNS_NAME 256
59
#define MAX_DNS_STRING 255
60
61
#ifndef T_EBL
62
/** not official yet - iEnum. */
63
0
#define T_EBL 65300
64
#endif
65
66
/* get_record flags */
67
0
#define RES_ONLY_TYPE 1 /* return only the specified type records */
68
0
#define RES_AR 2    /* return also the additional records */
69
70
/* counter for failed/slow DNS requests
71
*/
72
struct dns_counters_h
73
{
74
  counter_handle_t failed_dns_req;
75
  counter_handle_t slow_dns_req;
76
};
77
78
extern struct dns_counters_h dns_cnts_h;
79
extern struct dns_func_t dns_func;
80
81
/* query union*/
82
union dns_query
83
{
84
  HEADER hdr;
85
  unsigned char buff[MAX_QUERY_SIZE];
86
};
87
88
89
/* rdata struct*/
90
struct rdata
91
{
92
  unsigned short type;
93
  unsigned short pclass;
94
  unsigned int ttl;
95
  void *rdata;
96
  struct rdata *next;
97
  unsigned char name_len; /* name length w/o the terminating 0 */
98
  char name[1];     /* null terminated name (len=name_len+1) */
99
};
100
/* real size of the structure */
101
#define RDATA_SIZE(s) (sizeof(struct rdata) + (s).name_len) /* +1-1 */
102
103
104
/* srv rec. struct*/
105
struct srv_rdata
106
{
107
  unsigned short priority;
108
  unsigned short weight;
109
  unsigned short port;
110
  unsigned char name_len; /* name length w/o the terminating 0 */
111
  char name[1];     /* null terminated name (len=name_len+1) */
112
};
113
114
115
/* real size of the structure */
116
0
#define SRV_RDATA_SIZE(s) (sizeof(struct srv_rdata) + (s).name_len)
117
118
/* naptr rec. struct*/
119
struct naptr_rdata
120
{
121
  char *flags;  /* points inside str_table */
122
  char *services; /* points inside str_table */
123
  char *regexp; /* points inside str_table */
124
  char *repl;   /* points inside str_table, null terminated */
125
126
  unsigned short order;
127
  unsigned short pref;
128
129
  unsigned char flags_len;
130
  unsigned char services_len;
131
  unsigned char regexp_len;
132
  unsigned char repl_len; /* not currently used */
133
  unsigned char skip_record;
134
135
  char str_table[1]; /* contains all the strings */
136
};
137
138
/* real size of the structure */
139
#define NAPTR_RDATA_SIZE(s)                                        \
140
0
  (sizeof(struct naptr_rdata) + (s).flags_len + (s).services_len \
141
0
      + (s).regexp_len + (s).repl_len + 1 - 1)
142
143
144
/* A rec. struct */
145
struct a_rdata
146
{
147
  unsigned char ip[4];
148
};
149
150
struct aaaa_rdata
151
{
152
  unsigned char ip6[16];
153
};
154
155
/* cname rec. struct*/
156
struct cname_rdata
157
{
158
  unsigned char name_len; /* name length w/o the terminating 0 */
159
  char name[1];     /* null terminated name (len=name_len+1) */
160
};
161
162
/* real size of the structure */
163
0
#define CNAME_RDATA_SIZE(s) (sizeof(struct cname_rdata) + (s).name_len)
164
165
/* dns character-string */
166
struct dns_cstr
167
{
168
  char *cstr; /* pointer to null term. string */
169
  unsigned char cstr_len;
170
};
171
172
/* txt rec. struct */
173
struct txt_rdata
174
{
175
  unsigned short cstr_no; /* number of strings */
176
  unsigned short tslen; /* total strings table len */
177
  struct dns_cstr txt[1]; /* at least 1 */
178
  /* all txt[*].cstr point inside a string table at the end of the struct.*/
179
};
180
181
#define TXT_RDATA_SIZE(s)                                                   \
182
0
  (sizeof(struct txt_rdata) + ((s).cstr_no - 1) * sizeof(struct dns_cstr) \
183
0
      + (s).tslen)
184
185
/* ebl rec. struct, see
186
   http://tools.ietf.org/html/draft-ietf-enum-branch-location-record-03 */
187
struct ebl_rdata
188
{
189
  char *separator;       /* points inside str_table */
190
  char *apex;          /* point inside str_table */
191
  unsigned char separator_len; /* separator len w/o the terminating 0 */
192
  unsigned char apex_len;    /* apex len w/p the terminating 0 */
193
  unsigned char position;
194
  char str_table[1]; /* contains the 2 strings: separator and apex */
195
};
196
#define EBL_RDATA_SIZE(s) \
197
0
  (sizeof(struct ebl_rdata) - 1 + (s).separator_len + 1 + (s).apex_len + 1)
198
199
200
struct ptr_rdata
201
{
202
  unsigned char ptrdname_len; /* name length w/o the terminating 0 */
203
  char ptrdname[1];     /* null terminated name (len=name_len+1) */
204
};
205
/* real size of the structure */
206
0
#define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata) - 1 + (s).ptrdname_len + 1)
207
208
209
#ifdef HAVE_RESOLV_RES
210
int match_search_list(const struct __res_state *res, char *name);
211
#endif
212
struct rdata *get_record(char *name, int type, int flags);
213
void free_rdata_list(struct rdata *head);
214
215
216
#define rev_resolvehost(ip) \
217
0
  gethostbyaddr((char *)(ip)->u.addr, (ip)->len, (ip)->af)
218
219
220
#define HEX2I(c)                                                \
221
0
  ((((c) >= '0') && ((c) <= '9'))      ? (c) - '0'        \
222
0
      : (((c) >= 'A') && ((c) <= 'F')) ? ((c) - 'A') + 10 \
223
0
      : (((c) >= 'a') && ((c) <= 'f')) ? ((c) - 'a') + 10 \
224
0
                       : -1)
225
226
227
int str2ipbuf(str *st, ip_addr_t *ipb);
228
int str2ip6buf(str *st, ip_addr_t *ipb);
229
int str2ipxbuf(str *st, ip_addr_t *ipb);
230
ip_addr_t *str2ip(str *st);
231
ip_addr_t *str2ip6(str *st);
232
ip_addr_t *str2ipx(str *st);
233
234
struct hostent *_sip_resolvehost(str *name, unsigned short *port, char *proto);
235
236
237
/* gethostbyname wrapper, handles ip/ipv6 automatically */
238
static inline struct hostent *_resolvehost(char *name)
239
0
{
240
0
  static struct hostent *he = 0;
241
#ifdef HAVE_GETIPNODEBYNAME
242
  int err;
243
  static struct hostent *he2 = 0;
244
#endif
245
#ifndef DNS_IP_HACK
246
  int len;
247
#endif
248
0
#ifdef DNS_IP_HACK
249
0
  struct ip_addr *ip;
250
0
  str s;
251
252
0
  s.s = (char *)name;
253
0
  s.len = strlen(name);
254
255
  /* check if it's an ip address */
256
0
  if(((ip = str2ip(&s)) != 0) || ((ip = str2ip6(&s)) != 0)) {
257
    /* we are lucky, this is an ip address */
258
0
    return ip_addr2he(&s, ip);
259
0
  }
260
261
#else /* DNS_IP_HACK */
262
  len = 0;
263
  if(*name == '[') {
264
    len = strlen(name);
265
    if(len && (name[len - 1] == ']')) {
266
      name[len - 1] = 0; /* remove '[' */
267
      name++;        /* skip '[' */
268
      goto skip_ipv4;
269
    }
270
  }
271
#endif
272
  /* ipv4 */
273
0
  he = dns_func.sr_gethostbyname(name);
274
275
0
  if(he == 0 && cfg_get(core, core_cfg, dns_try_ipv6)) {
276
#ifndef DNS_IP_HACK
277
  skip_ipv4:
278
#endif
279
    /*try ipv6*/
280
0
#ifdef HAVE_GETHOSTBYNAME2
281
0
    he = dns_func.sr_gethostbyname2(name, AF_INET6);
282
#elif defined HAVE_GETIPNODEBYNAME
283
    /* on solaris 8 getipnodebyname has a memory leak,
284
     * after some time calls to it will fail with err=3
285
     * solution: patch your solaris 8 installation */
286
    if(he2)
287
      freehostent(he2);
288
    he = he2 = getipnodebyname(name, AF_INET6, 0, &err);
289
#else
290
#error neither gethostbyname2 or getipnodebyname present
291
#endif
292
#ifndef DNS_IP_HACK
293
    if(len)
294
      name[len - 2] = ']'; /* restore */
295
#endif
296
0
  }
297
0
  return he;
298
0
}
Unexecuted instantiation: main.c:_resolvehost
Unexecuted instantiation: resolve.c:_resolvehost
Unexecuted instantiation: route.c:_resolvehost
Unexecuted instantiation: select_core.c:_resolvehost
Unexecuted instantiation: socket_info.c:_resolvehost
Unexecuted instantiation: action.c:_resolvehost
Unexecuted instantiation: cfg.tab.c:_resolvehost
Unexecuted instantiation: cfg_core.c:_resolvehost
Unexecuted instantiation: dns_cache.c:_resolvehost
Unexecuted instantiation: dst_blocklist.c:_resolvehost
Unexecuted instantiation: fmsg.c:_resolvehost
Unexecuted instantiation: forward.c:_resolvehost
Unexecuted instantiation: ip_addr.c:_resolvehost
Unexecuted instantiation: kemi.c:_resolvehost
Unexecuted instantiation: msg_translator.c:_resolvehost
Unexecuted instantiation: proxy.c:_resolvehost
299
300
301
int resolv_init(void);
302
303
/* callback/fixup functions executed by the configuration framework */
304
void resolv_reinit(str *gname, str *name);
305
int dns_reinit_fixup(void *handle, str *gname, str *name, void **val);
306
int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val);
307
void reinit_proto_prefs(str *gname, str *name);
308
309
struct dns_srv_proto
310
{
311
  char proto;
312
  int proto_pref;
313
};
314
void create_srv_name(char proto, str *name, char *srv);
315
size_t create_srv_pref_list(char *proto, struct dns_srv_proto *list);
316
317
#ifdef DNS_WATCHDOG_SUPPORT
318
/* callback function that is called by the child processes
319
 * when they reinitialize the resolver
320
 *
321
 * Note, that this callback is called by each chiled process separately!!!
322
 * If the callback is registered after forking, only the child process
323
 * that installs the hook will call the callback.
324
 */
325
typedef void (*on_resolv_reinit)(str *);
326
int register_resolv_reinit_cb(on_resolv_reinit cb);
327
#endif
328
329
330
int sip_hostport2su(
331
    union sockaddr_union *su, str *host, unsigned short port, char *proto);
332
333
334
/* Wrapper functions that check for dns_cache_init */
335
struct hostent *__resolvehost(char *name);
336
struct hostent *__sip_resolvehost(str *name, unsigned short *port, char *proto);
337
338
339
/* wrappers */
340
0
#define resolvehost __resolvehost
341
0
#define sip_resolvehost __sip_resolvehost
342
343
344
#ifdef USE_NAPTR
345
/* NAPTR helper functions */
346
typedef unsigned int naptr_bmp_t; /* type used for keeping track of tried
347
                   naptr records*/
348
0
#define MAX_NAPTR_RRS (sizeof(naptr_bmp_t) * 8)
349
350
/* use before first call to naptr_sip_iterate */
351
#define naptr_iterate_init(bmp) \
352
0
  do {                        \
353
0
    *(bmp) = 0;             \
354
0
  } while(0)
355
356
struct rdata *naptr_sip_iterate(struct rdata *naptr_head, naptr_bmp_t *tried,
357
    str *srv_name, char *proto);
358
/* returns sip proto if valis sip naptr record, .-1 otherwise */
359
char naptr_get_sip_proto(struct naptr_rdata *n);
360
/* returns true if new_proto is preferred over old_proto */
361
int naptr_proto_preferred(char new_proto, char old_proto);
362
/* returns true if we support the protocol */
363
int naptr_proto_supported(char proto);
364
/* choose between 2 naptr records, should take into account local
365
 * preferences too
366
 * returns 1 if the new record was selected, 0 otherwise */
367
int naptr_choose(struct naptr_rdata **crt, char *crt_proto,
368
    struct naptr_rdata *n, char n_proto);
369
370
#endif /* USE_NAPTR */
371
372
struct hostent *no_naptr_srv_sip_resolvehost(
373
    str *name, unsigned short *port, char *proto);
374
375
#endif