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;
}