#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__ |
Definition in file dns.c.
| #define MAX_SIZE 4096 |
| 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).
| 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 }
| struct dn_answer __packed__ |
1.5.1