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