Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions base/hsocket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
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;
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) {
Expand All @@ -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;
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_