Added: 增加IPv6支持

1、将IP_ADDRESS_SIZE的值由16修改为INET6_ADDRSTRLEN(46)。
2、新定义in_addr_64结构体替换in_addr结构体,以支持IPv6地址长度。
3、将connection_pool相关文件的socket_domain预设值由AF_INET修改为AF_UNSPEC。
4、增加IPv6的本地回环地址判断。
5、新增从字符串中解析IP地址和端口号方法(支持IPv4和IPv6)。
6、sockopt增加IPv6的支持
pull/47/head
sunqiangwei1988 2023-11-02 10:13:42 +08:00
parent 05a694df77
commit 718906e477
10 changed files with 179 additions and 84 deletions

View File

@ -48,6 +48,13 @@ typedef DWORD (WINAPI *ThreadEntranceFunc)(LPVOID lpThreadParameter);
//#include <sys/syscall.h> //#include <sys/syscall.h>
#endif #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 "/" #define FILE_SEPERATOR "/"
typedef int SOCKET; typedef int SOCKET;
#define closesocket close #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 #define FC_IOV_BATCH_SIZE IOV_MAX
#endif #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 INFINITE_FILE_SIZE (256 * 1024LL * 1024 * 1024 * 1024 * 1024LL)
#define FILE_RESOURCE_TAG_STR "file://" #define FILE_RESOURCE_TAG_STR "file://"

View File

@ -487,7 +487,7 @@ int conn_pool_parse_server_info(const char *pServerStr,
memcpy(server_info, pServerStr, len); memcpy(server_info, pServerStr, len);
*(server_info + len) = '\0'; *(server_info + len) = '\0';
count = splitEx(server_info, ':', parts, 2); count = parseAddress(server_info,parts);
if (count == 1) { if (count == 1) {
pServerInfo->port = default_port; pServerInfo->port = default_port;
} }
@ -501,7 +501,7 @@ int conn_pool_parse_server_info(const char *pServerStr,
return EINVAL; return EINVAL;
} }
} }
if (getIpaddrByName(parts[0], pServerInfo->ip_addr, if (getIpaddrByName(parts[0], pServerInfo->ip_addr,
sizeof(pServerInfo->ip_addr)) == INADDR_NONE) sizeof(pServerInfo->ip_addr)) == INADDR_NONE)
{ {
@ -511,7 +511,7 @@ int conn_pool_parse_server_info(const char *pServerStr,
return EINVAL; return EINVAL;
} }
pServerInfo->socket_domain = AF_INET; pServerInfo->socket_domain = AF_UNSPEC;
pServerInfo->sock = -1; pServerInfo->sock = -1;
return 0; return 0;
} }

View File

@ -46,7 +46,7 @@ typedef struct
uint16_t port; uint16_t port;
short socket_domain; //socket domain, AF_INET, AF_INET6 or AF_UNSPEC for auto dedect short socket_domain; //socket domain, AF_INET, AF_INET6 or AF_UNSPEC for auto dedect
bool validate_flag; //for connection pool bool validate_flag; //for connection pool
char ip_addr[INET6_ADDRSTRLEN]; char ip_addr[IP_ADDRESS_SIZE];
char args[0]; //for extra data char args[0]; //for extra data
} ConnectionInfo; } 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, static inline int conn_pool_init(ConnectionPool *cp, int connect_timeout,
const int max_count_per_entry, const int max_idle_time) 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 htable_init_capacity = 0;
const int extra_data_size = 0; const int extra_data_size = 0;
return conn_pool_init_ex1(cp, connect_timeout, max_count_per_entry, return conn_pool_init_ex1(cp, connect_timeout, max_count_per_entry,

View File

@ -84,6 +84,8 @@ int id_generator_init_extra_ex(struct idg_context *context, const char *filename
const char *local_ip; const char *local_ip;
const char *private_ip; const char *private_ip;
struct in_addr ip_addr; struct in_addr ip_addr;
struct in6_addr ip6_addr;
bool is_local_ip_ok = false;
private_ip = get_first_local_private_ip(); private_ip = get_first_local_private_ip();
if (private_ip != NULL) if (private_ip != NULL)
@ -100,16 +102,25 @@ int id_generator_init_extra_ex(struct idg_context *context, const char *filename
context->fd = -1; context->fd = -1;
return ENOENT; 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, " logWarning("file: "__FILE__", line: %d, "
"can't get local ip address, set to %s", "can't get local ip address, set to %s or %s",
__LINE__, LOCAL_LOOPBACK_IP); __LINE__, LOCAL_LOOPBACK_IPv4, LOCAL_LOOPBACK_IPv6);
} }
} }
if (inet_pton(AF_INET, local_ip, &ip_addr) != 1) 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, " logError("file: "__FILE__", line: %d, "
"invalid local ip address: %s", "invalid local ip address: %s",
__LINE__, local_ip); __LINE__, local_ip);

View File

@ -96,7 +96,7 @@ void load_local_host_ip_addrs()
char *if_alias_prefixes[STORAGE_MAX_ALIAS_PREFIX_COUNT]; char *if_alias_prefixes[STORAGE_MAX_ALIAS_PREFIX_COUNT];
int alias_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)); memset(if_alias_prefixes, 0, sizeof(if_alias_prefixes));
if (*g_if_alias_prefix == '\0') if (*g_if_alias_prefix == '\0')
@ -124,8 +124,8 @@ void load_local_host_ip_addrs()
insert_into_local_host_ip(ip_addresses[k]); insert_into_local_host_ip(ip_addresses[k]);
} }
//log_local_host_ip_addrs(); // log_local_host_ip_addrs();
//print_local_host_ip_addrs(); // print_local_host_ip_addrs();
} }
void 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; IP_ADDRESS_SIZE * g_local_host_ip_count;
for (p=g_local_host_ip_addrs; p<pEnd; p+=IP_ADDRESS_SIZE) for (p=g_local_host_ip_addrs; p<pEnd; p+=IP_ADDRESS_SIZE)
{ {
if (strcmp(p, LOCAL_LOOPBACK_IP) != 0) if (strcmp(p, LOCAL_LOOPBACK_IPv4) != 0 &&
strcmp(p, LOCAL_LOOPBACK_IPv6) !=0 )
{ {
if (found) if (found)
{ {
@ -187,7 +188,8 @@ const char *get_first_local_ip()
} }
else else
{ {
return LOCAL_LOOPBACK_IP; // 注意当系统存在IPv6回环地址时为了简化系统的改动会将IPv6回环地址修改成IPv4回环地址返回
return LOCAL_LOOPBACK_IPv4;
} }
} }

View File

@ -27,7 +27,8 @@
#define FAST_IF_ALIAS_PREFIX_MAX_SIZE 32 #define FAST_IF_ALIAS_PREFIX_MAX_SIZE 32
#define FAST_MAX_LOCAL_IP_ADDRS 16 #define FAST_MAX_LOCAL_IP_ADDRS 16
#define LOCAL_LOOPBACK_IP "127.0.0.1" #define LOCAL_LOOPBACK_IPv4 "127.0.0.1"
#define LOCAL_LOOPBACK_IPv6 "::1"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

View File

@ -1976,15 +1976,15 @@ int set_run_by(const char *group_name, const char *username)
return 0; return 0;
} }
static int check_realloc_allow_ips(in_addr_t **allow_ip_addrs, static int check_realloc_allow_ips(in_addr_64_t **allow_ip_addrs,
int *alloc_count, const int target_ip_count) int *alloc_count, const int target_ip_count)
{ {
int bytes; int bytes;
if (*alloc_count < target_ip_count) if (*alloc_count < target_ip_count)
{ {
*alloc_count = target_ip_count; *alloc_count = target_ip_count;
bytes = sizeof(in_addr_t) * (*alloc_count); bytes = sizeof(in_addr_64_t) * (*alloc_count);
*allow_ip_addrs = (in_addr_t *)fc_realloc(*allow_ip_addrs, bytes); *allow_ip_addrs = (in_addr_64_t *)fc_realloc(*allow_ip_addrs, bytes);
if (*allow_ip_addrs == NULL) if (*allow_ip_addrs == NULL)
{ {
return ENOMEM; return ENOMEM;
@ -1994,7 +1994,7 @@ static int check_realloc_allow_ips(in_addr_t **allow_ip_addrs,
return 0; return 0;
} }
static int parse_cidr_ips(const char *ip_addr, in_addr_t **allow_ip_addrs, static int parse_cidr_ips(const char *ip_addr, in_addr_64_t **allow_ip_addrs,
int *alloc_count, int *allow_ip_count, const int remain_items) int *alloc_count, int *allow_ip_count, const int remain_items)
{ {
char *pSlash; char *pSlash;
@ -2091,14 +2091,14 @@ static int parse_cidr_ips(const char *ip_addr, in_addr_t **allow_ip_addrs,
} }
static int parse_range_hosts(const char *value, char *pStart, char *pEnd, static int parse_range_hosts(const char *value, char *pStart, char *pEnd,
char *hostname, const int nHeadLen, in_addr_t **allow_ip_addrs, char *hostname, const int nHeadLen, in_addr_64_t **allow_ip_addrs,
int *alloc_count, int *allow_ip_count, const int remain_items) int *alloc_count, int *allow_ip_count, const int remain_items)
{ {
char *pTail; char *pTail;
char *p; char *p;
int result; int result;
int i; int i;
in_addr_t addr; in_addr_64_t addr;
pTail = pEnd + 1; pTail = pEnd + 1;
p = pStart + 1; //skip [ p = pStart + 1; //skip [
@ -2238,7 +2238,7 @@ static int parse_range_hosts(const char *value, char *pStart, char *pEnd,
} }
int load_allow_hosts(IniContext *pIniContext, \ int load_allow_hosts(IniContext *pIniContext, \
in_addr_t **allow_ip_addrs, int *allow_ip_count) in_addr_64_t **allow_ip_addrs, int *allow_ip_count)
{ {
int result; int result;
int count; int count;
@ -2276,7 +2276,7 @@ int load_allow_hosts(IniContext *pIniContext, \
alloc_count = count; alloc_count = count;
*allow_ip_count = 0; *allow_ip_count = 0;
*allow_ip_addrs = (in_addr_t *)fc_malloc(sizeof(in_addr_t) * alloc_count); *allow_ip_addrs = (in_addr_64_t *)fc_malloc(sizeof(in_addr_64_t) * alloc_count);
if (*allow_ip_addrs == NULL) if (*allow_ip_addrs == NULL)
{ {
return ENOMEM; return ENOMEM;
@ -2829,6 +2829,35 @@ bool is_private_ip(const char* ip)
return false; return false;
} }
int parseAddress(char *src, char *parts[2]){
char *ip = NULL;
char *port = NULL;
// 检查输入字符串是否为IPv6地址格式
if (src[0] == '[') {
ip = strtok(src, "[]");
parts[0] = ip;
port = strtok(NULL, ":");
if(port=='\0'){
return 1;
}else{
parts[1]=port;
return 2;
}
} else {
ip = strtok(src, ":");
parts[0] = ip;
port = strtok(NULL, ":");
if(port=='\0'){
return 1;
}else{
parts[1]=port;
return 2;
}
}
}
int64_t get_current_time_ns() int64_t get_current_time_ns()
{ {
struct timespec ts; struct timespec ts;

View File

@ -544,7 +544,7 @@ void set_log_level(char *pLogLevel);
* return: error no , 0 success, != 0 fail * return: error no , 0 success, != 0 fail
*/ */
int load_allow_hosts(IniContext *pIniContext, \ int load_allow_hosts(IniContext *pIniContext, \
in_addr_t **allow_ip_addrs, int *allow_ip_count); in_addr_64_t **allow_ip_addrs, int *allow_ip_count);
/** get time item from config context /** get time item from config context
@ -754,7 +754,7 @@ int fd_set_cloexec(int fd);
*/ */
int set_run_by(const char *group_name, const char *username); int set_run_by(const char *group_name, const char *username);
/** compare ip address, type is (in_addr_t *) /** compare ip address, type is (in_addr_64_t *)
* parameters: * parameters:
* p1: the first ip address * p1: the first ip address
* p2: the second ip address * p2: the second ip address
@ -807,6 +807,16 @@ double get_line_distance_km(const double lat1, const double lon1,
*/ */
bool is_private_ip(const char* ip); bool is_private_ip(const char* ip);
/** 从字符串中解析IP地址和端口号
* parameters:
* src: the source string, will be modified by this function
* parts: store split strings
* return: string array / column count
*/
int parseAddress(char *src, char *parts[2]);
/** get current time in ns /** get current time in ns
* return: current time * return: current time
*/ */

View File

@ -1068,7 +1068,7 @@ const char *fc_inet_ntop(const struct sockaddr *addr,
{ {
void *sin_addr; void *sin_addr;
const char *output; const char *output;
if (addr->sa_family == AF_INET) { if (addr->sa_family == AF_INET) {
sin_addr = &((struct sockaddr_in *)addr)->sin_addr; sin_addr = &((struct sockaddr_in *)addr)->sin_addr;
} else if (addr->sa_family == AF_INET6) { } else if (addr->sa_family == AF_INET6) {
@ -1092,7 +1092,7 @@ const char *fc_inet_ntop(const struct sockaddr *addr,
return output; return output;
} }
in_addr_t getIpaddr(getnamefunc getname, int sock, \ in_addr_64_t getIpaddr(getnamefunc getname, int sock, \
char *buff, const int bufferSize) char *buff, const int bufferSize)
{ {
sockaddr_convert_t convert; sockaddr_convert_t convert;
@ -1106,7 +1106,7 @@ in_addr_t getIpaddr(getnamefunc getname, int sock, \
} }
if (convert.len > 0) if (convert.len > 0)
{ {
fc_inet_ntop(&convert.sa.addr, buff, bufferSize); fc_inet_ntop(&convert.sa.addr, buff, bufferSize);
} }
else else
@ -1114,7 +1114,13 @@ in_addr_t getIpaddr(getnamefunc getname, int sock, \
*buff = '\0'; *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, int getIpAndPort(getnamefunc getname, int sock,
@ -1172,45 +1178,54 @@ char *getHostnameByIp(const char *szIpAddr, char *buff, const int bufferSize)
return buff; 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 addrinfo hints, *res, *p;
struct hostent *ent; int status;
in_addr_t **addr_list; 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') && for (p = res; p != NULL; p = p->ai_next)
inet_pton(AF_INET, name, &ip_addr) == 1) {
{ if (p->ai_family == AF_INET) // 处理IPv4地址
if (buff != NULL) {
{ struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
snprintf(buff, bufferSize, "%s", name); if (buff != NULL)
} {
return ip_addr.s_addr; if (inet_ntop(AF_INET, &(ipv4->sin_addr), buff, bufferSize) == NULL)
} {
*buff = '\0';
}
}
ent = gethostbyname(name); freeaddrinfo(res);
if (ent == NULL) return ipv4->sin_addr.s_addr;
{ }
return INADDR_NONE; 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; in_addr_64_t ip_addr = 0;
if (addr_list[0] == NULL) memcpy(&ip_addr, &ipv6->sin6_addr, sizeof(in_addr_64_t));
{
return INADDR_NONE;
}
memset(&ip_addr, 0, sizeof(ip_addr)); freeaddrinfo(res);
ip_addr.s_addr = *(addr_list[0]); return ip_addr;
if (buff != NULL) }
{ }
if (inet_ntop(AF_INET, &ip_addr, buff, bufferSize) == NULL)
{ return INADDR_NONE;
*buff = '\0';
}
}
return ip_addr.s_addr;
} }
int getIpaddrsByName(const char *name, 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); sprintf(bind_ip_prompt, "bind ip %s, ", bind_ipaddr);
} }
if (bind(sock, &convert.sa.addr, convert.len) < 0) if (bind(sock, &convert.sa.addr, convert.len) < 0)
{ {
logError("file: "__FILE__", line: %d, " logError("file: "__FILE__", line: %d, "
@ -2173,20 +2188,22 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
ifc1 = ifc; ifc1 = ifc;
while (NULL != ifc) while (NULL != ifc)
{ {
struct sockaddr *s; if(NULL == ifc->ifa_addr ){
s = ifc->ifa_addr; continue;
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 (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) sin_addr, ip_addrs[*count], IP_ADDRESS_SIZE) != NULL)
{ {
(*count)++; (*count)++;
@ -2199,6 +2216,22 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
__LINE__, errno, STRERROR(errno)); __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; ifc = ifc->ifa_next;
} }

View File

@ -26,6 +26,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <netdb.h>
#include "common_define.h" #include "common_define.h"
#define FC_NET_TYPE_NONE 0 #define FC_NET_TYPE_NONE 0
@ -55,11 +56,11 @@ typedef struct fast_if_config {
char name[IF_NAMESIZE]; //if name char name[IF_NAMESIZE]; //if name
char mac[64]; char mac[64];
char ipv4[IP_ADDRESS_SIZE]; char ipv4[IP_ADDRESS_SIZE];
char ipv6[48]; char ipv6[IP_ADDRESS_SIZE];
} FastIFConfig; } FastIFConfig;
typedef struct ip_addr_s { typedef struct ip_addr_s {
char ip_addr[INET6_ADDRSTRLEN]; char ip_addr[IP_ADDRESS_SIZE];
int socket_domain; int socket_domain;
} ip_addr_t; } ip_addr_t;
@ -344,9 +345,9 @@ int tcpprintkeepalive(int fd);
* sock: the socket * sock: the socket
* buff: buffer to store the ip address * buff: buffer to store the ip address
* bufferSize: the buffer size (max bytes) * 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); char *buff, const int bufferSize);
/** get ip address /** get ip address
@ -370,14 +371,14 @@ int getIpAndPort(getnamefunc getname, int sock,
*/ */
char *getHostnameByIp(const char *szIpAddr, char *buff, const int bufferSize); 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: * parameters:
* name: the hostname * name: the hostname
* buff: buffer to store the ip address * buff: buffer to store the ip address
* bufferSize: the buffer size (max bytes) * 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 /** get by ip addresses by it's hostname
* parameters: * parameters: