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 56
 void dns_cache_delete_a(rpc_t* rpc, void* ctx);
57 57
 void dns_cache_delete_aaaa(rpc_t* rpc, void* ctx);
58 58
 void dns_cache_delete_srv(rpc_t* rpc, void* ctx);
59
+void dns_cache_delete_naptr(rpc_t* rpc, void* ctx);
60
+void dns_cache_delete_cname(rpc_t* rpc, void* ctx);
61
+void dns_cache_delete_txt(rpc_t* rpc, void* ctx);
59 62
 
60 63
 
61 64
 static const char* dns_cache_mem_info_doc[] = {
... ...
@@ -77,6 +81,11 @@ static const char* dns_cache_view_doc[] = {
77 77
 	0
78 78
 };
79 79
 
80
+static const char* dns_cache_rpc_lookup_doc[] = {
81
+	"perform a dns lookup",
82
+	0
83
+};
84
+
80 85
 static const char* dns_cache_delete_all_doc[] = {
81 86
 	"deletes all the entries from the DNS cache",
82 87
 	0
... ...
@@ -111,6 +120,22 @@ static const char* dns_cache_delete_srv_doc[] = {
111 111
 	0
112 112
 };
113 113
 
114
+static const char* dns_cache_delete_naptr_doc[] = {
115
+	"deletes a NAPTR record from the DNS cache",
116
+	0
117
+};
118
+
119
+static const char* dns_cache_delete_cname_doc[] = {
120
+	"deletes a CNAME record from the DNS cache",
121
+	0
122
+};
123
+
124
+static const char* dns_cache_delete_txt_doc[] = {
125
+	"deletes a TXT record from the DNS cache",
126
+	0
127
+};
128
+
129
+
114 130
 #ifdef USE_DNS_CACHE_STATS
115 131
 void dns_cache_stats_get(rpc_t* rpc, void* ctx);
116 132
 
... ...
@@ -684,33 +709,60 @@ rpc_export_t core_rpc_methods[] = {
684 684
 		0},
685 685
 	{"core.sctp_info",         core_sctpinfo,          core_sctpinfo_doc,   0},
686 686
 #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	},
687
+	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,
688
+		0	},
689
+	{"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,
690
+		0	},
691
+	{"dns.debug_all",      dns_cache_debug_all,       dns_cache_debug_all_doc,
692
+		0	},
693
+	{"dns.view",               dns_cache_view,        dns_cache_view_doc,
694
+		0	},
695
+	{"dns.lookup",             dns_cache_rpc_lookup,  dns_cache_rpc_lookup_doc,
696
+		0	},
697
+	{"dns.delete_all",         dns_cache_delete_all,  dns_cache_delete_all_doc,
698
+		0	},
699
+	{"dns.add_a",              dns_cache_add_a,       dns_cache_add_a_doc,
700
+		0	},
701
+	{"dns.add_aaaa",           dns_cache_add_aaaa,    dns_cache_add_aaaa_doc,
702
+		0	},
703
+	{"dns.add_srv",            dns_cache_add_srv,     dns_cache_add_srv_doc,
704
+		0	},
705
+	{"dns.delete_a",           dns_cache_delete_a,    dns_cache_delete_a_doc,
706
+		0	},
707
+	{"dns.delete_aaaa",        dns_cache_delete_aaaa,
708
+		dns_cache_delete_aaaa_doc, 0	},
709
+	{"dns.delete_srv",         dns_cache_delete_srv,
710
+		dns_cache_delete_srv_doc,  0	},
711
+	{"dns.delete_naptr",         dns_cache_delete_naptr,
712
+		dns_cache_delete_naptr_doc,  0	},
713
+	{"dns.delete_cname",         dns_cache_delete_cname,
714
+		dns_cache_delete_cname_doc,  0	},
715
+	{"dns.delete_txt",         dns_cache_delete_txt,
716
+		dns_cache_delete_txt_doc,  0	},
698 717
 #ifdef USE_DNS_CACHE_STATS
699
-	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,        0	},
718
+	{"dns.stats_get",    dns_cache_stats_get,   dns_cache_stats_get_doc,
719
+		0	},
700 720
 #endif /* USE_DNS_CACHE_STATS */
701 721
 #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 },
722
+	{"dns.set_server_state",   dns_set_server_state_rpc,
723
+		dns_set_server_state_doc, 0 },
724
+	{"dns.get_server_state",   dns_get_server_state_rpc,
725
+		dns_get_server_state_doc, 0 },
704 726
 #endif
705 727
 #endif
706 728
 #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	},
729
+	{"dst_blacklist.mem_info",  dst_blst_mem_info,     dst_blst_mem_info_doc,
730
+		0	},
731
+	{"dst_blacklist.debug",    dst_blst_debug,         dst_blst_debug_doc,
732
+		0	},
733
+	{"dst_blacklist.view",     dst_blst_view,         dst_blst_view_doc,
734
+		0	},
735
+	{"dst_blacklist.delete_all", dst_blst_delete_all, dst_blst_delete_all_doc,
736
+		0	},
737
+	{"dst_blacklist.add",      dst_blst_add,          dst_blst_add_doc,
738
+		0	},
712 739
 #ifdef USE_DST_BLACKLIST_STATS
713
-	{"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0 },
740
+	{"dst_blacklist.stats_get", dst_blst_stats_get, dst_blst_stats_get_doc, 0},
714 741
 #endif /* USE_DST_BLACKLIST_STATS */
715 742
 #endif
716 743
 	{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 51
 #ifdef DNS_SRV_LB
52 52
 #include <stdlib.h> /* FIXME: rand() */
53 53
 #endif
54
+#include <string.h>
54 55
 
55 56
 #include "globals.h"
56 57
 #include "cfg_core.h"
... ...
@@ -1006,6 +1008,7 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1006 1006
 	ticks_t now;
1007 1007
 	unsigned int max_ttl;
1008 1008
 	unsigned int ttl;
1009
+	int i;
1009 1010
 
1010 1011
 #define rec_matches(rec, t, n) /*(struct rdata* record, int type, str* name)*/\
1011 1012
 	(	((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 1143
 				 * just been elimintated */
1144 1144
 			}
1145 1145
 			break;
1146
+		case T_TXT:
1147
+			for(; *p;){
1148
+				if (!rec_matches((*p), type, name)){
1149
+					/* skip this record */
1150
+					p=&(*p)->next; /* advance */
1151
+					continue;
1152
+				}
1153
+				/* padding to char* (because of txt[]->cstr*/
1154
+				size+=ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1155
+						TXT_RDATA_SIZE(*(struct txt_rdata*)(*p)->rdata));
1156
+				/* add it to our tmp. lst */
1157
+				*tail=*p;
1158
+				tail=&(*p)->next;
1159
+				/* detach it from the rd list */
1160
+				*p=(*p)->next;
1161
+				/* don't advance p, because the crt. elem. has
1162
+				 * just been elimintated */
1163
+			}
1164
+			break;
1146 1165
 		default:
1147 1166
 			LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1148 1167
 							"supported\n", type);
... ...
@@ -1269,6 +1291,28 @@ inline static struct dns_hash_entry* dns_cache_mk_rd_entry(str* name, int type,
1269 1269
 				rr=rr->next;
1270 1270
 			}
1271 1271
 			break;
1272
+		case T_TXT:
1273
+			for(l=tmp_lst; l; l=l->next){
1274
+				ttl=FIX_TTL(l->ttl);
1275
+				rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1276
+				max_ttl=MAX(max_ttl, ttl);
1277
+				rr->rdata=(void*)((char*)rr+
1278
+							ROUND_POINTER(sizeof(struct dns_rr)));
1279
+				memcpy(rr->rdata, l->rdata,
1280
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1281
+				/* adjust the string pointers */
1282
+				for (i=0; i<((struct txt_rdata*)l->rdata)->cstr_no; i++){
1283
+					((struct txt_rdata*)rr->rdata)->txt[i].cstr=
1284
+						translate_pointer((char*)rr->rdata, (char*)l->rdata,
1285
+								((struct txt_rdata*)l->rdata)->txt[i].cstr);
1286
+				}
1287
+				rr->next=(void*)((char*)rr+
1288
+						ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1289
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata)));
1290
+				tail_rr=&(rr->next);
1291
+				rr=rr->next;
1292
+			}
1293
+			break;
1272 1294
 		default:
1273 1295
 			/* do nothing */
1274 1296
 			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 1304
 	ticks_t now;
1305 1305
 	struct tmp_rec rec[MAX_DNS_RECORDS];
1306 1306
 	int rec_idx[MAX_DNS_RECORDS];
1307
-	int r, i;
1307
+	int r, i, j;
1308 1308
 	int no_records; /* number of different records */
1309 1309
 	unsigned int ttl;
1310 1310
 
... ...
@@ -1382,6 +1426,12 @@ found:
1382 1382
 				rec[r].size+=ROUND_POINTER(sizeof(struct dns_rr)+
1383 1383
 							CNAME_RDATA_SIZE(*(struct cname_rdata*)l->rdata));
1384 1384
 				break;
1385
+			case T_TXT:
1386
+					/* padding to char* (because of txt[]->cstr*/
1387
+				rec[r].size+=ROUND_POINTER(ROUND_POINTER(
1388
+												sizeof(struct dns_rr))+
1389
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1390
+				break;
1385 1391
 			default:
1386 1392
 				LOG(L_CRIT, "BUG: dns_cache_mk_rd_entry: type %d not "
1387 1393
 							"supported\n", l->type);
... ...
@@ -1501,6 +1551,26 @@ found:
1501 1501
 				rec[r].tail_rr=&(rec[r].rr->next);
1502 1502
 				rec[r].rr=rec[r].rr->next;
1503 1503
 				break;
1504
+			case T_TXT:
1505
+				rec[r].rr->expire=now+S_TO_TICKS(ttl); /* maximum expire */
1506
+				rec[r].max_ttl=MAX(rec[r].max_ttl, ttl);
1507
+				rec[r].rr->rdata=(void*)((char*)rec[r].rr+
1508
+									ROUND_POINTER(sizeof(struct dns_rr)));
1509
+				memcpy(rec[r].rr->rdata, l->rdata,
1510
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata));
1511
+				/* adjust the string pointers */
1512
+				for (j=0; j<((struct txt_rdata*)l->rdata)->cstr_no; j++){
1513
+					((struct txt_rdata*)rec[r].rr->rdata)->txt[j].cstr=
1514
+						translate_pointer((char*)rec[r].rr->rdata,
1515
+								(char*)l->rdata,
1516
+								((struct txt_rdata*)l->rdata)->txt[j].cstr);
1517
+				}
1518
+				rec[r].rr->next=(void*)((char*)rec[r].rr+
1519
+						ROUND_POINTER(ROUND_POINTER(sizeof(struct dns_rr))+
1520
+							TXT_RDATA_SIZE(*(struct txt_rdata*)l->rdata)));
1521
+				rec[r].tail_rr=&(rec[r].rr->next);
1522
+				rec[r].rr=rec[r].rr->next;
1523
+				break;
1504 1524
 			default:
1505 1525
 				/* do nothing */
1506 1526
 				;
... ...
@@ -3445,6 +3515,12 @@ void dns_cache_debug_all(rpc_t* rpc, void* ctx)
3445 3445
 							rpc->add(ctx, "ss", "cname",
3446 3446
 									((struct cname_rdata*)(rr->rdata))->name);
3447 3447
 							break;
3448
+						case T_TXT:
3449
+							rpc->add(ctx, "ss", "txt",
3450
+								((struct txt_rdata*)(rr->rdata))->cstr_no?
3451
+								((struct txt_rdata*)(rr->rdata))->txt[0].cstr:
3452
+								"");
3453
+							break;
3448 3454
 						default:
3449 3455
 							rpc->add(ctx, "ss", "unknown", "?");
3450 3456
 					}
... ...
@@ -3472,103 +3548,167 @@ static char *print_type(unsigned short type)
3472 3472
 			return "NAPTR";
3473 3473
 		case T_CNAME:
3474 3474
 			return "CNAME";
3475
+		case T_TXT:
3476
+			return "TXT";
3475 3477
 		default:
3476 3478
 			return "unkown";
3477 3479
 	}
3478 3480
 }
3479 3481
 
3480
-/* dumps the content of the cache in a human-readable format */
3481
-void dns_cache_view(rpc_t* rpc, void* ctx)
3482
+
3483
+/** convert string type to dns integer T_*.
3484
+ * used for rpc type translation.
3485
+ * @return T_* on success, -1 on error.
3486
+ */
3487
+static int dns_get_type(str* s)
3488
+{
3489
+	char *t;
3490
+	int len;
3491
+	
3492
+	t=s->s;
3493
+	len=s->len;
3494
+	/* skip over a T_ or t_ prefix */
3495
+	if ((len>2) && (t[0]=='T' || t[0]=='t') && (t[1]=='_')){
3496
+		t+=2;
3497
+		len-=2;
3498
+	}
3499
+	switch(len){
3500
+		case 1:
3501
+			if (t[0]=='A' || t[0]=='a')
3502
+				return T_A;
3503
+			break;
3504
+		case 4:
3505
+			if (strncasecmp(t, "AAAA", len)==0)
3506
+				return T_AAAA;
3507
+			break;
3508
+		case 3:
3509
+			if (strncasecmp(t, "SRV", len)==0)
3510
+				return T_SRV;
3511
+			else if (strncasecmp(t, "TXT", len)==0)
3512
+				return T_TXT;
3513
+			break;
3514
+		case 5:
3515
+			if (strncasecmp(t, "NAPTR", len)==0)
3516
+				return T_NAPTR;
3517
+			else if (strncasecmp(t, "CNAME", len)==0)
3518
+				return T_CNAME;
3519
+			break;
3520
+	}
3521
+	return -1;
3522
+}
3523
+
3524
+
3525
+/** rpc-prints a dns cache entry.
3526
+  */
3527
+void dns_cache_print_entry(rpc_t* rpc, void* ctx, struct dns_hash_entry* e)
3482 3528
 {
3483
-	int h;
3484 3529
 	int expires;
3485
-	struct dns_hash_entry* e;
3486 3530
 	struct dns_rr* rr;
3487 3531
 	struct ip_addr ip;
3488 3532
 	ticks_t now;
3489 3533
 	str s;
3534
+	int i;
3535
+
3536
+	now=get_ticks_raw();
3537
+	expires = (s_ticks_t)(e->expire-now)<0?-1: TICKS_TO_S(e->expire-now);
3538
+	if (expires < 0) {
3539
+		return;
3540
+	}
3541
+	rpc->printf(ctx, "%sname: %s", SPACE_FORMAT, e->name);
3542
+	rpc->printf(ctx, "%stype: %s", SPACE_FORMAT, print_type(e->type));
3543
+	rpc->printf(ctx, "%ssize (bytes): %d", SPACE_FORMAT,
3544
+						e->total_size);
3545
+	rpc->printf(ctx, "%sreference counter: %d", SPACE_FORMAT,
3546
+						e->refcnt.val);
3547
+	rpc->printf(ctx, "%sexpires in (s): %d", SPACE_FORMAT, expires);
3548
+	rpc->printf(ctx, "%slast used (s): %d", SPACE_FORMAT,
3549
+						TICKS_TO_S(now-e->last_used));
3550
+	rpc->printf(ctx, "%serror flags: %d", SPACE_FORMAT, e->err_flags);
3551
+	
3552
+	for (rr=e->rr_lst; rr; rr=rr->next) {
3553
+		switch(e->type) {
3554
+			case T_A:
3555
+			case T_AAAA:
3556
+				if (dns_rr2ip(e->type, rr, &ip)==0){
3557
+				  rpc->printf(ctx, "%srr ip: %s", SPACE_FORMAT,
3558
+									ip_addr2a(&ip) );
3559
+				}else{
3560
+				  rpc->printf(ctx, "%srr ip: <error: bad rr>", 
3561
+									SPACE_FORMAT);
3562
+				}
3563
+				break;
3564
+			case T_SRV:
3565
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3566
+							((struct srv_rdata*)(rr->rdata))->name);
3567
+				rpc->printf(ctx, "%srr port: %d", SPACE_FORMAT,
3568
+							((struct srv_rdata*)(rr->rdata))->port);
3569
+				rpc->printf(ctx, "%srr priority: %d", SPACE_FORMAT,
3570
+						((struct srv_rdata*)(rr->rdata))->priority);
3571
+				rpc->printf(ctx, "%srr weight: %d", SPACE_FORMAT,
3572
+							((struct srv_rdata*)(rr->rdata))->weight);
3573
+				break;
3574
+			case T_NAPTR:
3575
+				rpc->printf(ctx, "%srr order: %d", SPACE_FORMAT,
3576
+							((struct naptr_rdata*)(rr->rdata))->order);
3577
+				rpc->printf(ctx, "%srr preference: %d", SPACE_FORMAT,
3578
+							((struct naptr_rdata*)(rr->rdata))->pref);
3579
+				s.s = ((struct naptr_rdata*)(rr->rdata))->flags;
3580
+				s.len = ((struct naptr_rdata*)(rr->rdata))->flags_len;
3581
+				rpc->printf(ctx, "%srr flags: %.*s", SPACE_FORMAT,
3582
+									s.len, s.s);
3583
+				s.s=((struct naptr_rdata*)(rr->rdata))->services;
3584
+				s.len=((struct naptr_rdata*)(rr->rdata))->services_len;
3585
+				rpc->printf(ctx, "%srr service: %.*s", SPACE_FORMAT,
3586
+									s.len, s.s);
3587
+				s.s = ((struct naptr_rdata*)(rr->rdata))->regexp;
3588
+				s.len = ((struct naptr_rdata*)(rr->rdata))->regexp_len;
3589
+				rpc->printf(ctx, "%srr regexp: %.*s", SPACE_FORMAT,
3590
+									s.len, s.s);
3591
+				s.s = ((struct naptr_rdata*)(rr->rdata))->repl;
3592
+				s.len = ((struct naptr_rdata*)(rr->rdata))->repl_len;
3593
+				rpc->printf(ctx, "%srr replacement: %.*s", 
3594
+									SPACE_FORMAT, s.len, s.s);
3595
+				break;
3596
+			case T_CNAME:
3597
+				rpc->printf(ctx, "%srr name: %s", SPACE_FORMAT,
3598
+							((struct cname_rdata*)(rr->rdata))->name);
3599
+				break;
3600
+			case T_TXT:
3601
+				for (i=0; i<((struct txt_rdata*)(rr->rdata))->cstr_no;
3602
+						i++){
3603
+					rpc->printf(ctx, "%stxt[%d]: %s", SPACE_FORMAT, i,
3604
+						((struct txt_rdata*)(rr->rdata))->txt[i].cstr);
3605
+				}
3606
+				break;
3607
+			default:
3608
+				rpc->printf(ctx, "%sresource record: unknown",
3609
+									SPACE_FORMAT);
3610
+		}
3611
+		rpc->printf(ctx, "%srr expires in (s): %d", SPACE_FORMAT,
3612
+						(s_ticks_t)(rr->expire-now)<0?-1 : 
3613
+						TICKS_TO_S(rr->expire-now));
3614
+		rpc->printf(ctx, "%srr error flags: %d", SPACE_FORMAT, 
3615
+						rr->err_flags);
3616
+	}
3617
+}
3618
+
3619
+
3620
+
3621
+/* dumps the content of the cache in a human-readable format */
3622
+void dns_cache_view(rpc_t* rpc, void* ctx)
3623
+{
3624
+	int h;
3625
+	struct dns_hash_entry* e;
3490 3626
 
3491 3627
 	if (!cfg_get(core, core_cfg, use_dns_cache)){
3492 3628
 		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
3493 3629
 		return;
3494 3630
 	}
3495
-	now=get_ticks_raw();
3496 3631
 	LOCK_DNS_HASH();
3497 3632
 	for (h=0; h<DNS_HASH_SIZE; h++){
3498 3633
 		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
-			}
3634
+			rpc->printf(ctx, "{\n");
3635
+			dns_cache_print_entry(rpc, ctx, e);
3572 3636
 			rpc->printf(ctx, "}");
3573 3637
 		}
3574 3638
 	}
... ...
@@ -3616,6 +3756,7 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3616 3616
 	struct dns_rr *rr, *last_rr, *new_rr;
3617 3617
 	int size, rounded_size, rr_size;
3618 3618
 	ticks_t now;
3619
+	int i;
3619 3620
 
3620 3621
 	now=get_ticks_raw();
3621 3622
 	size = e->total_size;
... ...
@@ -3635,6 +3776,9 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3635 3635
 			case T_NAPTR:
3636 3636
 				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3637 3637
 				break;
3638
+			case T_TXT:
3639
+				rr_size = ROUND_POINTER(sizeof(struct dns_rr));
3640
+				break;
3638 3641
 			default:
3639 3642
 				LOG(L_ERR, "ERROR: dns_cache_clone_entry: type %d not "
3640 3643
 							"supported\n", e->type);
... ...
@@ -3692,6 +3836,13 @@ static struct dns_hash_entry *dns_cache_clone_entry(struct dns_hash_entry *e,
3692 3692
 			((struct naptr_rdata*)rr->rdata)->repl =
3693 3693
 				translate_pointer((char*)new, (char*)e,
3694 3694
 					((struct naptr_rdata*)rr->rdata)->repl);
3695
+		}else if (e->type == T_TXT){
3696
+			/* there are pointers inside the TXT structure */
3697
+			for (i=0; i<((struct txt_rdata*)rr->rdata)->cstr_no; i++){
3698
+				((struct txt_rdata*)rr->rdata)->txt[i].cstr=
3699
+					translate_pointer((char*) new, (char*) e,
3700
+						((struct txt_rdata*)rr->rdata)->txt[i].cstr);
3701
+			}
3695 3702
 		}
3696 3703
 	}
3697 3704
 
... ...
@@ -3763,6 +3914,7 @@ static void dns_cache_add_record(rpc_t* rpc, void* ctx, unsigned short type)
3763 3763
 		break;
3764 3764
 	case T_CNAME:
3765 3765
 	case T_NAPTR:
3766
+	case T_TXT:
3766 3767
 		rpc->fault(ctx, 400, "not implemented");
3767 3768
 		return;
3768 3769
 	default:
... ...
@@ -3980,6 +4132,37 @@ static void dns_cache_delete_record(rpc_t* rpc, void* ctx, unsigned short type)
3980 3980
 }
3981 3981
 
3982 3982
 
3983
+/* performs  a dns lookup over rpc */
3984
+void dns_cache_rpc_lookup(rpc_t* rpc, void* ctx)
3985
+{
3986
+	struct dns_hash_entry *e;
3987
+	str name;
3988
+	str type;
3989
+	int t;
3990
+
3991
+	if (!cfg_get(core, core_cfg, use_dns_cache)){
3992
+		rpc->fault(ctx, 500, "dns cache support disabled (see use_dns_cache)");
3993
+		return;
3994
+	}
3995
+	
3996
+	if (rpc->scan(ctx, "SS", &type, &name) < 1)
3997
+		return;
3998
+	t=dns_get_type(&type);
3999
+	if (t<0){
4000
+		rpc->fault(ctx, 400, "Invalid type");
4001
+		return;
4002
+	}
4003
+	e=dns_get_entry(&name, t);
4004
+	if (e==0){
4005
+		rpc->fault(ctx, 400, "Not found");
4006
+		return;
4007
+	}
4008
+	dns_cache_print_entry(rpc, ctx, e);
4009
+	dns_hash_put(e);
4010
+}
4011
+
4012
+
4013
+
3983 4014
 /* wrapper functions for adding and deleting records */
3984 4015
 void dns_cache_add_a(rpc_t* rpc, void* ctx)
3985 4016
 {
... ...
@@ -4017,6 +4200,24 @@ void dns_cache_delete_srv(rpc_t* rpc, void* ctx)
4017 4017
 }
4018 4018
 
4019 4019
 
4020
+void dns_cache_delete_naptr(rpc_t* rpc, void* ctx)
4021
+{
4022
+	dns_cache_delete_record(rpc, ctx, T_NAPTR);
4023
+}
4024
+
4025
+
4026
+void dns_cache_delete_cname(rpc_t* rpc, void* ctx)
4027
+{
4028
+	dns_cache_delete_record(rpc, ctx, T_CNAME);
4029
+}
4030
+
4031
+
4032
+void dns_cache_delete_txt(rpc_t* rpc, void* ctx)
4033
+{
4034
+	dns_cache_delete_record(rpc, ctx, T_TXT);
4035
+}
4036
+
4037
+
4020 4038
 
4021 4039
 #ifdef DNS_WATCHDOG_SUPPORT
4022 4040
 /* sets the DNS server states */