replace inet_ntop to getnameinfo for IPv6

use_iouring
YuQing 2023-12-01 11:31:13 +08:00
parent dd77da144f
commit 78caf9224b
3 changed files with 211 additions and 131 deletions

View File

@ -1,6 +1,7 @@
Version 1.71 2023-11-24
Version 1.71 2023-12-01
* full support IPv6 by pull request #47
* replace inet_ntop to getnameinfo for IPv6
Version 1.70 2023-09-30
* get full mac address of infiniband NIC under Linux

View File

@ -802,27 +802,46 @@ int tcpwritev_nb(int sock, const struct iovec *iov,
return 0;
}
int setsockaddrbyip(const char *ip, const uint16_t port, sockaddr_convert_t *convert)
int setsockaddrbyip(const char *ip, const uint16_t port,
sockaddr_convert_t *convert)
{
int af;
int result;
void *dest;
if (is_ipv6_addr(ip))
{
convert->len = sizeof(convert->sa.addr6);
dest = &convert->sa.addr6.sin6_addr;
if (strchr(ip, '#') != NULL)
{
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET6;
if ((result=getaddrinfo(ip, NULL, &hints, &res)) != 0)
{
return result;
}
convert->sa.addr6 = *((struct sockaddr_in6 *)res->ai_addr);
convert->sa.addr6.sin6_port = htons(port);
freeaddrinfo(res);
return 0;
}
af = AF_INET6;
convert->sa.addr6.sin6_family = PF_INET6;
dest = &convert->sa.addr6.sin6_addr;
convert->sa.addr6.sin6_family = AF_INET6;
convert->sa.addr6.sin6_port = htons(port);
convert->sa.addr6.sin6_flowinfo = 0;
convert->sa.addr6.sin6_scope_id = 0;
}
else //ipv4
{
af = AF_INET;
convert->len = sizeof(convert->sa.addr4);
dest = &convert->sa.addr4.sin_addr;
af = AF_INET;
convert->sa.addr4.sin_family = PF_INET;
convert->sa.addr4.sin_family = AF_INET;
convert->sa.addr4.sin_port = htons(port);
}
@ -922,7 +941,6 @@ int connectserverbyip_nb_ex(int sock, const char *server_ip, \
break;
}
#ifdef USE_SELECT
FD_ZERO(&rset);
FD_ZERO(&wset);
@ -1066,13 +1084,12 @@ int socketClientEx2(int af, const char *server_ip,
const char *fc_inet_ntop(const struct sockaddr *addr,
char *buff, const int bufferSize)
{
void *sin_addr;
const char *output;
int len;
if (addr->sa_family == AF_INET) {
sin_addr = &((struct sockaddr_in *)addr)->sin_addr;
len = sizeof(struct sockaddr_in);
} else if (addr->sa_family == AF_INET6) {
sin_addr = &((struct sockaddr_in6 *)addr)->sin6_addr;
len = sizeof(struct sockaddr_in6);
} else {
*buff = '\0';
logWarning("file: "__FILE__", line: %d, "
@ -1080,16 +1097,13 @@ const char *fc_inet_ntop(const struct sockaddr *addr,
return NULL;
}
if ((output=inet_ntop(addr->sa_family, sin_addr, buff, bufferSize)) == NULL)
if (getnameinfo(addr, len, buff, bufferSize, NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV) != 0)
{
*buff = '\0';
logWarning("file: "__FILE__", line: %d, "
"call inet_ntop fail, "
"errno: %d, error info: %s",
__LINE__, errno, STRERROR(errno));
return NULL;
}
return output;
return buff;
}
in_addr_64_t getIpaddr(getnamefunc getname, int sock,
@ -1107,7 +1121,11 @@ in_addr_64_t getIpaddr(getnamefunc getname, int sock,
if (convert.len > 0)
{
fc_inet_ntop(&convert.sa.addr, buff, bufferSize);
if (getnameinfo(&convert.sa.addr, convert.len, buff, bufferSize,
NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV) != 0)
{
*buff = '\0';
}
}
else
{
@ -1136,7 +1154,11 @@ int getIpAndPort(getnamefunc getname, int sock,
if (convert.len > 0)
{
fc_inet_ntop(&convert.sa.addr, buff, bufferSize);
if (getnameinfo(&convert.sa.addr, convert.len, buff, bufferSize,
NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV) != 0)
{
*buff = '\0';
}
}
else
{
@ -1180,8 +1202,31 @@ in_addr_64_t getIpaddrByNameEx(const char *name, char *buff,
const int bufferSize, short *af)
{
struct addrinfo hints, *res, *p;
struct in_addr addr4;
struct in6_addr addr6;
in_addr_64_t ip_addr;
if ((*name >= '0' && *name <= '9') &&
inet_pton(AF_INET, name, &addr4) == 1)
{
if (buff != NULL)
{
snprintf(buff, bufferSize, "%s", name);
}
*af = AF_INET;
return addr4.s_addr;
}
if (strchr(name, ':') != NULL && inet_pton(
AF_INET6, name, &addr6) == 1)
{
if (buff != NULL)
{
snprintf(buff, bufferSize, "%s", name);
}
*af = AF_INET6;
return *((in_addr_64_t *)((char *)&addr6 + 8));
}
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // 支持IPv4和IPv6
if (getaddrinfo(name, NULL, &hints, &res) != 0)
@ -1213,11 +1258,17 @@ in_addr_64_t getIpaddrByNameEx(const char *name, char *buff,
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
if (buff != NULL)
{
if (inet_ntop(AF_INET6, &(ipv6->sin6_addr), buff, bufferSize) == NULL)
if (getnameinfo((struct sockaddr *)ipv6, sizeof(*ipv6),
buff, bufferSize, NULL, 0, NI_NUMERICHOST |
NI_NUMERICSERV) != 0)
{
if (inet_ntop(AF_INET6, &(ipv6->sin6_addr),
buff, bufferSize) == NULL)
{
*buff = '\0';
}
}
}
ip_addr = *((in_addr_64_t *)((char *)&ipv6->sin6_addr + 8));
freeaddrinfo(res);
@ -1233,9 +1284,9 @@ in_addr_64_t getIpaddrByNameEx(const char *name, char *buff,
int getIpaddrsByName(const char *name,
ip_addr_t *ip_addr_arr, const int ip_addr_arr_size)
{
int result;
int ip_count;
struct sockaddr_in *addr;
struct sockaddr_in6 *addr6;
int len;
struct addrinfo hints, *res, *res0;
memset(&hints, 0, sizeof(hints));
@ -1247,10 +1298,19 @@ int getIpaddrsByName(const char *name,
}
for (ip_count = 0, res = res0; res; res = res->ai_next) {
if (res->ai_family != AF_INET6 && res->ai_family != AF_INET) {
logError("file: "__FILE__", line: %d, " \
"unsupported family %d, " \
"only suppport AF_INET6 and AF_INET", \
if (res->ai_family == AF_INET)
{
len = sizeof(struct sockaddr_in);
}
else if (res->ai_family == AF_INET6)
{
len = sizeof(struct sockaddr_in6);
}
else
{
logError("file: "__FILE__", line: %d, "
"unsupported family %d, "
"only suppport AF_INET and AF_INET6",
__LINE__, res->ai_family);
continue;
}
@ -1259,27 +1319,15 @@ int getIpaddrsByName(const char *name,
break;
}
if (res->ai_family == AF_INET6) {
addr6 = (struct sockaddr_in6 *)res->ai_addr;
if (inet_ntop(res->ai_family, &addr6->sin6_addr,
ip_addr_arr[ip_count].ip_addr, INET6_ADDRSTRLEN) == NULL)
if ((result=getnameinfo(res->ai_addr, len, ip_addr_arr[ip_count].
ip_addr, IP_ADDRESS_SIZE, NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
{
logError("file: "__FILE__", line: %d, " \
"inet_ntop failed: %d, %s", \
__LINE__, errno, strerror(errno));
logError("file: "__FILE__", line: %d, "
"getnameinfo fail, errno: %d, error info: %s",
__LINE__, result, gai_strerror(result));
continue;
}
} else {
addr = (struct sockaddr_in *)res->ai_addr;
if (inet_ntop(res->ai_family, &addr->sin_addr,
ip_addr_arr[ip_count].ip_addr, INET6_ADDRSTRLEN) == NULL)
{
logError("file: "__FILE__", line: %d, " \
"inet_ntop failed: %d, %s", \
__LINE__, errno, strerror(errno));
continue;
}
}
ip_addr_arr[ip_count++].af = res->ai_family;
}
@ -1346,6 +1394,7 @@ int socketBind2(int af, int sock, const char *bind_ipaddr, const int port)
char bind_ip_prompt[256];
int result;
memset(&convert, 0, sizeof(convert));
convert.sa.addr.sa_family = af;
if (bind_ipaddr == NULL || *bind_ipaddr == '\0')
{
@ -1414,16 +1463,32 @@ int socketServer2(int af, const char *bind_ipaddr, const int port, int *err_no)
SET_SOCKOPT_NOSIGPIPE(sock);
result = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &result, sizeof(int))<0)
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
&result, sizeof(int)) < 0)
{
*err_no = errno != 0 ? errno : ENOMEM;
logError("file: "__FILE__", line: %d, " \
"setsockopt failed, errno: %d, error info: %s", \
logError("file: "__FILE__", line: %d, "
"setsockopt failed, errno: %d, error info: %s",
__LINE__, errno, STRERROR(errno));
close(sock);
return -2;
}
if (af == AF_INET6 && (bind_ipaddr == NULL || *bind_ipaddr == '\0'))
{
result = 1;
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
&result, sizeof(result)) < 0)
{
*err_no = errno != 0 ? errno : ENOMEM;
logError("file: "__FILE__", line: %d, "
"setsockopt failed, errno: %d, error info: %s",
__LINE__, errno, STRERROR(errno));
close(sock);
return -2;
}
}
if ((*err_no=socketBind2(af, sock, bind_ipaddr, port)) != 0)
{
close(sock);
@ -2174,6 +2239,8 @@ int tcpsetnodelay(int fd, const int timeout)
int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
const int max_count, int *count)
{
int result;
int len;
struct ifaddrs *ifc;
struct ifaddrs *ifc1;
@ -2204,36 +2271,33 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
return ENOSPC;
}
do {
if (ifc->ifa_addr->sa_family == AF_INET)
{
if (inet_ntop(AF_INET, &((struct sockaddr_in *)ifc->ifa_addr)->
sin_addr, ip_addrs[*count], IP_ADDRESS_SIZE) != NULL)
{
(*count)++;
}
else
{
logWarning("file: "__FILE__", line: %d, " \
"call inet_ntop fail, " \
"errno: %d, error info: %s", \
__LINE__, errno, STRERROR(errno));
}
len = sizeof(struct sockaddr_in);
}
else if (ifc->ifa_addr->sa_family == AF_INET6)
{
if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifc->ifa_addr)->
sin6_addr, ip_addrs[*count], IP_ADDRESS_SIZE) != NULL)
len = sizeof(struct sockaddr_in6);
}
else
{
break;
}
if ((result=getnameinfo(ifc->ifa_addr, len, ip_addrs[*count],
IP_ADDRESS_SIZE, NULL, 0, NI_NUMERICHOST |
NI_NUMERICSERV)) == 0)
{
(*count)++;
}
else
{
logWarning("file: "__FILE__", line: %d, " \
"call inet_ntop fail, " \
"errno: %d, error info: %s", \
__LINE__, errno, STRERROR(errno));
}
logWarning("file: "__FILE__", line: %d, "
"getnameinfo fail, errno: %d, error info: %s",
__LINE__, result, gai_strerror(result));
}
} while (0);
ifc = ifc->ifa_next;
}
@ -2247,7 +2311,8 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
const int max_count, int *count)
{
int s;
int sock;
int len;
struct ifconf ifconf;
struct ifreq ifr[32];
struct ifreq *ifrp;
@ -2255,24 +2320,24 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
int result;
*count = 0;
s = socket(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0)
{
logError("file: "__FILE__", line: %d, " \
"socket create fail, errno: %d, error info: %s", \
logError("file: "__FILE__", line: %d, "
"socket create fail, errno: %d, error info: %s",
__LINE__, errno, STRERROR(errno));
return errno != 0 ? errno : EMFILE;
}
ifconf.ifc_buf = (char *) ifr;
ifconf.ifc_len = sizeof(ifr);
if (ioctl(s, SIOCGIFCONF, &ifconf) < 0)
if (ioctl(sock, SIOCGIFCONF, &ifconf) < 0)
{
result = errno != 0 ? errno : EMFILE;
logError("file: "__FILE__", line: %d, " \
"call ioctl fail, errno: %d, error info: %s", \
logError("file: "__FILE__", line: %d, "
"call ioctl fail, errno: %d, error info: %s",
__LINE__, result, STRERROR(result));
close(s);
close(sock);
return result;
}
@ -2281,33 +2346,33 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
while ((char *)ifrp < p_end)
{
struct sockaddr *sa = &ifrp->ifr_addr;
struct sockaddr_in *s_in;
if (*count >= max_count)
{
logError("file: "__FILE__", line: %d, " \
"max_count: %d < iterface count: %d", \
logError("file: "__FILE__", line: %d, "
"max_count: %d < iterface count: %d",
__LINE__, max_count, *count);
close(s);
close(sock);
return ENOSPC;
}
s_in = (struct sockaddr_in *) &ifrp->ifr_addr;
if (sa->sa_family == AF_INET)
if (sa->sa_family == AF_INET6)
{
if (!inet_ntop(AF_INET, &s_in->sin_addr, \
ip_addrs[*count], IP_ADDRESS_SIZE))
len = sizeof(struct sockaddr_in6);
} else
{
result = errno != 0 ? errno : EMFILE;
logError("file: "__FILE__", line: %d, " \
"call inet_ntop fail, " \
"errno: %d, error info: %s", \
__LINE__, result, STRERROR(result));
close(s);
len = sizeof(struct sockaddr_in);
}
if ((result=getnameinfo(sa, len, ip_addrs[*count], IP_ADDRESS_SIZE,
NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
{
logError("file: "__FILE__", line: %d, "
"call getnameinfo fail, errno: %d, error info: %s",
__LINE__, result, gai_strerror(result));
close(sock);
return result;
}
(*count)++;
}
#ifdef OS_FREEBSD
ifrp = (struct ifreq*)((caddr_t)&ifrp->ifr_addr + sa->sa_len);
@ -2316,7 +2381,7 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
#endif
}
close(s);
close(sock);
return *count > 0 ? 0 : ENOENT;
}
@ -2332,9 +2397,10 @@ int gethostaddrs(char **if_alias_prefixes, const int prefix_count, \
int true_count;
int i;
int k;
int len;
int sock;
struct ifreq req;
struct sockaddr_in *addr;
struct sockaddr *addr;
int ret;
*count = 0;
@ -2394,9 +2460,17 @@ int gethostaddrs(char **if_alias_prefixes, const int prefix_count, \
break;
}
addr = (struct sockaddr_in*)&req.ifr_addr;
if (inet_ntop(AF_INET, &addr->sin_addr, ip_addrs[*count], \
IP_ADDRESS_SIZE) != NULL)
addr = &req.ifr_addr;
if (addr->sa_family == AF_INET6)
{
len = sizeof(struct sockaddr_in6);
}
else
{
len = sizeof(struct sockaddr_in);
}
if (getnameinfo(addr, len, ip_addrs[*count], IP_ADDRESS_SIZE,
NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV) == 0)
{
(*count)++;
if (*count >= max_count)
@ -2440,7 +2514,7 @@ int gethostaddrs(char **if_alias_prefixes, const int prefix_count, \
break;
}
if (inet_ntop(ent->h_addrtype, ent->h_addr_list[k], \
if (inet_ntop(ent->h_addrtype, ent->h_addr_list[k],
ip_addrs[*count], IP_ADDRESS_SIZE) != NULL)
{
(*count)++;
@ -2603,8 +2677,9 @@ int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count)
struct ifaddrs *ifc1;
FastIFConfig *config;
char *buff;
void *sin_addr;
int result;
int buff_size;
int len;
int i;
*count = 0;
@ -2655,21 +2730,21 @@ int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count)
{
buff = config->ipv4;
buff_size = sizeof(config->ipv4);
sin_addr = &((struct sockaddr_in *)s)->sin_addr;
len = sizeof(struct sockaddr_in);
}
else
{
buff = config->ipv6;
buff_size = sizeof(config->ipv6);
sin_addr = &((struct sockaddr_in6 *)s)->sin6_addr;
len = sizeof(struct sockaddr_in6);
}
if (inet_ntop(s->sa_family, sin_addr, buff, buff_size) == NULL)
if ((result=getnameinfo(s, len, buff, buff_size, NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV)) != 0)
{
logWarning("file: "__FILE__", line: %d, " \
"call inet_ntop fail, " \
"errno: %d, error info: %s", \
__LINE__, errno, STRERROR(errno));
logWarning("file: "__FILE__", line: %d, "
"getnameinfo fail, errno: %d, error info: %s",
__LINE__, result, gai_strerror(result));
}
}
}

View File

@ -696,7 +696,8 @@ int getifconfigs(FastIFConfig *if_configs, const int max_count, int *count);
* convert: the convert struct for IPv4 and IPv6 compatibility
* return: error no, 0 success, != 0 fail
*/
int setsockaddrbyip(const char *ip, const uint16_t port, sockaddr_convert_t *convert);
int setsockaddrbyip(const char *ip, const uint16_t port,
sockaddr_convert_t *convert);
static inline bool is_ipv6_addr(const char *ip)
{
@ -718,6 +719,9 @@ int fc_get_net_type_by_name(const char *net_type);
int fc_get_net_type_by_ip(const char *ip);
const char *fc_inet_ntop(const struct sockaddr *addr,
char *buff, const int bufferSize);
static inline bool is_network_error(const int err_no)
{
switch (err_no)