Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:47 2009

## 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

struct 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 ast_iax2_firmware_header __packed__