From fba59b99b91e97fa2d6458a645cee260eaff9e60 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sat, 13 Jan 2024 09:48:27 +0100 Subject: [PATCH] Socket and InetAddress cleanups. --- sfw/core/inet_address.cpp | 30 +++++--- sfw/core/inet_address.h | 21 +++--- sfw/core/socket.cpp | 139 +++++++++++++++++++++++++------------- sfw/core/socket.h | 66 +++++++++--------- 4 files changed, 156 insertions(+), 100 deletions(-) diff --git a/sfw/core/inet_address.cpp b/sfw/core/inet_address.cpp index 1fbc766..8ed5570 100755 --- a/sfw/core/inet_address.cpp +++ b/sfw/core/inet_address.cpp @@ -13,7 +13,7 @@ #include #include -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) #ifdef __GNUC__ #define GCCWIN @@ -102,12 +102,16 @@ bool InetAddress::is_intranet_ip() const { auto addrP = ip6_net_endian(); // Loopback ip if (*addrP == 0 && *(addrP + 1) == 0 && *(addrP + 2) == 0 && - ntohl(*(addrP + 3)) == 1) + ntohl(*(addrP + 3)) == 1) { return true; + } + // Privated ip is prefixed by FEC0::/10 or FE80::/10, need testing auto i32 = (ntohl(*addrP) & 0xffc00000); - if (i32 == 0xfec00000 || i32 == 0xfe800000) + if (i32 == 0xfec00000 || i32 == 0xfe800000) { return true; + } + if (*addrP == 0 && *(addrP + 1) == 0 && ntohl(*(addrP + 2)) == 0xffff) { // the IPv6 version of an IPv4 IP address uint32_t ip_addr = ntohl(*(addrP + 3)); @@ -133,12 +137,14 @@ bool InetAddress::is_loopback_ip() const { } else { auto addrP = ip6_net_endian(); if (*addrP == 0 && *(addrP + 1) == 0 && *(addrP + 2) == 0 && - ntohl(*(addrP + 3)) == 1) + ntohl(*(addrP + 3)) == 1) { return true; + } // the IPv6 version of an IPv4 loopback address if (*addrP == 0 && *(addrP + 1) == 0 && ntohl(*(addrP + 2)) == 0xffff && - ntohl(*(addrP + 3)) == 0x7f000001) + ntohl(*(addrP + 3)) == 0x7f000001) { return true; + } } return false; } @@ -185,7 +191,7 @@ const uint32_t *InetAddress::ip6_net_endian() const { // assert(family() == AF_INET6); #if defined __linux__ || defined __HAIKU__ return _addr6.sin6_addr.s6_addr32; -#elif defined _WIN32 +#elif defined(_WIN64) || defined(_WIN32) // TODO is this OK ? const struct in6__addruint *_addrtemp = reinterpret_cast(&_addr6.sin6_addr); @@ -215,8 +221,9 @@ bool InetAddress::is_ip_v6() const { return _is_ip_v6; } -InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6) : - _is_ip_v6(ipv6) { +InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6) { + _is_ip_v6 = ipv6; + if (ipv6) { memset(&_addr6, 0, sizeof(_addr6)); _addr6.sin6_family = AF_INET6; @@ -234,11 +241,13 @@ InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6) : _addr.sin_addr.s_addr = htonl(ip); _addr.sin_port = htons(port); } + _is_unspecified = false; } -InetAddress::InetAddress(const String &ip, uint16_t port, bool ipv6) : - _is_ip_v6(ipv6) { +InetAddress::InetAddress(const String &ip, uint16_t port, bool ipv6) { + _is_ip_v6 = ipv6; + if (ipv6) { memset(&_addr6, 0, sizeof(_addr6)); _addr6.sin6_family = AF_INET6; @@ -256,5 +265,6 @@ InetAddress::InetAddress(const String &ip, uint16_t port, bool ipv6) : return; } } + _is_unspecified = false; } diff --git a/sfw/core/inet_address.h b/sfw/core/inet_address.h index cb2229e..9c1aa82 100755 --- a/sfw/core/inet_address.h +++ b/sfw/core/inet_address.h @@ -24,9 +24,9 @@ //On windows link to ws2_32 -#include +#include "int_types.h" -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) #include using sa_family_t = unsigned short; using in_addr_t = uint32_t; @@ -37,7 +37,9 @@ using uint16_t = unsigned short; #include #endif +//--STRIP #include "core/ustring.h" +//--STRIP class InetAddress { public: @@ -68,12 +70,15 @@ public: InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false); InetAddress(const String &ip, uint16_t port, bool ipv6 = false); - explicit InetAddress(const struct sockaddr_in &addr) : - _addr(addr), _is_unspecified(false) { + explicit InetAddress(const struct sockaddr_in &addr) { + _addr = addr; + _is_unspecified = false; } - explicit InetAddress(const struct sockaddr_in6 &addr) : - _addr6(addr), _is_ip_v6(true), _is_unspecified(false) { + explicit InetAddress(const struct sockaddr_in6 &addr) { + _addr6 = addr; + _is_ip_v6 = true; + _is_unspecified = false; } private: @@ -82,8 +87,8 @@ private: struct sockaddr_in6 _addr6; }; - bool _is_ip_v6{ false }; - bool _is_unspecified{ true }; + bool _is_ip_v6; + bool _is_unspecified; }; #endif diff --git a/sfw/core/socket.cpp b/sfw/core/socket.cpp index 08a705a..e3986dc 100755 --- a/sfw/core/socket.cpp +++ b/sfw/core/socket.cpp @@ -16,7 +16,7 @@ * */ -#ifndef _WIN32 +#if !defined(_WIN64) && !defined(_WIN32) #include #endif #include @@ -25,15 +25,17 @@ //http://www.virtsync.com/c-error-codes-include-errno #include -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) #include #else #include #include #endif +//--STRIP #include "core/error_macros.h" #include "core/ustring.h" +//--STRIP void Socket::create_net_socket() { create(AF_INET); @@ -47,16 +49,35 @@ void Socket::create(int family) { #endif } +void Socket::close_socket() { + if (!_socket) { + return; + } + +#if !defined(_WIN64) && !defined(_WIN32) + close(_socket); +#else + closesocket(_socket); +#endif + + _socket = 0; +} + // taken from muduo -void Socket::set_non_block_and_close_on_exit() { -#ifdef _WIN32 +int Socket::set_non_block_and_close_on_exit() { + ERR_FAIL_COND_V(_socket == 0, -1); + +#if defined(_WIN64) || defined(_WIN32) // TODO how to set FD_CLOEXEC on windows? is it necessary? u_long arg = 1; auto ret = ioctlsocket(_socket, (long)FIONBIO, &arg); if (ret) { - LOG_ERR("ioctlsocket error"); + //LOG_ERR("ioctlsocket error"); + return -1; } + + return 0; #else // non-block int flags = ::fcntl(_socket, F_GETFL, 0); @@ -70,16 +91,18 @@ void Socket::set_non_block_and_close_on_exit() { ret = ::fcntl(_socket, F_SETFD, flags); // TODO check - (void)ret; + return ret; #endif } int Socket::get_error() { + ERR_FAIL_COND_V(_socket == 0, -1); + int optval; socklen_t optlen = static_cast(sizeof optval); -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) if (::getsockopt(_socket, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen) < 0) #else if (::getsockopt(_socket, SOL_SOCKET, SO_ERROR, &optval, &optlen) < 0) @@ -92,6 +115,8 @@ int Socket::get_error() { } int Socket::connect(const InetAddress &addr) { + ERR_FAIL_COND_V(_socket == 0, -1); + if (addr.is_ip_v6()) { return ::connect(_socket, addr.get_sock_addr(), static_cast(sizeof(struct sockaddr_in6))); } else { @@ -100,6 +125,8 @@ int Socket::connect(const InetAddress &addr) { } bool Socket::is_self_connect() { + ERR_FAIL_COND_V(_socket == 0, false); + struct sockaddr_in6 localaddr = get_local_addr(); struct sockaddr_in6 peeraddr = get_peer_addr(); @@ -114,8 +141,8 @@ bool Socket::is_self_connect() { } } -void Socket::bind_address(const InetAddress &address) { - ERR_FAIL_COND(_socket == 0); +int Socket::bind_address(const InetAddress &address) { + ERR_FAIL_COND_V(_socket == 0, -1); int ret; if (address.is_ip_v6()) { @@ -125,24 +152,23 @@ void Socket::bind_address(const InetAddress &address) { } if (ret != 0) { -#ifdef _WIN32 - LOG_ERR("Bind address failed: " + address.to_ip_port() + " " + itos(WSAGetLastError())); +#if defined(_WIN64) || defined(_WIN32) + return WSAGetLastError(); #else - LOG_ERR("Bind address failed: " + address.to_ip_port() + " " + itos(errno)); + return errno; #endif } } -void Socket::listen() { - ERR_FAIL_COND(_socket == 0); +int Socket::listen() { + ERR_FAIL_COND_V(_socket == 0, -1); - int ret = ::listen(_socket, SOMAXCONN); - if (ret < 0) { - LOG_ERR("listen failed"); - } + return ::listen(_socket, SOMAXCONN); } int Socket::accept(Socket *sock) { + ERR_FAIL_COND_V(!sock, -1); + struct sockaddr_in6 addr6; memset(&addr6, 0, sizeof(addr6)); socklen_t size = sizeof(addr6); @@ -164,19 +190,20 @@ int Socket::accept(Socket *sock) { return connfd; } -void Socket::close_write() { -#ifndef _WIN32 - if (::shutdown(_socket, SHUT_WR) < 0) +int Socket::close_write() { + ERR_FAIL_COND_V(_socket == 0, -1); + +#if !defined(_WIN64) && !defined(_WIN32) + return ::shutdown(_socket, SHUT_WR); #else - if (::shutdown(_socket, SD_SEND) < 0) + return ::shutdown(_socket, SD_SEND); #endif - { - LOG_ERR("sockets::shutdownwrite"); - } } int Socket::read(char *buffer, uint64_t len) { -#ifndef _WIN32 + //ERR_FAIL_COND_V(_socket == 0, -1); + +#if !defined(_WIN64) && !defined(_WIN32) return ::read(_socket, buffer, len); #else return recv(_socket, buffer, static_cast(len), 0); @@ -184,7 +211,9 @@ int Socket::read(char *buffer, uint64_t len) { } int Socket::send(const char *buffer, uint64_t len) { -#ifndef _WIN32 + //ERR_FAIL_COND_V(_socket == 0, -1); + +#if !defined(_WIN64) && !defined(_WIN32) return write(_socket, buffer, len); #else errno = 0; @@ -193,7 +222,9 @@ int Socket::send(const char *buffer, uint64_t len) { } void Socket::set_tcp_nodelay(bool on) { -#ifdef _WIN32 + ERR_FAIL_COND(_socket == 0); + +#if defined(_WIN64) || defined(_WIN32) char optval = on ? 1 : 0; #else int optval = on ? 1 : 0; @@ -202,7 +233,9 @@ void Socket::set_tcp_nodelay(bool on) { } void Socket::set_reuse_addr(bool on) { -#ifdef _WIN32 + ERR_FAIL_COND(_socket == 0); + +#if defined(_WIN64) || defined(_WIN32) char optval = on ? 1 : 0; #else int optval = on ? 1 : 0; @@ -210,27 +243,32 @@ void Socket::set_reuse_addr(bool on) { ::setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, &optval, static_cast(sizeof optval)); } -void Socket::set_reuse_port(bool on) { +int Socket::set_reuse_port(bool on) { + ERR_FAIL_COND_V(_socket == 0, -1); + #ifdef SO_REUSEPORT -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) char optval = on ? 1 : 0; #else int optval = on ? 1 : 0; #endif int ret = ::setsockopt(_socket, SOL_SOCKET, SO_REUSEPORT, &optval, static_cast(sizeof optval)); - if (ret < 0 && on) { - LOG_ERR("SO_REUSEPORT failed."); - } + return ret; #else if (on) { - LOG_ERR("SO_REUSEPORT is not supported."); + //LOG_ERR("SO_REUSEPORT is not supported."); + return -1; } + + return 0; #endif } void Socket::set_keep_alive(bool on) { -#ifdef _WIN32 + ERR_FAIL_COND(_socket == 0); + +#if defined(_WIN64) || defined(_WIN32) char optval = on ? 1 : 0; #else int optval = on ? 1 : 0; @@ -238,32 +276,41 @@ void Socket::set_keep_alive(bool on) { ::setsockopt(_socket, SOL_SOCKET, SO_KEEPALIVE, &optval, static_cast(sizeof optval)); } -struct sockaddr_in6 Socket::get_local_addr() { +struct sockaddr_in6 Socket::get_local_addr(int *r_err) { struct sockaddr_in6 localaddr; + + ERR_FAIL_COND_V(_socket == 0, localaddr); + memset(&localaddr, 0, sizeof(localaddr)); socklen_t addrlen = static_cast(sizeof localaddr); - if (::getsockname(_socket, static_cast((void *)(&localaddr)), &addrlen) < 0) { - LOG_ERR("sockets::getLocalAddr"); + int err = ::getsockname(_socket, static_cast((void *)(&localaddr)), &addrlen); + + if (r_err) { + *r_err = err; } return localaddr; } -struct sockaddr_in6 Socket::get_peer_addr() { +struct sockaddr_in6 Socket::get_peer_addr(int *r_err) { struct sockaddr_in6 peeraddr; + ERR_FAIL_COND_V(_socket == 0, peeraddr); + memset(&peeraddr, 0, sizeof(peeraddr)); socklen_t addrlen = static_cast(sizeof peeraddr); - if (::getpeername(_socket, static_cast((void *)(&peeraddr)), &addrlen) < 0) { - LOG_ERR("sockets::getPeerAddr"); + int err = ::getpeername(_socket, static_cast((void *)(&peeraddr)), &addrlen); + + if (r_err) { + *r_err = err; } return peeraddr; } int Socket::global_init() { -#ifdef _WIN32 +#if defined(_WIN64) || defined(_WIN32) int r; WSADATA wsa_data; @@ -286,10 +333,6 @@ Socket::Socket(int socketFD, const InetAddress &address) { Socket::~Socket() { if (_socket >= 0) { -#ifndef _WIN32 - close(_socket); -#else - closesocket(_socket); -#endif + close_socket(); } } diff --git a/sfw/core/socket.h b/sfw/core/socket.h index 2ec623a..1138caf 100755 --- a/sfw/core/socket.h +++ b/sfw/core/socket.h @@ -17,48 +17,46 @@ * */ -#ifndef _WIN32 -#include -#endif -#include - #include "inet_address.h" -class Socket -{ +class Socket { public: - void create_net_socket(); - void create(int family); - void set_non_block_and_close_on_exit(); - int get_error(); - int connect(const InetAddress &address); - bool is_self_connect(); - void bind_address(const InetAddress &address); - void listen(); - int accept(Socket *sock); - void close_write(); - int read(char *buffer, uint64_t len); - int send(const char *buffer, uint64_t len); + void create_net_socket(); + void create(int family); + void close_socket(); - void set_tcp_nodelay(bool on); - void set_reuse_addr(bool on); - void set_reuse_port(bool on); - void set_keep_alive(bool on); + int connect(const InetAddress &address); + int bind_address(const InetAddress &address); + int listen(); + int accept(Socket *sock); - struct sockaddr_in6 get_local_addr(); - struct sockaddr_in6 get_peer_addr(); + int close_write(); - static int global_init(); + int read(char *buffer, uint64_t len); + int send(const char *buffer, uint64_t len); - Socket(); - Socket(int socketFD, const InetAddress &address); - ~Socket(); + bool is_self_connect(); - int _socket; - InetAddress _address; + void set_tcp_nodelay(bool on); + void set_reuse_addr(bool on); + int set_reuse_port(bool on); + void set_keep_alive(bool on); + + int set_non_block_and_close_on_exit(); + + int get_error(); + + struct sockaddr_in6 get_local_addr(int *r_err = NULL); + struct sockaddr_in6 get_peer_addr(int *r_err = NULL); + + static int global_init(); + + Socket(); + Socket(int socketFD, const InetAddress &address); + ~Socket(); + + int _socket; + InetAddress _address; }; - #endif // SOCKET_H - -