Export sockaddr comparison functionality.

svn:r1400
This commit is contained in:
Nick Mathewson 2009-07-30 22:11:23 +00:00
parent cf54d74a65
commit 621aafd27a
4 changed files with 51 additions and 35 deletions

View File

@ -8,7 +8,9 @@ Changes in 2.0.3-alpha:
o Expose an ev_socklen_t type for consistent use across platforms.
o Make bufferevenr_socket_connect() work when the original fd was -1.
o Fix a bug in bufferevent_socket_connect() when the connection succeeds too quickly.
o Export an evutil_sockaddr_cmp() to compare to sockaddr objects for equality.
Changes in 2.0.2-alpha:
o Add a new flag to bufferevents to make all callbacks automatically deferred.
o Make evdns functionality locked, and automatically defer dns callbacks.

37
evdns.c
View File

@ -448,39 +448,6 @@ debug_ntop(const struct sockaddr *sa)
return "<unknown>";
}
static int
sockaddr_eq(const struct sockaddr *sa1, const struct sockaddr *sa2,
int include_port)
{
if (sa1->sa_family != sa2->sa_family)
return 0;
if (sa1->sa_family == AF_INET) {
const struct sockaddr_in *sin1, *sin2;
sin1 = (const struct sockaddr_in *)sa1;
sin2 = (const struct sockaddr_in *)sa2;
if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr)
return 0;
else if (include_port && sin1->sin_port != sin2->sin_port)
return 0;
else
return 1;
}
#ifdef AF_INET6
if (sa1->sa_family == AF_INET6) {
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *)sa1;
sin2 = (const struct sockaddr_in6 *)sa2;
if (memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16))
return 0;
else if (include_port && sin1->sin6_port != sin2->sin6_port)
return 0;
else
return 1;
}
#endif
return 1;
}
static evdns_debug_log_fn_type evdns_log_fn = NULL;
void
@ -1349,7 +1316,7 @@ nameserver_read(struct nameserver *ns) {
evutil_socket_error_to_string(err));
return;
}
if (!sockaddr_eq((struct sockaddr*)&ss,
if (evutil_sockaddr_cmp((struct sockaddr*)&ss,
(struct sockaddr*)&ns->address, 0)) {
log(EVDNS_LOG_WARN, "Address mismatch on received "
"DNS packet. Apparent source was %s",
@ -2398,7 +2365,7 @@ _evdns_nameserver_add_impl(struct evdns_base *base, const struct sockaddr *addre
ASSERT_LOCKED(base);
if (server) {
do {
if (sockaddr_eq((struct sockaddr*)&server->address, address, 1)) return 3;
if (!evutil_sockaddr_cmp((struct sockaddr*)&server->address, address, 1)) return 3;
server = server->next;
} while (server != started_at);
}

View File

@ -716,6 +716,45 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *
}
}
int
evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
int include_port)
{
int r;
if (0 != (r = (sa1->sa_family - sa2->sa_family)))
return r;
if (sa1->sa_family == AF_INET) {
const struct sockaddr_in *sin1, *sin2;
sin1 = (const struct sockaddr_in *)sa1;
sin2 = (const struct sockaddr_in *)sa2;
if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
return -1;
else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
return 1;
else if (include_port &&
(r = ((int)sin1->sin_port - (int)sin2->sin_port)))
return r;
else
return 0;
}
#ifdef AF_INET6
else if (sa1->sa_family == AF_INET6) {
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *)sa1;
sin2 = (const struct sockaddr_in6 *)sa2;
if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
return r;
else if (include_port &&
(r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
return r;
else
return 0;
}
#endif
return 1;
}
/* Tables to implement ctypes-replacement EVUTIL_IS*() functions. Each table
* has 256 bits to look up whether a character is in some set or not. This
* fails on non-ASCII platforms, but so does every other place where we

View File

@ -303,6 +303,14 @@ struct sockaddr;
*/
int evutil_parse_sockaddr_port(const char *str, struct sockaddr *out, int *outlen);
/** Compare two sockaddrs; return 0 if they are equal, or less than 0 if sa1
* preceeds sa2, or greater than 0 if sa1 follows sa2. If include_port is
* true, consider the port as well as the address. Only implemented for
* AF_INET and AF_INET6 addresses. The ordering is not guaranteed to remain
* the same between Libevent versions. */
int evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
int include_port);
/** As strcasecmp, but always compares the characters in locale-independent
ASCII. That's useful if you're handling data in ASCII-based protocols.
*/