diff --git a/base/hsocket.c b/base/hsocket.c index da491b796..ed87a8cc8 100644 --- a/base/hsocket.c +++ b/base/hsocket.c @@ -170,6 +170,26 @@ const char* sockaddr_str(sockaddr_u* addr, char* buf, int len) { return buf; } +int sockaddr_compare(const sockaddr_u* addr1, const sockaddr_u* addr2) { + if (addr1->sa.sa_family != addr2->sa.sa_family) + return addr1->sa.sa_family - addr2->sa.sa_family; + if (addr1->sa.sa_family == AF_INET) { + if (addr1->sin.sin_family != addr2->sin.sin_family) + return addr1->sin.sin_family - addr2->sin.sin_family; + if (addr1->sin.sin_port != addr2->sin.sin_port) + return addr1->sin.sin_port - addr2->sin.sin_port; + return memcmp(&addr1->sin.sin_addr, &addr2->sin.sin_addr, sizeof(struct in_addr)); + } + else if (addr1->sa.sa_family == AF_INET6) { + if (addr1->sin6.sin6_family != addr2->sin6.sin6_family) + return addr1->sin6.sin6_family - addr2->sin6.sin6_family; + if (addr1->sin6.sin6_port != addr2->sin6.sin6_port) + return addr1->sin6.sin6_port - addr2->sin6.sin6_port; + return memcmp(&addr1->sin6.sin6_addr, &addr2->sin6.sin6_addr, sizeof(struct in_addr)); + } + return memcmp(addr1, addr2, sizeof(sockaddr_u)); +} + static int sockaddr_bind(sockaddr_u* localaddr, int type) { // socket -> setsockopt -> bind #ifdef SOCK_CLOEXEC diff --git a/base/hsocket.h b/base/hsocket.h index d7ec5bf00..4e3c287ca 100644 --- a/base/hsocket.h +++ b/base/hsocket.h @@ -121,6 +121,7 @@ HV_EXPORT void sockaddr_set_port(sockaddr_u* addr, int port); HV_EXPORT int sockaddr_set_ipport(sockaddr_u* addr, const char* host, int port); HV_EXPORT socklen_t sockaddr_len(sockaddr_u* addr); HV_EXPORT const char* sockaddr_str(sockaddr_u* addr, char* buf, int len); +HV_EXPORT int sockaddr_compare(const sockaddr_u* addr1, const sockaddr_u* addr2); //#define INET_ADDRSTRLEN 16 //#define INET6_ADDRSTRLEN 46 diff --git a/event/rudp.c b/event/rudp.c index 2a3df23b3..6c7a6f373 100644 --- a/event/rudp.c +++ b/event/rudp.c @@ -3,6 +3,7 @@ #if WITH_RUDP #include "hevent.h" +#include "hsocket.h" void rudp_entry_free(rudp_entry_t* entry) { #if WITH_KCP @@ -38,7 +39,7 @@ bool rudp_insert(rudp_t* rudp, rudp_entry_t* entry) { while (*n) { parent = *n; e = rb_entry(*n, rudp_entry_t, rb_node); - cmp = memcmp(&entry->addr, &e->addr, sizeof(sockaddr_u)); + cmp = sockaddr_compare(&entry->addr, &e->addr); if (cmp < 0) { n = &(*n)->rb_left; } else if (cmp > 0) { @@ -63,7 +64,7 @@ rudp_entry_t* rudp_search(rudp_t* rudp, struct sockaddr* addr) { bool exists = false; while (n) { e = rb_entry(n, rudp_entry_t, rb_node); - cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u)); + cmp = sockaddr_compare((sockaddr_u*)addr, &e->addr); if (cmp < 0) { n = n->rb_left; } else if (cmp > 0) { @@ -99,7 +100,7 @@ rudp_entry_t* rudp_get(rudp_t* rudp, struct sockaddr* addr) { while (*n) { parent = *n; e = rb_entry(*n, rudp_entry_t, rb_node); - cmp = memcmp(addr, &e->addr, sizeof(sockaddr_u)); + cmp = sockaddr_compare((sockaddr_u*)addr, &e->addr); if (cmp < 0) { n = &(*n)->rb_left; } else if (cmp > 0) {