From 07dd8722dc8863f9b51a43e9801fbbd04e406c35 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 21:41:35 +0800 Subject: [PATCH 1/8] Add multicast helper function --- base/hsocket.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/base/hsocket.h b/base/hsocket.h index 4e3c287ca..9a086aba7 100644 --- a/base/hsocket.h +++ b/base/hsocket.h @@ -283,6 +283,58 @@ HV_INLINE int so_linger(int sockfd, int timeout DEFAULT(1)) { #endif } +HV_INLINE int udp_multicast_loop(int sockfd, int value DEFAULT(1)) +{ + return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&value, sizeof(int)); +} +HV_INLINE int udp_multicast_loop6(int sockfd, int value DEFAULT(1)) +{ + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *)&value, sizeof(int)); +} + +HV_INLINE int udp_multicast_ttl(int sockfd, int value) +{ + return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&value, sizeof(int)); +} +HV_INLINE int udp_multicast_ttl6(int sockfd, int value) +{ + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&value, sizeof(int)); +} + +HV_INLINE int udp_joingroup(int sockfd, const char* group_ip, const char* intf_ip DEFAULT(ANYADDR)) +{ + struct ip_mreq mreq; + inet_pton(AF_INET, group_ip, &mreq.imr_multiaddr); + inet_pton(AF_INET, intf_ip, &mreq.imr_interface); + return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); +} + +HV_INLINE int udp_leavegroup(int sockfd, const char* group_ip, const char* intf_ip DEFAULT(ANYADDR)) +{ + struct ip_mreq mreq; + inet_pton(AF_INET, group_ip, &mreq.imr_multiaddr); + inet_pton(AF_INET, intf_ip, &mreq.imr_interface); + return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); +} + +// intf_idx 填写字符串整数 为了和ipv4保持一致 +HV_INLINE int udp_joingroup6(int sockfd, const char* group_ip, const char* intf_idx DEFAULT("0")) +{ + struct ipv6_mreq mreq; + inet_pton(AF_INET6, group_ip, &mreq.ipv6mr_multiaddr); + mreq.ipv6mr_interface = atoi(intf_idx); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); +} + +HV_INLINE int udp_leavegroup6(int sockfd, const char* group_ip, const char* intf_idx DEFAULT("0")) +{ + struct ipv6_mreq mreq; + inet_pton(AF_INET6, group_ip, &mreq.ipv6mr_multiaddr); + mreq.ipv6mr_interface = atoi(intf_idx); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); +} + + END_EXTERN_C #endif // HV_SOCKET_H_ From 5294336cebff40ee9df8165f660de3b14db3cbcb Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 23:27:49 +0800 Subject: [PATCH 2/8] fix void* to const char* --- base/hsocket.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/base/hsocket.h b/base/hsocket.h index 9a086aba7..e35f0ea2b 100644 --- a/base/hsocket.h +++ b/base/hsocket.h @@ -285,20 +285,20 @@ HV_INLINE int so_linger(int sockfd, int timeout DEFAULT(1)) { HV_INLINE int udp_multicast_loop(int sockfd, int value DEFAULT(1)) { - return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&value, sizeof(int)); + return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&value, sizeof(int)); } HV_INLINE int udp_multicast_loop6(int sockfd, int value DEFAULT(1)) { - return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void *)&value, sizeof(int)); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const char*)&value, sizeof(int)); } HV_INLINE int udp_multicast_ttl(int sockfd, int value) { - return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (void *)&value, sizeof(int)); + return setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&value, sizeof(int)); } HV_INLINE int udp_multicast_ttl6(int sockfd, int value) { - return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (void *)&value, sizeof(int)); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&value, sizeof(int)); } HV_INLINE int udp_joingroup(int sockfd, const char* group_ip, const char* intf_ip DEFAULT(ANYADDR)) @@ -306,7 +306,7 @@ HV_INLINE int udp_joingroup(int sockfd, const char* group_ip, const char* intf_i struct ip_mreq mreq; inet_pton(AF_INET, group_ip, &mreq.imr_multiaddr); inet_pton(AF_INET, intf_ip, &mreq.imr_interface); - return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + return setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)); } HV_INLINE int udp_leavegroup(int sockfd, const char* group_ip, const char* intf_ip DEFAULT(ANYADDR)) @@ -314,7 +314,7 @@ HV_INLINE int udp_leavegroup(int sockfd, const char* group_ip, const char* intf_ struct ip_mreq mreq; inet_pton(AF_INET, group_ip, &mreq.imr_multiaddr); inet_pton(AF_INET, intf_ip, &mreq.imr_interface); - return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + return setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)); } // intf_idx 填写字符串整数 为了和ipv4保持一致 @@ -323,7 +323,7 @@ HV_INLINE int udp_joingroup6(int sockfd, const char* group_ip, const char* intf_ struct ipv6_mreq mreq; inet_pton(AF_INET6, group_ip, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = atoi(intf_idx); - return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)); } HV_INLINE int udp_leavegroup6(int sockfd, const char* group_ip, const char* intf_idx DEFAULT("0")) @@ -331,7 +331,7 @@ HV_INLINE int udp_leavegroup6(int sockfd, const char* group_ip, const char* intf struct ipv6_mreq mreq; inet_pton(AF_INET6, group_ip, &mreq.ipv6mr_multiaddr); mreq.ipv6mr_interface = atoi(intf_idx); - return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (void *)&mreq, sizeof(mreq)); + return setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)); } From ff7ec72e2cbe6160def325ac1bc73beefa114d26 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 23:32:47 +0800 Subject: [PATCH 3/8] new file: text.txt --- text.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 text.txt diff --git a/text.txt b/text.txt new file mode 100644 index 000000000..37bcc8b8c --- /dev/null +++ b/text.txt @@ -0,0 +1 @@ +1 From 1365aecf8f50486bde9d83fb665b5553565b8e95 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 23:34:45 +0800 Subject: [PATCH 4/8] deleted: text.txt --- text.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 text.txt diff --git a/text.txt b/text.txt deleted file mode 100644 index 37bcc8b8c..000000000 --- a/text.txt +++ /dev/null @@ -1 +0,0 @@ -1 From 6c6c7592dfbc46d9cd3148c71efe34ab24332589 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 23:42:00 +0800 Subject: [PATCH 5/8] Revert " deleted: text.txt" This reverts commit 1365aecf8f50486bde9d83fb665b5553565b8e95. --- text.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 text.txt diff --git a/text.txt b/text.txt new file mode 100644 index 000000000..37bcc8b8c --- /dev/null +++ b/text.txt @@ -0,0 +1 @@ +1 From 8346de870fb36258e9dedb39c5d597ab53dac897 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sat, 20 Jun 2026 23:42:15 +0800 Subject: [PATCH 6/8] Revert " new file: text.txt" This reverts commit ff7ec72e2cbe6160def325ac1bc73beefa114d26. --- text.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 text.txt diff --git a/text.txt b/text.txt deleted file mode 100644 index 37bcc8b8c..000000000 --- a/text.txt +++ /dev/null @@ -1 +0,0 @@ -1 From 353601ae3460a6d8991f07afacc151e7f596161c Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sun, 28 Jun 2026 18:04:36 +0800 Subject: [PATCH 7/8] add is_multicast_ip() series function, add missing return0 in ResolveAddr() --- base/hsocket.c | 21 +++++++++++++++++++-- base/hsocket.h | 6 ++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/base/hsocket.c b/base/hsocket.c index c6f023db1..abba3fe47 100644 --- a/base/hsocket.c +++ b/base/hsocket.c @@ -48,12 +48,28 @@ const char* socket_strerror(int err) { bool is_ipv4(const char* host) { struct sockaddr_in sin; - return inet_pton(AF_INET, host, &sin) == 1; + return inet_pton(AF_INET, host, &sin.sin_addr) == 1; } bool is_ipv6(const char* host) { struct sockaddr_in6 sin6; - return inet_pton(AF_INET6, host, &sin6) == 1; + return inet_pton(AF_INET6, host, &sin6.sin6_addr) == 1; +} + +bool is_multicast_ipv4(const char* host) { + struct sockaddr_in addr={0}; + if(inet_pton(AF_INET, host, &addr.sin_addr)){ + return addr.sin_addr.s_net >> 4 == 0xE; + } + return 0; +} + +bool is_multicast_ipv6(const char* host) { + struct sockaddr_in6 addr={0}; + if(inet_pton(AF_INET6, host, &addr.sin6_addr)){ + return addr.sin6_addr.s6_addr[0] == 0xFF; + } + return 0; } int ResolveAddr(const char* host, sockaddr_u* addr) { @@ -67,6 +83,7 @@ int ResolveAddr(const char* host, sockaddr_u* addr) { if (inet_pton(AF_INET6, host, &addr->sin6.sin6_addr) == 1) { addr->sa.sa_family = AF_INET6; // host is ipv6 + return 0; } struct addrinfo* ais = NULL; diff --git a/base/hsocket.h b/base/hsocket.h index e35f0ea2b..0166cb110 100644 --- a/base/hsocket.h +++ b/base/hsocket.h @@ -110,6 +110,12 @@ HV_INLINE bool is_ipaddr(const char* host) { return is_ipv4(host) || is_ipv6(host); } +HV_EXPORT bool is_multicast_ipv4(const char* host); +HV_EXPORT bool is_multicast_ipv6(const char* host); +HV_INLINE bool is_multicast_ip(const char* host) { + return is_multicast_ipv4(host) || is_multicast_ipv6(host); +} + // @param host: domain or ip // @retval 0:succeed HV_EXPORT int ResolveAddr(const char* host, sockaddr_u* addr); From a8269956d5c710dd8d56dee43c005dc347b485d7 Mon Sep 17 00:00:00 2001 From: rorschach-py Date: Sun, 28 Jun 2026 18:08:21 +0800 Subject: [PATCH 8/8] remove {0} --- base/hsocket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/base/hsocket.c b/base/hsocket.c index abba3fe47..66d5e7c6e 100644 --- a/base/hsocket.c +++ b/base/hsocket.c @@ -57,7 +57,7 @@ bool is_ipv6(const char* host) { } bool is_multicast_ipv4(const char* host) { - struct sockaddr_in addr={0}; + struct sockaddr_in addr; if(inet_pton(AF_INET, host, &addr.sin_addr)){ return addr.sin_addr.s_net >> 4 == 0xE; } @@ -65,7 +65,7 @@ bool is_multicast_ipv4(const char* host) { } bool is_multicast_ipv6(const char* host) { - struct sockaddr_in6 addr={0}; + struct sockaddr_in6 addr; if(inet_pton(AF_INET6, host, &addr.sin6_addr)){ return addr.sin6_addr.s6_addr[0] == 0xFF; }