Sat Nov 1 06:31:02 2008

Asterisk developer's documentation


dns.c File Reference

DNS Support for Asterisk. More...

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <unistd.h>
#include "asterisk.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, char *answer, int len, char *fullanswer))
 Perform DNS lookup (used by enum and SRV lookups).
static int dns_parse_answer (void *context, int class, int type, char *answer, int len, int(*callback)(void *context, char *answer, int len, char *fullanswer))
static int skip_name (char *s, int len)

Variables

dn_answer __packed__


Detailed Description

DNS Support for Asterisk.

Author:
Thorsten Lockert <tholo@trollphone.org>

Definition in file dns.c.


Define Documentation

#define MAX_SIZE   4096

Definition at line 44 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, char *answer, int len, char *fullanswer)  callback 
)

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

Parameters:
context 
dname Domain name to lookup (host, SRV domain, TXT record name)
class Record Class (see "man res_search")
type Record type (see "man res_search")
callback Callback function for handling DNS result

Definition at line 248 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().

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

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

Definition at line 173 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().

00176 {
00177    char *fullanswer = answer;
00178    struct dn_answer *ans;
00179    dns_HEADER *h;
00180    int res;
00181    int x;
00182 
00183    h = (dns_HEADER *)answer;
00184    answer += sizeof(dns_HEADER);
00185    len -= sizeof(dns_HEADER);
00186 
00187    for (x = 0; x < ntohs(h->qdcount); x++) {
00188       if ((res = skip_name(answer, len)) < 0) {
00189          ast_log(LOG_WARNING, "Couldn't skip over name\n");
00190          return -1;
00191       }
00192       answer += res + 4;   /* Skip name and QCODE / QCLASS */
00193       len -= res + 4;
00194       if (len < 0) {
00195          ast_log(LOG_WARNING, "Strange query size\n");
00196          return -1;
00197       }
00198    }
00199 
00200    for (x = 0; x < ntohs(h->ancount); x++) {
00201       if ((res = skip_name(answer, len)) < 0) {
00202          ast_log(LOG_WARNING, "Failed skipping name\n");
00203          return -1;
00204       }
00205       answer += res;
00206       len -= res;
00207       ans = (struct dn_answer *)answer;
00208       answer += sizeof(struct dn_answer);
00209       len -= sizeof(struct dn_answer);
00210       if (len < 0) {
00211          ast_log(LOG_WARNING, "Strange result size\n");
00212          return -1;
00213       }
00214       if (len < 0) {
00215          ast_log(LOG_WARNING, "Length exceeds frame\n");
00216          return -1;
00217       }
00218 
00219       if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
00220          if (callback) {
00221             if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
00222                ast_log(LOG_WARNING, "Failed to parse result\n");
00223                return -1;
00224             }
00225             if (res > 0)
00226                return 1;
00227          }
00228       }
00229       answer += ntohs(ans->size);
00230       len -= ntohs(ans->size);
00231    }
00232    return 0;
00233 }

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

Definition at line 149 of file dns.c.

Referenced by dns_parse_answer().

00150 {
00151    int x = 0;
00152 
00153    while (x < len) {
00154       if (*s == '\0') {
00155          s++;
00156          x++;
00157          break;
00158       }
00159       if ((*s & 0xc0) == 0xc0) {
00160          s += 2;
00161          x += 2;
00162          break;
00163       }
00164       x += *s + 1;
00165       s += *s + 1;
00166    }
00167    if (x >= len)
00168       return -1;
00169    return x;
00170 }


Variable Documentation

struct dn_answer __packed__


Generated on Sat Nov 1 06:31:02 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1