Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


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"

Go to the source code of this file.

Data Structures

struct  dn_answer
 
struct  dns_HEADER
 

Macros

#define MAX_SIZE   4096
 

Functions

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. More...
 
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. More...
 
static int skip_name (unsigned char *s, int len)
 

Detailed Description

DNS Support for Asterisk.

Author
Thorsten Lockert tholo.nosp@m.@tro.nosp@m.llpho.nosp@m.ne.o.nosp@m.rg
Reference

Definition in file dns.c.

Macro Definition Documentation

#define MAX_SIZE   4096

Definition at line 48 of file dns.c.

Referenced by ast_search_dns().

Function Documentation

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

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

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

262 {
263 #ifdef HAVE_RES_NINIT
264  struct __res_state dnsstate;
265 #endif
266  unsigned char answer[MAX_SIZE];
267  int res, ret = -1;
268 
269 #ifdef HAVE_RES_NINIT
270  memset(&dnsstate, 0, sizeof(dnsstate));
271  res_ninit(&dnsstate);
272  res = res_nsearch(&dnsstate, dname, class, type, answer, sizeof(answer));
273 #else
274  ast_mutex_lock(&res_lock);
275  res_init();
276  res = res_search(dname, class, type, answer, sizeof(answer));
277 #endif
278  if (res > 0) {
279  if ((res = dns_parse_answer(context, class, type, answer, res, callback)) < 0) {
280  ast_log(LOG_WARNING, "DNS Parse error for %s\n", dname);
281  ret = -1;
282  } else if (res == 0) {
283  ast_debug(1, "No matches found in DNS for %s\n", dname);
284  ret = 0;
285  } else
286  ret = 1;
287  }
288 #ifdef HAVE_RES_NINIT
289 #ifdef HAVE_RES_NDESTROY
290  res_ndestroy(&dnsstate);
291 #else
292  res_nclose(&dnsstate);
293 #endif
294 #else
295 #ifdef HAVE_RES_CLOSE
296  res_close();
297 #endif
298  ast_mutex_unlock(&res_lock);
299 #endif
300 
301  return ret;
302 }
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char type[]
Definition: chan_nbs.c:57
#define MAX_SIZE
Definition: dns.c:48
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
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.
Definition: dns.c:189
#define ast_mutex_unlock(a)
Definition: lock.h:156
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, LOG_WARNING, dns_HEADER::qdcount, dn_answer::rtype, dn_answer::size, and skip_name().

Referenced by ast_search_dns().

192 {
193  unsigned char *fullanswer = answer;
194  struct dn_answer *ans;
195  dns_HEADER *h;
196  int ret = 0;
197  int res;
198  int x;
199 
200  h = (dns_HEADER *)answer;
201  answer += sizeof(dns_HEADER);
202  len -= sizeof(dns_HEADER);
203 
204  for (x = 0; x < ntohs(h->qdcount); x++) {
205  if ((res = skip_name(answer, len)) < 0) {
206  ast_log(LOG_WARNING, "Couldn't skip over name\n");
207  return -1;
208  }
209  answer += res + 4; /* Skip name and QCODE / QCLASS */
210  len -= res + 4;
211  if (len < 0) {
212  ast_log(LOG_WARNING, "Strange query size\n");
213  return -1;
214  }
215  }
216 
217  for (x = 0; x < ntohs(h->ancount); x++) {
218  if ((res = skip_name(answer, len)) < 0) {
219  ast_log(LOG_WARNING, "Failed skipping name\n");
220  return -1;
221  }
222  answer += res;
223  len -= res;
224  ans = (struct dn_answer *)answer;
225  answer += sizeof(struct dn_answer);
226  len -= sizeof(struct dn_answer);
227  if (len < 0) {
228  ast_log(LOG_WARNING, "Strange result size\n");
229  return -1;
230  }
231  if (len < 0) {
232  ast_log(LOG_WARNING, "Length exceeds frame\n");
233  return -1;
234  }
235 
236  if (ntohs(ans->class) == class && ntohs(ans->rtype) == type) {
237  if (callback) {
238  if ((res = callback(context, answer, ntohs(ans->size), fullanswer)) < 0) {
239  ast_log(LOG_WARNING, "Failed to parse result\n");
240  return -1;
241  }
242  ret = 1;
243  }
244  }
245  answer += ntohs(ans->size);
246  len -= ntohs(ans->size);
247  }
248  return ret;
249 }
unsigned ancount
Definition: dns.c:153
#define LOG_WARNING
Definition: logger.h:144
unsigned short size
Definition: dns.c:162
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
unsigned short class
Definition: dns.c:160
static const char type[]
Definition: chan_nbs.c:57
static int skip_name(unsigned char *s, int len)
Definition: dns.c:165
unsigned short rtype
Definition: dns.c:159
unsigned qdcount
Definition: dns.c:152
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
Definition: dns.c:158
static int skip_name ( unsigned char *  s,
int  len 
)
static

Definition at line 165 of file dns.c.

Referenced by dns_parse_answer().

166 {
167  int x = 0;
168 
169  while (x < len) {
170  if (*s == '\0') {
171  s++;
172  x++;
173  break;
174  }
175  if ((*s & 0xc0) == 0xc0) {
176  s += 2;
177  x += 2;
178  break;
179  }
180  x += *s + 1;
181  s += *s + 1;
182  }
183  if (x >= len)
184  return -1;
185  return x;
186 }
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)