blob: 770a2a723fab31f0815d7e8ba180d06a2306d86d [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 __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
29PJ_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 */
81typedef 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 AAAA if SRV resolution fails,
88 * and then to DNS A resolution if the AAAA 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_A to
96 * make the resolver fallback to AAAA if SRV resolution fails,
97 * and then to DNS A resolution if the AAAA 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 first of each targets in the DNS SRV record. If
104 * this option is not specified, the SRV resolver will query
105 * the DNS A record for the target instead.
106 */
107 PJ_DNS_SRV_RESOLVE_AAAA = 4
108
109} pj_dns_srv_option;
110
111
112/**
113 * This structure represents DNS SRV records as the result of DNS SRV
114 * resolution using #pj_dns_srv_resolve().
115 */
116typedef struct pj_dns_srv_record
117{
118 /** Number of address records. */
119 unsigned count;
120
121 /** Address records. */
122 struct
123 {
124 /** Server priority (the lower the higher the priority). */
125 unsigned priority;
126
127 /** Server weight (the higher the more load it can handle). */
128 unsigned weight;
129
130 /** Port number. */
131 pj_uint16_t port;
132
133 /** The host address. */
134 pj_dns_a_record server;
135
136 } entry[PJ_DNS_SRV_MAX_ADDR];
137
138} pj_dns_srv_record;
139
140
141/** Opaque declaration for DNS SRV query */
142typedef struct pj_dns_srv_async_query pj_dns_srv_async_query;
143
144/**
145 * Type of callback function to receive notification from the resolver
146 * when the resolution process completes.
147 */
148typedef void pj_dns_srv_resolver_cb(void *user_data,
149 pj_status_t status,
150 const pj_dns_srv_record *rec);
151
152
153/**
154 * Start DNS SRV resolution for the specified name. The full name of the
155 * entry will be concatenated from \a res_name and \a domain_name fragments.
156 *
157 * @param domain_name The domain name part of the name.
158 * @param res_name The full service name, including the transport name
159 * and with all the leading underscore characters and
160 * ending dot (e.g. "_sip._udp.", "_stun._udp.").
161 * @param def_port The port number to be assigned to the resolved address
162 * when the DNS SRV resolution fails and the name is
163 * resolved with DNS A resolution.
164 * @param pool Memory pool used to allocate memory for the query.
165 * @param resolver The resolver instance.
166 * @param option Option flags, which can be constructed from
167 * #pj_dns_srv_option bitmask. Note that this argument
168 * was called "fallback_a" in pjsip version 0.8.0 and
169 * older, but the new option should be backward
170 * compatible with existing applications. If application
171 * specifies PJ_TRUE as "fallback_a" value, it will
172 * correspond to PJ_DNS_SRV_FALLBACK_A option.
173 * @param token Arbitrary data to be associated with this query when
174 * the calback is called.
175 * @param cb Pointer to callback function to receive the
176 * notification when the resolution process completes.
177 * @param p_query Optional pointer to receive the query object, if one
178 * was started. If this pointer is specified, a NULL may
179 * be returned if response cache is available immediately.
180 *
181 * @return PJ_SUCCESS on success, or the appropriate error code.
182 */
183PJ_DECL(pj_status_t) pj_dns_srv_resolve(const pj_str_t *domain_name,
184 const pj_str_t *res_name,
185 unsigned def_port,
186 pj_pool_t *pool,
187 pj_dns_resolver *resolver,
188 unsigned option,
189 void *token,
190 pj_dns_srv_resolver_cb *cb,
191 pj_dns_srv_async_query **p_query);
192
193
194/**
195 * Cancel an outstanding DNS SRV query.
196 *
197 * @param query The pending asynchronous query to be cancelled.
198 * @param notify If non-zero, the callback will be called with failure
199 * status to notify that the query has been cancelled.
200 *
201 * @return PJ_SUCCESS on success, or the appropriate error code,
202 */
203PJ_DECL(pj_status_t) pj_dns_srv_cancel_query(pj_dns_srv_async_query *query,
204 pj_bool_t notify);
205
206
207/**
208 * @}
209 */
210
211PJ_END_DECL
212
213
214#endif /* __PJLIB_UTIL_SRV_RESOLVER_H__ */
215