Module: sip-router
Branch: master
Commit: d354557c249324874c413f7490fdf78a511b8184
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d354557…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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