blob: 5a12cf781fd3fe951c2a0c2bd59db83ed4c63af7 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $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
34PJ_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 *
122 *
123 * \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features
124 *
125 * The PJSIP server resolution framework uses PJLIB-UTIL DNS resolver engine
126 * for performing the asynchronous DNS request. The PJLIB-UTIL DNS resolver
127 * has some useful features, such as:
128 * - queries are asynchronous with configurable timeout,
129 * - query aggregation to combine multiple pending queries to the same
130 * DNS target into a single DNS request (to save message round-trip and
131 * processing),
132 * - response caching with TTL negotiated between the minimum TTL found in
133 * the response and the maximum TTL allowed in the configuration,
134 * - multiple nameservers, with active nameserver is selected from nameserver
135 * which provides the best response time,
136 * - fallback nameserver, with periodic detection of which name servers are
137 * active or down.
138 * - etc.
139 *
140 * Please consult PJLIB-UTIL DNS resolver documentation for more details.
141 *
142 *
143 * \section PJSIP_RESOLVE_USING Using the Resolver
144 *
145 * To maintain backward compatibility, the resolver MUST be enabled manually.
146 * With the default settings, the resolver WILL NOT perform DNS SRV resolution,
147 * as it will just resolve the name with standard pj_gethostbyname() function.
148 *
149 * Application can enable the SRV resolver by creating the PJLIB-UTIL DNS
150 * resolver with #pjsip_endpt_create_resolver(), configure the
151 * nameservers of the PJLIB-UTIL DNS resolver object by calling
152 * pj_dns_resolver_set_ns() function, and pass the DNS resolver object to
153 * #pjsip_resolver_set_resolver() function.
154 *
155 * Once the resolver is set, it will be used automatically by PJSIP everytime
156 * PJSIP needs to send SIP request/response messages.
157 *
158 *
159 * \section PJSIP_RESOLVE_REFERENCE Reference
160 *
161 * Reference:
162 * - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
163 * - RFC 3263: Locating SIP Servers
164 */
165
166/**
167 * The server addresses returned by the resolver.
168 */
169typedef struct pjsip_server_addresses
170{
171 /** Number of address records. */
172 unsigned count;
173
174 /** Address records. */
175 struct
176 {
177 /** Preferable transport to be used to contact this address. */
178 pjsip_transport_type_e type;
179
180 /** Server priority (the lower the higher the priority). */
181 unsigned priority;
182
183 /** Server weight (the higher the more load it can handle). */
184 unsigned weight;
185
186 /** The server's address. */
187 pj_sockaddr addr;
188
189 /** Address length. */
190 int addr_len;
191
192 } entry[PJSIP_MAX_RESOLVED_ADDRESSES];
193
194} pjsip_server_addresses;
195
196
197/**
198 * The type of callback function to be called when resolver finishes the job.
199 *
200 * @param status The status of the operation, which is zero on success.
201 * @param token The token that was associated with the job when application
202 * call the resolve function.
203 * @param addr The addresses resolved by the operation.
204 */
205typedef void pjsip_resolver_callback(pj_status_t status,
206 void *token,
207 const struct pjsip_server_addresses *addr);
208
209/**
210 * Create SIP resolver engine. Note that this function is normally called
211 * internally by pjsip_endpoint instance.
212 *
213 * @param pool Pool to allocate memory from.
214 * @param p_res Pointer to receive SIP resolver instance.
215 *
216 * @return PJ_SUCCESS when resolver can be successfully created.
217 */
218PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,
219 pjsip_resolver_t **p_res);
220
221/**
222 * Set the DNS resolver instance of the SIP resolver engine. Before the
223 * DNS resolver is set, the SIP resolver will use standard pj_gethostbyname()
224 * to resolve addresses.
225 *
226 * Note that application normally will use #pjsip_endpt_set_resolver() instead
227 * since it does not normally have access to the SIP resolver instance.
228 *
229 * @param res The SIP resolver engine.
230 * @param dns_res The DNS resolver instance to be used by the SIP resolver.
231 * This argument can be NULL to reset the internal DNS
232 * instance.
233 *
234 * @return PJ_SUCCESS on success, or the appropriate error code.
235 */
236PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
237 pj_dns_resolver *dns_res);
238
239
240/**
241 * Get the DNS resolver instance of the SIP resolver engine.
242 *
243 * Note that application normally will use #pjsip_endpt_get_resolver() instead
244 * since it does not normally have access to the SIP resolver instance.
245 *
246 * @param res The SIP resolver engine.
247 *
248 * @return The DNS resolver instance (may be NULL)
249 */
250PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);
251
252/**
253 * Destroy resolver engine. Note that this will also destroy the internal
254 * DNS resolver inside the engine. If application doesn't want the internal
255 * DNS resolver to be destroyed, it should set the internal DNS resolver
256 * to NULL before calling this function.
257 *
258 * Note that this function will normally called by the SIP endpoint instance
259 * when the SIP endpoint instance is destroyed.
260 *
261 * @param resolver The resolver.
262 */
263PJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);
264
265/**
266 * Asynchronously resolve a SIP target host or domain according to rule
267 * specified in RFC 3263 (Locating SIP Servers). When the resolving operation
268 * has completed, the callback will be called.
269 *
270 * Note that application normally will use #pjsip_endpt_resolve() instead
271 * since it does not normally have access to the SIP resolver instance.
272 *
273 * @param resolver The resolver engine.
274 * @param pool The pool to allocate resolver job.
275 * @param target The target specification to be resolved.
276 * @param token A user defined token to be passed back to callback function.
277 * @param cb The callback function.
278 */
279PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
280 pj_pool_t *pool,
281 const pjsip_host_info *target,
282 void *token,
283 pjsip_resolver_callback *cb);
284
285/**
286 * @}
287 */
288
289PJ_END_DECL
290
291#endif /* __PJSIP_SIP_RESOLVE_H__ */