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
parent
05a694df77
commit
718906e477
|
|
@ -48,6 +48,13 @@ typedef DWORD (WINAPI *ThreadEntranceFunc)(LPVOID lpThreadParameter);
|
|||
//#include <sys/syscall.h>
|
||||
#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://"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
@ -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; 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)
|
||||
{
|
||||
|
|
@ -187,7 +188,8 @@ const char *get_first_local_ip()
|
|||
}
|
||||
else
|
||||
{
|
||||
return LOCAL_LOOPBACK_IP;
|
||||
// 注意,当系统存在IPv6回环地址时,为了简化系统的改动,会将IPv6回环地址修改成IPv4回环地址返回
|
||||
return LOCAL_LOOPBACK_IPv4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@
|
|||
#define FAST_IF_ALIAS_PREFIX_MAX_SIZE 32
|
||||
#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
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -1976,15 +1976,15 @@ int set_run_by(const char *group_name, const char *username)
|
|||
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 bytes;
|
||||
if (*alloc_count < target_ip_count)
|
||||
{
|
||||
*alloc_count = target_ip_count;
|
||||
bytes = sizeof(in_addr_t) * (*alloc_count);
|
||||
*allow_ip_addrs = (in_addr_t *)fc_realloc(*allow_ip_addrs, bytes);
|
||||
bytes = sizeof(in_addr_64_t) * (*alloc_count);
|
||||
*allow_ip_addrs = (in_addr_64_t *)fc_realloc(*allow_ip_addrs, bytes);
|
||||
if (*allow_ip_addrs == NULL)
|
||||
{
|
||||
return ENOMEM;
|
||||
|
|
@ -1994,7 +1994,7 @@ static int check_realloc_allow_ips(in_addr_t **allow_ip_addrs,
|
|||
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)
|
||||
{
|
||||
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,
|
||||
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)
|
||||
{
|
||||
char *pTail;
|
||||
char *p;
|
||||
int result;
|
||||
int i;
|
||||
in_addr_t addr;
|
||||
in_addr_64_t addr;
|
||||
|
||||
pTail = pEnd + 1;
|
||||
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, \
|
||||
in_addr_t **allow_ip_addrs, int *allow_ip_count)
|
||||
in_addr_64_t **allow_ip_addrs, int *allow_ip_count)
|
||||
{
|
||||
int result;
|
||||
int count;
|
||||
|
|
@ -2276,7 +2276,7 @@ int load_allow_hosts(IniContext *pIniContext, \
|
|||
|
||||
alloc_count = count;
|
||||
*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)
|
||||
{
|
||||
return ENOMEM;
|
||||
|
|
@ -2829,6 +2829,35 @@ bool is_private_ip(const char* ip)
|
|||
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()
|
||||
{
|
||||
struct timespec ts;
|
||||
|
|
|
|||
|
|
@ -544,7 +544,7 @@ void set_log_level(char *pLogLevel);
|
|||
* return: error no , 0 success, != 0 fail
|
||||
*/
|
||||
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
|
||||
|
|
@ -754,7 +754,7 @@ int fd_set_cloexec(int fd);
|
|||
*/
|
||||
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:
|
||||
* p1: the first 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);
|
||||
|
||||
|
||||
/** 从字符串中解析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
|
||||
* return: current time
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ent = gethostbyname(name);
|
||||
if (ent == NULL)
|
||||
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;
|
||||
}
|
||||
|
||||
addr_list = (in_addr_t **)ent->h_addr_list;
|
||||
if (addr_list[0] == NULL)
|
||||
for (p = res; p != NULL; p = p->ai_next)
|
||||
{
|
||||
return INADDR_NONE;
|
||||
}
|
||||
|
||||
memset(&ip_addr, 0, sizeof(ip_addr));
|
||||
ip_addr.s_addr = *(addr_list[0]);
|
||||
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, &ip_addr, buff, bufferSize) == NULL)
|
||||
if (inet_ntop(AF_INET, &(ipv4->sin_addr), buff, bufferSize) == NULL)
|
||||
{
|
||||
*buff = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return ip_addr.s_addr;
|
||||
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';
|
||||
}
|
||||
}
|
||||
|
||||
in_addr_64_t ip_addr = 0;
|
||||
memcpy(&ip_addr, &ipv6->sin6_addr, sizeof(in_addr_64_t));
|
||||
|
||||
freeaddrinfo(res);
|
||||
return ip_addr;
|
||||
}
|
||||
}
|
||||
|
||||
return INADDR_NONE;
|
||||
}
|
||||
|
||||
int getIpaddrsByName(const char *name,
|
||||
|
|
@ -2173,10 +2188,10 @@ 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(NULL == ifc->ifa_addr ){
|
||||
continue;
|
||||
}
|
||||
|
||||
if (max_count <= *count)
|
||||
{
|
||||
logError("file: "__FILE__", line: %d, "\
|
||||
|
|
@ -2186,7 +2201,9 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
|
|||
return ENOSPC;
|
||||
}
|
||||
|
||||
if (inet_ntop(AF_INET, &((struct sockaddr_in *)s)-> \
|
||||
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)++;
|
||||
|
|
@ -2200,6 +2217,22 @@ int getlocaladdrs(char ip_addrs[][IP_ADDRESS_SIZE], \
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue