diff --git a/src/common_define.h b/src/common_define.h index fe92638..9c63882 100644 --- a/src/common_define.h +++ b/src/common_define.h @@ -48,6 +48,13 @@ typedef DWORD (WINAPI *ThreadEntranceFunc)(LPVOID lpThreadParameter); //#include #endif +/* Internet address (兼容IPv6长度). */ +typedef unsigned long int in_addr_64_t; +struct in_addr_64 + { + in_addr_64_t s_addr; + }; + #define FILE_SEPERATOR "/" typedef int SOCKET; #define closesocket close @@ -115,7 +122,8 @@ extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind); #define FC_IOV_BATCH_SIZE IOV_MAX #endif -#define IP_ADDRESS_SIZE 16 +// 由于要支持IPv6,所以将IP_ADDRESS_SIZE的值由16修改为46 +#define IP_ADDRESS_SIZE INET6_ADDRSTRLEN //46 #define INFINITE_FILE_SIZE (256 * 1024LL * 1024 * 1024 * 1024 * 1024LL) #define FILE_RESOURCE_TAG_STR "file://" diff --git a/src/connection_pool.c b/src/connection_pool.c index 6d05941..4088ad9 100644 --- a/src/connection_pool.c +++ b/src/connection_pool.c @@ -487,7 +487,7 @@ int conn_pool_parse_server_info(const char *pServerStr, memcpy(server_info, pServerStr, len); *(server_info + len) = '\0'; - count = splitEx(server_info, ':', parts, 2); + count = parseAddress(server_info,parts); if (count == 1) { pServerInfo->port = default_port; } @@ -501,7 +501,7 @@ int conn_pool_parse_server_info(const char *pServerStr, return EINVAL; } } - + if (getIpaddrByName(parts[0], pServerInfo->ip_addr, sizeof(pServerInfo->ip_addr)) == INADDR_NONE) { @@ -511,7 +511,7 @@ int conn_pool_parse_server_info(const char *pServerStr, return EINVAL; } - pServerInfo->socket_domain = AF_INET; + pServerInfo->socket_domain = AF_UNSPEC; pServerInfo->sock = -1; return 0; } diff --git a/src/connection_pool.h b/src/connection_pool.h index 923c484..b6ec8f5 100644 --- a/src/connection_pool.h +++ b/src/connection_pool.h @@ -46,7 +46,7 @@ typedef struct uint16_t port; short socket_domain; //socket domain, AF_INET, AF_INET6 or AF_UNSPEC for auto dedect bool validate_flag; //for connection pool - char ip_addr[INET6_ADDRSTRLEN]; + char ip_addr[IP_ADDRESS_SIZE]; char args[0]; //for extra data } ConnectionInfo; @@ -151,7 +151,7 @@ static inline int conn_pool_init_ex(ConnectionPool *cp, int connect_timeout, static inline int conn_pool_init(ConnectionPool *cp, int connect_timeout, const int max_count_per_entry, const int max_idle_time) { - const int socket_domain = AF_INET; + const int socket_domain = AF_UNSPEC; const int htable_init_capacity = 0; const int extra_data_size = 0; return conn_pool_init_ex1(cp, connect_timeout, max_count_per_entry, diff --git a/src/id_generator.c b/src/id_generator.c index b666af8..530378b 100644 --- a/src/id_generator.c +++ b/src/id_generator.c @@ -84,6 +84,8 @@ int id_generator_init_extra_ex(struct idg_context *context, const char *filename const char *local_ip; const char *private_ip; struct in_addr ip_addr; + struct in6_addr ip6_addr; + bool is_local_ip_ok = false; private_ip = get_first_local_private_ip(); if (private_ip != NULL) @@ -100,16 +102,25 @@ int id_generator_init_extra_ex(struct idg_context *context, const char *filename context->fd = -1; return ENOENT; } - else if (strcmp(local_ip, LOCAL_LOOPBACK_IP) == 0) + else if (strcmp(local_ip, LOCAL_LOOPBACK_IPv4) == 0) { + // 注意,当系统存在IPv6回环地址时,为了简化系统的改动,会将IPv6回环地址修改成IPv4回环地址返回 + // 此处错误打印时,需要带上IPv6回环地址 logWarning("file: "__FILE__", line: %d, " - "can't get local ip address, set to %s", - __LINE__, LOCAL_LOOPBACK_IP); + "can't get local ip address, set to %s or %s", + __LINE__, LOCAL_LOOPBACK_IPv4, LOCAL_LOOPBACK_IPv6); } } if (inet_pton(AF_INET, local_ip, &ip_addr) != 1) { + is_local_ip_ok = true; + }else if(inet_pton(AF_INET6, local_ip, &ip6_addr) != 1) + { + is_local_ip_ok = true; + } + + if(is_local_ip_ok){ logError("file: "__FILE__", line: %d, " "invalid local ip address: %s", __LINE__, local_ip); diff --git a/src/local_ip_func.c b/src/local_ip_func.c index 77813d5..6f9d1b5 100644 --- a/src/local_ip_func.c +++ b/src/local_ip_func.c @@ -96,7 +96,7 @@ void load_local_host_ip_addrs() char *if_alias_prefixes[STORAGE_MAX_ALIAS_PREFIX_COUNT]; int alias_count; - insert_into_local_host_ip(LOCAL_LOOPBACK_IP); + insert_into_local_host_ip(LOCAL_LOOPBACK_IPv4); memset(if_alias_prefixes, 0, sizeof(if_alias_prefixes)); if (*g_if_alias_prefix == '\0') @@ -124,8 +124,8 @@ void load_local_host_ip_addrs() insert_into_local_host_ip(ip_addresses[k]); } - //log_local_host_ip_addrs(); - //print_local_host_ip_addrs(); + // log_local_host_ip_addrs(); + // print_local_host_ip_addrs(); } void print_local_host_ip_addrs() @@ -161,7 +161,8 @@ const char *get_next_local_ip(const char *previous_ip) IP_ADDRESS_SIZE * g_local_host_ip_count; for (p=g_local_host_ip_addrs; psa_family == AF_INET) { sin_addr = &((struct sockaddr_in *)addr)->sin_addr; } else if (addr->sa_family == AF_INET6) { @@ -1092,7 +1092,7 @@ const char *fc_inet_ntop(const struct sockaddr *addr, return output; } -in_addr_t getIpaddr(getnamefunc getname, int sock, \ +in_addr_64_t getIpaddr(getnamefunc getname, int sock, \ char *buff, const int bufferSize) { sockaddr_convert_t convert; @@ -1106,7 +1106,7 @@ in_addr_t getIpaddr(getnamefunc getname, int sock, \ } if (convert.len > 0) - { + { fc_inet_ntop(&convert.sa.addr, buff, bufferSize); } else @@ -1114,7 +1114,13 @@ in_addr_t getIpaddr(getnamefunc getname, int sock, \ *buff = '\0'; } - return convert.sa.addr4.sin_addr.s_addr; //DO NOT support IPv6 + if (convert.sa.addr.sa_family == AF_INET) { + return convert.sa.addr4.sin_addr.s_addr; + } else { + in_addr_64_t ip_addr = 0; + memcpy(&ip_addr, &((struct sockaddr_in6 *)&convert.sa.addr)->sin6_addr, sizeof(in_addr_64_t)); + return ip_addr; + } } int getIpAndPort(getnamefunc getname, int sock, @@ -1172,45 +1178,54 @@ char *getHostnameByIp(const char *szIpAddr, char *buff, const int bufferSize) return buff; } -in_addr_t getIpaddrByName(const char *name, char *buff, const int bufferSize) +in_addr_64_t getIpaddrByName(const char *name, char *buff, const int bufferSize) { - struct in_addr ip_addr; - struct hostent *ent; - in_addr_t **addr_list; + struct addrinfo hints, *res, *p; + int status; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; // 支持IPv4和IPv6 + status = getaddrinfo(name, NULL, &hints, &res); + if (status != 0) + { + return INADDR_NONE; + } - if ((*name >= '0' && *name <= '9') && - inet_pton(AF_INET, name, &ip_addr) == 1) - { - if (buff != NULL) - { - snprintf(buff, bufferSize, "%s", name); - } - return ip_addr.s_addr; - } + for (p = res; p != NULL; p = p->ai_next) + { + if (p->ai_family == AF_INET) // 处理IPv4地址 + { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; + if (buff != NULL) + { + if (inet_ntop(AF_INET, &(ipv4->sin_addr), buff, bufferSize) == NULL) + { + *buff = '\0'; + } + } - ent = gethostbyname(name); - if (ent == NULL) - { - return INADDR_NONE; - } + freeaddrinfo(res); + return ipv4->sin_addr.s_addr; + } + else if (p->ai_family == AF_INET6) // 处理IPv6地址 + { + struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr; + if (buff != NULL) + { + if (inet_ntop(AF_INET6, &(ipv6->sin6_addr), buff, bufferSize) == NULL) + { + *buff = '\0'; + } + } - addr_list = (in_addr_t **)ent->h_addr_list; - if (addr_list[0] == NULL) - { - return INADDR_NONE; - } + in_addr_64_t ip_addr = 0; + memcpy(&ip_addr, &ipv6->sin6_addr, sizeof(in_addr_64_t)); - memset(&ip_addr, 0, sizeof(ip_addr)); - ip_addr.s_addr = *(addr_list[0]); - if (buff != NULL) - { - if (inet_ntop(AF_INET, &ip_addr, buff, bufferSize) == NULL) - { - *buff = '\0'; - } - } - - return ip_addr.s_addr; + freeaddrinfo(res); + return ip_addr; + } + } + + return INADDR_NONE; } int getIpaddrsByName(const char *name, @@ -1354,7 +1369,7 @@ int socketBind2(int af, int sock, const char *bind_ipaddr, const int port) } sprintf(bind_ip_prompt, "bind ip %s, ", bind_ipaddr); } - + if (bind(sock, &convert.sa.addr, convert.len) < 0) { logError("file: "__FILE__", line: %d, " @@ -2173,20 +2188,22 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \ ifc1 = ifc; while (NULL != ifc) { - struct sockaddr *s; - s = ifc->ifa_addr; - if (NULL != s && AF_INET == s->sa_family) - { - if (max_count <= *count) - { - logError("file: "__FILE__", line: %d, "\ - "max_count: %d < iterface count: %d", \ - __LINE__, max_count, *count); - freeifaddrs(ifc1); - return ENOSPC; - } + if(NULL == ifc->ifa_addr ){ + continue; + } - if (inet_ntop(AF_INET, &((struct sockaddr_in *)s)-> \ + if (max_count <= *count) + { + logError("file: "__FILE__", line: %d, "\ + "max_count: %d < iterface count: %d", \ + __LINE__, max_count, *count); + freeifaddrs(ifc1); + return ENOSPC; + } + + if (AF_INET == ifc->ifa_addr->sa_family) + { + if (inet_ntop(AF_INET, &((struct sockaddr_in *)ifc->ifa_addr)-> \ sin_addr, ip_addrs[*count], IP_ADDRESS_SIZE) != NULL) { (*count)++; @@ -2199,6 +2216,22 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \ __LINE__, errno, STRERROR(errno)); } } + + if (AF_INET6 == ifc->ifa_addr->sa_family) + { + if (inet_ntop(AF_INET6, &((struct sockaddr_in6 *)ifc->ifa_addr)-> \ + sin6_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)); + } + } ifc = ifc->ifa_next; } diff --git a/src/sockopt.h b/src/sockopt.h index 11fd6b6..3a0b02f 100644 --- a/src/sockopt.h +++ b/src/sockopt.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "common_define.h" #define FC_NET_TYPE_NONE 0 @@ -55,11 +56,11 @@ typedef struct fast_if_config { char name[IF_NAMESIZE]; //if name char mac[64]; char ipv4[IP_ADDRESS_SIZE]; - char ipv6[48]; + char ipv6[IP_ADDRESS_SIZE]; } FastIFConfig; typedef struct ip_addr_s { - char ip_addr[INET6_ADDRSTRLEN]; + char ip_addr[IP_ADDRESS_SIZE]; int socket_domain; } ip_addr_t; @@ -344,9 +345,9 @@ int tcpprintkeepalive(int fd); * sock: the socket * buff: buffer to store the ip address * bufferSize: the buffer size (max bytes) - * return: in_addr_t, INADDR_NONE for fail + * return: in_addr_64_t, INADDR_NONE for fail */ -in_addr_t getIpaddr(getnamefunc getname, int sock, \ +in_addr_64_t getIpaddr(getnamefunc getname, int sock, \ char *buff, const int bufferSize); /** get ip address @@ -370,14 +371,14 @@ int getIpAndPort(getnamefunc getname, int sock, */ char *getHostnameByIp(const char *szIpAddr, char *buff, const int bufferSize); -/** get by IPv4 address by it's hostname +/** get by IPv4 or IPv6 address by it's hostname * parameters: * name: the hostname * buff: buffer to store the ip address * bufferSize: the buffer size (max bytes) - * return: in_addr_t, INADDR_NONE for fail + * return: in_addr_64_t, INADDR_NONE for fail */ -in_addr_t getIpaddrByName(const char *name, char *buff, const int bufferSize); +in_addr_64_t getIpaddrByName(const char *name, char *buff, const int bufferSize); /** get by ip addresses by it's hostname * parameters: