diff options
-rw-r--r-- | src/or/eventdns.c | 92 | ||||
-rw-r--r-- | src/or/eventdns.h | 2 |
2 files changed, 78 insertions, 16 deletions
diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 8fd09a1a1..a7b85d998 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -1587,20 +1587,24 @@ evdns_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, } int -evdns_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *name, int ttl) +evdns_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl) { u32 a; char buf[32]; - assert(in); - a = ntohl(in->s_addr); - sprintf(buf, "%d.%d.%d.%d.in-addr.arpa", - (int)(u8)((a )&0xff), - (int)(u8)((a>>8 )&0xff), - (int)(u8)((a>>16)&0xff), - (int)(u8)((a>>24)&0xff)); + assert(in || inaddr_name); + assert(!(in && inaddr_name)); + if (in) { + a = ntohl(in->s_addr); + sprintf(buf, "%d.%d.%d.%d.in-addr.arpa", + (int)(u8)((a )&0xff), + (int)(u8)((a>>8 )&0xff), + (int)(u8)((a>>16)&0xff), + (int)(u8)((a>>24)&0xff)); + inaddr_name = buf; + } return evdns_request_add_reply( - req, EVDNS_ANSWER_SECTION, buf, TYPE_PTR, CLASS_INET, - ttl, -1, 1, name); + req, EVDNS_ANSWER_SECTION, inaddr_name, TYPE_PTR, CLASS_INET, + ttl, -1, 1, hostname); } int @@ -1625,12 +1629,22 @@ evdns_request_response_format(struct server_request *req, int flags) dnslabel_table_init(&table); // XXXX need to call dnslable_table_clear. APPEND16(req->trans_id); APPEND16(flags); - APPEND16(0); /* questions */ + APPEND16(req->base.nquestions); APPEND16(req->n_answer); APPEND16(req->n_authority); APPEND16(req->n_additional); - /* Add questions : none. */ + /* Add questions. */ + for (i=0; i < req->base.nquestions; ++i) { + const char *s = req->base.questions[i]->name; + j = dnsname_to_labels(buf, buf_len, j, s, strlen(s), &table); + if (j < 0) + return (int) j; + APPEND16(req->base.questions[i]->type); + APPEND16(req->base.questions[i]->class); + } + + /* Add answer-like sections. */ for (i=0; i<3; ++i) { struct server_request_item *item; if (i==0) @@ -2894,17 +2908,49 @@ main_callback(int result, char type, int count, int ttl, } fflush(stdout); } +void +evdns_server_callback(struct evdns_server_request *req, void *data) +{ + int i, r; + (void)data; + /* dummy; give 192.168.11.11 as an answer for all A questions. */ + for (i = 0; i < req->nquestions; ++i) { + u32 ans = htonl(0xc0a80b0bUL); + if (req->questions[i]->type == TYPE_A && + req->questions[i]->class == CLASS_INET) { + printf(" -- replying for %s (A)\n", req->questions[i]->name); + r = evdns_request_add_a_reply(req, req->questions[i]->name, + 1, &ans, 10); + if (r<0) + printf("eeep, didn't work.\n"); + } else if (req->questions[i]->type == TYPE_PTR && + req->questions[i]->class == CLASS_INET) { + printf(" -- replying for %s (PTR)\n", req->questions[i]->name); + r = evdns_request_add_ptr_reply(req, NULL, req->questions[i]->name, + "foo.bar.example.com", 10); + } else { + printf(" -- skipping %s [%d %d]\n", req->questions[i]->name, + req->questions[i]->type, req->questions[i]->class); + } + } + + r = evdns_request_respond(req, 0x8000); + if (r<0) + printf("eeek, couldn't send reply.\n"); +} void -logfn(const char *msg) { - fprintf(stderr, "%s\n", msg); +logfn(int is_warn, const char *msg) { + (void) is_warn; + fprintf(stderr, "%s\n", msg); } int main(int c, char **v) { int idx; - int reverse = 0, verbose = 1; + int reverse = 0, verbose = 1, servertest = 0; if (c<2) { fprintf(stderr, "syntax: %s [-x] [-v] hostname\n", v[0]); + fprintf(stderr, "syntax: %s [-servertest]\n", v[0]); return 1; } idx = 1; @@ -2913,6 +2959,8 @@ main(int c, char **v) { reverse = 1; else if (!strcmp(v[idx], "-v")) verbose = 1; + else if (!strcmp(v[idx], "-servertest")) + servertest = 1; else fprintf(stderr, "Unknown option %s\n", v[idx]); ++idx; @@ -2921,6 +2969,20 @@ main(int c, char **v) { if (verbose) evdns_set_log_fn(logfn); evdns_resolv_conf_parse(DNS_OPTION_NAMESERVERS, "/etc/resolv.conf"); + if (servertest) { + int sock; + struct sockaddr_in my_addr; + sock = socket(PF_INET, SOCK_DGRAM, 0); + fcntl(sock, F_SETFL, O_NONBLOCK); + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(10053); + my_addr.sin_addr.s_addr = INADDR_ANY; + if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) { + perror("bind"); + exit(1); + } + evdns_add_server_port(sock, 0, evdns_server_callback, NULL); + } for (; idx < c; ++idx) { if (reverse) { struct in_addr addr; diff --git a/src/or/eventdns.h b/src/or/eventdns.h index b30498124..fb5873b1a 100644 --- a/src/or/eventdns.h +++ b/src/or/eventdns.h @@ -95,7 +95,7 @@ void evdns_close_server_port(struct evdns_server_port *port); int evdns_request_add_reply(struct evdns_server_request *req, int section, const char *name, int type, int class, int ttl, int datalen, int is_name, const char *data); int evdns_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl); int evdns_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl); -int evdns_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *name, int ttl); +int evdns_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl); int evdns_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl); int evdns_request_respond(struct evdns_server_request *req, int flags); |