mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-03 12:28:49 +08:00
supporting IPV6
This commit is contained in:
parent
9498838177
commit
9986105018
@ -14,7 +14,7 @@ extern "C" {
|
||||
#endif
|
||||
#include "../event/acl_events.h"
|
||||
#include "../aio/acl_aio.h"
|
||||
#include "acl_sane_socket.h"
|
||||
#include "acl_sane_inet.h"
|
||||
#include "acl_netdb.h"
|
||||
|
||||
/* DNS 查询时的错误码定义 */
|
||||
|
@ -7,7 +7,7 @@ extern "C" {
|
||||
|
||||
#include "../stdlib/acl_define.h"
|
||||
#include "../stdlib/acl_argv.h"
|
||||
#include "acl_sane_socket.h"
|
||||
#include "acl_sane_inet.h"
|
||||
|
||||
typedef struct ACL_IFADDR {
|
||||
char *name; /* ½Ó¿ÚÃû³Æ */
|
||||
|
@ -8,7 +8,7 @@
|
||||
#endif
|
||||
|
||||
#include "../stdlib/acl_array.h"
|
||||
#include "acl_sane_socket.h"
|
||||
#include "acl_sane_inet.h"
|
||||
|
||||
/**
|
||||
* 主机地址结构
|
||||
|
@ -9,8 +9,54 @@ extern "C" {
|
||||
|
||||
#ifdef ACL_UNIX
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
struct sockaddr_storage ss;
|
||||
#ifdef AF_INET6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr_in in;
|
||||
#ifdef ACL_UNIX
|
||||
struct sockaddr_un un;
|
||||
#endif
|
||||
struct sockaddr sa;
|
||||
} ACL_SOCKADDR;
|
||||
|
||||
/**
|
||||
* 将 socket 地址转为字符串格式,同时支持 IPV4 与 IPV6 及 UNIX 域套接口
|
||||
* @param sa {const struct sockaddr*}
|
||||
* @param buf {char*} 存储转换结果
|
||||
* @param size {size_t} buf 空间大小
|
||||
* @return {size_t} 返回 sockaddr 地址所对应地址类型的实际长度,如对于 IPV4 则
|
||||
* 对应 struct sockaddr_in 的结构体长度,对于 IPV6 则对应 struct sockaddr_in6
|
||||
* 的结构体长度,返回值 0 表示转换出错
|
||||
*/
|
||||
ACL_API size_t acl_inet_ntop(const struct sockaddr *sa, char *buf, size_t size);
|
||||
|
||||
/**
|
||||
* 将字符串表示的地址转为 socket 地址,支持 IPV4 与 IPV6 及 UNIX 域套接口
|
||||
* @param af {int} 地址类型,AF_INET(IPV4)或 AF_INET6(IPV6)
|
||||
* @param src {const char*} 字符串表示的地址,可以为 ip、ip#port 或 ipv4:port
|
||||
* @param dst {struct sockaddr*} 存储转换结果
|
||||
* @return {size_t} 返回对应 IPV4 或 IPV6 地址结构体的大小,如对于 IPV4 则
|
||||
* 对应 struct sockaddr_in 的结构体长度,对于 IPV6 则对应 struct sockaddr_in6
|
||||
* 的结构体长度,返回值 0 表示转换出错
|
||||
*/
|
||||
ACL_API size_t acl_inet_pton(int af, const char *src, struct sockaddr *dst);
|
||||
|
||||
/**
|
||||
* 将字符串表示的地址转为 socket 地址,支持 IPV4 与 IPV6 及 UNIX 域套接口,
|
||||
* 内部将自动探测所给地址字符串的地址类型,即自动区分是 IPV4 还是 IPV6
|
||||
* @param src {const char*} 字符串表示的地址,可以为 ip、ip#port 或 ipv4:port
|
||||
* @param dst {struct sockaddr*} 存储转换结果
|
||||
* @return {size_t} 返回对应 IPV4 或 IPV6 地址结构体的大小,如对于 IPV4 则
|
||||
* 对应 struct sockaddr_in 的结构体长度,对于 IPV6 则对应 struct sockaddr_in6
|
||||
* 的结构体长度,返回值 0 表示转换出错
|
||||
*/
|
||||
ACL_API size_t acl_sane_pton(const char *src, struct sockaddr *dst);
|
||||
|
||||
/**
|
||||
* 将IP地址转换成字符串格式
|
||||
* @param src {const unsigned char*} struct in_addr in.s_addr 的连续内存表示
|
||||
|
@ -14,18 +14,6 @@ extern "C" {
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
struct sockaddr_storage ss;
|
||||
#ifdef AF_INET6
|
||||
struct sockaddr_in6 in6;
|
||||
#endif
|
||||
struct sockaddr_in in;
|
||||
#ifdef ACL_UNIX
|
||||
struct sockaddr_un un;
|
||||
#endif
|
||||
struct sockaddr sa;
|
||||
} ACL_SOCKADDR;
|
||||
|
||||
/**
|
||||
* 取得套接字连接对方的网络地址, 地址格式为: IP:PORT
|
||||
* @param fd {ACL_SOCKET} 网络套接字
|
||||
|
@ -93,5 +93,9 @@ typedef struct acl_stat acl_stat_t;
|
||||
#define ACL_DEPRECATED_FOR(f) ACL_DEPRECATED
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifndef ACL_ADDR_SEP
|
||||
#define ACL_ADDR_SEP '#'
|
||||
#endif
|
||||
|
||||
#endif /* __ACL_DEFINE_INCLUDE_H__ */
|
||||
|
||||
|
@ -817,9 +817,9 @@ ACL_API void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr);
|
||||
* 当 ACL_VSTREAM 为网络流时,此函数设置远程连接地址
|
||||
* @param fp {ACL_VSTREAM*} 网络流,非空
|
||||
* @param sa {const struct sockaddr *} 远程连接地址,非空
|
||||
* @return {int} 返回值 == 0 表示成功,< 0 表示失败
|
||||
*/
|
||||
ACL_API void acl_vstream_set_peer_addr(ACL_VSTREAM *fp,
|
||||
const struct sockaddr *sa);
|
||||
ACL_API int acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa);
|
||||
|
||||
/**
|
||||
* 当 ACL_VSTREAM 为网络流时,用此宏取得本地的地址
|
||||
@ -837,9 +837,9 @@ ACL_API void acl_vstream_set_local(ACL_VSTREAM *fp, const char *addr);
|
||||
* 当 ACL_VSTREAM 为网络流时,此函数设置本地地址
|
||||
* @param fp {ACL_VSTREAM*} 网络流,非空
|
||||
* @param sa {const sockaddr*} 本地地址,非空
|
||||
* @return {int} 返回值 == 0 表示成功,< 0 表示失败
|
||||
*/
|
||||
ACL_API void acl_vstream_set_local_addr(ACL_VSTREAM *fp,
|
||||
const struct sockaddr *sa);
|
||||
ACL_API int acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa);
|
||||
|
||||
ACL_API int acl_vstream_add_object(ACL_VSTREAM *fp, const char *key, void *obj);
|
||||
ACL_API int acl_vstream_del_object(ACL_VSTREAM *fp, const char *key);
|
||||
|
@ -147,3 +147,118 @@ int acl_ipv4_addr_valid(const char *addr)
|
||||
return (1);
|
||||
}
|
||||
|
||||
#define IPLEN 64
|
||||
|
||||
size_t acl_inet_ntop(const struct sockaddr *sa, char *buf, size_t size)
|
||||
{
|
||||
if (sa->sa_family == AF_INET) {
|
||||
int port;
|
||||
char ip[IPLEN];
|
||||
struct sockaddr_in *in = (struct sockaddr_in*) sa;
|
||||
|
||||
if (!inet_ntop(sa->sa_family, &in->sin_addr, ip, IPLEN))
|
||||
return 0;
|
||||
port = ntohs(in->sin_port);
|
||||
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
|
||||
return sizeof(struct sockaddr_in);
|
||||
#ifdef AF_INET6
|
||||
} else if (sa->sa_family == AF_INET6) {
|
||||
int port;
|
||||
char ip[IPLEN];
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*) sa;
|
||||
|
||||
if (!inet_ntop(sa->sa_family, &in6->sin6_addr, ip, IPLEN))
|
||||
return 0;
|
||||
port = ntohs(in6->sin6_port);
|
||||
snprintf(buf, size, "%s%c%d", ip, ACL_ADDR_SEP, port);
|
||||
return sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
#ifdef ACL_UNIX
|
||||
} else if (sa->sa_family == AF_UNIX) {
|
||||
struct sockaddr_un *un = (struct sockaddr_un *) sa;
|
||||
|
||||
ACL_SAFE_STRNCPY(buf, un->sun_path, size);
|
||||
return sizeof(struct sockaddr_un);
|
||||
#endif
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t acl_inet_pton(int af, const char *src, struct sockaddr *dst)
|
||||
{
|
||||
if (af == AF_INET) {
|
||||
char buf[1024], *ptr;
|
||||
int port = 0;
|
||||
struct sockaddr_in *in;
|
||||
|
||||
ACL_SAFE_STRNCPY(buf, src, sizeof(buf));
|
||||
|
||||
if ((ptr = strrchr(buf, ':'))
|
||||
|| (ptr = strrchr(buf, ACL_ADDR_SEP))) {
|
||||
|
||||
*ptr++ = 0;
|
||||
port = atoi(ptr);
|
||||
}
|
||||
|
||||
in = (struct sockaddr_in *) dst;
|
||||
if (inet_pton(af, buf, &in->sin_addr) == 0)
|
||||
return 0;
|
||||
in->sin_port = htons(port);
|
||||
return sizeof(struct sockaddr_in);
|
||||
#ifdef AF_INET6
|
||||
} else if (af == AF_INET6) {
|
||||
char buf[1024], *ptr;
|
||||
int port = 0;
|
||||
struct sockaddr_in6 *in6;
|
||||
|
||||
ACL_SAFE_STRNCPY(buf, src, sizeof(buf));
|
||||
|
||||
if((ptr = strrchr(buf, ACL_ADDR_SEP))) {
|
||||
*ptr++ = 0;
|
||||
port = atoi(ptr);
|
||||
}
|
||||
|
||||
in6 = (struct sockaddr_in6 *) dst;
|
||||
if (inet_pton(af, buf, &in6->sin6_addr) == 0)
|
||||
return 0;
|
||||
in6->sin6_port = htons(port);
|
||||
return sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
#ifdef ACL_UNIX
|
||||
} else if (af == AF_UNIX) {
|
||||
struct sockaddr_un *un = (struct sockaddr_un *) dst;
|
||||
size_t len = strlen(src) + 1;
|
||||
|
||||
if (sizeof(un->sun_path) < len) {
|
||||
len = sizeof(un->sun_path);
|
||||
}
|
||||
|
||||
dst->sa_family = AF_UNIX;
|
||||
# ifdef HAS_SUN_LEN
|
||||
un->sun_len = len + 1;
|
||||
# endif
|
||||
ACL_SAFE_STRNCPY(un->sun_path, src, len);
|
||||
return sizeof(struct sockaddr_un);
|
||||
#endif
|
||||
} else {
|
||||
acl_msg_error("%s(%d): invalid af=%d",
|
||||
__FUNCTION__, __LINE__, af);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
size_t acl_sane_pton(const char *src, struct sockaddr *dst)
|
||||
{
|
||||
int af;
|
||||
|
||||
if (acl_valid_ipv4_hostaddr(src, 0))
|
||||
af = AF_INET;
|
||||
else if (acl_valid_ipv6_hostaddr(src, 0))
|
||||
af = AF_INET6;
|
||||
else if (*src == '/')
|
||||
af = AF_UNIX;
|
||||
else
|
||||
return 0;
|
||||
|
||||
return acl_inet_pton(af, src, dst);
|
||||
}
|
||||
|
@ -21,15 +21,11 @@
|
||||
|
||||
#endif
|
||||
|
||||
#define LEN 64
|
||||
|
||||
int acl_getpeername(ACL_SOCKET fd, char *buf, size_t size)
|
||||
{
|
||||
ACL_SOCKADDR addr;
|
||||
struct sockaddr *sa = (struct sockaddr*) &addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
char ip[LEN];
|
||||
int port;
|
||||
|
||||
if (fd == ACL_SOCKET_INVALID || buf == NULL || size <= 0)
|
||||
return -1;
|
||||
@ -39,36 +35,20 @@ int acl_getpeername(ACL_SOCKET fd, char *buf, size_t size)
|
||||
if (getpeername(fd, sa, &len) == -1)
|
||||
return -1;
|
||||
|
||||
#ifndef ACL_WINDOWS
|
||||
#ifdef ACL_UNIX
|
||||
if (sa->sa_family == AF_UNIX) {
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
len = sizeof(addr);
|
||||
|
||||
if (getsockname(fd, sa, &len) == -1)
|
||||
return -1;
|
||||
|
||||
snprintf(buf, size, "%s", addr.un.sun_path);
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
if (sa->sa_family == AF_INET) {
|
||||
if (!inet_ntop(sa->sa_family, &addr.in.sin_addr, ip, LEN))
|
||||
return -1;
|
||||
port = ntohs(addr.in.sin_port);
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (sa->sa_family == AF_INET6) {
|
||||
if (!inet_ntop(sa->sa_family, &addr.in6.sin6_addr, ip, LEN))
|
||||
return -1;
|
||||
port = ntohs(addr.in6.sin6_port);
|
||||
} else
|
||||
return -1;
|
||||
#else
|
||||
#endif
|
||||
|
||||
if (acl_inet_ntop(sa, buf, size) > 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
#endif
|
||||
snprintf(buf, size, "%s:%d", ip, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_getsockname(ACL_SOCKET fd, char *buf, size_t size)
|
||||
@ -76,8 +56,6 @@ int acl_getsockname(ACL_SOCKET fd, char *buf, size_t size)
|
||||
ACL_SOCKADDR addr;
|
||||
struct sockaddr *sa = (struct sockaddr*) &addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
char ip[LEN];
|
||||
int port;
|
||||
|
||||
if (fd == ACL_SOCKET_INVALID || buf == NULL || size <= 0)
|
||||
return -1;
|
||||
@ -87,31 +65,10 @@ int acl_getsockname(ACL_SOCKET fd, char *buf, size_t size)
|
||||
if (getsockname(fd, sa, &len) == -1)
|
||||
return -1;
|
||||
|
||||
#ifndef ACL_WINDOWS
|
||||
if (sa->sa_family == AF_UNIX) {
|
||||
snprintf(buf, size, "%s", addr.un.sun_path);
|
||||
if (acl_inet_ntop(sa, buf, size) > 0)
|
||||
return 0;
|
||||
} else
|
||||
#endif
|
||||
if (sa->sa_family == AF_INET) {
|
||||
if (!inet_ntop(sa->sa_family, &addr.in.sin_addr, ip, LEN))
|
||||
return -1;
|
||||
port = ntohs(addr.in.sin_port);
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (sa->sa_family == AF_INET6) {
|
||||
if (!inet_ntop(sa->sa_family, &addr.in6.sin6_addr, ip, LEN))
|
||||
return -1;
|
||||
port = ntohs(addr.in6.sin6_port);
|
||||
} else
|
||||
return -1;
|
||||
#else
|
||||
else
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
snprintf(buf, size, "%s:%d", ip, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int acl_getsocktype(ACL_SOCKET fd)
|
||||
@ -126,10 +83,11 @@ int acl_getsocktype(ACL_SOCKET fd)
|
||||
if (getsockname(fd, sa, &len) == -1)
|
||||
return -1;
|
||||
|
||||
#ifndef ACL_WINDOWS
|
||||
#ifdef ACL_UNIX
|
||||
if (sa->sa_family == AF_UNIX)
|
||||
return AF_UNIX;
|
||||
#endif
|
||||
|
||||
#ifdef AF_INET6
|
||||
if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6)
|
||||
#else
|
||||
|
@ -39,8 +39,8 @@ void acl_tcp_set_rcvbuf(ACL_SOCKET fd, int size)
|
||||
return;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &size, sizeof(size)) < 0)
|
||||
{
|
||||
(char *) &size, sizeof(size)) < 0) {
|
||||
|
||||
acl_msg_error("%s(%d): size(%d), setsockopt error(%s)",
|
||||
myname, __LINE__, size, acl_last_serror());
|
||||
}
|
||||
@ -59,8 +59,8 @@ void acl_tcp_set_sndbuf(ACL_SOCKET fd, int size)
|
||||
return;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF,
|
||||
(char *) &size, sizeof(size)) < 0)
|
||||
{
|
||||
(char *) &size, sizeof(size)) < 0) {
|
||||
|
||||
acl_msg_error("%s: FD %d, SIZE %d: %s\n",
|
||||
myname, fd, size, acl_last_serror());
|
||||
}
|
||||
@ -86,10 +86,10 @@ int acl_tcp_get_rcvbuf(ACL_SOCKET fd)
|
||||
{
|
||||
acl_msg_error("%s(%d): size(%d), getsockopt error(%s)",
|
||||
myname, __LINE__, size, acl_last_serror());
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (size);
|
||||
return size;
|
||||
}
|
||||
|
||||
int acl_tcp_get_sndbuf(ACL_SOCKET fd)
|
||||
@ -110,10 +110,10 @@ int acl_tcp_get_sndbuf(ACL_SOCKET fd)
|
||||
if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, &len) < 0) {
|
||||
acl_msg_error("%s(%d): size(%d), getsockopt error(%s)",
|
||||
myname, __LINE__, size, acl_last_serror());
|
||||
return (-1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (size);
|
||||
return size;
|
||||
}
|
||||
|
||||
void acl_tcp_set_nodelay(ACL_SOCKET fd)
|
||||
@ -135,8 +135,8 @@ void acl_tcp_nodelay(ACL_SOCKET fd, int onoff)
|
||||
return;
|
||||
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(char *) &on, sizeof(on)) < 0)
|
||||
{
|
||||
(char *) &on, sizeof(on)) < 0) {
|
||||
|
||||
acl_msg_error("%s(%d): set nodelay error(%s), onoff(%d)",
|
||||
myname, __LINE__, acl_last_serror(), onoff);
|
||||
}
|
||||
@ -145,8 +145,8 @@ void acl_tcp_nodelay(ACL_SOCKET fd, int onoff)
|
||||
int acl_get_tcp_nodelay(ACL_SOCKET fd)
|
||||
{
|
||||
const char *myname = "acl_get_tcp_nodelay";
|
||||
int on = 0;
|
||||
socklen_t len;
|
||||
int on = 0;
|
||||
int n = acl_getsocktype(fd);
|
||||
|
||||
#ifdef AF_INET6
|
||||
@ -182,9 +182,7 @@ void acl_tcp_so_linger(ACL_SOCKET fd, int onoff, int timeout)
|
||||
|
||||
l.l_onoff = onoff ? 1 : 0;
|
||||
l.l_linger = timeout >= 0 ? timeout : 0;
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_LINGER,
|
||||
(char *) &l, sizeof(l)) < 0)
|
||||
{
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &l, sizeof(l)) < 0) {
|
||||
acl_msg_error("%s(%d): setsockopt(SO_LINGER) error(%s),"
|
||||
" onoff(%d), timeout(%d)", myname, __LINE__,
|
||||
acl_last_serror(), onoff, timeout);
|
||||
@ -242,8 +240,8 @@ void acl_tcp_fastopen(ACL_SOCKET fd, int on)
|
||||
if (on)
|
||||
on = 1;
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN,
|
||||
(const void *) &on, sizeof(on)) < 0)
|
||||
{
|
||||
(const void *) &on, sizeof(on)) < 0) {
|
||||
|
||||
acl_msg_error("%s: setsocket(TCP_FASTOPEN): %s",
|
||||
myname, acl_last_serror());
|
||||
}
|
||||
|
@ -130,9 +130,9 @@ int acl_valid_ipv4_hostaddr(const char *addr_in, int gripe)
|
||||
#define BYTES_NEEDED 4
|
||||
|
||||
ACL_SAFE_STRNCPY(addr, addr_in, sizeof(addr));
|
||||
if ((ptr = strrchr(addr, ':')) != NULL) {
|
||||
if ((ptr = strrchr(addr, ACL_ADDR_SEP)) != NULL) {
|
||||
*ptr = 0;
|
||||
} else if ((ptr = strrchr(addr, '#')) != NULL) {
|
||||
} else if ((ptr = strrchr(addr, ':')) != NULL) {
|
||||
*ptr = 0;
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ int acl_valid_ipv6_hostaddr(const char *addr_in, int gripe)
|
||||
const unsigned char *cp;
|
||||
|
||||
ACL_SAFE_STRNCPY(addr, addr_in, sizeof(addr));
|
||||
if ((ptr = strrchr(addr, '#')) != NULL) {
|
||||
if ((ptr = strrchr(addr, ACL_ADDR_SEP)) != NULL) {
|
||||
*ptr = 0;
|
||||
}
|
||||
cp = (const unsigned char *) addr;
|
||||
|
@ -45,7 +45,7 @@ ACL_VSTREAM *acl_vstream_listen_ex(const char *addr, int qlen,
|
||||
|
||||
#ifdef ACL_UNIX
|
||||
/* this maybe unix addr, such as '/home/test/listen.sock' */
|
||||
if (strchr(addr, '/') != NULL) {
|
||||
if (*addr == '/' || (*addr == '.' && *(addr + 1) == '/')) {
|
||||
listenfd = acl_unix_listen(addr, qlen, 0);
|
||||
if (listenfd == ACL_SOCKET_INVALID)
|
||||
return NULL;
|
||||
@ -172,31 +172,22 @@ ACL_VSTREAM *acl_vstream_connect_ex(const char *addr,
|
||||
const char *myname = "acl_vstream_connect_ex";
|
||||
ACL_VSTREAM *client;
|
||||
ACL_SOCKET connfd;
|
||||
char *ptr, buf[256];
|
||||
char buf[256];
|
||||
|
||||
if (addr == NULL || *addr == 0)
|
||||
acl_msg_fatal("%s: addr null", myname);
|
||||
|
||||
ptr = strchr(addr, ':');
|
||||
if (ptr != NULL)
|
||||
#if defined(ACL_UNIX)
|
||||
if (*addr == '/' || (*addr == '.' && *(addr + 1) == '/'))
|
||||
connfd = acl_unix_connect(addr, block_mode, connect_timeout);
|
||||
else
|
||||
#endif
|
||||
connfd = acl_inet_connect_ex(addr, block_mode,
|
||||
connect_timeout, he_errorp);
|
||||
#ifdef ACL_WINDOWS
|
||||
else {
|
||||
acl_msg_error("%s(%d): addr(%s) invalid",
|
||||
myname, __LINE__, addr);
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(ACL_UNIX)
|
||||
else
|
||||
connfd = acl_unix_connect(addr, block_mode, connect_timeout);
|
||||
#else
|
||||
else
|
||||
connfd = ACL_SOCKET_INVALID;
|
||||
#endif
|
||||
|
||||
if (connfd == ACL_SOCKET_INVALID)
|
||||
return NULL;
|
||||
|
||||
client = acl_vstream_fdopen(connfd, ACL_VSTREAM_FLAG_RW,
|
||||
rw_bufsize, rw_timeout, ACL_VSTREAM_TYPE_SOCK);
|
||||
if (client == NULL) {
|
||||
|
@ -78,9 +78,7 @@ static ACL_SOCKET inet_connect_one(const struct addrinfo *peer,
|
||||
return ACL_SOCKET_INVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Timed connect.
|
||||
*/
|
||||
/* Timed connect. */
|
||||
if (timeout > 0) {
|
||||
acl_non_blocking(sock, ACL_NON_BLOCKING);
|
||||
#ifdef ACL_WINDOWS
|
||||
@ -105,9 +103,7 @@ static ACL_SOCKET inet_connect_one(const struct addrinfo *peer,
|
||||
return sock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Maybe block until connected.
|
||||
*/
|
||||
/* Maybe block until connected. */
|
||||
acl_non_blocking(sock, blocking);
|
||||
#ifdef ACL_WINDOWS
|
||||
if (acl_sane_connect(sock, peer->ai_addr,
|
||||
@ -175,7 +171,7 @@ ACL_SOCKET acl_inet_connect_ex(const char *addr, int blocking,
|
||||
const char *myname = "acl_inet_connect_ex";
|
||||
int err;
|
||||
ACL_SOCKET sock;
|
||||
char buf[256], *ptr;
|
||||
char buf[256], *ptr = NULL;
|
||||
const char *peer, *local, *port;
|
||||
struct addrinfo hints, *peer_res0, *res, *local_res0;
|
||||
|
||||
@ -183,7 +179,15 @@ ACL_SOCKET acl_inet_connect_ex(const char *addr, int blocking,
|
||||
*h_error = 0;
|
||||
|
||||
snprintf(buf, sizeof(buf) - 1, "%s", addr);
|
||||
ptr = strrchr(buf, ':');
|
||||
|
||||
if (acl_valid_ipv6_hostaddr(buf, 0)) {
|
||||
ptr = strrchr(buf, ACL_ADDR_SEP);
|
||||
} else if (acl_valid_ipv4_hostaddr(buf, 0)) {
|
||||
ptr = strrchr(buf, ACL_ADDR_SEP);
|
||||
if (ptr == NULL)
|
||||
ptr = strrchr(buf, '.');
|
||||
}
|
||||
|
||||
if (ptr == NULL) {
|
||||
acl_msg_error("%s, %s(%d): invalid addr(%s)",
|
||||
__FILE__, myname, __LINE__, addr);
|
||||
@ -191,7 +195,8 @@ ACL_SOCKET acl_inet_connect_ex(const char *addr, int blocking,
|
||||
}
|
||||
|
||||
*ptr++ = 0;
|
||||
port = ptr;
|
||||
port = ptr;
|
||||
|
||||
if (atoi(port) <= 0) {
|
||||
acl_msg_error("%s, %s(%d): invalid port(%s)",
|
||||
__FILE__, myname, __LINE__, port);
|
||||
|
@ -60,8 +60,8 @@ int acl_sane_connect(ACL_SOCKET sock, const struct sockaddr *sa, socklen_t len)
|
||||
|
||||
#ifdef SO_REUSEADDR
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &on, sizeof(on)) < 0)
|
||||
{
|
||||
(char *) &on, sizeof(on)) < 0) {
|
||||
|
||||
acl_msg_error("acl_sane_connect: setsockopt error(%s)",
|
||||
acl_last_serror());
|
||||
}
|
||||
|
@ -33,9 +33,7 @@ ACL_SOCKET acl_unix_connect(const char *addr, int block_mode, int timeout)
|
||||
int len = (int) strlen(addr);
|
||||
ACL_SOCKET sock;
|
||||
|
||||
/*
|
||||
* Translate address information to internal form.
|
||||
*/
|
||||
/* Translate address information to internal form. */
|
||||
if (len >= (int) sizeof(sun.sun_path))
|
||||
acl_msg_fatal("unix-domain name too long: %s", addr);
|
||||
memset((char *) &sun, 0, sizeof(sun));
|
||||
@ -45,17 +43,13 @@ ACL_SOCKET acl_unix_connect(const char *addr, int block_mode, int timeout)
|
||||
#endif
|
||||
memcpy(sun.sun_path, addr, len + 1);
|
||||
|
||||
/*
|
||||
* Create a client socket.
|
||||
*/
|
||||
/* Create a client socket. */
|
||||
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
char tbuf[256];
|
||||
acl_msg_fatal("socket: %s", acl_last_strerror(tbuf, sizeof(tbuf)));
|
||||
acl_msg_fatal("%s(%d): socket: %s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
}
|
||||
|
||||
/*
|
||||
* Timed connect.
|
||||
*/
|
||||
/* Timed connect. */
|
||||
if (timeout > 0) {
|
||||
acl_non_blocking(sock, ACL_NON_BLOCKING);
|
||||
if (acl_timed_connect(sock, (struct sockaddr *) & sun,
|
||||
@ -68,19 +62,14 @@ ACL_SOCKET acl_unix_connect(const char *addr, int block_mode, int timeout)
|
||||
return (sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Maybe block until connected.
|
||||
*/
|
||||
else {
|
||||
acl_non_blocking(sock, block_mode);
|
||||
if (acl_sane_connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
|
||||
&& acl_last_error() != EINPROGRESS) {
|
||||
/* Maybe block until connected. */
|
||||
acl_non_blocking(sock, block_mode);
|
||||
if (acl_sane_connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
|
||||
&& acl_last_error() != EINPROGRESS) {
|
||||
|
||||
close(sock);
|
||||
return (-1);
|
||||
}
|
||||
return (sock);
|
||||
close(sock);
|
||||
return (-1);
|
||||
}
|
||||
return (sock);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -96,7 +96,7 @@ ACL_SOCKET acl_inet_accept(ACL_SOCKET listen_fd)
|
||||
|
||||
ACL_SOCKET acl_inet_accept_ex(ACL_SOCKET listen_fd, char *ipbuf, size_t size)
|
||||
{
|
||||
struct sockaddr_storage sa;
|
||||
ACL_SOCKADDR sa;
|
||||
socklen_t len = sizeof(sa);
|
||||
ACL_SOCKET fd;
|
||||
|
||||
@ -109,7 +109,7 @@ ACL_SOCKET acl_inet_accept_ex(ACL_SOCKET listen_fd, char *ipbuf, size_t size)
|
||||
if (fd == ACL_SOCKET_INVALID)
|
||||
return fd;
|
||||
|
||||
if (ipbuf != NULL && size > 0 && acl_getpeername(fd, ipbuf, size) < 0)
|
||||
if (ipbuf == NULL && size == 0 && !acl_inet_ntop(&sa.sa, ipbuf, size))
|
||||
ipbuf[0] = 0;
|
||||
|
||||
return fd;
|
||||
|
@ -124,7 +124,6 @@ ACL_SOCKET acl_accept(ACL_SOCKET sock, char *buf, size_t size, int* sock_type)
|
||||
socklen_t len = sizeof(addr);
|
||||
struct sockaddr *sa = (struct sockaddr*) &addr;
|
||||
ACL_SOCKET fd;
|
||||
size_t n;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
@ -140,58 +139,19 @@ ACL_SOCKET acl_accept(ACL_SOCKET sock, char *buf, size_t size, int* sock_type)
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
if (sa->sa_family == AF_INET) {
|
||||
#ifdef ACL_WINDOWS
|
||||
if (!inet_ntop(sa->sa_family, &addr.in.sin_addr, buf, size))
|
||||
#else
|
||||
if (!inet_ntop(sa->sa_family, &addr.in.sin_addr,
|
||||
buf, (socklen_t) size))
|
||||
#endif
|
||||
{
|
||||
acl_msg_error("%s(%d): inet_ntop error=%s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
return fd;
|
||||
}
|
||||
|
||||
n = strlen(buf);
|
||||
if (n >= size)
|
||||
return fd;
|
||||
snprintf(buf + n, size - n, ":%u",
|
||||
(unsigned short) ntohs(addr.in.sin_port));
|
||||
buf[size - 1] = 0;
|
||||
return fd;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (sa->sa_family == AF_INET6) {
|
||||
#ifdef ACL_WINDOWS
|
||||
if (!inet_ntop(sa->sa_family, &addr.in6.sin6_addr, buf, size))
|
||||
#else
|
||||
if (!inet_ntop(sa->sa_family, &addr.in6.sin6_addr,
|
||||
buf, (socklen_t) size))
|
||||
#endif
|
||||
{
|
||||
acl_msg_error("%s(%d): inet_ntop error=%s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
return fd;
|
||||
}
|
||||
|
||||
n = strlen(buf);
|
||||
if (n >= size)
|
||||
return fd;
|
||||
snprintf(buf + n, size - n, ":%u",
|
||||
(unsigned short) ntohs(addr.in6.sin6_port));
|
||||
buf[size - 1] = 0;
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
#ifdef ACL_UNIX
|
||||
else if (sa->sa_family == AF_UNIX) {
|
||||
if (acl_getsockname(fd, buf, size) < 0)
|
||||
if (sa->sa_family == AF_UNIX) {
|
||||
if (acl_getsockname(fd, buf, size) < 0) {
|
||||
buf[0] = 0;
|
||||
acl_msg_error("%s(%d): getsockname error=%s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return fd;
|
||||
if (acl_inet_ntop(sa, buf, size) == 0) {
|
||||
acl_msg_error("%s(%d): inet_ntop error=%s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
@ -2992,75 +2992,14 @@ int acl_vstream_close(ACL_VSTREAM *fp)
|
||||
|
||||
static struct sockaddr *set_sock_addr(const char *addr, size_t *sa_size)
|
||||
{
|
||||
char buf[1024], *ptr;
|
||||
int port;
|
||||
struct sockaddr *sa = (struct sockaddr *)
|
||||
acl_mycalloc(1, sizeof(ACL_SOCKADDR));
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", (addr));
|
||||
|
||||
if ((ptr = strrchr(buf, '#')) || (ptr = strrchr(buf, ':'))) {
|
||||
*ptr++ = 0;
|
||||
port = atoi(ptr);
|
||||
} else
|
||||
port = -1;
|
||||
|
||||
if (acl_is_ipv4(buf)) {
|
||||
struct sockaddr_in *in;
|
||||
if (port < 0) {
|
||||
*sa_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
in = (struct sockaddr_in *)
|
||||
acl_mycalloc(1, sizeof(struct sockaddr_in));
|
||||
in->sin_family = AF_INET;
|
||||
in->sin_port = htons(port);
|
||||
(void) inet_pton(AF_INET, buf, &in->sin_addr);
|
||||
*sa_size = sizeof(struct sockaddr_in);
|
||||
return (struct sockaddr *) in;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (acl_is_ipv6(buf)) {
|
||||
struct sockaddr_in6 *in;
|
||||
if (port < 0) {
|
||||
*sa_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
in = (struct sockaddr_in6 *)
|
||||
acl_mycalloc(1, sizeof(struct sockaddr_in6));
|
||||
in->sin6_family = AF_INET6;
|
||||
in->sin6_port = htons(port);
|
||||
(void) inet_pton(AF_INET6, buf, &in->sin6_addr);
|
||||
*sa_size = sizeof(struct sockaddr_in6);
|
||||
return (struct sockaddr *) in;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ACL_UNIX
|
||||
#define UDP_SUFFIX "@udp"
|
||||
|
||||
if (acl_strrncasecmp(buf, UDP_SUFFIX, sizeof(UDP_SUFFIX) - 1) == 0) {
|
||||
struct sockaddr_un *un;
|
||||
char *at = strrchr(buf, '@');
|
||||
int len;
|
||||
|
||||
*at = 0;
|
||||
len = (int) strlen(buf);
|
||||
if (len == 0) {
|
||||
*sa_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
un = (struct sockaddr_un *)
|
||||
acl_mycalloc(1, sizeof(struct sockaddr_un));
|
||||
un->sun_family = AF_UNIX;
|
||||
#ifdef HAS_SUN_LEN
|
||||
un->sun_len = len + 1;
|
||||
#endif
|
||||
memcpy(un->sun_path, buf, len + 1);
|
||||
*sa_size = sizeof(struct sockaddr_un);
|
||||
return (struct sockaddr *) un;
|
||||
}
|
||||
#endif
|
||||
*sa_size = acl_sane_pton(addr, sa);
|
||||
if (*sa_size > 0)
|
||||
return sa;
|
||||
|
||||
acl_myfree(sa);
|
||||
*sa_size = 0;
|
||||
return NULL;
|
||||
}
|
||||
@ -3088,46 +3027,20 @@ void acl_vstream_set_local(ACL_VSTREAM *fp, const char *addr)
|
||||
fp->sa_local_len = fp->sa_local_size;
|
||||
}
|
||||
|
||||
void acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
int acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
{
|
||||
char addr[256];
|
||||
char addr[1024];
|
||||
|
||||
if (fp->sa_local != NULL) {
|
||||
acl_myfree(fp->sa_local);
|
||||
fp->sa_local = NULL;
|
||||
}
|
||||
|
||||
if (sa->sa_family == AF_INET) {
|
||||
char ip[64];
|
||||
int port;
|
||||
struct sockaddr_in *in = (struct sockaddr_in *) sa;
|
||||
|
||||
if (!inet_ntop(AF_INET, &in->sin_addr, ip, sizeof(ip)))
|
||||
ip[0] = 0;
|
||||
port = ntohs(in->sin_port);
|
||||
snprintf(addr, sizeof(addr), "%s:%d", ip, port);
|
||||
fp->sa_local_size = sizeof(struct sockaddr_in);
|
||||
if (!(fp->sa_local_size = acl_inet_ntop(sa, addr, sizeof(addr)))) {
|
||||
acl_msg_error("%s(%d): get local addr error %s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
return -1;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (sa->sa_family == AF_INET6) {
|
||||
char ip[64];
|
||||
int port;
|
||||
struct sockaddr_in6 *in = (struct sockaddr_in6 *) sa;
|
||||
|
||||
if (!inet_ntop(AF_INET6, &in->sin6_addr, ip, sizeof(ip)))
|
||||
ip[0] = 0;
|
||||
port = ntohs(in->sin6_port);
|
||||
snprintf(addr, sizeof(addr), "%s:%d", ip, port);
|
||||
fp->sa_local_size = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#endif
|
||||
#ifdef ACL_UNIX
|
||||
else if (sa->sa_family == AF_UNIX) {
|
||||
struct sockaddr_un *un = (struct sockaddr_un *) sa;
|
||||
snprintf(addr, sizeof(addr), "%s", un->sun_path);
|
||||
fp->sa_local_size = sizeof(struct sockaddr_un);
|
||||
}
|
||||
#endif
|
||||
|
||||
fp->sa_local = (struct sockaddr *) acl_mymalloc(fp->sa_local_size);
|
||||
memcpy(fp->sa_local, sa, fp->sa_local_size);
|
||||
@ -3139,6 +3052,8 @@ void acl_vstream_set_local_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
acl_myfree(fp->addr_local);
|
||||
fp->addr_local = acl_mystrdup(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr)
|
||||
@ -3164,46 +3079,20 @@ void acl_vstream_set_peer(ACL_VSTREAM *fp, const char *addr)
|
||||
fp->sa_peer_len = fp->sa_peer_size;
|
||||
}
|
||||
|
||||
void acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
int acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
{
|
||||
char addr[256];
|
||||
char addr[1024];
|
||||
|
||||
if (fp->sa_peer != NULL) {
|
||||
acl_myfree(fp->sa_peer);
|
||||
fp->sa_peer = NULL;
|
||||
}
|
||||
|
||||
if (sa->sa_family == AF_INET) {
|
||||
char ip[64];
|
||||
int port;
|
||||
struct sockaddr_in *in = (struct sockaddr_in *) sa;
|
||||
|
||||
if (!inet_ntop(AF_INET, &in->sin_addr, ip, sizeof(ip)))
|
||||
ip[0] = 0;
|
||||
port = ntohs(in->sin_port);
|
||||
snprintf(addr, sizeof(addr), "%s:%d", ip, port);
|
||||
fp->sa_peer_size = sizeof(struct sockaddr_in);
|
||||
if (!(fp->sa_peer_size = acl_inet_ntop(sa, addr, sizeof(addr)))) {
|
||||
acl_msg_error("%s(%d): get peer addr error %s",
|
||||
__FUNCTION__, __LINE__, acl_last_serror());
|
||||
return -1;
|
||||
}
|
||||
#ifdef AF_INET6
|
||||
else if (sa->sa_family == AF_INET6) {
|
||||
char ip[64];
|
||||
int port;
|
||||
struct sockaddr_in6 *in = (struct sockaddr_in6 *) sa;
|
||||
|
||||
if (!inet_ntop(AF_INET, &in->sin6_addr, ip, sizeof(ip)))
|
||||
ip[0] = 0;
|
||||
port = ntohs(in->sin6_port);
|
||||
snprintf(addr, sizeof(addr), "%s:%d", ip, port);
|
||||
fp->sa_peer_size = sizeof(struct sockaddr_in6);
|
||||
}
|
||||
#endif
|
||||
#ifdef ACL_UNIX
|
||||
else if (sa->sa_family == AF_UNIX) {
|
||||
struct sockaddr_un *un = (struct sockaddr_un *) sa;
|
||||
snprintf(addr, sizeof(addr), "%s", un->sun_path);
|
||||
fp->sa_peer_size = sizeof(struct sockaddr_un);
|
||||
}
|
||||
#endif
|
||||
|
||||
fp->sa_peer = (struct sockaddr *) acl_mymalloc(fp->sa_peer_size);
|
||||
memcpy(fp->sa_peer, sa, fp->sa_peer_size);
|
||||
@ -3215,6 +3104,8 @@ void acl_vstream_set_peer_addr(ACL_VSTREAM *fp, const struct sockaddr *sa)
|
||||
acl_myfree(fp->addr_peer);
|
||||
fp->addr_peer = acl_mystrdup(addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void acl_vstream_set_path(ACL_VSTREAM *fp, const char *path)
|
||||
|
Loading…
Reference in New Issue
Block a user