dns.c File Reference

DNS Support for Asterisk. More...

#include "asterisk.h"
#include "asterisk/network.h"
#include <arpa/nameser.h>
#include <resolv.h>
#include "asterisk/channel.h"
#include "asterisk/dns.h"
#include "asterisk/endian.h"

Include dependency graph for dns.c:

Go to the source code of this file.

Data Structures

struct  dn_answer
struct  dns_HEADER

Defines

#define MAX_SIZE   4096

Functions

struct ao2_containerast_dns_get_nameservers (void)
 Retrieve the configured nameservers of the system.
int ast_search_dns (void *context, const char *dname, int class, int type, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
 Lookup record in DNS.
static int dns_parse_answer (void *context, int class, int type, unsigned char *answer, int len, int(*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer))
 Parse DNS lookup result, call callback.
static int skip_name (unsigned char *s, int len)

Variables

static ast_mutex_t res_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 }


Detailed Description

DNS Support for Asterisk.

Author:
Thorsten Lockert <tholo@trollphone.org>
Reference

Definition in file dns.c.


Define Documentation

#define MAX_SIZE   4096

Definition at line 48 of file dns.c.

Referenced by ast_search_dns().


Function Documentation

struct ao2_container* ast_dns_get_nameservers ( void   )  [read]

Retrieve the configured nameservers of the system.

Definition at line 300 of file dns.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_str_container_add(), ast_str_container_alloc_options(), NULL, and res_lock.

Referenced by system_create_resolver_and_set_nameservers().

00301 {
00302 #ifdef HAVE_RES_NINIT
00303    struct __res_state dnsstate;
00304 #endif
00305    struct __res_state *state;
00306    struct ao2_container *nameservers;
00307    int i;
00308 
00309    nameservers = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 3);
00310    if (!nameservers) {
00311       return NULL;
00312    }
00313 
00314 #ifdef HAVE_RES_NINIT
00315    memset(&dnsstate, 0, sizeof(dnsstate));
00316    res_ninit(&dnsstate);
00317    state = &dnsstate;
00318 #else
00319    ast_mutex_lock(&res_lock);
00320    res_init();
00321    state = &_res;
00322 #endif
00323 
00324    for (i = 0; i < state->nscount; i++) {
00325       ast_str_container_add(nameservers, ast_inet_ntoa(state->nsaddr_list[i].sin_addr));
00326    }
00327 
00328 #ifdef HAVE_RES_NINIT
00329 #ifdef HAVE_RES_NDESTROY
00330    res_ndestroy(&dnsstate);
00331 #else
00332    res_nclose(&dnsstate);
00333 #endif
00334 #else
00335 #ifdef HAVE_RES_CLOSE
00336    res_close();
00337 #endif
00338    ast_mutex_unlock(&res_lock);
00339 #endif
00340 
00341    return nameservers;
00342 }

int ast_search_dns ( void *  context,
const char *  dname,
int  class,
int  type,
int(*)(void *context, unsigned char *answer, int len, unsigned char *fullanswer)  callback 
)

Lookup record in DNS.

Perform DNS lookup (used by DNS, enum and SRV lookups).

Note:
Asterisk DNS is synchronus at this time. This means that if your DNS does not work properly, Asterisk might not start properly or a channel may lock.

Definition at line 255 of file dns.c.

References ast_debug, ast_log, ast_mutex_lock, ast_mutex_unlock, dns_parse_answer(), LOG_WARNING, MAX_SIZE, and res_lock.

Referenced by ast_get_enum(), ast_get_srv(), ast_srv_lookup(), blr_ebl(), and blr_txt().

00258 {
00259 #ifdef HAVE_RES_NINIT
00260    struct __res_state dnsstate;
00261 #endif
00262    unsigned char answer[MAX_SIZE];
00263    int res, ret = -1;
00264 
00265 #ifdef HAVE_RES_NINIT
00266    memset(&dnsstate, 0, sizeof(dnsstate));
00267    res_ninit(&dnsstate);
00268    res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
00269 #else
00270    ast_mutex_lock(&res_lock);
00271    res_init();
00272    res = res_search(dname, class, type, answer, sizeof(answer));
00273 #endif
00274    if (res > 0) {
00275       if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) {
00276          ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname);
00277          ret = -1;
00278       } else if (res == 0) {
00279          ast_debug(1, "No matches found in DNS for %s\n", dname);
00280          ret = 0;
00281       } else
00282          ret = 1;
00283    }
00284 #ifdef HAVE_RES_NINIT
00285 #ifdef HAVE_RES_NDESTROY
00286    res_ndestroy(&dnsstate);
00287 #else
00288    res_nclose(&dnsstate);
00289 #endif
00290 #else
00291 #ifdef HAVE_RES_CLOSE
00292    res_close();
00293 #endif
00294    ast_mutex_unlock(&res_lock);
00295 #endif
00296 
00297    return ret;
00298 }

static int dns_parse_answer ( void *  context,
int  class,
int  type,
unsigned char *  answer,
int  len,
int(*)(void *context, unsigned char *answer, int len, unsigned char *fullanswer)  callback 
) [static]

Parse DNS lookup result, call callback.

Definition at line 189 of file dns.c.

References dns_HEADER::ancount, ast_log, dn_answer::class, h, LOG_WARNING, dns_HEADER::qdcount, dn_answer::rtype, dn_answer::size, and skip_name().

Referenced by ast_search_dns().

00192 {
00193    unsigned char *fullanswer = answer;
00194    struct dn_answer *ans;
00195    dns_HEADER *h;
00196    int ret = 0;
00197    int res;
00198    int x;
00199 
00200    h = (dns_HEADER *)answer;
00201    answer += sizeof(dns_HEADER);
00202    len -= sizeof(dns_HEADER);
00203 
00204    for (x = 0; x < ntohs(h->qdcount); x++) {
00205       if ((res = skip_name(answer, len)) < 0) {
00206          ast_log(LOG_WARNING, "Couldn't skip over name\n");
00207          return -1;
00208       }
00209       answer += res + 4;   /* Skip name and QCODE / QCLASS */
00210       len -= res + 4;
00211       if (len < 0) {
00212          ast_log(LOG_WARNING, "Strange query size\n");
00213          return -1;
00214       }
00215    }
00216 
00217    for (x = 0; x < ntohs(h->ancount); x++) {
00218       if ((res = skip_name(answer, len)) < 0) {
00219          ast_log(LOG_WARNING, "Failed skipping name\n");
00220          return -1;
00221       }
00222       answer += res;
00223       len -= res;
00224       ans = (struct dn_answer *)answer;
00225       answer += sizeof(struct dn_answer);
00226       len -= sizeof(struct dn_answer);
00227       if (len < 0) {
00228          ast_log(LOG_WARNING, "Length of DNS answer exceeds frame\n");
00229          return -1;
00230       }
00231 
00232       if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
00233          if (callback) {
00234             if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
00235                ast_log(LOG_WARNING, "Failed to parse result\n");
00236                return -1;
00237             }
00238             ret = 1;
00239          }
00240       }
00241       answer += ntohs(ans->size);
00242       len -= ntohs(ans->size);
00243    }
00244    return ret;
00245 }

static int skip_name ( unsigned char *  s,
int  len 
) [static]

Definition at line 165 of file dns.c.

Referenced by dns_parse_answer().

00166 {
00167    int x = 0;
00168 
00169    while (x < len) {
00170       if (*s == '\0') {
00171          s++;
00172          x++;
00173          break;
00174       }
00175       if ((*s & 0xc0) == 0xc0) {
00176          s += 2;
00177          x += 2;
00178          break;
00179       }
00180       x += *s + 1;
00181       s += *s + 1;
00182    }
00183    if (x >= len)
00184       return -1;
00185    return x;
00186 }


Variable Documentation

ast_mutex_t res_lock = { PTHREAD_MUTEX_INITIALIZER , NULL, 1 } [static]

Definition at line 248 of file dns.c.

Referenced by ast_dns_get_nameservers(), and ast_search_dns().


Generated on Thu Apr 16 06:30:41 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6