Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Unified Diff: third_party/libevent/evdns.c

Issue 412006: posix: upgrade libevent from 1.4.7 to 1.4.13 (Closed)
Patch Set: better readme Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/libevent/evdns.c
diff --git a/third_party/libevent/evdns.c b/third_party/libevent/evdns.c
index 6861161cfca8c215cd87d0e114825c70f81255a9..f07ecc98a140bafc499012d5c26872c411c50ea5 100644
--- a/third_party/libevent/evdns.c
+++ b/third_party/libevent/evdns.c
@@ -74,7 +74,9 @@
#include <openssl/rand.h>
#endif
+#ifndef _FORTIFY_SOURCE
#define _FORTIFY_SOURCE 3
+#endif
#include <string.h>
#include <fcntl.h>
@@ -209,6 +211,7 @@ struct reply {
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;
@@ -469,7 +472,6 @@ nameserver_probe_failed(struct nameserver *const ns) {
global_nameserver_timeouts_length - 1)];
ns->failed_times++;
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -498,7 +500,6 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
ns->state = 0;
ns->failed_times = 1;
- evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
@@ -680,7 +681,10 @@ reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply)
static void
reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
int error;
- static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
+ static const int error_codes[] = {
+ DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST,
+ DNS_ERR_NOTIMPL, DNS_ERR_REFUSED
+ };
if (flags & 0x020f || !reply || !reply->have_answer) {
/* there was an error */
@@ -709,9 +713,10 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
}
break;
case DNS_ERR_SERVERFAILED:
- /* rcode 2 (servfailed) sometimes means "we are broken" and
- * sometimes (with some binds) means "that request was very
- * confusing." Treat this as a timeout, not a failure.
+ /* rcode 2 (servfailed) sometimes means "we
+ * are broken" and sometimes (with some binds)
+ * means "that request was very confusing."
+ * Treat this as a timeout, not a failure.
*/
log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
"will allow the request to time out.",
@@ -723,10 +728,13 @@ reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply)
}
if (req->search_state && req->request_type != TYPE_PTR) {
- /* if we have a list of domains to search in, try the next one */
+ /* if we have a list of domains to search in,
+ * try the next one */
if (!search_try_next(req)) {
- /* a new request was issued so this request is finished and */
- /* the user callback will be made when that request (or a */
+ /* a new request was issued so this
+ * request is finished and */
+ /* the user callback will be made when
+ * that request (or a */
/* child of it) finishes. */
request_finished(req, &req_head);
return;
@@ -803,10 +811,10 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
/* parses a raw request from a nameserver */
static int
reply_parse(u8 *packet, int length) {
- int j = 0; /* index into packet */
+ int j = 0, k = 0; /* index into packet */
u16 _t; /* used by the macros */
u32 _t32; /* used by the macros */
- char tmp_name[256]; /* used by the macros */
+ char tmp_name[256], cmp_name[256]; /* used by the macros */
u16 trans_id, questions, answers, authority, additional, datalength;
u16 flags = 0;
@@ -839,10 +847,21 @@ reply_parse(u8 *packet, int length) {
/* This macro skips a name in the DNS reply. */
#define SKIP_NAME \
- do { tmp_name[0] = '\0'; \
- if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
- goto err; \
- } while(0);
+ do { tmp_name[0] = '\0'; \
+ if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
+ goto err; \
+ } while(0)
+#define TEST_NAME \
+ do { tmp_name[0] = '\0'; \
+ cmp_name[0] = '\0'; \
+ k = j; \
+ if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\
+ goto err; \
+ if (name_parse(req->request, req->request_len, &k, cmp_name, sizeof(cmp_name))<0) \
+ goto err; \
+ if (memcmp(tmp_name, cmp_name, strlen (tmp_name)) != 0) \
+ return (-1); /* we ignore mismatching names */ \
+ } while(0)
reply.type = req->request_type;
@@ -851,7 +870,7 @@ reply_parse(u8 *packet, int length) {
/* the question looks like
* <label:name><u16:type><u16:class>
*/
- SKIP_NAME;
+ TEST_NAME;
j += 4;
if (j > length) goto err;
}
@@ -1134,19 +1153,38 @@ nameserver_pick(void) {
}
}
+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);
}
@@ -1667,7 +1705,7 @@ evdns_server_request_format_response(struct server_request *req, int err)
if (j > 512) {
overflow:
j = 512;
- buf[3] |= 0x02; /* set the truncated bit. */
+ buf[2] |= 0x02; /* set the truncated bit. */
}
req->response_len = j;
@@ -1874,7 +1912,15 @@ evdns_request_timeout_callback(int fd, short events, void *arg) {
/* 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;
@@ -1923,7 +1969,6 @@ evdns_request_transmit(struct request *req) {
/* all ok */
log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
- evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
if (evtimer_add(&req->timeout_event, &global_timeout) < 0) {
log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
@@ -2070,7 +2115,6 @@ _evdns_nameserver_add_impl(unsigned long int address, int port) {
const struct nameserver *server = server_head, *const started_at = server_head;
struct nameserver *ns;
- struct sockaddr_in sin;
int err = 0;
if (server) {
do {
@@ -2084,18 +2128,14 @@ _evdns_nameserver_add_impl(unsigned long int address, int port) {
memset(ns, 0, sizeof(struct nameserver));
+ evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
+
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) {
@@ -2208,6 +2248,8 @@ request_new(int type, const char *name, int flags,
if (!req) return NULL;
memset(req, 0, sizeof(struct request));
+ evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
+
/* request data lives just after the header */
req->request = ((u8 *) req) + sizeof(struct request);
/* denotes that the request data shouldn't be free()ed */
@@ -2277,7 +2319,7 @@ int evdns_resolve_ipv6(const char *name, int flags,
}
}
-int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
+int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
char buf[32];
struct request *req;
u32 a;
@@ -2295,7 +2337,7 @@ int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type cal
return 0;
}
-int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
+int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
/* 32 nybbles, 32 periods, "ip6.arpa", NUL. */
char buf[73];
char *cp;
@@ -2947,7 +2989,7 @@ load_nameservers_from_registry(void)
#undef TRY
}
-static int
+int
evdns_config_windows_nameservers(void)
{
if (load_nameservers_with_getnetworkparams() == 0)

Powered by Google App Engine
This is Rietveld 408576698