From 998610501844cda073eb71a7996b13cca7f03232 Mon Sep 17 00:00:00 2001 From: zsx Date: Wed, 12 Sep 2018 17:43:46 +0800 Subject: [PATCH] supporting IPV6 --- lib_acl/include/net/acl_dns.h | 2 +- lib_acl/include/net/acl_ifconf.h | 2 +- lib_acl/include/net/acl_netdb.h | 2 +- lib_acl/include/net/acl_sane_inet.h | 46 +++++++ lib_acl/include/net/acl_sane_socket.h | 12 -- lib_acl/include/stdlib/acl_define.h | 4 + lib_acl/include/stdlib/acl_vstream.h | 8 +- lib_acl/src/net/acl_sane_inet.c | 115 ++++++++++++++++ lib_acl/src/net/acl_sane_socket.c | 58 ++------ lib_acl/src/net/acl_tcp_ctl.c | 30 ++-- lib_acl/src/net/acl_valid_hostname.c | 6 +- lib_acl/src/net/acl_vstream_net.c | 25 ++-- lib_acl/src/net/connect/acl_inet_connect.c | 23 ++-- lib_acl/src/net/connect/acl_sane_connect.c | 4 +- lib_acl/src/net/connect/acl_unix_connect.c | 35 ++--- lib_acl/src/net/listen/acl_inet_listen.c | 4 +- lib_acl/src/net/listen/acl_sane_accept.c | 58 ++------ lib_acl/src/stdlib/acl_vstream.c | 153 +++------------------ 18 files changed, 266 insertions(+), 321 deletions(-) diff --git a/lib_acl/include/net/acl_dns.h b/lib_acl/include/net/acl_dns.h index 7733a394a..d5a4b266d 100644 --- a/lib_acl/include/net/acl_dns.h +++ b/lib_acl/include/net/acl_dns.h @@ -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 查询时的错误码定义 */ diff --git a/lib_acl/include/net/acl_ifconf.h b/lib_acl/include/net/acl_ifconf.h index 9ac37507b..282c00fca 100644 --- a/lib_acl/include/net/acl_ifconf.h +++ b/lib_acl/include/net/acl_ifconf.h @@ -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; /* 接口名称 */ diff --git a/lib_acl/include/net/acl_netdb.h b/lib_acl/include/net/acl_netdb.h index b793fdba9..93af3af72 100644 --- a/lib_acl/include/net/acl_netdb.h +++ b/lib_acl/include/net/acl_netdb.h @@ -8,7 +8,7 @@ #endif #include "../stdlib/acl_array.h" -#include "acl_sane_socket.h" +#include "acl_sane_inet.h" /** * 主机地址结构 diff --git a/lib_acl/include/net/acl_sane_inet.h b/lib_acl/include/net/acl_sane_inet.h index 7cf72b624..23082f3f4 100644 --- a/lib_acl/include/net/acl_sane_inet.h +++ b/lib_acl/include/net/acl_sane_inet.h @@ -9,8 +9,54 @@ extern "C" { #ifdef ACL_UNIX #include +#include #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 的连续内存表示 diff --git a/lib_acl/include/net/acl_sane_socket.h b/lib_acl/include/net/acl_sane_socket.h index a0b6fbd17..eb1a3c147 100644 --- a/lib_acl/include/net/acl_sane_socket.h +++ b/lib_acl/include/net/acl_sane_socket.h @@ -14,18 +14,6 @@ extern "C" { #include #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} 网络套接字 diff --git a/lib_acl/include/stdlib/acl_define.h b/lib_acl/include/stdlib/acl_define.h index d1e5d7180..18ac7cf93 100644 --- a/lib_acl/include/stdlib/acl_define.h +++ b/lib_acl/include/stdlib/acl_define.h @@ -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__ */ diff --git a/lib_acl/include/stdlib/acl_vstream.h b/lib_acl/include/stdlib/acl_vstream.h index 934b0edb9..3a7de05dc 100644 --- a/lib_acl/include/stdlib/acl_vstream.h +++ b/lib_acl/include/stdlib/acl_vstream.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); diff --git a/lib_acl/src/net/acl_sane_inet.c b/lib_acl/src/net/acl_sane_inet.c index a47506cd8..a4ad8103c 100644 --- a/lib_acl/src/net/acl_sane_inet.c +++ b/lib_acl/src/net/acl_sane_inet.c @@ -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); +} diff --git a/lib_acl/src/net/acl_sane_socket.c b/lib_acl/src/net/acl_sane_socket.c index 298eaaf22..da05ebe4f 100644 --- a/lib_acl/src/net/acl_sane_socket.c +++ b/lib_acl/src/net/acl_sane_socket.c @@ -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 diff --git a/lib_acl/src/net/acl_tcp_ctl.c b/lib_acl/src/net/acl_tcp_ctl.c index fae707fcb..cce2056e3 100644 --- a/lib_acl/src/net/acl_tcp_ctl.c +++ b/lib_acl/src/net/acl_tcp_ctl.c @@ -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()); } diff --git a/lib_acl/src/net/acl_valid_hostname.c b/lib_acl/src/net/acl_valid_hostname.c index 66e7df427..12752cd9d 100644 --- a/lib_acl/src/net/acl_valid_hostname.c +++ b/lib_acl/src/net/acl_valid_hostname.c @@ -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; diff --git a/lib_acl/src/net/acl_vstream_net.c b/lib_acl/src/net/acl_vstream_net.c index d0025db90..2074e4216 100644 --- a/lib_acl/src/net/acl_vstream_net.c +++ b/lib_acl/src/net/acl_vstream_net.c @@ -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) { diff --git a/lib_acl/src/net/connect/acl_inet_connect.c b/lib_acl/src/net/connect/acl_inet_connect.c index 38165da3d..7cedb65c1 100644 --- a/lib_acl/src/net/connect/acl_inet_connect.c +++ b/lib_acl/src/net/connect/acl_inet_connect.c @@ -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); diff --git a/lib_acl/src/net/connect/acl_sane_connect.c b/lib_acl/src/net/connect/acl_sane_connect.c index dd36e1e0b..f2cbf987a 100644 --- a/lib_acl/src/net/connect/acl_sane_connect.c +++ b/lib_acl/src/net/connect/acl_sane_connect.c @@ -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()); } diff --git a/lib_acl/src/net/connect/acl_unix_connect.c b/lib_acl/src/net/connect/acl_unix_connect.c index 99d2e75b5..ef52086e5 100644 --- a/lib_acl/src/net/connect/acl_unix_connect.c +++ b/lib_acl/src/net/connect/acl_unix_connect.c @@ -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 - diff --git a/lib_acl/src/net/listen/acl_inet_listen.c b/lib_acl/src/net/listen/acl_inet_listen.c index e3a50d994..13a39b276 100644 --- a/lib_acl/src/net/listen/acl_inet_listen.c +++ b/lib_acl/src/net/listen/acl_inet_listen.c @@ -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; diff --git a/lib_acl/src/net/listen/acl_sane_accept.c b/lib_acl/src/net/listen/acl_sane_accept.c index 1bc4ba84e..3197a9359 100644 --- a/lib_acl/src/net/listen/acl_sane_accept.c +++ b/lib_acl/src/net/listen/acl_sane_accept.c @@ -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; } diff --git a/lib_acl/src/stdlib/acl_vstream.c b/lib_acl/src/stdlib/acl_vstream.c index 030edc938..8a08b9e96 100644 --- a/lib_acl/src/stdlib/acl_vstream.c +++ b/lib_acl/src/stdlib/acl_vstream.c @@ -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)