sip_resolve.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #ifndef __PJSIP_SIP_RESOLVE_H__
  20. #define __PJSIP_SIP_RESOLVE_H__
  21. /**
  22. * @file sip_resolve.h
  23. * @brief
  24. * This module contains the mechanism to resolve server address as specified by
  25. * RFC 3263 - Locating SIP Servers
  26. */
  27. #include <pjsip/sip_types.h>
  28. #include <pjlib-util/resolver.h>
  29. #include <pj/sock.h>
  30. PJ_BEGIN_DECL
  31. /**
  32. * @defgroup PJSIP_RESOLVE SIP SRV Server Resolution (RFC 3263 - Locating SIP Servers)
  33. * @ingroup PJSIP_TRANSPORT
  34. * @brief Framework to resolve SIP servers based on RFC 3263.
  35. * @{
  36. * \section PJSIP_RESOLVE_FEATURES Features
  37. *
  38. * This is the SIP server resolution framework, which is modelled after
  39. * RFC 3263 - Locating SIP Servers document. The SIP server resolution
  40. * framework is asynchronous; callback will be called once the server
  41. * address has been resolved (successfully or with errors).
  42. *
  43. * \subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263
  44. *
  45. * The SIP server resolution framework is modelled after RFC 3263 (Locating
  46. * SIP Servers) document, and it provides a single function (#pjsip_resolve())
  47. * to resolve a domain into actual IP addresses of the servers, by querying
  48. * DNS SRV record and DNS A record where necessary.
  49. *
  50. * The #pjsip_resolve() function performs the server resolution according
  51. * to RFC 3263 with some additional fallback mechanisms, as follows:
  52. * - if the target name is an IP address, the callback will be called
  53. * immediately with the IP address. If port number was specified, this
  54. * port number will be used, otherwise the default port number for the
  55. * transport will be used (5060 for TCP/UDP, 5061 for TLS) if the transport
  56. * is specified. If the transport is not specified, UDP with port number
  57. * 5060 will be used.
  58. * - if target name is not an IP address but it contains port number,
  59. * then the target name is resolved with DNS A (or AAAA, when IPv6 is
  60. * supported in the future) query, and the port is taken from the
  61. * port number argument. The callback will be called once the DNS A
  62. * resolution completes. If the DNS A resolution returns multiple IP
  63. * addresses, these IP addresses will be returned to the caller.
  64. * - if target name is not an IP address and port number is not specified,
  65. * DNS SRV resolution will be performed for the specified name and
  66. * transport type (or UDP when transport is not specified),
  67. * then followed by DNS A (or AAAA, when IPv6 is supported)
  68. * resolution for each target in the SRV record. If DNS SRV
  69. * resolution returns error, DNS A (or AAAA) resolution will be
  70. * performed for the original target (it is assumed that the target domain
  71. * does not support SRV records). Upon successful completion,
  72. * application callback will be called with each IP address of the
  73. * target selected based on the load-balancing and fail-over criteria
  74. * below.
  75. *
  76. * The above server resolution procedure differs from RFC 3263 in these
  77. * regards:
  78. * - currently #pjsip_resolve() doesn't support DNS NAPTR record.
  79. * - if transport is not specified, it is assumed to be UDP (the proper
  80. * behavior is to query the NAPTR record, but we don't support this
  81. * yet).
  82. *
  83. *
  84. * \subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
  85. *
  86. * When multiple targets are returned in the DNS SRV response, server entries
  87. * are selected based on the following rule (which is described in RFC 2782):
  88. * - targets will be sorted based on the priority first.
  89. * - for targets with the same priority, #pjsip_resolve() will select
  90. * only one target according to its weight. To select this one target,
  91. * the function associates running-sum for all targets, and generates
  92. * a random number between zero and the total running-sum (inclusive).
  93. * The target selected is the first target with running-sum greater than
  94. * or equal to this random number.
  95. *
  96. * The above procedure will select one target for each priority, allowing
  97. * application to fail-over to the next target when the previous target fails.
  98. * These targets are returned in the #pjsip_server_addresses structure
  99. * argument of the callback.
  100. *
  101. * \subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features
  102. *
  103. * Some features of the SIP resolver:
  104. * - DNS SRV entries are returned on sorted order based on priority
  105. * to allow failover to the next appropriate server.
  106. * - The procedure in RFC 2782 is used to select server with the same
  107. * priority to load-balance the servers load.
  108. * - A single function (#pjsip_resolve()) performs all server resolution
  109. * works, from resolving the SRV records to getting the actual IP addresses
  110. * of the servers with DNS A (or AAAA) resolution.
  111. * - When multiple DNS SRV records are returned, parallel DNS A (or AAAA)
  112. * queries will be issued simultaneously.
  113. * - The PJLIB-UTIL DNS resolver provides additional functionality such as
  114. * response caching, query aggregation, parallel nameservers, fallback
  115. * nameserver, etc., which will be described below.
  116. * - Enable application to provide its own resolver implementation.
  117. *
  118. *
  119. * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features
  120. *
  121. * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine
  122. * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver
  123. * has some useful features, such as:
  124. * - queries are asynchronous with configurable timeout,
  125. * - query aggregation to combine multiple pending queries to the same
  126. * DNS target into a single DNS request (to save message round-trip and
  127. * processing),
  128. * - response caching with TTL negotiated between the minimum TTL found in
  129. * the response and the maximum TTL allowed in the configuration,
  130. * - multiple nameservers, with active nameserver is selected from nameserver
  131. * which provides the best response time,
  132. * - fallback nameserver, with periodic detection of which name servers are
  133. * active or down.
  134. * - etc.
  135. *
  136. * Please consult PJLIB-UTIL DNS resolver documentation for more details.
  137. *
  138. *
  139. * \section PJSIP_RESOLVE_USING Using the Resolver
  140. *
  141. * To maintain backward compatibility, the resolver MUST be enabled manually.
  142. * With the default settings, the resolver WILL NOT perform DNS SRV resolution,
  143. * as it will just resolve the name with standard pj_gethostbyname() function.
  144. *
  145. * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS
  146. * resolver with #pjsip_endpt_create_resolver(), configure the
  147. * nameservers of the PJLIB-UTIL DNS resolver object by calling
  148. * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to
  149. * #pjsip_resolver_set_resolver() function.
  150. *
  151. * Once the resolver is set, it will be used automatically by PJSIP everytime
  152. * PJSIP needs to send SIP request/response messages.
  153. *
  154. * \section PJSIP_RESOLVE_EXT_RESOLVER External Resolver
  155. *
  156. * As an alternative to enabling PJLIB-UTIL DNS resolver, application can
  157. * provide its own resolver implementation by defining the callback in
  158. * pjsip_ext_resolver and pass the callback to
  159. * #pjsip_resolver_set_ext_resolver() function. Please note that if the
  160. * implementation needs feature from PJLIB-UTL DNS resolver, it has to create
  161. * its own PJLIB-UTL DNS resolver instance.
  162. *
  163. * \section PJSIP_RESOLVE_REFERENCE Reference
  164. *
  165. * Reference:
  166. * - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
  167. * - RFC 3263: Locating SIP Servers
  168. */
  169. /** Address records. */
  170. typedef struct pjsip_server_address_record
  171. {
  172. /** Preferable transport to be used to contact this address. */
  173. pjsip_transport_type_e type;
  174. /** Server priority (the lower the higher the priority). */
  175. unsigned priority;
  176. /** Server weight (the higher the more load it can handle). */
  177. unsigned weight;
  178. /** The server's address. */
  179. pj_sockaddr addr;
  180. /** Address length. */
  181. int addr_len;
  182. } pjsip_server_address_record;
  183. /**
  184. * The server addresses returned by the resolver.
  185. */
  186. typedef struct pjsip_server_addresses
  187. {
  188. /** Number of address records. */
  189. unsigned count;
  190. /** Address records. */
  191. pjsip_server_address_record entry[PJSIP_MAX_RESOLVED_ADDRESSES];
  192. } pjsip_server_addresses;
  193. /**
  194. * The type of callback function to be called when resolver finishes the job.
  195. *
  196. * @param status The status of the operation, which is zero on success.
  197. * @param token The token that was associated with the job when application
  198. * call the resolve function.
  199. * @param addr The addresses resolved by the operation.
  200. */
  201. typedef void pjsip_resolver_callback(pj_status_t status,
  202. void *token,
  203. const struct pjsip_server_addresses *addr);
  204. /**
  205. * This structure describes application callback to receive various event from
  206. * the SIP resolver engine. Application can use this for its own resolver
  207. * implementation.
  208. */
  209. typedef struct pjsip_ext_resolver
  210. {
  211. /**
  212. * Notify application when the resolution should begin.
  213. *
  214. * @param resolver The resolver engine.
  215. * @param pool The pool to allocate resolver job.
  216. * @param target The target specification to be resolved.
  217. * @param token A user defined token to be passed back to callback
  218. * function.
  219. * @param cb The callback function.
  220. */
  221. void (*resolve) (pjsip_resolver_t *resolver, pj_pool_t *pool,
  222. const pjsip_host_info *target, void *token,
  223. pjsip_resolver_callback *cb);
  224. } pjsip_ext_resolver;
  225. /**
  226. * Create SIP resolver engine. Note that this function is normally called
  227. * internally by pjsip_endpoint instance.
  228. *
  229. * @param pool Pool to allocate memory from.
  230. * @param p_res Pointer to receive SIP resolver instance.
  231. *
  232. * @return PJ_SUCCESS when resolver can be successfully created.
  233. */
  234. PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,
  235. pjsip_resolver_t **p_res);
  236. /**
  237. * Set the DNS resolver instance of the SIP resolver engine. Before the
  238. * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname()
  239. * to resolve addresses.
  240. *
  241. * Note that application normally will use #pjsip_endpt_set_resolver() instead
  242. * since it does not normally have access to the SIP resolver instance.
  243. *
  244. * @param res The SIP resolver engine.
  245. * @param dns_res The DNS resolver instance to be used by the SIP resolver.
  246. * This argument can be NULL to reset the internal DNS
  247. * instance.
  248. *
  249. * @return PJ_SUCCESS on success, or the appropriate error code.
  250. */
  251. PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
  252. pj_dns_resolver *dns_res);
  253. /**
  254. * Set the DNS external resolver implementation to use in the SIP resolver
  255. * engine. Naturally when implementing its own resolver, application would not
  256. * need the internal resolver, hence this function will also destroy the
  257. * PJLIB-UTIL DNS resolver if any (e.g: set using
  258. * #pjsip_resolver_set_resolver()). Application that needs it, still be able
  259. * create its own instance.
  260. *
  261. * Note that application normally will use #pjsip_endpt_set_ext_resolver()
  262. * instead since it does not normally have access to the SIP resolver instance.
  263. *
  264. * @param res The SIP resolver engine.
  265. * @param ext_res The external resolver implementation callback. This argument
  266. * can be NULL to reset the whole external implementation.
  267. * However, it is prohibited to reset individual callback.
  268. *
  269. * @return PJ_SUCCESS on success, or the appropriate error code.
  270. */
  271. PJ_DECL(pj_status_t) pjsip_resolver_set_ext_resolver(
  272. pjsip_resolver_t *res,
  273. pjsip_ext_resolver *ext_res);
  274. /**
  275. * Get the DNS resolver instance of the SIP resolver engine.
  276. *
  277. * Note that application normally will use #pjsip_endpt_get_resolver() instead
  278. * since it does not normally have access to the SIP resolver instance.
  279. *
  280. * @param res The SIP resolver engine.
  281. *
  282. * @return The DNS resolver instance (may be NULL)
  283. */
  284. PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);
  285. /**
  286. * Destroy resolver engine. Note that this will also destroy the internal
  287. * DNS resolver inside the engine. If application doesn't want the internal
  288. * DNS resolver to be destroyed, it should set the internal DNS resolver
  289. * to NULL before calling this function.
  290. *
  291. * Note that this function will normally called by the SIP endpoint instance
  292. * when the SIP endpoint instance is destroyed.
  293. *
  294. * @param resolver The resolver.
  295. */
  296. PJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);
  297. /**
  298. * Asynchronously resolve a SIP target host or domain according to rule
  299. * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
  300. * has completed, the callback will be called.
  301. *
  302. * Note that application normally will use #pjsip_endpt_resolve() instead
  303. * since it does not normally have access to the SIP resolver instance.
  304. *
  305. * @param resolver The resolver engine.
  306. * @param pool The pool to allocate resolver job.
  307. * @param target The target specification to be resolved.
  308. * @param token A user defined token to be passed back to callback function.
  309. * @param cb The callback function.
  310. */
  311. PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
  312. pj_pool_t *pool,
  313. const pjsip_host_info *target,
  314. void *token,
  315. pjsip_resolver_callback *cb);
  316. /**
  317. * @}
  318. */
  319. PJ_END_DECL
  320. #endif /* __PJSIP_SIP_RESOLVE_H__ */