Coverage Report

Created: 2024-02-25 06:34

/src/kamailio/src/core/dns_cache.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * resolver/dns related functions, dns cache and failover
3
 *
4
 * Copyright (C) 2006 iptelorg GmbH
5
 *
6
 * This file is part of Kamailio, a free SIP server.
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
/**
25
 * @file
26
 * @brief Kamailio core :: resolver/dns related functions, dns cache and failover
27
 * @author andrei
28
 * @ingroup core
29
 * Module: @ref core
30
 */
31
32
33
#ifndef __dns_cache_h
34
#define __dns_cache_h
35
36
#include "str.h"
37
#include "config.h" /* MAX_BRANCHES */
38
#include "timer.h"
39
#include "ip_addr.h"
40
#include "atomic_ops.h"
41
#include "resolve.h"
42
43
44
#if defined(USE_DNS_FAILOVER) && !defined(USE_DNS_CACHE)
45
#error "DNS FAILOVER requires DNS CACHE support (define USE_DNS_CACHE)"
46
#endif
47
48
#if defined(DNS_WATCHDOG_SUPPORT) && !defined(USE_DNS_CACHE)
49
#error "DNS WATCHDOG requires DNS CACHE support (define USE_DNS_CACHE)"
50
#endif
51
52
#define DEFAULT_DNS_NEG_CACHE_TTL 60           /* 1 min. */
53
#define DEFAULT_DNS_CACHE_MIN_TTL 0            /* (disabled) */
54
#define DEFAULT_DNS_CACHE_MAX_TTL ((unsigned int)(-1)) /* (maxint) */
55
#define DEFAULT_DNS_MAX_MEM 500              /* 500 Kb */
56
57
/** @brief uncomment the define below for SRV weight based load balancing */
58
#define DNS_SRV_LB
59
60
61
/** @brief dns functions return them as negative values (e.g. return -E_DNS_NO_IP)
62
 *
63
 * listed in the order of importance ( if more errors, only the most important
64
 * is returned)
65
 */
66
enum dns_errors
67
{
68
  E_DNS_OK = 0,
69
  E_DNS_EOR, /**< no more records (not an error)
70
                        -- returned only by the dns_resolve*
71
                  functions when called iteratively,; it
72
                  signals the end of the ip/records list */
73
  E_DNS_UNKNOWN /**< unknown error */,
74
  E_DNS_INTERNAL_ERR /**< internal error */,
75
  E_DNS_BAD_SRV_ENTRY,
76
  E_DNS_NO_SRV /**< unresolvable srv record */,
77
  E_DNS_BAD_IP_ENTRY,
78
  E_DNS_NO_IP /**< unresolvable a or aaaa records*/,
79
  E_DNS_BAD_IP /**< the ip is invalid */,
80
  E_DNS_BLOCKLIST_IP /**< the ip is blocklisted */,
81
  E_DNS_NAME_TOO_LONG /**< try again with a shorter name */,
82
  E_DNS_AF_MISMATCH /**< ipv4 or ipv6 only requested, but
83
                     name contains an ip addr. of the
84
                     opossite type */
85
  ,
86
  E_DNS_NO_NAPTR /**< unresolvable naptr record */,
87
  E_DNS_CRITICAL /**< critical error, marks the end
88
                    of the error table (always last) */
89
};
90
91
92
/** @brief return a short string, printable error description (err <=0) */
93
const char *dns_strerror(int err);
94
95
/** @brief dns entry flags,
96
 * shall be on the power of 2 */
97
/*@{ */
98
0
#define DNS_FLAG_BAD_NAME 1 /**< error flag: unresolvable */
99
#define DNS_FLAG_PERMANENT \
100
0
  2 /**< permanent record, never times out,
101
          never deleted, never overwritten
102
          unless explicitely requested */
103
/*@} */
104
105
/** @name dns requests flags */
106
/*@{ */
107
#define DNS_NO_FLAGS 0
108
0
#define DNS_IPV4_ONLY 1
109
0
#define DNS_IPV6_ONLY 2
110
0
#define DNS_IPV6_FIRST 4
111
0
#define DNS_SRV_RR_LB 8   /**< SRV RR weight based load balancing */
112
0
#define DNS_TRY_NAPTR 16 /**< enable naptr lookup */
113
/*@} */
114
115
116
/** @name ip blocklist error flags */
117
/*@{ */
118
#define IP_ERR_BAD_DST 2 /* destination is marked as bad (e.g. bad ip) */
119
#define IP_ERR_SND 3   /* send error while using this as destination */
120
#define IP_ERR_TIMEOUT 4 /* timeout waiting for a response */
121
#define IP_ERR_TCP_CON 5 /* could not establish tcp connection */
122
/*@} */
123
124
125
/** @brief stripped down dns rr
126
  @note name, type and class are not needed, contained in struct dns_query */
127
struct dns_rr
128
{
129
  struct dns_rr *next;
130
  void *rdata;  /**< depends on the type */
131
  ticks_t expire; /**< = ttl + crt_time */
132
};
133
134
135
struct dns_lu_lst
136
{ /* last used ordered list */
137
  struct dns_lu_lst *next;
138
  struct dns_lu_lst *prev;
139
};
140
141
struct dns_hash_entry
142
{
143
  /* hash table links */
144
  struct dns_hash_entry *next;
145
  struct dns_hash_entry *prev;
146
  struct dns_lu_lst last_used_lst;
147
  struct dns_rr *rr_lst;
148
  atomic_t refcnt;
149
  ticks_t last_used;
150
  ticks_t expire; /* when the whole entry will expire */
151
  int total_size;
152
  unsigned short type;
153
  unsigned char ent_flags; /* entry flags: unresolvable/permanent */
154
  unsigned char name_len;  /* can be maximum 255 bytes */
155
  char name[1];      /* variable length, name, null terminated
156
                   (actual length = name_len +1)*/
157
};
158
159
160
/* to fit in the limit of MAX_BRANCHES */
161
#if MAX_BRANCHES_LIMIT < 32
162
typedef unsigned int srv_flags_t;
163
#else
164
typedef unsigned long long srv_flags_t;
165
#endif
166
167
struct dns_srv_handle
168
{
169
  struct dns_hash_entry *srv; /**< srv entry */
170
  struct dns_hash_entry *a; /**< a or aaaa current entry */
171
#ifdef DNS_SRV_LB
172
  srv_flags_t srv_tried_rrs;
173
#endif
174
  unsigned short port;  /**< current port */
175
  unsigned char srv_no; /**< current record no. in the srv entry */
176
  unsigned char ip_no;  /**< current record no. in the a/aaaa entry */
177
  unsigned char proto;  /**< protocol number */
178
};
179
180
181
const char *dns_strerror(int err);
182
183
void fix_dns_flags(str *gname, str *name);
184
int use_dns_failover_fixup(void *handle, str *gname, str *name, void **val);
185
int use_dns_cache_fixup(void *handle, str *gname, str *name, void **val);
186
int dns_cache_max_mem_fixup(void *handle, str *gname, str *name, void **val);
187
int init_dns_cache(void);
188
#ifdef USE_DNS_CACHE_STATS
189
int init_dns_cache_stats(int iproc_num);
190
#define DNS_CACHE_ALL_STATS "dc_all_stats"
191
#endif
192
void destroy_dns_cache(void);
193
194
195
void dns_hash_put(struct dns_hash_entry *e);
196
void dns_hash_put_shm_unsafe(struct dns_hash_entry *e);
197
198
inline static void dns_srv_handle_put(struct dns_srv_handle *h)
199
0
{
200
0
  if(h) {
201
0
    if(h->srv) {
202
0
      dns_hash_put(h->srv);
203
0
      h->srv = 0;
204
0
    }
205
0
    if(h->a) {
206
0
      dns_hash_put(h->a);
207
0
      h->a = 0;
208
0
    }
209
0
  }
210
0
}
Unexecuted instantiation: main.c:dns_srv_handle_put
Unexecuted instantiation: resolve.c:dns_srv_handle_put
Unexecuted instantiation: cfg_core.c:dns_srv_handle_put
Unexecuted instantiation: dns_cache.c:dns_srv_handle_put
Unexecuted instantiation: forward.c:dns_srv_handle_put
211
212
213
/** @brief use it when copying, it manually increases the ref cound */
214
inline static void dns_srv_handle_ref(struct dns_srv_handle *h)
215
0
{
216
0
  if(h) {
217
0
    if(h->srv)
218
0
      atomic_inc(&h->srv->refcnt);
219
0
    if(h->a)
220
0
      atomic_inc(&h->a->refcnt);
221
0
  }
222
0
}
Unexecuted instantiation: main.c:dns_srv_handle_ref
Unexecuted instantiation: resolve.c:dns_srv_handle_ref
Unexecuted instantiation: cfg_core.c:dns_srv_handle_ref
Unexecuted instantiation: dns_cache.c:dns_srv_handle_ref
Unexecuted instantiation: forward.c:dns_srv_handle_ref
223
224
225
/** @brief safe copy increases the refcnt, src must not change while in this function
226
 * WARNING: the copy must be dns_srv_handle_put ! */
227
inline static void dns_srv_handle_cpy(
228
    struct dns_srv_handle *dst, struct dns_srv_handle *src)
229
0
{
230
0
  dns_srv_handle_ref(src);
231
0
  *dst = *src;
232
0
}
Unexecuted instantiation: main.c:dns_srv_handle_cpy
Unexecuted instantiation: resolve.c:dns_srv_handle_cpy
Unexecuted instantiation: cfg_core.c:dns_srv_handle_cpy
Unexecuted instantiation: dns_cache.c:dns_srv_handle_cpy
Unexecuted instantiation: forward.c:dns_srv_handle_cpy
233
234
235
/** @brief same as above but assume shm_lock held (for internal tm use only) */
236
inline static void dns_srv_handle_put_shm_unsafe(struct dns_srv_handle *h)
237
0
{
238
0
  if(h) {
239
0
    if(h->srv) {
240
0
      dns_hash_put_shm_unsafe(h->srv);
241
0
      h->srv = 0;
242
0
    }
243
0
    if(h->a) {
244
0
      dns_hash_put_shm_unsafe(h->a);
245
0
      h->a = 0;
246
0
    }
247
0
  }
248
0
}
Unexecuted instantiation: main.c:dns_srv_handle_put_shm_unsafe
Unexecuted instantiation: resolve.c:dns_srv_handle_put_shm_unsafe
Unexecuted instantiation: cfg_core.c:dns_srv_handle_put_shm_unsafe
Unexecuted instantiation: dns_cache.c:dns_srv_handle_put_shm_unsafe
Unexecuted instantiation: forward.c:dns_srv_handle_put_shm_unsafe
249
250
251
/** @brief get "next" ip next time a dns_srv_handle function is called
252
 * params: h   - struct dns_srv_handler
253
 *         err - return code of the last dns_*_resolve* call
254
 * returns: 0 if it doesn't make sense to try another record,
255
 * 1 otherwise
256
 */
257
inline static int dns_srv_handle_next(struct dns_srv_handle *h, int err)
258
0
{
259
0
  if(err < 0)
260
0
    return 0;
261
0
  h->ip_no++;
262
0
  return (h->srv || h->a);
263
0
}
Unexecuted instantiation: main.c:dns_srv_handle_next
Unexecuted instantiation: resolve.c:dns_srv_handle_next
Unexecuted instantiation: cfg_core.c:dns_srv_handle_next
Unexecuted instantiation: dns_cache.c:dns_srv_handle_next
Unexecuted instantiation: forward.c:dns_srv_handle_next
264
265
266
inline static void dns_srv_handle_init(struct dns_srv_handle *h)
267
0
{
268
0
  h->srv = h->a = 0;
269
0
  h->srv_no = h->ip_no = 0;
270
0
  h->port = 0;
271
0
  h->proto = 0;
272
0
#ifdef DNS_SRV_LB
273
0
  h->srv_tried_rrs = 0;
274
0
#endif
275
0
}
Unexecuted instantiation: main.c:dns_srv_handle_init
Unexecuted instantiation: resolve.c:dns_srv_handle_init
Unexecuted instantiation: cfg_core.c:dns_srv_handle_init
Unexecuted instantiation: dns_cache.c:dns_srv_handle_init
Unexecuted instantiation: forward.c:dns_srv_handle_init
276
277
278
/** @brief performes a srv query on name
279
 * Params:  name  - srv query target (e.g. _sip._udp.foo.bar)
280
 *          ip    - result: first good ip found
281
 *          port  - result: corresponding port number
282
 *          flags - resolve options (like ipv4 only, ipv6 prefered a.s.o)
283
 * Returns: < 0 on error (can be passed to dns_strerror(), 0 on success
284
 */
285
int dns_srv_get_ip(
286
    str *name, struct ip_addr *ip, unsigned short *port, int flags);
287
288
/** @brief performs an A, AAAA (or both) query/queries
289
 * Params:  name  - query target (e.g. foo.bar)
290
 *          ip    - result: first good ip found
291
 *          flags - resolve options (like ipv4 only, ipv6 prefered a.s.o)
292
 * Returns: < 0 on error (can be passed to dns_strerror(), 0 on success
293
 */
294
int dns_get_ip(str *name, struct ip_addr *ip, int flags);
295
296
struct hostent *dns_srv_get_he(str *name, unsigned short *port, int flags);
297
struct hostent *dns_get_he(str *name, int flags);
298
299
300
/** @brief resolve name to an ip, using srv record. Can be called multiple times
301
 * to iterate on all the possible ips, e.g :
302
 * dns_srv_handle_init(h);
303
 * ret_code=dns_sip_resolve(h,...);
304
 *  while( dns_srv_handle_next(h, ret_code){ ret_code=dns_sip_resolve(h...); }
305
 * dns_srv_handle_put(h);
306
 * WARNING: dns_srv_handle_init() must be called to initialize h and
307
 *  dns_srv_handle_put(h) must be called when h is no longer needed
308
 */
309
int dns_sip_resolve(struct dns_srv_handle *h, str *name, struct ip_addr *ip,
310
    unsigned short *port, char *proto, int flags);
311
312
/** @brief same as above, but fills su instead of changing port and filling an ip */
313
inline static int dns_sip_resolve2su(struct dns_srv_handle *h,
314
    union sockaddr_union *su, str *name, unsigned short port, char *proto,
315
    int flags)
316
0
{
317
0
  struct ip_addr ip;
318
0
  int ret;
319
320
0
  ret = dns_sip_resolve(h, name, &ip, &port, proto, flags);
321
0
  if(ret >= 0)
322
0
    init_su(su, &ip, port);
323
0
  return ret;
324
0
}
Unexecuted instantiation: main.c:dns_sip_resolve2su
Unexecuted instantiation: resolve.c:dns_sip_resolve2su
Unexecuted instantiation: cfg_core.c:dns_sip_resolve2su
Unexecuted instantiation: dns_cache.c:dns_sip_resolve2su
Unexecuted instantiation: forward.c:dns_sip_resolve2su
325
326
/** @brief Delete all the entries from the cache.
327
 * If del_permanent is 0, then only the
328
 * non-permanent entries are deleted.
329
 */
330
void dns_cache_flush(int del_permanent);
331
332
#ifdef DNS_WATCHDOG_SUPPORT
333
/** @brief sets the state of the DNS servers:
334
 * 1: at least one server is up
335
 * 0: all the servers are down
336
 */
337
void dns_set_server_state(int state);
338
339
/** @brief returns the state of the DNS servers */
340
int dns_get_server_state(void);
341
#endif /* DNS_WATCHDOG_SUPPORT */
342
343
/** @brief Adds a new record to the cache.
344
 * If there is an existing record with the same name and value
345
 * (ip address in case of A/AAAA record, name in case of SRV record)
346
 * only the remaining fields are updated.
347
 *
348
 * Note that permanent records cannot be overwritten unless
349
 * the new record is also permanent. A permanent record
350
 * completely replaces a non-permanent one.
351
 *
352
 * Currently only A, AAAA, and SRV records are supported.
353
 */
354
int dns_cache_add_record(unsigned short type, str *name, int ttl, str *value,
355
    int priority, int weight, int port, int flags);
356
357
/** @brief Delete a single record from the cache,
358
 * i.e. the record with the same name and value
359
 * (ip address in case of A/AAAA record, name in case of SRV record).
360
 *
361
 * Currently only A, AAAA, and SRV records are supported.
362
 */
363
int dns_cache_delete_single_record(
364
    unsigned short type, str *name, str *value, int flags);
365
366
void dns_set_local_ttl(int ttl);
367
368
#endif