sresolv.docs 7.66 KB
Newer Older
1
/**@MODULEPAGE "sresolv" - Asynchronous DNS Resolver
Pekka Pessi's avatar
Pekka Pessi committed
2 3 4 5

@section sresolv_meta Module Information

The Sofia @b sresolv module consists of an asynchronous DNS resolver with
6 7
EDNS extensions. The interface to library using #su_root_t is declared in
<sofia-sip/sresolv.h>.
8 9 10 11

An alternative interface is defined by <sofia-resolv/sres.h>,
<sofia-resolv/sres_record.h>, <sofia-resolv/sres_async.h>, and
<sofia-resolv/sres_cache.h>.
Pekka Pessi's avatar
Pekka Pessi committed
12

13 14
@sa @RFC1034, @RFC1035, @RFC1886, @RFC2671, @RFC2782, @RFC2915

Pekka Pessi's avatar
Pekka Pessi committed
15 16
@CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>

17
@STATUS @SofiaSIP Core library
Pekka Pessi's avatar
Pekka Pessi committed
18 19 20

@LICENSE LGPL

21 22 23 24
@todo Caching Policy and Cache Poisoning

The policy for caching non-authoritave entries should be solved.

25 26 27 28 29 30 31 32 33 34
@section sresolv_overview Why Sofia Resolver?

The generally available open source DNS libraries are either synchronous,
that is, they block the thread making the query or they resolve only host
names. As SIP protocol uses NAPTR and SRV records in addition ot the usual A
or AAAA records, these DNS libraries are inadequate for a SIP application.

Sofia resolver uses the usual configuration for DNS. In Unix-based systems,
the DNS configuration is stored in the file /etc/resolv.conf, on Windows, it
is available through the registry. Sofia resolvers reloads the configuration
35
when it detect that it has been changed.
36 37 38 39 40 41

In addition to the configuration files, the environment variables
#SRES_OPTIONS and #RES_OPTIONS can be used to change the behaviour of the
resolver.

@section sresolv_interfaces Using Sofia Resolver
Pekka Pessi's avatar
Pekka Pessi committed
42

43 44 45 46
Sofia resolver works usually asynchronously, in other words, it generates a
a query, sends it to DNS server and returns immediately to the caller. When
a response is received and the query is completed, sresolv signals
application through a callback function.
47 48 49

The application can either explicitly poll(2) or select(2) on file
descriptors used by resolver and call the driver functions, or it can use
50
@ref su_root_t "su root" a pointer to a #su_root_t object. Third option is to
51
use resolver synchronously with sres_blocking_query().
52

53 54 55
There is an internal cache used by sresolv. The query functions add
records to the cache: using the cache is made similar as if receiving
entries directly from DNS server.
56

57 58 59
Please note that you have to create a separate resolver object for each
thread using Sofia resolver. The resolver objects can share the cache,
however.
60

61
@section sofia_sip_sresolv_h Interface in <sofia-sip/sresolv.h>
62

63 64
The simple use of Sofia resolver driven from #su_root_t is defined in
<sofia-sip/sresolv.h>. The resolver object can be created with
65 66
sres_resolver_create(). The provided @ref su_root_t "root object" takes care
of calling the sres_query() and sres_query_sockaddr() callback functions.
67

68 69
@code
#include <sofia-sip/sresolv.h>
70

71
sres_resolver_t *sres_resolver_create(su_root_t *root,
72 73
				      char const *resolv_conf,
				      tag_type_t, tag_value_t, ...);
74

75
int sres_resolver_destroy(sres_resolver_t *res);
76

77
@endcode
78

79 80 81
@section sres_query Sending DNS Queries

The second part of interface is used when sending DNS queries:
82

83
@code
84 85 86 87 88 89
sres_query_t *sres_query(sres_resolver_t *res,
			 sres_answer_f *callback,
			 sres_context_t *context,
			 int socket,
			 uint16_t type,
			 char const *domain);
90

91 92 93 94 95 96
sres_query_t *sres_query_sockaddr(sres_resolver_t *res,
				  sres_answer_f *callback,
				  sres_context_t *context,
				  int socket,
				  uint16_t type,
				  struct sockaddr const *addr);
97 98 99 100

void sres_query_bind(sres_query_t *q,
                     sres_answer_f *callback,
                     sres_context_t *context);
101 102 103 104 105 106
@endcode

@section sres_record Handling DNS Records

The third part is used to handle the records which were returned by DNS
query or stored into the cache:
107

108
@code
109 110 111 112 113 114 115 116 117 118
sres_record_t **sres_cached_answers(sres_resolver_t *res,
				    uint16_t type,
				    char const *domain);

sres_record_t **sres_cached_answers_sockaddr(sres_resolver_t *res,
                                             uint16_t type,
					     struct sockaddr const *addr);

int sres_sort_answers(sres_resolver_t *res, sres_record_t **answers);

119
int sres_filter_answers(sres_resolver_t *sres, sres_record_t **answers,
120 121 122 123 124 125 126
			uint16_t type);

void sres_free_answers(sres_resolver_t *res, sres_record_t **answers);

void sres_free_answer(sres_resolver_t *res, sres_record_t *answer);

@endcode
Pekka Pessi's avatar
Pekka Pessi committed
127

128 129
@section sofia_resolv_sres_h Interface in <sofia-resolv/sres.h>

130
The generic interface to Sofia resolver is defined in <sofia-resolv/sres.h>.
131 132 133 134 135 136 137 138 139 140 141 142
The first part of interface consists of functions for handling resolver
objects:

@code

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <sofia-resolv/sres.h>

sres_resolver_t *sres_resolver_new(char const *resolv_conf_path);
Pekka Pessi's avatar
Pekka Pessi committed
143

144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
sres_resolver_t *sres_resolver_new_with_cache(char const *conf_file_path,
					      sres_cache_t *cache,
			                      char const *options, ...);

sres_resolver_t *sres_resolver_ref(sres_resolver_t *res);
void sres_resolver_unref(sres_resolver_t *res);

sres_resolver_t *sres_resolver_copy(sres_resolver_t *);

void *sres_resolver_set_userdata(sres_resolver_t *res, void *userdata);
void *sres_resolver_get_userdata(sres_resolver_t const *res);

@endcode

@subsection sresolv_blocking Using Sofia Resolver Synchronously

160 161 162
The blocking interface defined in <sofia-resolv/sres.h> makes it possible to
use Sofia resolver synchronously, that is, the function call making the DNS
query does not return until the query is responded or it times out.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184

@code
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <sofia-resolv/sres.h>

int sres_blocking_query(sres_resolver_t *res,
			uint16_t type,
			char const *domain,
			sres_record_t ***return_records);

int sres_blocking_query_sockaddr(sres_resolver_t *res,
				 uint16_t type,
				 struct sockaddr const *addr,
				 sres_record_t ***return_records);

@endcode

@subsection sresolv_async Asynchronous Interface in <sofia-resolv/sres_async.h>

185
It is also possible to use resolver asynchronously without #su_root_t object.
186 187 188 189 190 191 192 193

@code
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <sofia-resolv/sres_async.h>

194
sres_async_t *sres_resolver_set_async(sres_resolver_t *res,
195 196 197 198 199 200 201 202 203 204 205 206 207 208
				      sres_update_f *update,
				      sres_async_t *async,
				      int update_all);
sres_async_t *sres_resolver_get_async(sres_resolver_t const *res,
				      sres_update_f *update);

int sres_resolver_sockets(sres_resolver_t const *res, int *sockets, int n);
void sres_resolver_timer(sres_resolver_t *, int socket);

int sres_resolver_receive(sres_resolver_t *res, int socket);
int sres_resolver_error(sres_resolver_t *res, int socket);

@endcode

209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
Here is a short code fragment showing how to use resolver driven from
#su_root_t:

@code

#define SRES_CONTEXT_T struct context

#include <sofia-sip/sresolv.h>

...

struct context
{
  ...
  su_root_t *root;
  sres_resolver_t *sres;
  sres_query_t *query;
  ...
} *context;

...

  context->sres = sres_resolver_create(context->root, NULL, TAG_END());

...

  sres_record_t *results;

  results = sres_cached_answers(context->sres, sres_type_naptr, domain);
  if (results) {
    process_natpr(context, NULL, results);
  }
  else {
242
    context->query = sres_query(context->sres,
243 244 245 246 247 248 249 250 251 252 253 254 255
                                process_natpr, context,
	                        sres_type_naptr, domain);
    if (!context->query)
      process_naptr(context, NULL, NULL);
  }
}
...

void process_natpr(sres_context_t *context,
		   sres_query_t *q,
		   sres_record_t *answers[])
{
  sres_sort_answers(context->sres, answers);
256

257
  ...
258

259 260 261 262
  sres_free_answers(context->sres, answers);
}
@endcode

263
*/
264 265 266 267 268 269 270

/** @defgroup sresolv_env Environment Variables Used by sresolv Module

In addition to the standard #RES_OPTIONS and #LOCALDOMAIN environment
variables, the #SRES_OPTIONS and #SRESOLV_DEBUG variables are supported.

*/