Browse code

dns: TXT record cache support & more rpcs

- TXT records can be cached (dns_get_entry supports T_TXT)
- more delete entry from cache rpcs:
dns.delete_naptr
dns.delete_cname
dns.delete_txt
- dns.lookup rpc: dns.lookup <type> <name>
(useful for debugging or for pre-populating the dns cache)
e.g.: utils/sercmd/sercmd dns.lookup A iptel.org

Andrei Pelinescu-Onciul authored on 30/03/2009 18:44:23
Showing 2 changed files
... ...
@@ -49,6 +49,7 @@ void dns_cache_debug(rpc_t* rpc, void* ctx);
49 49
 void dns_cache_debug_all(rpc_t* rpc, void* ctx);
50 50
 void dns_cache_mem_info(rpc_t* rpc, void* ctx);
51 51
 void dns_cache_view(rpc_t* rpc, void* ctx);
52
+void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx);
52 53
 void dns_cache_delete_all(rpc_t* rpc, void* ctx);
53 54
 void dns_cache_add_a(rpc_t* rpc, void* ctx);
54 55
 void dns_cache_add_aaaa(rpc_t* rpc, void* ctx);
... ...
@@ -56,6 +57,9 @@ void dns_cache_add_srv(rpc_t* rpc, void* ctx);
56 57
 void dns_cache_delete_a(rpc_t* rpc, void* ctx);
57 58
 void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx);
58 59
 void dns_cache_delete_srv(rpc_t* rpc, void* ctx);
60
+void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
61
+void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
62
+void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
59 63
 
60 64
 
61 65
 static const char* dns_cache_mem_info_doc[] = {
... ...
@@ -77,6 +81,11 @@ static const char* dns_cache_view_doc[] = {
77 81
 	0
78 82
 };
79 83
 
84
+static const char* dns_cache_rpc_lookup_doc[] = {
85
+	"perform a dns lookup",
86
+	0
87
+};
88
+
80 89
 static const char* dns_cache_delete_all_doc[] = {
81 90
 	"deletes all the entries from the DNS cache",
82 91
 	0
... ...
@@ -111,6 +120,22 @@ static const char* dns_cache_delete_srv_doc[] = {
111 120
 	0
112 121
 };
113 122
 
123
+static const char* dns_cache_delete_naptr_doc[] = {
124
+	"deletes a NAPTR record from the DNS cache",
125
+	0
126
+};
127
+
128
+static const char* dns_cache_delete_cname_doc[] = {
129
+	"deletes a CNAME record from the DNS cache",
130
+	0
131
+};
132
+
133
+static const char* dns_cache_delete_txt_doc[] = {
134
+	"deletes a TXT record from the DNS cache",
135
+	0
136
+};
137
+
138
+
114 139
 #ifdef USE_DNS_CACHE_STATS
115 140
 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
116 141
 
... ...
@@ -684,33 +709,60 @@ rpc_export_t core_rpc_methods[] = {
684 709
 		0},
685 710
 	{"core.sctp_info",         core_sctpinfo,          core_sctpinfo_doc,   0},
686 711
 #ifdef USE_DNS_CACHE
687
-	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,     0	},
688
-	{"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,        0	},
689
-	{"dns.debug_all",      dns_cache_debug_all,       dns_cache_debug_all_doc,        0	},
690
-	{"dns.view",               dns_cache_view,        dns_cache_view_doc,        0	},
691
-	{"dns.delete_all",         dns_cache_delete_all,  dns_cache_delete_all_doc,  0	},
692
-	{"dns.add_a",              dns_cache_add_a,       dns_cache_add_a_doc,       0	},
693
-	{"dns.add_aaaa",           dns_cache_add_aaaa,    dns_cache_add_aaaa_doc,    0	},
694
-	{"dns.add_srv",            dns_cache_add_srv,     dns_cache_add_srv_doc,     0	},
695
-	{"dns.delete_a",           dns_cache_delete_a,    dns_cache_delete_a_doc,    0	},
696
-	{"dns.delete_aaaa",        dns_cache_delete_aaaa, dns_cache_delete_aaaa_doc, 0	},
697
-	{"dns.delete_srv",         dns_cache_delete_srv,  dns_cache_delete_srv_doc,  0	},
712
+	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,
713
+		0	},
714
+	{"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,
715
+		0	},
716
+	{"dns.debug_all",      dns_cache_debug_all,       dns_cache_debug_all_doc,
717
+		0	},
718
+	{"dns.view",               dns_cache_view,        dns_cache_view_doc,
719
+		0	},
720
+	{"dns.lookup",             dns_cache_rpc_lookup,  dns_cache_rpc_lookup_doc,
721
+		0	},
722
+	{"dns.delete_all",         dns_cache_delete_all,  dns_cache_delete_all_doc,
723
+		0	},
724
+	{"dns.add_a",              dns_cache_add_a,       dns_cache_add_a_doc,
725
+		0	},
726
+	{"dns.add_aaaa",           dns_cache_add_aaaa,    dns_cache_add_aaaa_doc,
727
+		0	},
728
+	{"dns.add_srv",            dns_cache_add_srv,     dns_cache_add_srv_doc,
729
+		0	},
730
+	{"dns.delete_a",           dns_cache_delete_a,    dns_cache_delete_a_doc,
731
+		0	},
732
+	{"dns.delete_aaaa",        dns_cache_delete_aaaa,
733
+		dns_cache_delete_aaaa_doc, 0	},
734
+	{"dns.delete_srv",         dns_cache_delete_srv,
735
+		dns_cache_delete_srv_doc,  0	},
736
+	{"dns.delete_naptr",         dns_cache_delete_naptr,
737
+		dns_cache_delete_naptr_doc,  0	},
738
+	{"dns.delete_cname",         dns_cache_delete_cname,
739
+		dns_cache_delete_cname_doc,  0	},
740
+	{"dns.delete_txt",         dns_cache_delete_txt,
741
+		dns_cache_delete_txt_doc,  0	},
698 742
 #ifdef USE_DNS_CACHE_STATS
699
-	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,        0	},
743
+	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
744
+		0	},
700 745
 #endif /* USE_DNS_CACHE_STATS */
701 746
 #ifdef DNS_WATCHDOG_SUPPORT
702
-	{"dns.set_server_state",   dns_set_server_state_rpc, dns_set_server_state_doc, 0 },
703
-	{"dns.get_server_state",   dns_get_server_state_rpc, dns_get_server_state_doc, 0 },
747
+	{"dns.set_server_state",   dns_set_server_state_rpc,
748
+		dns_set_server_state_doc, 0 },
749
+	{"dns.get_server_state",   dns_get_server_state_rpc,
750
+		dns_get_server_state_doc, 0 },
704 751
 #endif
705 752
 #endif
706 753
 #ifdef USE_DST_BLACKLIST
707
-	{"dst_blacklist.mem_info",  dst_blst_mem_info,     dst_blst_mem_info_doc,     0	},
708
-	{"dst_blacklist.debug",    dst_blst_debug,         dst_blst_debug_doc,        0	},
709
-	{"dst_blacklist.view",     dst_blst_view,         dst_blst_view_doc,         0	},
710
-	{"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,   0	},
711
-	{"dst_blacklist.add",      dst_blst_add,          dst_blst_add_doc,          0	},
754
+	{"dst_blacklist.mem_info",  dst_blst_mem_info,     dst_blst_mem_info_doc,
755
+		0	},
756
+	{"dst_blacklist.debug",    dst_blst_debug,         dst_blst_debug_doc,
757
+		0	},
758
+	{"dst_blacklist.view",     dst_blst_view,         dst_blst_view_doc,
759
+		0	},
760
+	{"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,
761
+		0	},
762
+	{"dst_blacklist.add",      dst_blst_add,          dst_blst_add_doc,
763
+		0	},
712 764
 #ifdef USE_DST_BLACKLIST_STATS
713
-	{"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0 },
765
+	{"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0},
714 766
 #endif /* USE_DST_BLACKLIST_STATS */
715 767
 #endif
716 768
 	{0, 0, 0, 0}
... ...
@@ -44,6 +44,7 @@
44 44
  *  2008-02-11  dns_cache_init cfg parameter is introduced (Miklos)
45 45
  *  2008-10-17  fixed srv continue with 0 hostname (when falling back to
46 46
                   aaaa) (andrei)
47
+ *  2009-03-30  TXT record support, more rpcs (andrei)
47 48
  */
48 49
 
49 50
 #ifdef USE_DNS_CACHE
... ...
@@ -51,6 +52,7 @@
51 52
 #ifdef DNS_SRV_LB
52 53
 #include <stdlib.h> /* FIXME: rand() */
53 54
 #endif
55
+#include <string.h>
54 56
 
55 57
 #include "globals.h"
56 58
 #include "cfg_core.h"
... ...
@@ -1006,6 +1008,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1006 1008
 	ticks_t now;
1007 1009
 	unsigned int max_ttl;
1008 1010
 	unsigned int ttl;
1011
+	int i;
1009 1012
 
1010 1013
 #define rec_matches(rec, t, n) /*(struct rdata* record, int type, str* name)*/\
1011 1014
 	(	((rec)->name_len==(n)->len) && ((rec)->type==(t)) && \
... ...
@@ -1143,6 +1146,25 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1143 1146
 				 * just been elimintated */
1144 1147
 			}
1145 1148
 			break;
1149
+		case T_TXT:
1150
+			for(; *p;){
1151
+				if (!rec_matches((*p), type, name)){
1152
+					/* skip this record */
1153
+					p=&(*p)->next; /* advance */
1154
+					continue;
1155
+				}
1156
+				/* padding to char* (because of txt[]->cstr*/
1157
+				size+=ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1158
+						TXT_RDATA_SIZE(*(struct txt_rdata*)(*p)->rdata));
1159
+				/* add it to our tmp. lst */
1160
+				*tail=*p;
1161
+				tail=&(*p)->next;
1162
+				/* detach it from the rd list */
1163
+				*p=(*p)->next;
1164
+				/* don't advance p, because the crt. elem. has
1165
+				 * just been elimintated */
1166
+			}
1167
+			break;
1146 1168
 		default:
1147 1169
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1148 1170
 							"supported\n", type);
... ...
@@ -1269,6 +1291,28 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1269 1291
 				rr=rr->next;
1270 1292
 			}
1271 1293
 			break;
1294
+		case T_TXT:
1295
+			for(l=tmp_lst; l; l=l->next){
1296
+				ttl=FIX_TTL(l->ttl);
1297
+				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1298
+				max_ttl=MAX(max_ttl, ttl);
1299
+				rr->rdata=(void*)((char*)rr+
1300
+							ROUND_POINTER(sizeof(struct dns_rr)));
1301
+				memcpy(rr->rdata, l->rdata,
1302
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1303
+				/* adjust the string pointers */
1304
+				for (i=0; i<((struct txt_rdata*)l->rdata)->cstr_no; i++){
1305
+					((struct txt_rdata*)rr->rdata)->txt[i].cstr=
1306
+						translate_pointer((char*)rr->rdata, (char*)l->rdata,
1307
+								((struct txt_rdata*)l->rdata)->txt[i].cstr);
1308
+				}
1309
+				rr->next=(void*)((char*)rr+
1310
+						ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1311
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata)));
1312
+				tail_rr=&(rr->next);
1313
+				rr=rr->next;
1314
+			}
1315
+			break;
1272 1316
 		default:
1273 1317
 			/* do nothing */
1274 1318
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: create: type %d not "
... ...
@@ -1304,7 +1348,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry2(struct rdata* rd)
1304 1348
 	ticks_t now;
1305 1349
 	struct tmp_rec rec[MAX_DNS_RECORDS];
1306 1350
 	int rec_idx[MAX_DNS_RECORDS];
1307
-	int r, i;
1351
+	int r, i, j;
1308 1352
 	int no_records; /* number of different records */
1309 1353
 	unsigned int ttl;
1310 1354
 
... ...
@@ -1382,6 +1426,12 @@ found:
1382 1426
 				rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
1383 1427
 							CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
1384 1428
 				break;
1429
+			case T_TXT:
1430
+					/* padding to char* (because of txt[]->cstr*/
1431
+				rec[r].size+=ROUND_POINTER(ROUND_POINTER(
1432
+												sizeof(struct dns_rr))+
1433
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1434
+				break;
1385 1435
 			default:
1386 1436
 				LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1387 1437
 							"supported\n", l->type);
... ...
@@ -1501,6 +1551,26 @@ found:
1501 1551
 				rec[r].tail_rr=&(rec[r].rr->next);
1502 1552
 				rec[r].rr=rec[r].rr->next;
1503 1553
 				break;
1554
+			case T_TXT:
1555
+				rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1556
+				rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
1557
+				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1558
+									ROUND_POINTER(sizeof(struct dns_rr)));
1559
+				memcpy(rec[r].rr->rdata, l->rdata,
1560
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1561
+				/* adjust the string pointers */
1562
+				for (j=0; j<((struct txt_rdata*)l->rdata)->cstr_no; j++){
1563
+					((struct txt_rdata*)rec[r].rr->rdata)->txt[j].cstr=
1564
+						translate_pointer((char*)rec[r].rr->rdata,
1565
+								(char*)l->rdata,
1566
+								((struct txt_rdata*)l->rdata)->txt[j].cstr);
1567
+				}
1568
+				rec[r].rr->next=(void*)((char*)rec[r].rr+
1569
+						ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1570
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata)));
1571
+				rec[r].tail_rr=&(rec[r].rr->next);
1572
+				rec[r].rr=rec[r].rr->next;
1573
+				break;
1504 1574
 			default:
1505 1575
 				/* do nothing */
1506 1576
 				;
... ...
@@ -3445,6 +3515,12 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3445 3515
 							rpc->add(ctx, "ss", "cname",
3446 3516
 									((struct cname_rdata*)(rr->rdata))->name);
3447 3517
 							break;
3518
+						case T_TXT:
3519
+							rpc->add(ctx, "ss", "txt",
3520
+								((struct txt_rdata*)(rr->rdata))->cstr_no?
3521
+								((struct txt_rdata*)(rr->rdata))->txt[0].cstr:
3522
+								"");
3523
+							break;
3448 3524
 						default:
3449 3525
 							rpc->add(ctx, "ss", "unknown", "?");
3450 3526
 					}
... ...
@@ -3472,103 +3548,167 @@ static char *print_type(unsigned short type)
3472 3548
 			return "NAPTR";
3473 3549
 		case T_CNAME:
3474 3550
 			return "CNAME";
3551
+		case T_TXT:
3552
+			return "TXT";
3475 3553
 		default:
3476 3554
 			return "unkown";
3477 3555
 	}
3478 3556
 }
3479 3557
 
3480
-/* dumps the content of the cache in a human-readable format */
3481
-void dns_cache_view(rpc_t* rpc, void* ctx)
3558
+
3559
+/** convert string type to dns integer T_*.
3560
+ * used for rpc type translation.
3561
+ * @return T_* on success, -1 on error.
3562
+ */
3563
+static int dns_get_type(str* s)
3564
+{
3565
+	char *t;
3566
+	int len;
3567
+	
3568
+	t=s->s;
3569
+	len=s->len;
3570
+	/* skip over a T_ or t_ prefix */
3571
+	if ((len>2) && (t[0]=='T' || t[0]=='t') && (t[1]=='_')){
3572
+		t+=2;
3573
+		len-=2;
3574
+	}
3575
+	switch(len){
3576
+		case 1:
3577
+			if (t[0]=='A' || t[0]=='a')
3578
+				return T_A;
3579
+			break;
3580
+		case 4:
3581
+			if (strncasecmp(t, "AAAA", len)==0)
3582
+				return T_AAAA;
3583
+			break;
3584
+		case 3:
3585
+			if (strncasecmp(t, "SRV", len)==0)
3586
+				return T_SRV;
3587
+			else if (strncasecmp(t, "TXT", len)==0)
3588
+				return T_TXT;
3589
+			break;
3590
+		case 5:
3591
+			if (strncasecmp(t, "NAPTR", len)==0)
3592
+				return T_NAPTR;
3593
+			else if (strncasecmp(t, "CNAME", len)==0)
3594
+				return T_CNAME;
3595
+			break;
3596
+	}
3597
+	return -1;
3598
+}
3599
+
3600
+
3601
+/** rpc-prints a dns cache entry.
3602
+  */
3603
+void dns_cache_print_entry(rpc_t* rpc, void* ctx, struct dns_hash_entry* e)
3482 3604
 {
3483
-	int h;
3484 3605
 	int expires;
3485
-	struct dns_hash_entry* e;
3486 3606
 	struct dns_rr* rr;
3487 3607
 	struct ip_addr ip;
3488 3608
 	ticks_t now;
3489 3609
 	str s;
3610
+	int i;
3611
+
3612
+	now=get_ticks_raw();
3613
+	expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
3614
+	if (expires < 0) {
3615
+		return;
3616
+	}
3617
+	rpc->printf(ctx, "%sname: %s", SPACE_FORMAT, e->name);
3618
+	rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
3619
+	rpc->printf(ctx, "%ssize (bytes): %d", SPACE_FORMAT,
3620
+						e->total_size);
3621
+	rpc->printf(ctx, "%sreference counter: %d", SPACE_FORMAT,
3622
+						e->refcnt.val);
3623
+	rpc->printf(ctx, "%sexpires in (s): %d", SPACE_FORMAT, expires);
3624
+	rpc->printf(ctx, "%slast used (s): %d", SPACE_FORMAT,
3625
+						TICKS_TO_S(now-e->last_used));
3626
+	rpc->printf(ctx, "%serror flags: %d", SPACE_FORMAT, e->err_flags);
3627
+	
3628
+	for (rr=e->rr_lst; rr; rr=rr->next) {
3629
+		switch(e->type) {
3630
+			case T_A:
3631
+			case T_AAAA:
3632
+				if (dns_rr2ip(e->type, rr, &ip)==0){
3633
+				  rpc->printf(ctx, "%srr ip: %s", SPACE_FORMAT,
3634
+									ip_addr2a(&ip) );
3635
+				}else{
3636
+				  rpc->printf(ctx, "%srr ip: <error: bad rr>", 
3637
+									SPACE_FORMAT);
3638
+				}
3639
+				break;
3640
+			case T_SRV:
3641
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3642
+							((struct srv_rdata*)(rr->rdata))->name);
3643
+				rpc->printf(ctx, "%srr port: %d", SPACE_FORMAT,
3644
+							((struct srv_rdata*)(rr->rdata))->port);
3645
+				rpc->printf(ctx, "%srr priority: %d", SPACE_FORMAT,
3646
+						((struct srv_rdata*)(rr->rdata))->priority);
3647
+				rpc->printf(ctx, "%srr weight: %d", SPACE_FORMAT,
3648
+							((struct srv_rdata*)(rr->rdata))->weight);
3649
+				break;
3650
+			case T_NAPTR:
3651
+				rpc->printf(ctx, "%srr order: %d", SPACE_FORMAT,
3652
+							((struct naptr_rdata*)(rr->rdata))->order);
3653
+				rpc->printf(ctx, "%srr preference: %d", SPACE_FORMAT,
3654
+							((struct naptr_rdata*)(rr->rdata))->pref);
3655
+				s.s = ((struct naptr_rdata*)(rr->rdata))->flags;
3656
+				s.len = ((struct naptr_rdata*)(rr->rdata))->flags_len;
3657
+				rpc->printf(ctx, "%srr flags: %.*s", SPACE_FORMAT,
3658
+									s.len, s.s);
3659
+				s.s=((struct naptr_rdata*)(rr->rdata))->services;
3660
+				s.len=((struct naptr_rdata*)(rr->rdata))->services_len;
3661
+				rpc->printf(ctx, "%srr service: %.*s", SPACE_FORMAT,
3662
+									s.len, s.s);
3663
+				s.s = ((struct naptr_rdata*)(rr->rdata))->regexp;
3664
+				s.len = ((struct naptr_rdata*)(rr->rdata))->regexp_len;
3665
+				rpc->printf(ctx, "%srr regexp: %.*s", SPACE_FORMAT,
3666
+									s.len, s.s);
3667
+				s.s = ((struct naptr_rdata*)(rr->rdata))->repl;
3668
+				s.len = ((struct naptr_rdata*)(rr->rdata))->repl_len;
3669
+				rpc->printf(ctx, "%srr replacement: %.*s", 
3670
+									SPACE_FORMAT, s.len, s.s);
3671
+				break;
3672
+			case T_CNAME:
3673
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3674
+							((struct cname_rdata*)(rr->rdata))->name);
3675
+				break;
3676
+			case T_TXT:
3677
+				for (i=0; i<((struct txt_rdata*)(rr->rdata))->cstr_no;
3678
+						i++){
3679
+					rpc->printf(ctx, "%stxt[%d]: %s", SPACE_FORMAT, i,
3680
+						((struct txt_rdata*)(rr->rdata))->txt[i].cstr);
3681
+				}
3682
+				break;
3683
+			default:
3684
+				rpc->printf(ctx, "%sresource record: unknown",
3685
+									SPACE_FORMAT);
3686
+		}
3687
+		rpc->printf(ctx, "%srr expires in (s): %d", SPACE_FORMAT,
3688
+						(s_ticks_t)(rr->expire-now)<0?-1 : 
3689
+						TICKS_TO_S(rr->expire-now));
3690
+		rpc->printf(ctx, "%srr error flags: %d", SPACE_FORMAT, 
3691
+						rr->err_flags);
3692
+	}
3693
+}
3694
+
3695
+
3696
+
3697
+/* dumps the content of the cache in a human-readable format */
3698
+void dns_cache_view(rpc_t* rpc, void* ctx)
3699
+{
3700
+	int h;
3701
+	struct dns_hash_entry* e;
3490 3702
 
3491 3703
 	if (!cfg_get(core, core_cfg, use_dns_cache)){
3492 3704
 		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
3493 3705
 		return;
3494 3706
 	}
3495
-	now=get_ticks_raw();
3496 3707
 	LOCK_DNS_HASH();
3497 3708
 	for (h=0; h<DNS_HASH_SIZE; h++){
3498 3709
 		clist_foreach(&dns_hash[h], e, next){
3499
-			expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
3500
-			if (expires < 0) {
3501
-				continue;
3502
-			}
3503
-			rpc->printf(ctx, "{\n%sname: %s", SPACE_FORMAT, e->name);
3504
-			rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
3505
-			rpc->printf(ctx, "%ssize (bytes): %d", SPACE_FORMAT,
3506
-								e->total_size);
3507
-			rpc->printf(ctx, "%sreference counter: %d", SPACE_FORMAT,
3508
-								e->refcnt.val);
3509
-			rpc->printf(ctx, "%sexpires in (s): %d", SPACE_FORMAT, expires);
3510
-			rpc->printf(ctx, "%slast used (s): %d", SPACE_FORMAT,
3511
-								TICKS_TO_S(now-e->last_used));
3512
-			rpc->printf(ctx, "%serror flags: %d", SPACE_FORMAT, e->err_flags);
3513
-			
3514
-			for (rr=e->rr_lst; rr; rr=rr->next) {
3515
-				switch(e->type) {
3516
-					case T_A:
3517
-					case T_AAAA:
3518
-						if (dns_rr2ip(e->type, rr, &ip)==0){
3519
-						  rpc->printf(ctx, "%srr ip: %s", SPACE_FORMAT,
3520
-								  			ip_addr2a(&ip) );
3521
-						}else{
3522
-						  rpc->printf(ctx, "%srr ip: <error: bad rr>", 
3523
-								  			SPACE_FORMAT);
3524
-						}
3525
-						break;
3526
-					case T_SRV:
3527
-						rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3528
-									((struct srv_rdata*)(rr->rdata))->name);
3529
-						rpc->printf(ctx, "%srr port: %d", SPACE_FORMAT,
3530
-									((struct srv_rdata*)(rr->rdata))->port);
3531
-						rpc->printf(ctx, "%srr priority: %d", SPACE_FORMAT,
3532
-								((struct srv_rdata*)(rr->rdata))->priority);
3533
-						rpc->printf(ctx, "%srr weight: %d", SPACE_FORMAT,
3534
-									((struct srv_rdata*)(rr->rdata))->weight);
3535
-						break;
3536
-					case T_NAPTR:
3537
-						rpc->printf(ctx, "%srr order: %d", SPACE_FORMAT,
3538
-									((struct naptr_rdata*)(rr->rdata))->order);
3539
-						rpc->printf(ctx, "%srr preference: %d", SPACE_FORMAT,
3540
-									((struct naptr_rdata*)(rr->rdata))->pref);
3541
-						s.s = ((struct naptr_rdata*)(rr->rdata))->flags;
3542
-						s.len = ((struct naptr_rdata*)(rr->rdata))->flags_len;
3543
-						rpc->printf(ctx, "%srr flags: %.*s", SPACE_FORMAT,
3544
-											s.len, s.s);
3545
-						s.s=((struct naptr_rdata*)(rr->rdata))->services;
3546
-						s.len=((struct naptr_rdata*)(rr->rdata))->services_len;
3547
-						rpc->printf(ctx, "%srr service: %.*s", SPACE_FORMAT,
3548
-											s.len, s.s);
3549
-						s.s = ((struct naptr_rdata*)(rr->rdata))->regexp;
3550
-						s.len = ((struct naptr_rdata*)(rr->rdata))->regexp_len;
3551
-						rpc->printf(ctx, "%srr regexp: %.*s", SPACE_FORMAT,
3552
-											s.len, s.s);
3553
-						s.s = ((struct naptr_rdata*)(rr->rdata))->repl;
3554
-						s.len = ((struct naptr_rdata*)(rr->rdata))->repl_len;
3555
-						rpc->printf(ctx, "%srr replacement: %.*s", 
3556
-											SPACE_FORMAT, s.len, s.s);
3557
-						break;
3558
-					case T_CNAME:
3559
-						rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3560
-									((struct cname_rdata*)(rr->rdata))->name);
3561
-						break;
3562
-					default:
3563
-						rpc->printf(ctx, "%sresource record: unknown",
3564
-											SPACE_FORMAT);
3565
-				}
3566
-				rpc->printf(ctx, "%srr expires in (s): %d", SPACE_FORMAT,
3567
-								(s_ticks_t)(rr->expire-now)<0?-1 : 
3568
-								TICKS_TO_S(rr->expire-now));
3569
-				rpc->printf(ctx, "%srr error flags: %d", SPACE_FORMAT, 
3570
-								rr->err_flags);
3571
-			}
3710
+			rpc->printf(ctx, "{\n");
3711
+			dns_cache_print_entry(rpc, ctx, e);
3572 3712
 			rpc->printf(ctx, "}");
3573 3713
 		}
3574 3714
 	}
... ...
@@ -3616,6 +3756,7 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3616 3756
 	struct dns_rr *rr, *last_rr, *new_rr;
3617 3757
 	int size, rounded_size, rr_size;
3618 3758
 	ticks_t now;
3759
+	int i;
3619 3760
 
3620 3761
 	now=get_ticks_raw();
3621 3762
 	size = e->total_size;
... ...
@@ -3635,6 +3776,9 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3635 3776
 			case T_NAPTR:
3636 3777
 				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3637 3778
 				break;
3779
+			case T_TXT:
3780
+				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3781
+				break;
3638 3782
 			default:
3639 3783
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not "
3640 3784
 							"supported\n", e->type);
... ...
@@ -3692,6 +3836,13 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3692 3836
 			((struct naptr_rdata*)rr->rdata)->repl =
3693 3837
 				translate_pointer((char*)new, (char*)e,
3694 3838
 					((struct naptr_rdata*)rr->rdata)->repl);
3839
+		}else if (e->type == T_TXT){
3840
+			/* there are pointers inside the TXT structure */
3841
+			for (i=0; i<((struct txt_rdata*)rr->rdata)->cstr_no; i++){
3842
+				((struct txt_rdata*)rr->rdata)->txt[i].cstr=
3843
+					translate_pointer((char*) new, (char*) e,
3844
+						((struct txt_rdata*)rr->rdata)->txt[i].cstr);
3845
+			}
3695 3846
 		}
3696 3847
 	}
3697 3848
 
... ...
@@ -3763,6 +3914,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3763 3914
 		break;
3764 3915
 	case T_CNAME:
3765 3916
 	case T_NAPTR:
3917
+	case T_TXT:
3766 3918
 		rpc->fault(ctx, 400, "not implemented");
3767 3919
 		return;
3768 3920
 	default:
... ...
@@ -3980,6 +4132,37 @@ static void dns_cache_delete_record(rpc_t* rpc, void* ctx, unsigned short type)
3980 4132
 }
3981 4133
 
3982 4134
 
4135
+/* performs  a dns lookup over rpc */
4136
+void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx)
4137
+{
4138
+	struct dns_hash_entry *e;
4139
+	str name;
4140
+	str type;
4141
+	int t;
4142
+
4143
+	if (!cfg_get(core, core_cfg, use_dns_cache)){
4144
+		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
4145
+		return;
4146
+	}
4147
+	
4148
+	if (rpc->scan(ctx, "SS", &type, &name) < 1)
4149
+		return;
4150
+	t=dns_get_type(&type);
4151
+	if (t<0){
4152
+		rpc->fault(ctx, 400, "Invalid type");
4153
+		return;
4154
+	}
4155
+	e=dns_get_entry(&name, t);
4156
+	if (e==0){
4157
+		rpc->fault(ctx, 400, "Not found");
4158
+		return;
4159
+	}
4160
+	dns_cache_print_entry(rpc, ctx, e);
4161
+	dns_hash_put(e);
4162
+}
4163
+
4164
+
4165
+
3983 4166
 /* wrapper functions for adding and deleting records */
3984 4167
 void dns_cache_add_a(rpc_t* rpc, void* ctx)
3985 4168
 {
... ...
@@ -4017,6 +4200,24 @@ void dns_cache_delete_srv(rpc_t* rpc, void* ctx)
4017 4200
 }
4018 4201
 
4019 4202
 
4203
+void dns_cache_delete_naptr(rpc_t* rpc, void* ctx)
4204
+{
4205
+	dns_cache_delete_record(rpc, ctx, T_NAPTR);
4206
+}
4207
+
4208
+
4209
+void dns_cache_delete_cname(rpc_t* rpc, void* ctx)
4210
+{
4211
+	dns_cache_delete_record(rpc, ctx, T_CNAME);
4212
+}
4213
+
4214
+
4215
+void dns_cache_delete_txt(rpc_t* rpc, void* ctx)
4216
+{
4217
+	dns_cache_delete_record(rpc, ctx, T_TXT);
4218
+}
4219
+
4220
+
4020 4221
 
4021 4222
 #ifdef DNS_WATCHDOG_SUPPORT
4022 4223
 /* sets the DNS server states */