Mon May 14 04:47:26 2007

Asterisk developer's documentation


dns.c File Reference

DNS Support for Asterisk. More...

#include "asterisk.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <unistd.h>
#include "asterisk/logger.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

 AST_MUTEX_DEFINE_STATIC (res_lock)
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))
 Perform DNS lookup (used by DNS, enum and SRV lookups).
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

dn_answer __packed__


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

AST_MUTEX_DEFINE_STATIC ( res_lock   ) 

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 
)

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 188 of file dns.c.

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

Referenced by ast_get_enum(), ast_get_srv(), and ast_get_txt().

00191 {
00192 #if HAVE_RES_NINIT
00193    struct __res_state dnsstate;
00194 #endif
00195    unsigned char answer[MAX_SIZE];
00196    int res, ret = -1;
00197 
00198 #if HAVE_RES_NINIT
00199    res_ninit(&dnsstate);
00200    res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
00201 #else
00202    ast_mutex_lock(&res_lock);
00203    res_init();
00204    res = res_search(dname, class, type, answer, sizeof(answer));
00205 #endif
00206    if (res > 0) {
00207       if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) {
00208          ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname);
00209          ret = -1;
00210       }
00211       else if (ret == 0) {
00212          ast_log(LOG_DEBUG, "No matches found in DNS for %s\n", dname);
00213          ret = 0;
00214       }
00215       else
00216          ret = 1;
00217    }
00218 #if HAVE_RES_NINIT
00219    res_nclose(&dnsstate);
00220 #else
00221 #ifndef __APPLE__
00222    res_close();
00223 #endif
00224    ast_mutex_unlock(&res_lock);
00225 #endif
00226 
00227    return ret;
00228 }

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 118 of file dns.c.

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

Referenced by ast_search_dns().

00121 {
00122    unsigned char *fullanswer = answer;
00123    struct dn_answer *ans;
00124    dns_HEADER *h;
00125    int res;
00126    int x;
00127 
00128    h = (dns_HEADER *)answer;
00129    answer += sizeof(dns_HEADER);
00130    len -= sizeof(dns_HEADER);
00131 
00132    for (x = 0; x < ntohs(h->qdcount); x++) {
00133       if ((res = skip_name(answer, len)) < 0) {
00134          ast_log(LOG_WARNING, "Couldn't skip over name\n");
00135          return -1;
00136       }
00137       answer += res + 4;   /* Skip name and QCODE / QCLASS */
00138       len -= res + 4;
00139       if (len < 0) {
00140          ast_log(LOG_WARNING, "Strange query size\n");
00141          return -1;
00142       }
00143    }
00144 
00145    for (x = 0; x < ntohs(h->ancount); x++) {
00146       if ((res = skip_name(answer, len)) < 0) {
00147          ast_log(LOG_WARNING, "Failed skipping name\n");
00148          return -1;
00149       }
00150       answer += res;
00151       len -= res;
00152       ans = (struct dn_answer *)answer;
00153       answer += sizeof(struct dn_answer);
00154       len -= sizeof(struct dn_answer);
00155       if (len < 0) {
00156          ast_log(LOG_WARNING, "Strange result size\n");
00157          return -1;
00158       }
00159       if (len < 0) {
00160          ast_log(LOG_WARNING, "Length exceeds frame\n");
00161          return -1;
00162       }
00163 
00164       if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
00165          if (callback) {
00166             if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
00167                ast_log(LOG_WARNING, "Failed to parse result\n");
00168                return -1;
00169             }
00170             if (res > 0)
00171                return 1;
00172          }
00173       }
00174       answer += ntohs(ans->size);
00175       len -= ntohs(ans->size);
00176    }
00177    return 0;
00178 }

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

Definition at line 94 of file dns.c.

Referenced by dns_parse_answer().

00095 {
00096    int x = 0;
00097 
00098    while (x < len) {
00099       if (*s == '\0') {
00100          s++;
00101          x++;
00102          break;
00103       }
00104       if ((*s & 0xc0) == 0xc0) {
00105          s += 2;
00106          x += 2;
00107          break;
00108       }
00109       x += *s + 1;
00110       s += *s + 1;
00111    }
00112    if (x >= len)
00113       return -1;
00114    return x;
00115 }


Variable Documentation

struct dn_answer __packed__


Generated on Mon May 14 04:47:26 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1