Skip to content
22 changes: 20 additions & 2 deletions base/hsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,31 @@ 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) {
unsigned char sin_addr[4]={0};
if(inet_pton(AF_INET, host, sin_addr)){
return sin_addr[0] >> 4 == 0xE;
}
return 0;
}

bool is_multicast_ipv6(const char* host) {
unsigned char sin6_addr[16]={0};
if(inet_pton(AF_INET6, host, sin6_addr)){
return sin6_addr[0] == 0xFF;
}
return 0;
}


int ResolveAddr(const char* host, sockaddr_u* addr) {
#ifdef OS_WIN
WSAInit();
Expand All @@ -67,6 +84,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;
Expand Down
58 changes: 58 additions & 0 deletions base/hsocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -283,6 +289,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, (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, (const char*)&value, sizeof(int));
}

HV_INLINE int udp_multicast_ttl(int sockfd, int value)
{
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, (const char*)&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, (const char*)&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, (const char*)&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, (const char*)&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, (const char*)&mreq, sizeof(mreq));
}


END_EXTERN_C

#endif // HV_SOCKET_H_