1
/* $Id: sip_resolve.h 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
20
#ifndef __PJSIP_SIP_RESOLVE_H__
21
#define __PJSIP_SIP_RESOLVE_H__
26
* This module contains the mechanism to resolve server address as specified by
27
* RFC 3263 - Locating SIP Servers
30
#include <pjsip/sip_types.h>
31
#include <pjlib-util/resolver.h>
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.
41
* \section PJSIP_RESOLVE_FEATURES Features
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).
48
* \subsection PJSIP_RESOLVE_CONFORMANT Conformance to RFC 3263
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.
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
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
81
* The above server resolution procedure differs from RFC 3263 in these
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
89
* \subsection PJSIP_SIP_RESOLVE_FAILOVER_LOADBALANCE Load-Balancing and Fail-Over
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.
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.
106
* \subsection PJSIP_SIP_RESOLVE_SIP_FEATURES SIP SRV Resolver Features
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.
123
* \subsection PJSIP_RESOLVE_DNS_FEATURES DNS Resolver Features
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
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
140
* Please consult PJLIB-UTIL DNS resolver documentation for more details.
143
* \section PJSIP_RESOLVE_USING Using the Resolver
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.
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.
155
* Once the resolver is set, it will be used automatically by PJSIP everytime
156
* PJSIP needs to send SIP request/response messages.
159
* \section PJSIP_RESOLVE_REFERENCE Reference
162
* - RFC 2782: A DNS RR for specifying the location of services (DNS SRV)
163
* - RFC 3263: Locating SIP Servers
167
* The server addresses returned by the resolver.
169
typedef struct pjsip_server_addresses
171
/** Number of address records. */
174
/** Address records. */
177
/** Preferable transport to be used to contact this address. */
178
pjsip_transport_type_e type;
180
/** Server priority (the lower the higher the priority). */
183
/** Server weight (the higher the more load it can handle). */
186
/** The server's address. */
189
/** Address length. */
192
} entry[PJSIP_MAX_RESOLVED_ADDRESSES];
194
} pjsip_server_addresses;
198
* The type of callback function to be called when resolver finishes the job.
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.
205
typedef void pjsip_resolver_callback(pj_status_t status,
207
const struct pjsip_server_addresses *addr);
210
* Create SIP resolver engine. Note that this function is normally called
211
* internally by pjsip_endpoint instance.
213
* @param pool Pool to allocate memory from.
214
* @param p_res Pointer to receive SIP resolver instance.
216
* @return PJ_SUCCESS when resolver can be successfully created.
218
PJ_DECL(pj_status_t) pjsip_resolver_create(pj_pool_t *pool,
219
pjsip_resolver_t **p_res);
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.
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.
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
234
* @return PJ_SUCCESS on success, or the appropriate error code.
236
PJ_DECL(pj_status_t) pjsip_resolver_set_resolver(pjsip_resolver_t *res,
237
pj_dns_resolver *dns_res);
241
* Get the DNS resolver instance of the SIP resolver engine.
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.
246
* @param res The SIP resolver engine.
248
* @return The DNS resolver instance (may be NULL)
250
PJ_DECL(pj_dns_resolver*) pjsip_resolver_get_resolver(pjsip_resolver_t *res);
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.
258
* Note that this function will normally called by the SIP endpoint instance
259
* when the SIP endpoint instance is destroyed.
261
* @param resolver The resolver.
263
PJ_DECL(void) pjsip_resolver_destroy(pjsip_resolver_t *resolver);
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.
270
* Note that application normally will use #pjsip_endpt_resolve() instead
271
* since it does not normally have access to the SIP resolver instance.
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.
279
PJ_DECL(void) pjsip_resolve( pjsip_resolver_t *resolver,
281
const pjsip_host_info *target,
283
pjsip_resolver_callback *cb);
291
#endif /* __PJSIP_SIP_RESOLVE_H__ */