dns_cache.h 11 KB

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