[SR-Dev] git:master: dns: PTR support

Andrei Pelinescu-Onciul andrei at iptel.org
Wed Apr 1 18:51:27 CEST 2009


Module: sip-router
Branch: master
Commit: d354557c249324874c413f7490fdf78a511b8184
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=d354557c249324874c413f7490fdf78a511b8184

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at 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




More information about the sr-dev mailing list