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