Browse code

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)

Andrei Pelinescu-Onciul authored on 01/04/2009 16:48:52
Showing 4 changed files
... ...
@@ -61,6 +61,7 @@ void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
61 61
 void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
62 62
 void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
63 63
 void dns_cache_delete_ebl(rpc_t* rpc, void* ctx);
64
+void dns_cache_delete_ptr(rpc_t* rpc, void* ctx);
64 65
 
65 66
 
66 67
 static const char* dns_cache_mem_info_doc[] = {
... ...
@@ -142,6 +143,12 @@ static const char* dns_cache_delete_ebl_doc[] = {
142 143
 };
143 144
 
144 145
 
146
+static const char* dns_cache_delete_ptr_doc[] = {
147
+	"deletes an PTR record from the DNS cache",
148
+	0
149
+};
150
+
151
+
145 152
 #ifdef USE_DNS_CACHE_STATS
146 153
 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
147 154
 
... ...
@@ -747,6 +754,8 @@ rpc_export_t core_rpc_methods[] = {
747 754
 		dns_cache_delete_txt_doc,  0	},
748 755
 	{"dns.delete_ebl",         dns_cache_delete_ebl,
749 756
 		dns_cache_delete_ebl_doc,  0	},
757
+	{"dns.delete_ptr",         dns_cache_delete_ptr,
758
+		dns_cache_delete_ptr_doc,  0	},
750 759
 #ifdef USE_DNS_CACHE_STATS
751 760
 	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
752 761
 		0	},
... ...
@@ -46,6 +46,7 @@
46 46
                   aaaa) (andrei)
47 47
  *  2009-03-30  TXT record support, more rpcs (andrei)
48 48
  *  2009-03-30  EBL record support (andrei)
49
+ *  2009-04-01  PTR record support (andrei)
49 50
  */
50 51
 
51 52
 #ifdef USE_DNS_CACHE
... ...
@@ -1185,6 +1186,25 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1185 1186
 				 * just been elimintated */
1186 1187
 			}
1187 1188
 			break;
1189
+		case T_PTR:
1190
+			for(; *p;){
1191
+				if (!rec_matches((*p), type, name)){
1192
+					/* skip this record */
1193
+					p=&(*p)->next; /* advance */
1194
+					continue;
1195
+				}
1196
+				/* no padding */
1197
+				size+=ROUND_POINTER(sizeof(struct dns_rr)+
1198
+						PTR_RDATA_SIZE(*(struct ptr_rdata*)(*p)->rdata));
1199
+				/* add it to our tmp. lst */
1200
+				*tail=*p;
1201
+				tail=&(*p)->next;
1202
+				/* detach it from the rd list */
1203
+				*p=(*p)->next;
1204
+				/* don't advance p, because the crt. elem. has
1205
+				 * just been elimintated */
1206
+			}
1207
+			break;
1188 1208
 		default:
1189 1209
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1190 1210
 							"supported\n", type);
... ...
@@ -1359,6 +1379,20 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1359 1379
 				rr=rr->next;
1360 1380
 			}
1361 1381
 			break;
1382
+		case T_PTR:
1383
+			for(l=tmp_lst; l; l=l->next){
1384
+				ttl=FIX_TTL(l->ttl);
1385
+				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1386
+				max_ttl=MAX(max_ttl, ttl);
1387
+				rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
1388
+				memcpy(rr->rdata, l->rdata,
1389
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1390
+				rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
1391
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)));
1392
+				tail_rr=&(rr->next);
1393
+				rr=rr->next;
1394
+			}
1395
+			break;
1362 1396
 		default:
1363 1397
 			/* do nothing */
1364 1398
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: create: type %d not "
... ...
@@ -1484,6 +1518,11 @@ found:
1484 1518
 												sizeof(struct dns_rr))+
1485 1519
 							EBL_RDATA_SIZE(*(struct ebl_rdata*)l->rdata));
1486 1520
 				break;
1521
+			case T_PTR:
1522
+					/* no padding */
1523
+				rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
1524
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1525
+				break;
1487 1526
 			default:
1488 1527
 				LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1489 1528
 							"supported\n", l->type);
... ...
@@ -1645,6 +1684,19 @@ found:
1645 1684
 				rec[r].tail_rr=&(rec[r].rr->next);
1646 1685
 				rec[r].rr=rec[r].rr->next;
1647 1686
 				break;
1687
+			case T_PTR:
1688
+				rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1689
+				rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
1690
+				rec[r].rr->rdata=(void*)((char*)rec[r].rr
1691
+									+sizeof(struct dns_rr));
1692
+				memcpy(rec[r].rr->rdata, l->rdata,
1693
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1694
+				rec[r].rr->next=(void*)((char*)rec[r].rr+
1695
+							ROUND_POINTER(sizeof(struct dns_rr)+
1696
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)));
1697
+				rec[r].tail_rr=&(rec[r].rr->next);
1698
+				rec[r].rr=rec[r].rr->next;
1699
+				break;
1648 1700
 			default:
1649 1701
 				/* do nothing */
1650 1702
 				;
... ...
@@ -3599,6 +3651,10 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3599 3651
 							rpc->add(ctx, "ss", "ebl",
3600 3652
 								((struct ebl_rdata*)(rr->rdata))->apex);
3601 3653
 							break;
3654
+						case T_PTR:
3655
+							rpc->add(ctx, "ss", "ptr",
3656
+								((struct ptr_rdata*)(rr->rdata))->ptrdname);
3657
+							break;
3602 3658
 						default:
3603 3659
 							rpc->add(ctx, "ss", "unknown", "?");
3604 3660
 					}
... ...
@@ -3630,8 +3686,10 @@ static char *print_type(unsigned short type)
3630 3686
 			return "TXT";
3631 3687
 		case T_EBL:
3632 3688
 			return "EBL";
3689
+		case T_PTR:
3690
+			return "PTR";
3633 3691
 		default:
3634
-			return "unkown";
3692
+			return "unknown";
3635 3693
 	}
3636 3694
 }
3637 3695
 
... ...
@@ -3668,6 +3726,8 @@ static int dns_get_type(str* s)
3668 3726
 				return T_TXT;
3669 3727
 			else if (strncasecmp(t, "EBL", len)==0)
3670 3728
 				return T_EBL;
3729
+			else if (strncasecmp(t, "PTR", len)==0)
3730
+				return T_PTR;
3671 3731
 			break;
3672 3732
 		case 5:
3673 3733
 			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)
3693 3753
 
3694 3754
 	now=get_ticks_raw();
3695 3755
 	expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
3696
-	if (expires < 0) {
3697
-		return;
3698
-	}
3756
+	
3699 3757
 	rpc->printf(ctx, "%sname: %s", SPACE_FORMAT, e->name);
3700 3758
 	rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
3701 3759
 	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)
3770 3828
 				rpc->printf(ctx, "%srr apex: %s", SPACE_FORMAT,
3771 3829
 							((struct ebl_rdata*)(rr->rdata))->apex);
3772 3830
 				break;
3831
+			case T_PTR:
3832
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3833
+							((struct ptr_rdata*)(rr->rdata))->ptrdname);
3834
+				break;
3773 3835
 			default:
3774 3836
 				rpc->printf(ctx, "%sresource record: unknown",
3775 3837
 									SPACE_FORMAT);
... ...
@@ -3789,14 +3851,19 @@ void dns_cache_view(rpc_t* rpc, void* ctx)
3789 3851
 {
3790 3852
 	int h;
3791 3853
 	struct dns_hash_entry* e;
3854
+	ticks_t now;
3792 3855
 
3793 3856
 	if (!cfg_get(core, core_cfg, use_dns_cache)){
3794 3857
 		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
3795 3858
 		return;
3796 3859
 	}
3860
+	now=get_ticks_raw();
3797 3861
 	LOCK_DNS_HASH();
3798 3862
 	for (h=0; h<DNS_HASH_SIZE; h++){
3799 3863
 		clist_foreach(&dns_hash[h], e, next){
3864
+			if (TICKS_LT(e->expire, now)) {
3865
+				continue;
3866
+			}
3800 3867
 			rpc->printf(ctx, "{\n");
3801 3868
 			dns_cache_print_entry(rpc, ctx, e);
3802 3869
 			rpc->printf(ctx, "}");
... ...
@@ -3872,6 +3939,9 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3872 3939
 			case T_EBL:
3873 3940
 				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3874 3941
 				break;
3942
+			case T_PTR:
3943
+				rr_size = sizeof(struct dns_rr);
3944
+				break;
3875 3945
 			default:
3876 3946
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not "
3877 3947
 							"supported\n", e->type);
... ...
@@ -4021,6 +4091,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
4021 4091
 	case T_NAPTR:
4022 4092
 	case T_TXT:
4023 4093
 	case T_EBL:
4094
+	case T_PTR:
4024 4095
 		rpc->fault(ctx, 400, "not implemented");
4025 4096
 		return;
4026 4097
 	default:
... ...
@@ -4328,6 +4399,11 @@ void dns_cache_delete_ebl(rpc_t* rpc, void* ctx)
4328 4399
 	dns_cache_delete_record(rpc, ctx, T_EBL);
4329 4400
 }
4330 4401
 
4402
+void dns_cache_delete_ptr(rpc_t* rpc, void* ctx)
4403
+{
4404
+	dns_cache_delete_record(rpc, ctx, T_PTR);
4405
+}
4406
+
4331 4407
 
4332 4408
 
4333 4409
 #ifdef DNS_WATCHDOG_SUPPORT
... ...
@@ -44,6 +44,9 @@
44 44
  *  2008-01-31  resolver options use the configuration framework, and the
45 45
  *               resolver is reinitialized when the options change (Miklos)
46 46
  *  2008-08-12  sctp preference support for NAPTR queries (andrei)
47
+ *  2009-03-30  TXT record support (andrei)
48
+ *  2009-03-31  EBL record support (andrei)
49
+ *  2009-04-01  PTR record support (andrei)
47 50
  */ 
48 51
 
49 52
 
... ...
@@ -591,6 +594,37 @@ error:
591 594
 
592 595
 
593 596
 
597
+/* parses a PTR record into a ptr_rdata structure */
598
+struct ptr_rdata* dns_ptr_parser( unsigned char* msg, unsigned char* end,
599
+									  unsigned char* rdata)
600
+{
601
+	struct ptr_rdata* pname;
602
+	int len;
603
+	char name[MAX_DNS_NAME];
604
+	
605
+	pname=0;
606
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
607
+		goto error;
608
+	len=strlen(name);
609
+	if (len>255)
610
+		goto error;
611
+	/* alloc sizeof struct + space for the null terminated name */
612
+	pname=local_malloc(sizeof(struct ptr_rdata)-1+len+1);
613
+	if(pname==0){
614
+		LOG(L_ERR, "ERROR: dns_ptr_parser: out of memory\n");
615
+		goto error;
616
+	}
617
+	pname->ptrdname_len=len;
618
+	memcpy(pname->ptrdname, name, pname->ptrdname_len);
619
+	pname->ptrdname[pname->ptrdname_len]=0;
620
+	return pname;
621
+error:
622
+	if (pname) local_free(pname);
623
+	return 0;
624
+}
625
+
626
+
627
+
594 628
 /* frees completely a struct rdata list */
595 629
 void free_rdata_list(struct rdata* head)
596 630
 {
... ...
@@ -836,6 +870,12 @@ again:
836 870
 				*last=rd;
837 871
 				last=&(rd->next);
838 872
 				break;
873
+			case T_PTR:
874
+				rd->rdata=(void*) dns_ptr_parser(buff.buff, end, p);
875
+				if(unlikely(rd->rdata==0)) goto error_parse;
876
+				*last=rd;
877
+				last=&(rd->next);
878
+				break;
839 879
 			default:
840 880
 				LOG(L_ERR, "WARNING: get_record: unknown type %d\n", rtype);
841 881
 				rd->rdata=0;
... ...
@@ -188,6 +188,14 @@ struct ebl_rdata {
188 188
 	(sizeof(struct ebl_rdata)-1+(s).separator_len+1+(s).apex_len+1)
189 189
 
190 190
 
191
+struct ptr_rdata {
192
+	unsigned char ptrdname_len; /* name length w/o the terminating 0 */
193
+	char ptrdname[1]; /* null terminated name (len=name_len+1) */
194
+};
195
+/* real size of the structure */
196
+#define PTR_RDATA_SIZE(s) (sizeof(struct ptr_rdata)-1+(s).ptrdname_len+1)
197
+
198
+
191 199
 #ifdef HAVE_RESOLV_RES
192 200
 int match_search_list(const struct __res_state* res, char* name);
193 201
 #endif