| OLD | NEW |
| 1 /* $Id: evdns.c 6979 2006-08-04 18:31:13Z nickm $ */ | 1 /* $Id: evdns.c 6979 2006-08-04 18:31:13Z nickm $ */ |
| 2 | 2 |
| 3 /* The original version of this module was written by Adam Langley; for | 3 /* The original version of this module was written by Adam Langley; for |
| 4 * a history of modifications, check out the subversion logs. | 4 * a history of modifications, check out the subversion logs. |
| 5 * | 5 * |
| 6 * When editing this module, try to keep it re-mergeable by Adam. Don't | 6 * When editing this module, try to keep it re-mergeable by Adam. Don't |
| 7 * reformat the whitespace, add Tor dependencies, or so on. | 7 * reformat the whitespace, add Tor dependencies, or so on. |
| 8 * | 8 * |
| 9 * TODO: | 9 * TODO: |
| 10 * - Support IPv6 and PTR records. | 10 * - Support IPv6 and PTR records. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 #include <time.h> | 67 #include <time.h> |
| 68 #endif | 68 #endif |
| 69 | 69 |
| 70 #ifdef DNS_USE_OPENSSL_FOR_ID | 70 #ifdef DNS_USE_OPENSSL_FOR_ID |
| 71 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID | 71 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID |
| 72 #error Multiple id options selected | 72 #error Multiple id options selected |
| 73 #endif | 73 #endif |
| 74 #include <openssl/rand.h> | 74 #include <openssl/rand.h> |
| 75 #endif | 75 #endif |
| 76 | 76 |
| 77 #ifndef _FORTIFY_SOURCE |
| 77 #define _FORTIFY_SOURCE 3 | 78 #define _FORTIFY_SOURCE 3 |
| 79 #endif |
| 78 | 80 |
| 79 #include <string.h> | 81 #include <string.h> |
| 80 #include <fcntl.h> | 82 #include <fcntl.h> |
| 81 #ifdef HAVE_SYS_TIME_H | 83 #ifdef HAVE_SYS_TIME_H |
| 82 #include <sys/time.h> | 84 #include <sys/time.h> |
| 83 #endif | 85 #endif |
| 84 #ifdef HAVE_STDINT_H | 86 #ifdef HAVE_STDINT_H |
| 85 #include <stdint.h> | 87 #include <stdint.h> |
| 86 #endif | 88 #endif |
| 87 #include <stdlib.h> | 89 #include <stdlib.h> |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 } aaaa; | 204 } aaaa; |
| 203 struct { | 205 struct { |
| 204 char name[HOST_NAME_MAX]; | 206 char name[HOST_NAME_MAX]; |
| 205 } ptr; | 207 } ptr; |
| 206 } data; | 208 } data; |
| 207 }; | 209 }; |
| 208 | 210 |
| 209 struct nameserver { | 211 struct nameserver { |
| 210 int socket; /* a connected UDP socket */ | 212 int socket; /* a connected UDP socket */ |
| 211 u32 address; | 213 u32 address; |
| 214 u16 port; |
| 212 int failed_times; /* number of times which we have given this server a
chance */ | 215 int failed_times; /* number of times which we have given this server a
chance */ |
| 213 int timedout; /* number of times in a row a request has timed out */ | 216 int timedout; /* number of times in a row a request has timed out */ |
| 214 struct event event; | 217 struct event event; |
| 215 /* these objects are kept in a circular list */ | 218 /* these objects are kept in a circular list */ |
| 216 struct nameserver *next, *prev; | 219 struct nameserver *next, *prev; |
| 217 struct event timeout_event; /* used to keep the timeout for */ | 220 struct event timeout_event; /* used to keep the timeout for */ |
| 218 /* when we next probe this server. */ | 221 /* when we next probe this server. */ |
| 219 /* Valid if state == 0 */ | 222 /* Valid if state == 0 */ |
| 220 char state; /* zero if we think that this server is down */ | 223 char state; /* zero if we think that this server is down */ |
| 221 char choked; /* true if we have an EAGAIN from this server's socket */ | 224 char choked; /* true if we have an EAGAIN from this server's socket */ |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 /* This can happen if the nameserver acts in a way which makes u
s mark */ | 465 /* This can happen if the nameserver acts in a way which makes u
s mark */ |
| 463 /* it as bad and then starts sending good replies. */ | 466 /* it as bad and then starts sending good replies. */ |
| 464 return; | 467 return; |
| 465 } | 468 } |
| 466 | 469 |
| 467 timeout = | 470 timeout = |
| 468 &global_nameserver_timeouts[MIN(ns->failed_times, | 471 &global_nameserver_timeouts[MIN(ns->failed_times, |
| 469 global_nameserver_timeouts_length - 1)
]; | 472 global_nameserver_timeouts_length - 1)
]; |
| 470 ns->failed_times++; | 473 ns->failed_times++; |
| 471 | 474 |
| 472 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns); | |
| 473 if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) { | 475 if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) { |
| 474 log(EVDNS_LOG_WARN, | 476 log(EVDNS_LOG_WARN, |
| 475 "Error from libevent when adding timer event for %s", | 477 "Error from libevent when adding timer event for %s", |
| 476 debug_ntoa(ns->address)); | 478 debug_ntoa(ns->address)); |
| 477 /* ???? Do more? */ | 479 /* ???? Do more? */ |
| 478 } | 480 } |
| 479 } | 481 } |
| 480 | 482 |
| 481 /* called when a nameserver has been deemed to have failed. For example, too */ | 483 /* called when a nameserver has been deemed to have failed. For example, too */ |
| 482 /* many packets have timed out etc */ | 484 /* many packets have timed out etc */ |
| 483 static void | 485 static void |
| 484 nameserver_failed(struct nameserver *const ns, const char *msg) { | 486 nameserver_failed(struct nameserver *const ns, const char *msg) { |
| 485 struct request *req, *started_at; | 487 struct request *req, *started_at; |
| 486 /* if this nameserver has already been marked as failed */ | 488 /* if this nameserver has already been marked as failed */ |
| 487 /* then don't do anything */ | 489 /* then don't do anything */ |
| 488 if (!ns->state) return; | 490 if (!ns->state) return; |
| 489 | 491 |
| 490 log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s", | 492 log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s", |
| 491 debug_ntoa(ns->address), msg); | 493 debug_ntoa(ns->address), msg); |
| 492 global_good_nameservers--; | 494 global_good_nameservers--; |
| 493 assert(global_good_nameservers >= 0); | 495 assert(global_good_nameservers >= 0); |
| 494 if (global_good_nameservers == 0) { | 496 if (global_good_nameservers == 0) { |
| 495 log(EVDNS_LOG_WARN, "All nameservers have failed"); | 497 log(EVDNS_LOG_WARN, "All nameservers have failed"); |
| 496 } | 498 } |
| 497 | 499 |
| 498 ns->state = 0; | 500 ns->state = 0; |
| 499 ns->failed_times = 1; | 501 ns->failed_times = 1; |
| 500 | 502 |
| 501 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns); | |
| 502 if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserve
r_timeouts[0]) < 0) { | 503 if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserve
r_timeouts[0]) < 0) { |
| 503 log(EVDNS_LOG_WARN, | 504 log(EVDNS_LOG_WARN, |
| 504 "Error from libevent when adding timer event for %s", | 505 "Error from libevent when adding timer event for %s", |
| 505 debug_ntoa(ns->address)); | 506 debug_ntoa(ns->address)); |
| 506 /* ???? Do more? */ | 507 /* ???? Do more? */ |
| 507 } | 508 } |
| 508 | 509 |
| 509 /* walk the list of inflight requests to see if any can be reassigned to
*/ | 510 /* walk the list of inflight requests to see if any can be reassigned to
*/ |
| 510 /* a different server. Requests in the waiting queue don't have a */ | 511 /* a different server. Requests in the waiting queue don't have a */ |
| 511 /* nameserver assigned yet */ | 512 /* nameserver assigned yet */ |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer
); | 674 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer
); |
| 674 return; | 675 return; |
| 675 } | 676 } |
| 676 assert(0); | 677 assert(0); |
| 677 } | 678 } |
| 678 | 679 |
| 679 /* this processes a parsed reply packet */ | 680 /* this processes a parsed reply packet */ |
| 680 static void | 681 static void |
| 681 reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
{ | 682 reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
{ |
| 682 int error; | 683 int error; |
| 683 » static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED,
DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED}; | 684 » static const int error_codes[] = { |
| 685 » » DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, |
| 686 » » DNS_ERR_NOTIMPL, DNS_ERR_REFUSED |
| 687 » }; |
| 684 | 688 |
| 685 if (flags & 0x020f || !reply || !reply->have_answer) { | 689 if (flags & 0x020f || !reply || !reply->have_answer) { |
| 686 /* there was an error */ | 690 /* there was an error */ |
| 687 if (flags & 0x0200) { | 691 if (flags & 0x0200) { |
| 688 error = DNS_ERR_TRUNCATED; | 692 error = DNS_ERR_TRUNCATED; |
| 689 } else { | 693 } else { |
| 690 u16 error_code = (flags & 0x000f) - 1; | 694 u16 error_code = (flags & 0x000f) - 1; |
| 691 if (error_code > 4) { | 695 if (error_code > 4) { |
| 692 error = DNS_ERR_UNKNOWN; | 696 error = DNS_ERR_UNKNOWN; |
| 693 } else { | 697 } else { |
| 694 error = error_codes[error_code]; | 698 error = error_codes[error_code]; |
| 695 } | 699 } |
| 696 } | 700 } |
| 697 | 701 |
| 698 switch(error) { | 702 switch(error) { |
| 699 case DNS_ERR_NOTIMPL: | 703 case DNS_ERR_NOTIMPL: |
| 700 case DNS_ERR_REFUSED: | 704 case DNS_ERR_REFUSED: |
| 701 /* we regard these errors as marking a bad nameserver */ | 705 /* we regard these errors as marking a bad nameserver */ |
| 702 if (req->reissue_count < global_max_reissues) { | 706 if (req->reissue_count < global_max_reissues) { |
| 703 char msg[64]; | 707 char msg[64]; |
| 704 evutil_snprintf(msg, sizeof(msg), | 708 evutil_snprintf(msg, sizeof(msg), |
| 705 "Bad response %d (%s)", | 709 "Bad response %d (%s)", |
| 706 error, evdns_err_to_string(error)); | 710 error, evdns_err_to_string(error)); |
| 707 nameserver_failed(req->ns, msg); | 711 nameserver_failed(req->ns, msg); |
| 708 if (!request_reissue(req)) return; | 712 if (!request_reissue(req)) return; |
| 709 } | 713 } |
| 710 break; | 714 break; |
| 711 case DNS_ERR_SERVERFAILED: | 715 case DNS_ERR_SERVERFAILED: |
| 712 » » » /* rcode 2 (servfailed) sometimes means "we are broken"
and | 716 » » » /* rcode 2 (servfailed) sometimes means "we |
| 713 » » » * sometimes (with some binds) means "that request was v
ery | 717 » » » * are broken" and sometimes (with some binds) |
| 714 » » » * confusing." Treat this as a timeout, not a failure. | 718 » » » * means "that request was very confusing." |
| 719 » » » * Treat this as a timeout, not a failure. |
| 715 */ | 720 */ |
| 716 log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver
%s; " | 721 log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver
%s; " |
| 717 "will allow the request to time out.", | 722 "will allow the request to time out.", |
| 718 debug_ntoa(req->ns->address)); | 723 debug_ntoa(req->ns->address)); |
| 719 break; | 724 break; |
| 720 default: | 725 default: |
| 721 /* we got a good reply from the nameserver */ | 726 /* we got a good reply from the nameserver */ |
| 722 nameserver_up(req->ns); | 727 nameserver_up(req->ns); |
| 723 } | 728 } |
| 724 | 729 |
| 725 if (req->search_state && req->request_type != TYPE_PTR) { | 730 if (req->search_state && req->request_type != TYPE_PTR) { |
| 726 » » » /* if we have a list of domains to search in, try the ne
xt one */ | 731 » » » /* if we have a list of domains to search in, |
| 732 » » » * try the next one */ |
| 727 if (!search_try_next(req)) { | 733 if (!search_try_next(req)) { |
| 728 » » » » /* a new request was issued so this request is f
inished and */ | 734 » » » » /* a new request was issued so this |
| 729 » » » » /* the user callback will be made when that requ
est (or a */ | 735 » » » » * request is finished and */ |
| 736 » » » » /* the user callback will be made when |
| 737 » » » » * that request (or a */ |
| 730 /* child of it) finishes. */ | 738 /* child of it) finishes. */ |
| 731 request_finished(req, &req_head); | 739 request_finished(req, &req_head); |
| 732 return; | 740 return; |
| 733 } | 741 } |
| 734 } | 742 } |
| 735 | 743 |
| 736 /* all else failed. Pass the failure up */ | 744 /* all else failed. Pass the failure up */ |
| 737 reply_callback(req, 0, error, NULL); | 745 reply_callback(req, 0, error, NULL); |
| 738 request_finished(req, &req_head); | 746 request_finished(req, &req_head); |
| 739 } else { | 747 } else { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 else | 804 else |
| 797 *idx = name_end; | 805 *idx = name_end; |
| 798 return 0; | 806 return 0; |
| 799 err: | 807 err: |
| 800 return -1; | 808 return -1; |
| 801 } | 809 } |
| 802 | 810 |
| 803 /* parses a raw request from a nameserver */ | 811 /* parses a raw request from a nameserver */ |
| 804 static int | 812 static int |
| 805 reply_parse(u8 *packet, int length) { | 813 reply_parse(u8 *packet, int length) { |
| 806 » int j = 0; /* index into packet */ | 814 » int j = 0, k = 0; /* index into packet */ |
| 807 u16 _t; /* used by the macros */ | 815 u16 _t; /* used by the macros */ |
| 808 u32 _t32; /* used by the macros */ | 816 u32 _t32; /* used by the macros */ |
| 809 » char tmp_name[256]; /* used by the macros */ | 817 » char tmp_name[256], cmp_name[256]; /* used by the macros */ |
| 810 | 818 |
| 811 u16 trans_id, questions, answers, authority, additional, datalength; | 819 u16 trans_id, questions, answers, authority, additional, datalength; |
| 812 u16 flags = 0; | 820 u16 flags = 0; |
| 813 u32 ttl, ttl_r = 0xffffffff; | 821 u32 ttl, ttl_r = 0xffffffff; |
| 814 struct reply reply; | 822 struct reply reply; |
| 815 struct request *req = NULL; | 823 struct request *req = NULL; |
| 816 unsigned int i; | 824 unsigned int i; |
| 817 | 825 |
| 818 GET16(trans_id); | 826 GET16(trans_id); |
| 819 GET16(flags); | 827 GET16(flags); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 832 /* If it's not an answer, it doesn't correspond to any request. */ | 840 /* If it's not an answer, it doesn't correspond to any request. */ |
| 833 if (!(flags & 0x8000)) return -1; /* must be an answer */ | 841 if (!(flags & 0x8000)) return -1; /* must be an answer */ |
| 834 if (flags & 0x020f) { | 842 if (flags & 0x020f) { |
| 835 /* there was an error */ | 843 /* there was an error */ |
| 836 goto err; | 844 goto err; |
| 837 } | 845 } |
| 838 /* if (!answers) return; */ /* must have an answer of some form */ | 846 /* if (!answers) return; */ /* must have an answer of some form */ |
| 839 | 847 |
| 840 /* This macro skips a name in the DNS reply. */ | 848 /* This macro skips a name in the DNS reply. */ |
| 841 #define SKIP_NAME \ | 849 #define SKIP_NAME \ |
| 842 » do { tmp_name[0] = '\0';» » » » » \ | 850 » do { tmp_name[0] = '\0';» » » » \ |
| 843 » » if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0
) \ | 851 » » if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0
)\ |
| 844 » » » goto err;» » » » » »
» » » » » » » \ | 852 » » » goto err;» » » » \ |
| 845 » } while(0); | 853 » } while(0) |
| 854 #define TEST_NAME \ |
| 855 » do { tmp_name[0] = '\0';» » » » \ |
| 856 » » cmp_name[0] = '\0';» » » » \ |
| 857 » » k = j;» » » » » » \ |
| 858 » » if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0
)\ |
| 859 » » » goto err;» » » » » \ |
| 860 » » if (name_parse(req->request, req->request_len, &k, cmp_name, siz
eof(cmp_name))<0)» \ |
| 861 » » » goto err;» » » » \ |
| 862 » » if (memcmp(tmp_name, cmp_name, strlen (tmp_name)) != 0)»\ |
| 863 » » » return (-1); /* we ignore mismatching names */» \ |
| 864 » } while(0) |
| 846 | 865 |
| 847 reply.type = req->request_type; | 866 reply.type = req->request_type; |
| 848 | 867 |
| 849 /* skip over each question in the reply */ | 868 /* skip over each question in the reply */ |
| 850 for (i = 0; i < questions; ++i) { | 869 for (i = 0; i < questions; ++i) { |
| 851 /* the question looks like | 870 /* the question looks like |
| 852 * <label:name><u16:type><u16:class> | 871 * <label:name><u16:type><u16:class> |
| 853 */ | 872 */ |
| 854 » » SKIP_NAME; | 873 » » TEST_NAME; |
| 855 j += 4; | 874 j += 4; |
| 856 if (j > length) goto err; | 875 if (j > length) goto err; |
| 857 } | 876 } |
| 858 | 877 |
| 859 /* now we have the answer section which looks like | 878 /* now we have the answer section which looks like |
| 860 * <label:name><u16:type><u16:class><u32:ttl><u16:len><data...> | 879 * <label:name><u16:type><u16:class><u32:ttl><u16:len><data...> |
| 861 */ | 880 */ |
| 862 | 881 |
| 863 for (i = 0; i < answers; ++i) { | 882 for (i = 0; i < answers; ++i) { |
| 864 u16 type, class; | 883 u16 type, class; |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1127 /* so we just return this one and hope for the */ | 1146 /* so we just return this one and hope for the */ |
| 1128 /* best */ | 1147 /* best */ |
| 1129 assert(global_good_nameservers == 0); | 1148 assert(global_good_nameservers == 0); |
| 1130 picked = server_head; | 1149 picked = server_head; |
| 1131 server_head = server_head->next; | 1150 server_head = server_head->next; |
| 1132 return picked; | 1151 return picked; |
| 1133 } | 1152 } |
| 1134 } | 1153 } |
| 1135 } | 1154 } |
| 1136 | 1155 |
| 1156 static int |
| 1157 address_is_correct(struct nameserver *ns, struct sockaddr *sa, socklen_t slen) |
| 1158 { |
| 1159 struct sockaddr_in *sin = (struct sockaddr_in*) sa; |
| 1160 if (sa->sa_family != AF_INET || slen != sizeof(struct sockaddr_in)) |
| 1161 return 0; |
| 1162 if (sin->sin_addr.s_addr != ns->address) |
| 1163 return 0; |
| 1164 return 1; |
| 1165 } |
| 1166 |
| 1137 /* this is called when a namesever socket is ready for reading */ | 1167 /* this is called when a namesever socket is ready for reading */ |
| 1138 static void | 1168 static void |
| 1139 nameserver_read(struct nameserver *ns) { | 1169 nameserver_read(struct nameserver *ns) { |
| 1140 u8 packet[1500]; | 1170 u8 packet[1500]; |
| 1171 struct sockaddr_storage ss; |
| 1172 socklen_t addrlen = sizeof(ss); |
| 1141 | 1173 |
| 1142 for (;;) { | 1174 for (;;) { |
| 1143 » const int r = recv(ns->socket, packet, sizeof(packet), 0); | 1175 » const int r = recvfrom(ns->socket, packet, sizeof(packet), 0, |
| 1176 » » (struct sockaddr*)&ss, &addrlen); |
| 1144 if (r < 0) { | 1177 if (r < 0) { |
| 1145 int err = last_error(ns->socket); | 1178 int err = last_error(ns->socket); |
| 1146 if (error_is_eagain(err)) return; | 1179 if (error_is_eagain(err)) return; |
| 1147 nameserver_failed(ns, strerror(err)); | 1180 nameserver_failed(ns, strerror(err)); |
| 1148 return; | 1181 return; |
| 1149 } | 1182 } |
| 1183 if (!address_is_correct(ns, (struct sockaddr*)&ss, addrlen)) { |
| 1184 log(EVDNS_LOG_WARN, "Address mismatch on received " |
| 1185 "DNS packet."); |
| 1186 return; |
| 1187 } |
| 1150 ns->timedout = 0; | 1188 ns->timedout = 0; |
| 1151 reply_parse(packet, r); | 1189 reply_parse(packet, r); |
| 1152 } | 1190 } |
| 1153 } | 1191 } |
| 1154 | 1192 |
| 1155 /* Read a packet from a DNS client on a server port s, parse it, and */ | 1193 /* Read a packet from a DNS client on a server port s, parse it, and */ |
| 1156 /* act accordingly. */ | 1194 /* act accordingly. */ |
| 1157 static void | 1195 static void |
| 1158 server_port_read(struct evdns_server_port *s) { | 1196 server_port_read(struct evdns_server_port *s) { |
| 1159 u8 packet[1500]; | 1197 u8 packet[1500]; |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 memcpy(buf+j, item->data, item->datalen); | 1698 memcpy(buf+j, item->data, item->datalen); |
| 1661 j += item->datalen; | 1699 j += item->datalen; |
| 1662 } | 1700 } |
| 1663 item = item->next; | 1701 item = item->next; |
| 1664 } | 1702 } |
| 1665 } | 1703 } |
| 1666 | 1704 |
| 1667 if (j > 512) { | 1705 if (j > 512) { |
| 1668 overflow: | 1706 overflow: |
| 1669 j = 512; | 1707 j = 512; |
| 1670 » » buf[3] |= 0x02; /* set the truncated bit. */ | 1708 » » buf[2] |= 0x02; /* set the truncated bit. */ |
| 1671 } | 1709 } |
| 1672 | 1710 |
| 1673 req->response_len = j; | 1711 req->response_len = j; |
| 1674 | 1712 |
| 1675 if (!(req->response = malloc(req->response_len))) { | 1713 if (!(req->response = malloc(req->response_len))) { |
| 1676 server_request_free_answers(req); | 1714 server_request_free_answers(req); |
| 1677 dnslabel_clear(&table); | 1715 dnslabel_clear(&table); |
| 1678 return (-1); | 1716 return (-1); |
| 1679 } | 1717 } |
| 1680 memcpy(req->response, buf, req->response_len); | 1718 memcpy(req->response, buf, req->response_len); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1867 } | 1905 } |
| 1868 | 1906 |
| 1869 /* try to send a request to a given server. */ | 1907 /* try to send a request to a given server. */ |
| 1870 /* */ | 1908 /* */ |
| 1871 /* return: */ | 1909 /* return: */ |
| 1872 /* 0 ok */ | 1910 /* 0 ok */ |
| 1873 /* 1 temporary failure */ | 1911 /* 1 temporary failure */ |
| 1874 /* 2 other failure */ | 1912 /* 2 other failure */ |
| 1875 static int | 1913 static int |
| 1876 evdns_request_transmit_to(struct request *req, struct nameserver *server) { | 1914 evdns_request_transmit_to(struct request *req, struct nameserver *server) { |
| 1877 » const int r = send(server->socket, req->request, req->request_len, 0); | 1915 » struct sockaddr_in sin; |
| 1916 » int r; |
| 1917 » memset(&sin, 0, sizeof(sin)); |
| 1918 » sin.sin_addr.s_addr = req->ns->address; |
| 1919 » sin.sin_port = req->ns->port; |
| 1920 » sin.sin_family = AF_INET; |
| 1921 |
| 1922 » r = sendto(server->socket, req->request, req->request_len, 0, |
| 1923 » (struct sockaddr*)&sin, sizeof(sin)); |
| 1878 if (r < 0) { | 1924 if (r < 0) { |
| 1879 int err = last_error(server->socket); | 1925 int err = last_error(server->socket); |
| 1880 if (error_is_eagain(err)) return 1; | 1926 if (error_is_eagain(err)) return 1; |
| 1881 nameserver_failed(req->ns, strerror(err)); | 1927 nameserver_failed(req->ns, strerror(err)); |
| 1882 return 2; | 1928 return 2; |
| 1883 } else if (r != (int)req->request_len) { | 1929 } else if (r != (int)req->request_len) { |
| 1884 return 1; /* short write */ | 1930 return 1; /* short write */ |
| 1885 } else { | 1931 } else { |
| 1886 return 0; | 1932 return 0; |
| 1887 } | 1933 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1916 nameserver_write_waiting(req->ns, 1); | 1962 nameserver_write_waiting(req->ns, 1); |
| 1917 return 1; | 1963 return 1; |
| 1918 case 2: | 1964 case 2: |
| 1919 /* failed in some other way */ | 1965 /* failed in some other way */ |
| 1920 retcode = 1; | 1966 retcode = 1; |
| 1921 /* fall through */ | 1967 /* fall through */ |
| 1922 default: | 1968 default: |
| 1923 /* all ok */ | 1969 /* all ok */ |
| 1924 log(EVDNS_LOG_DEBUG, | 1970 log(EVDNS_LOG_DEBUG, |
| 1925 "Setting timeout for request %lx", (unsigned long) req); | 1971 "Setting timeout for request %lx", (unsigned long) req); |
| 1926 evtimer_set(&req->timeout_event, evdns_request_timeout_callback,
req); | |
| 1927 if (evtimer_add(&req->timeout_event, &global_timeout) < 0) { | 1972 if (evtimer_add(&req->timeout_event, &global_timeout) < 0) { |
| 1928 log(EVDNS_LOG_WARN, | 1973 log(EVDNS_LOG_WARN, |
| 1929 "Error from libevent when adding timer for request %lx", | 1974 "Error from libevent when adding timer for request %lx", |
| 1930 (unsigned long) req); | 1975 (unsigned long) req); |
| 1931 /* ???? Do more? */ | 1976 /* ???? Do more? */ |
| 1932 } | 1977 } |
| 1933 req->tx_count++; | 1978 req->tx_count++; |
| 1934 req->transmit_me = 0; | 1979 req->transmit_me = 0; |
| 1935 return retcode; | 1980 return retcode; |
| 1936 } | 1981 } |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2063 evdns_requests_pump_waiting_queue(); | 2108 evdns_requests_pump_waiting_queue(); |
| 2064 return 0; | 2109 return 0; |
| 2065 } | 2110 } |
| 2066 | 2111 |
| 2067 static int | 2112 static int |
| 2068 _evdns_nameserver_add_impl(unsigned long int address, int port) { | 2113 _evdns_nameserver_add_impl(unsigned long int address, int port) { |
| 2069 /* first check to see if we already have this nameserver */ | 2114 /* first check to see if we already have this nameserver */ |
| 2070 | 2115 |
| 2071 const struct nameserver *server = server_head, *const started_at = serve
r_head; | 2116 const struct nameserver *server = server_head, *const started_at = serve
r_head; |
| 2072 struct nameserver *ns; | 2117 struct nameserver *ns; |
| 2073 struct sockaddr_in sin; | |
| 2074 int err = 0; | 2118 int err = 0; |
| 2075 if (server) { | 2119 if (server) { |
| 2076 do { | 2120 do { |
| 2077 if (server->address == address) return 3; | 2121 if (server->address == address) return 3; |
| 2078 server = server->next; | 2122 server = server->next; |
| 2079 } while (server != started_at); | 2123 } while (server != started_at); |
| 2080 } | 2124 } |
| 2081 | 2125 |
| 2082 ns = (struct nameserver *) malloc(sizeof(struct nameserver)); | 2126 ns = (struct nameserver *) malloc(sizeof(struct nameserver)); |
| 2083 if (!ns) return -1; | 2127 if (!ns) return -1; |
| 2084 | 2128 |
| 2085 memset(ns, 0, sizeof(struct nameserver)); | 2129 memset(ns, 0, sizeof(struct nameserver)); |
| 2086 | 2130 |
| 2131 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns); |
| 2132 |
| 2087 ns->socket = socket(PF_INET, SOCK_DGRAM, 0); | 2133 ns->socket = socket(PF_INET, SOCK_DGRAM, 0); |
| 2088 if (ns->socket < 0) { err = 1; goto out1; } | 2134 if (ns->socket < 0) { err = 1; goto out1; } |
| 2089 evutil_make_socket_nonblocking(ns->socket); | 2135 evutil_make_socket_nonblocking(ns->socket); |
| 2090 sin.sin_addr.s_addr = address; | |
| 2091 sin.sin_port = htons(port); | |
| 2092 sin.sin_family = AF_INET; | |
| 2093 if (connect(ns->socket, (struct sockaddr *) &sin, sizeof(sin)) != 0) { | |
| 2094 err = 2; | |
| 2095 goto out2; | |
| 2096 } | |
| 2097 | 2136 |
| 2098 ns->address = address; | 2137 ns->address = address; |
| 2138 ns->port = htons(port); |
| 2099 ns->state = 1; | 2139 ns->state = 1; |
| 2100 event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready
_callback, ns); | 2140 event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready
_callback, ns); |
| 2101 if (event_add(&ns->event, NULL) < 0) { | 2141 if (event_add(&ns->event, NULL) < 0) { |
| 2102 err = 2; | 2142 err = 2; |
| 2103 goto out2; | 2143 goto out2; |
| 2104 } | 2144 } |
| 2105 | 2145 |
| 2106 log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address)); | 2146 log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address)); |
| 2107 | 2147 |
| 2108 /* insert this nameserver into the list of them */ | 2148 /* insert this nameserver into the list of them */ |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2201 const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff; | 2241 const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff; |
| 2202 /* the request data is alloced in a single block with the header */ | 2242 /* the request data is alloced in a single block with the header */ |
| 2203 struct request *const req = | 2243 struct request *const req = |
| 2204 (struct request *) malloc(sizeof(struct request) + request_max_len); | 2244 (struct request *) malloc(sizeof(struct request) + request_max_len); |
| 2205 int rlen; | 2245 int rlen; |
| 2206 (void) flags; | 2246 (void) flags; |
| 2207 | 2247 |
| 2208 if (!req) return NULL; | 2248 if (!req) return NULL; |
| 2209 memset(req, 0, sizeof(struct request)); | 2249 memset(req, 0, sizeof(struct request)); |
| 2210 | 2250 |
| 2251 evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req); |
| 2252 |
| 2211 /* request data lives just after the header */ | 2253 /* request data lives just after the header */ |
| 2212 req->request = ((u8 *) req) + sizeof(struct request); | 2254 req->request = ((u8 *) req) + sizeof(struct request); |
| 2213 /* denotes that the request data shouldn't be free()ed */ | 2255 /* denotes that the request data shouldn't be free()ed */ |
| 2214 req->request_appended = 1; | 2256 req->request_appended = 1; |
| 2215 rlen = evdns_request_data_build(name, name_len, trans_id, | 2257 rlen = evdns_request_data_build(name, name_len, trans_id, |
| 2216 type, CLASS_INET, req->request, request_max_len); | 2258 type, CLASS_INET, req->request, request_max_len); |
| 2217 if (rlen < 0) | 2259 if (rlen < 0) |
| 2218 goto err1; | 2260 goto err1; |
| 2219 req->request_len = rlen; | 2261 req->request_len = rlen; |
| 2220 req->trans_id = trans_id; | 2262 req->trans_id = trans_id; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2270 request_new(TYPE_AAAA, name, flags, callback, ptr); | 2312 request_new(TYPE_AAAA, name, flags, callback, ptr); |
| 2271 if (req == NULL) | 2313 if (req == NULL) |
| 2272 return (1); | 2314 return (1); |
| 2273 request_submit(req); | 2315 request_submit(req); |
| 2274 return (0); | 2316 return (0); |
| 2275 } else { | 2317 } else { |
| 2276 return (search_request_new(TYPE_AAAA, name, flags, callback, ptr
)); | 2318 return (search_request_new(TYPE_AAAA, name, flags, callback, ptr
)); |
| 2277 } | 2319 } |
| 2278 } | 2320 } |
| 2279 | 2321 |
| 2280 int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal
lback, void *ptr) { | 2322 int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_ty
pe callback, void *ptr) { |
| 2281 char buf[32]; | 2323 char buf[32]; |
| 2282 struct request *req; | 2324 struct request *req; |
| 2283 u32 a; | 2325 u32 a; |
| 2284 assert(in); | 2326 assert(in); |
| 2285 a = ntohl(in->s_addr); | 2327 a = ntohl(in->s_addr); |
| 2286 evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", | 2328 evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa", |
| 2287 (int)(u8)((a )&0xff), | 2329 (int)(u8)((a )&0xff), |
| 2288 (int)(u8)((a>>8 )&0xff), | 2330 (int)(u8)((a>>8 )&0xff), |
| 2289 (int)(u8)((a>>16)&0xff), | 2331 (int)(u8)((a>>16)&0xff), |
| 2290 (int)(u8)((a>>24)&0xff)); | 2332 (int)(u8)((a>>24)&0xff)); |
| 2291 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf); | 2333 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf); |
| 2292 req = request_new(TYPE_PTR, buf, flags, callback, ptr); | 2334 req = request_new(TYPE_PTR, buf, flags, callback, ptr); |
| 2293 if (!req) return 1; | 2335 if (!req) return 1; |
| 2294 request_submit(req); | 2336 request_submit(req); |
| 2295 return 0; | 2337 return 0; |
| 2296 } | 2338 } |
| 2297 | 2339 |
| 2298 int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_ty
pe callback, void *ptr) { | 2340 int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callb
ack_type callback, void *ptr) { |
| 2299 /* 32 nybbles, 32 periods, "ip6.arpa", NUL. */ | 2341 /* 32 nybbles, 32 periods, "ip6.arpa", NUL. */ |
| 2300 char buf[73]; | 2342 char buf[73]; |
| 2301 char *cp; | 2343 char *cp; |
| 2302 struct request *req; | 2344 struct request *req; |
| 2303 int i; | 2345 int i; |
| 2304 assert(in); | 2346 assert(in); |
| 2305 cp = buf; | 2347 cp = buf; |
| 2306 for (i=15; i >= 0; --i) { | 2348 for (i=15; i >= 0; --i) { |
| 2307 u8 byte = in->s6_addr[i]; | 2349 u8 byte = in->s6_addr[i]; |
| 2308 *cp++ = "0123456789abcdef"[byte & 0x0f]; | 2350 *cp++ = "0123456789abcdef"[byte & 0x0f]; |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2940 } | 2982 } |
| 2941 | 2983 |
| 2942 if (found == 0) { | 2984 if (found == 0) { |
| 2943 log(EVDNS_LOG_WARN,"Didn't find any nameservers."); | 2985 log(EVDNS_LOG_WARN,"Didn't find any nameservers."); |
| 2944 } | 2986 } |
| 2945 | 2987 |
| 2946 return found ? 0 : -1; | 2988 return found ? 0 : -1; |
| 2947 #undef TRY | 2989 #undef TRY |
| 2948 } | 2990 } |
| 2949 | 2991 |
| 2950 static int | 2992 int |
| 2951 evdns_config_windows_nameservers(void) | 2993 evdns_config_windows_nameservers(void) |
| 2952 { | 2994 { |
| 2953 if (load_nameservers_with_getnetworkparams() == 0) | 2995 if (load_nameservers_with_getnetworkparams() == 0) |
| 2954 return 0; | 2996 return 0; |
| 2955 return load_nameservers_from_registry(); | 2997 return load_nameservers_from_registry(); |
| 2956 } | 2998 } |
| 2957 #endif | 2999 #endif |
| 2958 | 3000 |
| 2959 int | 3001 int |
| 2960 evdns_init(void) | 3002 evdns_init(void) |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3137 } else { | 3179 } else { |
| 3138 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]); | 3180 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]); |
| 3139 evdns_resolve_ipv4(v[idx], 0, main_callback, v[idx]); | 3181 evdns_resolve_ipv4(v[idx], 0, main_callback, v[idx]); |
| 3140 } | 3182 } |
| 3141 } | 3183 } |
| 3142 fflush(stdout); | 3184 fflush(stdout); |
| 3143 event_dispatch(); | 3185 event_dispatch(); |
| 3144 return 0; | 3186 return 0; |
| 3145 } | 3187 } |
| 3146 #endif | 3188 #endif |
| OLD | NEW |