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 |