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 __PJLIB_UTIL_SRV_RESOLVER_H__ 21 #define __PJLIB_UTIL_SRV_RESOLVER_H__ 22 23 /** 24 * @file srv_resolver.h 25 * @brief DNS SRV resolver 26 */ 27 #include <pjlib-util/resolver.h> 28 29 PJ_BEGIN_DECL 30 31 /** 32 * @defgroup PJ_DNS_SRV_RESOLVER DNS SRV Resolution Helper 33 * @ingroup PJ_DNS 34 * @{ 35 * 36 * \section PJ_DNS_SRV_RESOLVER_INTRO DNS SRV Resolution Helper 37 * 38 * This module provides an even higher layer of abstraction for the DNS 39 * resolution framework, to resolve DNS SRV names. 40 * 41 * The #pj_dns_srv_resolve() function will asynchronously resolve the server 42 * name into IP address(es) with a single function call. If the SRV name 43 * contains multiple names, then each will be resolved with individual 44 * DNS A resolution to get the IP addresses. Upon successful completion, 45 * application callback will be called with each IP address of the 46 * target selected based on the load-balancing and fail-over criteria 47 * below. 48 * 49 * When the resolver fails to resolve the name using DNS SRV resolution 50 * (for example when the DNS SRV record is not present in the DNS server), 51 * the resolver will fallback to using DNS A record resolution to resolve 52 * the name. 53 * 54 * \subsection PJ_DNS_SRV_RESOLVER_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over 55 * 56 * When multiple targets are returned in the DNS SRV response, server entries 57 * are selected based on the following rule (which is described in RFC 2782): 58 * - targets will be sorted based on the priority first. 59 * - for targets with the same priority, #pj_dns_srv_resolve() will select 60 * only one target according to its weight. To select this one target, 61 * the function associates running-sum for all targets, and generates 62 * a random number between zero and the total running-sum (inclusive). 63 * The target selected is the first target with running-sum greater than 64 * or equal to this random number. 65 * 66 * The above procedure will select one target for each priority, allowing 67 * application to fail-over to the next target when the previous target fails. 68 * These targets are returned in the #pj_dns_srv_record structure 69 * argument of the callback. 70 * 71 * \section PJ_DNS_SRV_RESOLVER_REFERENCE Reference 72 * 73 * Reference: 74 * - <A HREF="http://www.ietf.org/rfc/rfc2782.txt">RFC 2782</A>: 75 * A DNS RR for specifying the location of services (DNS SRV) 76 */ 77 78 /** 79 * Flags to be specified when starting the DNS SRV query. 80 */ 81 typedef enum pj_dns_srv_option 82 { 83 /** 84 * Specify if the resolver should fallback with DNS A 85 * resolution when the SRV resolution fails. This option may 86 * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to 87 * make the resolver fallback to both DNS A and DNS AAAA 88 * resolutions if SRV resolution fails. 89 */ 90 PJ_DNS_SRV_FALLBACK_A = 1, 91 92 /** 93 * Specify if the resolver should fallback with DNS AAAA 94 * resolution when the SRV resolution fails. This option may 95 * be specified together with PJ_DNS_SRV_FALLBACK_AAAA to 96 * make the resolver fallback to both DNS A and DNS AAAA 97 * resolutions if SRV resolution fails. 98 */ 99 PJ_DNS_SRV_FALLBACK_AAAA = 2, 100 101 /** 102 * Specify if the resolver should try to resolve with DNS AAAA 103 * resolution of each targets in the DNS SRV record. If this 104 * option is not specified, the SRV resolver will query the 105 * DNS A record for the target instead. 106 */ 107 PJ_DNS_SRV_RESOLVE_AAAA = 4, 108 109 /** 110 * Specify if the resolver should try to resolve with DNS AAAA 111 * resolution only (i.e: without DNS A resolution) for each targets 112 * in the DNS SRV record. 113 */ 114 PJ_DNS_SRV_RESOLVE_AAAA_ONLY = 8 115 116 } pj_dns_srv_option; 117 118 119 /** 120 * This structure represents DNS SRV records as the result of DNS SRV 121 * resolution using #pj_dns_srv_resolve(). 122 */ 123 typedef struct pj_dns_srv_record 124 { 125 /** Number of address records. */ 126 unsigned count; 127 128 /** Address records. */ 129 struct 130 { 131 /** Server priority (the lower the higher the priority). */ 132 unsigned priority; 133 134 /** Server weight (the higher the more load it can handle). */ 135 unsigned weight; 136 137 /** Port number. */ 138 pj_uint16_t port; 139 140 /** The host address. */ 141 pj_dns_addr_record server; 142 143 } entry[PJ_DNS_SRV_MAX_ADDR]; 144 145 } pj_dns_srv_record; 146 147 148 /** Opaque declaration for DNS SRV query */ 149 typedef struct pj_dns_srv_async_query pj_dns_srv_async_query; 150 151 /** 152 * Type of callback function to receive notification from the resolver 153 * when the resolution process completes. 154 */ 155 typedef void pj_dns_srv_resolver_cb(void *user_data, 156 pj_status_t status, 157 const pj_dns_srv_record *rec); 158 159 160 /** 161 * Start DNS SRV resolution for the specified name. The full name of the 162 * entry will be concatenated from \a res_name and \a domain_name fragments. 163 * 164 * @param domain_name The domain name part of the name. 165 * @param res_name The full service name, including the transport name 166 * and with all the leading underscore characters and 167 * ending dot (e.g. "_sip._udp.", "_stun._udp."). 168 * @param def_port The port number to be assigned to the resolved address 169 * when the DNS SRV resolution fails and the name is 170 * resolved with DNS A resolution. 171 * @param pool Memory pool used to allocate memory for the query. 172 * @param resolver The resolver instance. 173 * @param option Option flags, which can be constructed from 174 * #pj_dns_srv_option bitmask. Note that this argument 175 * was called "fallback_a" in pjsip version 0.8.0 and 176 * older, but the new option should be backward 177 * compatible with existing applications. If application 178 * specifies PJ_TRUE as "fallback_a" value, it will 179 * correspond to PJ_DNS_SRV_FALLBACK_A option. 180 * @param token Arbitrary data to be associated with this query when 181 * the calback is called. 182 * @param cb Pointer to callback function to receive the 183 * notification when the resolution process completes. 184 * @param p_query Optional pointer to receive the query object, if one 185 * was started. If this pointer is specified, a NULL may 186 * be returned if response cache is available immediately. 187 * 188 * @return PJ_SUCCESS on success, or the appropriate error code. 189 */ 190 PJ_DECL(pj_status_t) pj_dns_srv_resolve(const pj_str_t *domain_name, 191 const pj_str_t *res_name, 192 unsigned def_port, 193 pj_pool_t *pool, 194 pj_dns_resolver *resolver, 195 unsigned option, 196 void *token, 197 pj_dns_srv_resolver_cb *cb, 198 pj_dns_srv_async_query **p_query); 199 200 201 /** 202 * Cancel an outstanding DNS SRV query. 203 * 204 * @param query The pending asynchronous query to be cancelled. 205 * @param notify If non-zero, the callback will be called with failure 206 * status to notify that the query has been cancelled. 207 * 208 * @return PJ_SUCCESS on success, or the appropriate error code, 209 */ 210 PJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query, 211 pj_bool_t notify); 212 213 214 /** 215 * @} 216 */ 217 218 PJ_END_DECL 219 220 221 #endif /* __PJLIB_UTIL_SRV_RESOLVER_H__ */ 222 223