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 142
 };
143 143
 
144 144
 
145
+static const char* dns_cache_delete_ptr_doc[] = {
146
+	"deletes an PTR record from the DNS cache",
147
+	0
148
+};
149
+
150
+
145 151
 #ifdef USE_DNS_CACHE_STATS
146 152
 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
147 153
 
... ...
@@ -747,6 +754,8 @@ rpc_export_t core_rpc_methods[] = {
747 747
 		dns_cache_delete_txt_doc,  0	},
748 748
 	{"dns.delete_ebl",         dns_cache_delete_ebl,
749 749
 		dns_cache_delete_ebl_doc,  0	},
750
+	{"dns.delete_ptr",         dns_cache_delete_ptr,
751
+		dns_cache_delete_ptr_doc,  0	},
750 752
 #ifdef USE_DNS_CACHE_STATS
751 753
 	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
752 754
 		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 1185
 				 * just been elimintated */
1186 1186
 			}
1187 1187
 			break;
1188
+		case T_PTR:
1189
+			for(; *p;){
1190
+				if (!rec_matches((*p), type, name)){
1191
+					/* skip this record */
1192
+					p=&(*p)->next; /* advance */
1193
+					continue;
1194
+				}
1195
+				/* no padding */
1196
+				size+=ROUND_POINTER(sizeof(struct dns_rr)+
1197
+						PTR_RDATA_SIZE(*(struct ptr_rdata*)(*p)->rdata));
1198
+				/* add it to our tmp. lst */
1199
+				*tail=*p;
1200
+				tail=&(*p)->next;
1201
+				/* detach it from the rd list */
1202
+				*p=(*p)->next;
1203
+				/* don't advance p, because the crt. elem. has
1204
+				 * just been elimintated */
1205
+			}
1206
+			break;
1188 1207
 		default:
1189 1208
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1190 1209
 							"supported\n", type);
... ...
@@ -1359,6 +1379,20 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1359 1359
 				rr=rr->next;
1360 1360
 			}
1361 1361
 			break;
1362
+		case T_PTR:
1363
+			for(l=tmp_lst; l; l=l->next){
1364
+				ttl=FIX_TTL(l->ttl);
1365
+				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1366
+				max_ttl=MAX(max_ttl, ttl);
1367
+				rr->rdata=(void*)((char*)rr+sizeof(struct dns_rr));
1368
+				memcpy(rr->rdata, l->rdata,
1369
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1370
+				rr->next=(void*)((char*)rr+ROUND_POINTER(sizeof(struct dns_rr)+
1371
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)));
1372
+				tail_rr=&(rr->next);
1373
+				rr=rr->next;
1374
+			}
1375
+			break;
1362 1376
 		default:
1363 1377
 			/* do nothing */
1364 1378
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: create: type %d not "
... ...
@@ -1484,6 +1518,11 @@ found:
1484 1484
 												sizeof(struct dns_rr))+
1485 1485
 							EBL_RDATA_SIZE(*(struct ebl_rdata*)l->rdata));
1486 1486
 				break;
1487
+			case T_PTR:
1488
+					/* no padding */
1489
+				rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
1490
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1491
+				break;
1487 1492
 			default:
1488 1493
 				LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1489 1494
 							"supported\n", l->type);
... ...
@@ -1645,6 +1684,19 @@ found:
1645 1645
 				rec[r].tail_rr=&(rec[r].rr->next);
1646 1646
 				rec[r].rr=rec[r].rr->next;
1647 1647
 				break;
1648
+			case T_PTR:
1649
+				rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1650
+				rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
1651
+				rec[r].rr->rdata=(void*)((char*)rec[r].rr
1652
+									+sizeof(struct dns_rr));
1653
+				memcpy(rec[r].rr->rdata, l->rdata,
1654
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata));
1655
+				rec[r].rr->next=(void*)((char*)rec[r].rr+
1656
+							ROUND_POINTER(sizeof(struct dns_rr)+
1657
+							PTR_RDATA_SIZE(*(struct ptr_rdata*)l->rdata)));
1658
+				rec[r].tail_rr=&(rec[r].rr->next);
1659
+				rec[r].rr=rec[r].rr->next;
1660
+				break;
1648 1661
 			default:
1649 1662
 				/* do nothing */
1650 1663
 				;
... ...
@@ -3599,6 +3651,10 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3599 3599
 							rpc->add(ctx, "ss", "ebl",
3600 3600
 								((struct ebl_rdata*)(rr->rdata))->apex);
3601 3601
 							break;
3602
+						case T_PTR:
3603
+							rpc->add(ctx, "ss", "ptr",
3604
+								((struct ptr_rdata*)(rr->rdata))->ptrdname);
3605
+							break;
3602 3606
 						default:
3603 3607
 							rpc->add(ctx, "ss", "unknown", "?");
3604 3608
 					}
... ...
@@ -3630,8 +3686,10 @@ static char *print_type(unsigned short type)
3630 3630
 			return "TXT";
3631 3631
 		case T_EBL:
3632 3632
 			return "EBL";
3633
+		case T_PTR:
3634
+			return "PTR";
3633 3635
 		default:
3634
-			return "unkown";
3636
+			return "unknown";
3635 3637
 	}
3636 3638
 }
3637 3639
 
... ...
@@ -3668,6 +3726,8 @@ static int dns_get_type(str* s)
3668 3668
 				return T_TXT;
3669 3669
 			else if (strncasecmp(t, "EBL", len)==0)
3670 3670
 				return T_EBL;
3671
+			else if (strncasecmp(t, "PTR", len)==0)
3672
+				return T_PTR;
3671 3673
 			break;
3672 3674
 		case 5:
3673 3675
 			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 3693
 
3694 3694
 	now=get_ticks_raw();
3695 3695
 	expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
3696
-	if (expires < 0) {
3697
-		return;
3698
-	}
3696
+	
3699 3697
 	rpc->printf(ctx, "%sname: %s", SPACE_FORMAT, e->name);
3700 3698
 	rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
3701 3699
 	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 3770
 				rpc->printf(ctx, "%srr apex: %s", SPACE_FORMAT,
3771 3771
 							((struct ebl_rdata*)(rr->rdata))->apex);
3772 3772
 				break;
3773
+			case T_PTR:
3774
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3775
+							((struct ptr_rdata*)(rr->rdata))->ptrdname);
3776
+				break;
3773 3777
 			default:
3774 3778
 				rpc->printf(ctx, "%sresource record: unknown",
3775 3779
 									SPACE_FORMAT);
... ...
@@ -3789,14 +3851,19 @@ void dns_cache_view(rpc_t* rpc, void* ctx)
3789 3789
 {
3790 3790
 	int h;
3791 3791
 	struct dns_hash_entry* e;
3792
+	ticks_t now;
3792 3793
 
3793 3794
 	if (!cfg_get(core, core_cfg, use_dns_cache)){
3794 3795
 		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
3795 3796
 		return;
3796 3797
 	}
3798
+	now=get_ticks_raw();
3797 3799
 	LOCK_DNS_HASH();
3798 3800
 	for (h=0; h<DNS_HASH_SIZE; h++){
3799 3801
 		clist_foreach(&dns_hash[h], e, next){
3802
+			if (TICKS_LT(e->expire, now)) {
3803
+				continue;
3804
+			}
3800 3805
 			rpc->printf(ctx, "{\n");
3801 3806
 			dns_cache_print_entry(rpc, ctx, e);
3802 3807
 			rpc->printf(ctx, "}");
... ...
@@ -3872,6 +3939,9 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3872 3872
 			case T_EBL:
3873 3873
 				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3874 3874
 				break;
3875
+			case T_PTR:
3876
+				rr_size = sizeof(struct dns_rr);
3877
+				break;
3875 3878
 			default:
3876 3879
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not "
3877 3880
 							"supported\n", e->type);
... ...
@@ -4021,6 +4091,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
4021 4021
 	case T_NAPTR:
4022 4022
 	case T_TXT:
4023 4023
 	case T_EBL:
4024
+	case T_PTR:
4024 4025
 		rpc->fault(ctx, 400, "not implemented");
4025 4026
 		return;
4026 4027
 	default:
... ...
@@ -4328,6 +4399,11 @@ void dns_cache_delete_ebl(rpc_t* rpc, void* ctx)
4328 4328
 	dns_cache_delete_record(rpc, ctx, T_EBL);
4329 4329
 }
4330 4330
 
4331
+void dns_cache_delete_ptr(rpc_t* rpc, void* ctx)
4332
+{
4333
+	dns_cache_delete_record(rpc, ctx, T_PTR);
4334
+}
4335
+
4331 4336
 
4332 4337
 
4333 4338
 #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 591
 
592 592
 
593 593
 
594
+/* parses a PTR record into a ptr_rdata structure */
595
+struct ptr_rdata* dns_ptr_parser( unsigned char* msg, unsigned char* end,
596
+									  unsigned char* rdata)
597
+{
598
+	struct ptr_rdata* pname;
599
+	int len;
600
+	char name[MAX_DNS_NAME];
601
+	
602
+	pname=0;
603
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
604
+		goto error;
605
+	len=strlen(name);
606
+	if (len>255)
607
+		goto error;
608
+	/* alloc sizeof struct + space for the null terminated name */
609
+	pname=local_malloc(sizeof(struct ptr_rdata)-1+len+1);
610
+	if(pname==0){
611
+		LOG(L_ERR, "ERROR: dns_ptr_parser: out of memory\n");
612
+		goto error;
613
+	}
614
+	pname->ptrdname_len=len;
615
+	memcpy(pname->ptrdname, name, pname->ptrdname_len);
616
+	pname->ptrdname[pname->ptrdname_len]=0;
617
+	return pname;
618
+error:
619
+	if (pname) local_free(pname);
620
+	return 0;
621
+}
622
+
623
+
624
+
594 625
 /* frees completely a struct rdata list */
595 626
 void free_rdata_list(struct rdata* head)
596 627
 {
... ...
@@ -836,6 +870,12 @@ again:
836 836
 				*last=rd;
837 837
 				last=&(rd->next);
838 838
 				break;
839
+			case T_PTR:
840
+				rd->rdata=(void*) dns_ptr_parser(buff.buff, end, p);
841
+				if(unlikely(rd->rdata==0)) goto error_parse;
842
+				*last=rd;
843
+				last=&(rd->next);
844
+				break;
839 845
 			default:
840 846
 				LOG(L_ERR, "WARNING: get_record: unknown type %d\n", rtype);
841 847
 				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