From: <ni...@us...> - 2009-06-24 22:39:14
|
Revision: 1328 http://levent.svn.sourceforge.net/levent/?rev=1328&view=rev Author: nickm Date: 2009-06-24 22:39:12 +0000 (Wed, 24 Jun 2009) Log Message: ----------- Let evdns keep working when our IP changes. Fix by Christopher Davis; backported by nickm. Modified Paths: -------------- branches/patches-1.4/libevent/ChangeLog branches/patches-1.4/libevent/evdns.c Modified: branches/patches-1.4/libevent/ChangeLog =================================================================== --- branches/patches-1.4/libevent/ChangeLog 2009-06-24 22:39:03 UTC (rev 1327) +++ branches/patches-1.4/libevent/ChangeLog 2009-06-24 22:39:12 UTC (rev 1328) @@ -4,6 +4,7 @@ o Use __VA_ARGS__ syntax for varargs macros in event_rpcgen when compiler is not GCC. o Activate fd events in a pseudorandom order with O(N) backends, so that we don't systematically favor low fds (select) or earlier-added fds (poll, win32). o Fix another pair of fencepost bugs in epoll.c. [Patch from Adam Langley.] + o Do not break evdns connections to nameservers when our IP changes. Changes in 1.4.11-stable: o Fix a bug when removing a timeout from the heap. [Patch from Marko Kreen] Modified: branches/patches-1.4/libevent/evdns.c =================================================================== --- branches/patches-1.4/libevent/evdns.c 2009-06-24 22:39:03 UTC (rev 1327) +++ branches/patches-1.4/libevent/evdns.c 2009-06-24 22:39:12 UTC (rev 1328) @@ -209,6 +209,7 @@ struct nameserver { int socket; /* a connected UDP socket */ u32 address; + u16 port; int failed_times; /* number of times which we have given this server a chance */ int timedout; /* number of times in a row a request has timed out */ struct event event; @@ -1150,19 +1151,38 @@ } } +static int +address_is_correct(struct nameserver *ns, struct sockaddr *sa, socklen_t slen) +{ + struct sockaddr_in *sin = (struct sockaddr_in*) sa; + if (sa->sa_family != AF_INET || slen != sizeof(struct sockaddr_in)) + return 0; + if (sin->sin_addr.s_addr != ns->address) + return 0; + return 1; +} + /* this is called when a namesever socket is ready for reading */ static void nameserver_read(struct nameserver *ns) { u8 packet[1500]; + struct sockaddr_storage ss; + socklen_t addrlen = sizeof(ss); for (;;) { - const int r = recv(ns->socket, packet, sizeof(packet), 0); + const int r = recvfrom(ns->socket, packet, sizeof(packet), 0, + (struct sockaddr*)&ss, &addrlen); if (r < 0) { int err = last_error(ns->socket); if (error_is_eagain(err)) return; nameserver_failed(ns, strerror(err)); return; } + if (!address_is_correct(ns, (struct sockaddr*)&ss, addrlen)) { + log(EVDNS_LOG_WARN, "Address mismatch on received " + "DNS packet."); + return; + } ns->timedout = 0; reply_parse(packet, r); } @@ -1890,7 +1910,15 @@ /* 2 other failure */ static int evdns_request_transmit_to(struct request *req, struct nameserver *server) { - const int r = send(server->socket, req->request, req->request_len, 0); + struct sockaddr_in sin; + int r; + memset(&sin, 0, sizeof(sin)); + sin.sin_addr.s_addr = req->ns->address; + sin.sin_port = req->ns->port; + sin.sin_family = AF_INET; + + r = sendto(server->socket, req->request, req->request_len, 0, + (struct sockaddr*)&sin, sizeof(sin)); if (r < 0) { int err = last_error(server->socket); if (error_is_eagain(err)) return 1; @@ -2085,7 +2113,6 @@ const struct nameserver *server = server_head, *const started_at = server_head; struct nameserver *ns; - struct sockaddr_in sin; int err = 0; if (server) { do { @@ -2104,15 +2131,9 @@ ns->socket = socket(PF_INET, SOCK_DGRAM, 0); if (ns->socket < 0) { err = 1; goto out1; } evutil_make_socket_nonblocking(ns->socket); - sin.sin_addr.s_addr = address; - sin.sin_port = htons(port); - sin.sin_family = AF_INET; - if (connect(ns->socket, (struct sockaddr *) &sin, sizeof(sin)) != 0) { - err = 2; - goto out2; - } ns->address = address; + ns->port = htons(port); ns->state = 1; event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready_callback, ns); if (event_add(&ns->event, NULL) < 0) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |