Module: sip-router Branch: master Commit: d354557c249324874c413f7490fdf78a511b8184 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d354557c...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Wed Apr 1 18:48:52 2009 +0200
dns: PTR support
- PTR resolve support - PTR dns cache support - rpc dns.delete_ptr (e.g. sercmd dns.delete_ptr 56.1.10.10.in-addr.arpa)
---
core_cmd.c | 9 ++++++ dns_cache.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- resolve.c | 40 ++++++++++++++++++++++++++++ resolve.h | 8 +++++ 4 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/core_cmd.c b/core_cmd.c index c19502c..c4af7a7 100644 --- a/core_cmd.c +++ b/core_cmd.c @@ -61,6 +61,7 @@ void dns_cache_delete_naptr(rpc_t* rpc, void* ctx); void dns_cache_delete_cname(rpc_t* rpc, void* ctx); void dns_cache_delete_txt(rpc_t* rpc, void* ctx); void dns_cache_delete_ebl(rpc_t* rpc, void* ctx); +void dns_cache_delete_ptr(rpc_t* rpc, void* ctx);
static const char* dns_cache_mem_info_doc[] = { @@ -142,6 +143,12 @@ static const char* dns_cache_delete_ebl_doc[] = { };
+static const char* dns_cache_delete_ptr_doc[] = { + "deletes an PTR record from the DNS cache", + 0 +}; + + #ifdef USE_DNS_CACHE_STATS void dns_cache_stats_get(rpc_t* rpc, void* ctx);
@@ -747,6 +754,8 @@ rpc_export_t core_rpc_methods[] = { dns_cache_delete_txt_doc, 0 }, {"dns.delete_ebl", dns_cache_delete_ebl, dns_cache_delete_ebl_doc, 0 }, + {"dns.delete_ptr", dns_cache_delete_ptr, + dns_cache_delete_ptr_doc, 0 }, #ifdef USE_DNS_CACHE_STATS {"dns.stats_get", dns_cache_stats_get, dns_cache_stats_get_doc, 0 }, diff --git a/dns_cache.c b/dns_cache.c index 87aaf60..0a39438 100644 --- a/dns_cache.c +++ b/dns_cache.c @@ -46,6 +46,7 @@ aaaa) (andrei) * 2009-03-30 TXT record support, more rpcs (andrei) * 2009-03-30 EBL record support (andrei) + * 2009-04-01 PTR record support (andrei) */
#ifdef USE_DNS_CACHE @@ -1185,6 +1186,25 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type, * just been elimintated */ } break; + case T_PTR: + for(; *p;){ + if (!rec_matches((*p), type, name)){ + /* skip this record */ + p=&(*p)->next; /* advance */ + continue; + } + /* no padding */ + size+=ROUND_POINTER(sizeof(struct dns_rr)+ + PTR_RDATA_SIZE(*(struct ptr_rdata*)(*p)->rdata)); + /* add it to our tmp. lst */ + *tail=*p; + tail=&(*p)->next; + /* detach it from the rd list */ + *p=(*p)->next; + /* don't advance p, because the crt. elem. has + * just been elimintated */ + } + break; default: LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not " "supported\n", type); @@ -1359,6 +1379,20 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type, rr=rr->next; } break; + case T_PTR: + for(l=tmp_lst; l; l=l->next){ + ttl=FIX_TTL(l->ttl); + rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */ + max_ttl=MAX(max_ttl, ttl); + rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr)); + memcpy(rr->rdata, l->rdata, + PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)); + rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+ + PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata))); + tail_rr=&(rr->next); + rr=rr->next; + } + break; default: /* do nothing */ LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: create: type %d not " @@ -1484,6 +1518,11 @@ found: sizeof(struct dns_rr))+ EBL_RDATA_SIZE(*(struct ebl_rdata*)l->rdata)); break; + case T_PTR: + /* no padding */ + rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+ + PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)); + break; default: LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not " "supported\n", l->type); @@ -1645,6 +1684,19 @@ found: rec[r].tail_rr=&(rec[r].rr->next); rec[r].rr=rec[r].rr->next; break; + case T_PTR: + rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */ + rec[r].max_ttl=MAX(rec[r].max_ttl, ttl); + rec[r].rr->rdata=(void*)((char*)rec[r].rr + +sizeof(struct dns_rr)); + memcpy(rec[r].rr->rdata, l->rdata, + PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)); + rec[r].rr->next=(void*)((char*)rec[r].rr+ + ROUND_POINTER(sizeof(struct dns_rr)+ + PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata))); + rec[r].tail_rr=&(rec[r].rr->next); + rec[r].rr=rec[r].rr->next; + break; default: /* do nothing */ ; @@ -3599,6 +3651,10 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx) rpc->add(ctx, "ss", "ebl", ((struct ebl_rdata*)(rr->rdata))->apex); break; + case T_PTR: + rpc->add(ctx, "ss", "ptr", + ((struct ptr_rdata*)(rr->rdata))->ptrdname); + break; default: rpc->add(ctx, "ss", "unknown", "?"); } @@ -3630,8 +3686,10 @@ static char *print_type(unsigned short type) return "TXT"; case T_EBL: return "EBL"; + case T_PTR: + return "PTR"; default: - return "unkown"; + return "unknown"; } }
@@ -3668,6 +3726,8 @@ static int dns_get_type(str* s) return T_TXT; else if (strncasecmp(t, "EBL", len)==0) return T_EBL; + else if (strncasecmp(t, "PTR", len)==0) + return T_PTR; break; case 5: if (strncasecmp(t, "NAPTR", len)==0) @@ -3693,9 +3753,7 @@ void dns_cache_print_entry(rpc_t* rpc, void* ctx, struct dns_hash_entry* e)
now=get_ticks_raw(); expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now); - if (expires < 0) { - return; - } + rpc->printf(ctx, "%sname: %s", SPACE_FORMAT, e->name); rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type)); rpc->printf(ctx, "%ssize (bytes): %d", SPACE_FORMAT, @@ -3770,6 +3828,10 @@ void dns_cache_print_entry(rpc_t* rpc, void* ctx, struct dns_hash_entry* e) rpc->printf(ctx, "%srr apex: %s", SPACE_FORMAT, ((struct ebl_rdata*)(rr->rdata))->apex); break; + case T_PTR: + rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT, + ((struct ptr_rdata*)(rr->rdata))->ptrdname); + break; default: rpc->printf(ctx, "%sresource record: unknown", SPACE_FORMAT); @@ -3789,14 +3851,19 @@ void dns_cache_view(rpc_t* rpc, void* ctx) { int h; struct dns_hash_entry* e; + ticks_t now;
if (!cfg_get(core, core_cfg, use_dns_cache)){ rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)"); return; } + now=get_ticks_raw(); LOCK_DNS_HASH(); for (h=0; h<DNS_HASH_SIZE; h++){ clist_foreach(&dns_hash[h], e, next){ + if (TICKS_LT(e->expire, now)) { + continue; + } rpc->printf(ctx, "{\n"); dns_cache_print_entry(rpc, ctx, e); rpc->printf(ctx, "}"); @@ -3872,6 +3939,9 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e, case T_EBL: rr_size = ROUND_POINTER(sizeof(struct dns_rr)); break; + case T_PTR: + rr_size = sizeof(struct dns_rr); + break; default: LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not " "supported\n", e->type); @@ -4021,6 +4091,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type) case T_NAPTR: case T_TXT: case T_EBL: + case T_PTR: rpc->fault(ctx, 400, "not implemented"); return; default: @@ -4328,6 +4399,11 @@ void dns_cache_delete_ebl(rpc_t* rpc, void* ctx) dns_cache_delete_record(rpc, ctx, T_EBL); }
+void dns_cache_delete_ptr(rpc_t* rpc, void* ctx) +{ + dns_cache_delete_record(rpc, ctx, T_PTR); +} +
#ifdef DNS_WATCHDOG_SUPPORT diff --git a/resolve.c b/resolve.c index 9e8d98b..bb850b5 100644 --- a/resolve.c +++ b/resolve.c @@ -44,6 +44,9 @@ * 2008-01-31 resolver options use the configuration framework, and the * resolver is reinitialized when the options change (Miklos) * 2008-08-12 sctp preference support for NAPTR queries (andrei) + * 2009-03-30 TXT record support (andrei) + * 2009-03-31 EBL record support (andrei) + * 2009-04-01 PTR record support (andrei) */
@@ -591,6 +594,37 @@ error:
+/* parses a PTR record into a ptr_rdata structure */ +struct ptr_rdata* dns_ptr_parser( unsigned char* msg, unsigned char* end, + unsigned char* rdata) +{ + struct ptr_rdata* pname; + int len; + char name[MAX_DNS_NAME]; + + pname=0; + if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1) + goto error; + len=strlen(name); + if (len>255) + goto error; + /* alloc sizeof struct + space for the null terminated name */ + pname=local_malloc(sizeof(struct ptr_rdata)-1+len+1); + if(pname==0){ + LOG(L_ERR, "ERROR: dns_ptr_parser: out of memory\n"); + goto error; + } + pname->ptrdname_len=len; + memcpy(pname->ptrdname, name, pname->ptrdname_len); + pname->ptrdname[pname->ptrdname_len]=0; + return pname; +error: + if (pname) local_free(pname); + return 0; +} + + + /* frees completely a struct rdata list */ void free_rdata_list(struct rdata* head) { @@ -836,6 +870,12 @@ again: *last=rd; last=&(rd->next); break; + case T_PTR: + rd->rdata=(void*) dns_ptr_parser(buff.buff, end, p); + if(unlikely(rd->rdata==0)) goto error_parse; + *last=rd; + last=&(rd->next); + break; default: LOG(L_ERR, "WARNING: get_record: unknown type %d\n", rtype); rd->rdata=0; diff --git a/resolve.h b/resolve.h index b4cb90c..65bd0c0 100644 --- a/resolve.h +++ b/resolve.h @@ -188,6 +188,14 @@ struct ebl_rdata { (sizeof(struct ebl_rdata)-1+(s).separator_len+1+(s).apex_len+1)
+struct ptr_rdata { + unsigned char ptrdname_len; /* name length w/o the terminating 0 */ + char ptrdname[1]; /* null terminated name (len=name_len+1) */ +}; +/* real size of the structure */ +#define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata)-1+(s).ptrdname_len+1) + + #ifdef HAVE_RESOLV_RES int match_search_list(const struct __res_state* res, char* name); #endif