mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-08 11:53:00 -04:00
Export sockaddr comparison functionality.
svn:r1400
This commit is contained in:
parent
cf54d74a65
commit
621aafd27a
@ -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
37
evdns.c
@ -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);
|
||||
}
|
||||
|
39
evutil.c
39
evutil.c
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user