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