v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
157
source/core/StarNetImpl.hpp
Normal file
157
source/core/StarNetImpl.hpp
Normal file
|
@ -0,0 +1,157 @@
|
|||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdio.h>
|
||||
#else
|
||||
#ifdef STAR_SYSTEM_FREEBSD
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include "StarHostAddress.hpp"
|
||||
|
||||
#ifndef AI_ADDRCONFIG
|
||||
#define AI_ADDRCONFIG 0
|
||||
#endif
|
||||
|
||||
namespace Star {
|
||||
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
struct WindowsSocketInitializer {
|
||||
WindowsSocketInitializer() {
|
||||
WSADATA wsaData;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
fatalError("WSAStartup failed", false);
|
||||
};
|
||||
};
|
||||
static WindowsSocketInitializer g_windowsSocketInitializer;
|
||||
#endif
|
||||
|
||||
inline String netErrorString() {
|
||||
#ifdef STAR_SYSTEM_WINDOWS
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
WSAGetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
String result = String((char*)lpMsgBuf);
|
||||
|
||||
if (lpMsgBuf != NULL)
|
||||
LocalFree(lpMsgBuf);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return strf("%s - %s", errno, strerror(errno));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool netErrorConnectionReset() {
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
return WSAGetLastError() == WSAECONNRESET || WSAGetLastError() == WSAENETRESET;
|
||||
#else
|
||||
return errno == ECONNRESET || errno == ETIMEDOUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool netErrorInterrupt() {
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
return WSAGetLastError() == WSAEINTR || WSAGetLastError() == WSAEWOULDBLOCK;
|
||||
#else
|
||||
return errno == EAGAIN || errno == EINTR || errno == EWOULDBLOCK;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void setAddressFromNative(HostAddressWithPort& addressWithPort, NetworkMode mode, struct sockaddr_storage* sockAddr) {
|
||||
switch (mode) {
|
||||
case NetworkMode::IPv4: {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)sockAddr;
|
||||
addressWithPort = HostAddressWithPort(mode, (uint8_t*)&(addr4->sin_addr.s_addr), ntohs(addr4->sin_port));
|
||||
break;
|
||||
}
|
||||
case NetworkMode::IPv6: {
|
||||
struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sockAddr;
|
||||
addressWithPort = HostAddressWithPort(mode, (uint8_t*)&addr6->sin6_addr.s6_addr, ntohs(addr6->sin6_port));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw NetworkException("Invalid network mode for setAddressFromNative");
|
||||
}
|
||||
}
|
||||
|
||||
inline void setNativeFromAddress(HostAddressWithPort const& addressWithPort, struct sockaddr_storage* sockAddr, socklen_t* sockAddrLen) {
|
||||
switch (addressWithPort.address().mode()) {
|
||||
case NetworkMode::IPv4: {
|
||||
struct sockaddr_in* addr4 = (struct sockaddr_in*)sockAddr;
|
||||
*sockAddrLen = sizeof(*addr4);
|
||||
|
||||
memset(addr4, 0, *sockAddrLen);
|
||||
addr4->sin_family = AF_INET;
|
||||
addr4->sin_port = htons(addressWithPort.port());
|
||||
memcpy(((char*)&addr4->sin_addr.s_addr), addressWithPort.address().bytes(), addressWithPort.address().size());
|
||||
|
||||
break;
|
||||
}
|
||||
case NetworkMode::IPv6: {
|
||||
struct sockaddr_in6* addr6 = (struct sockaddr_in6*)sockAddr;
|
||||
*sockAddrLen = sizeof(*addr6);
|
||||
|
||||
memset(addr6, 0, *sockAddrLen);
|
||||
addr6->sin6_family = AF_INET6;
|
||||
addr6->sin6_port = htons(addressWithPort.port());
|
||||
memcpy(((char*)&addr6->sin6_addr.s6_addr), addressWithPort.address().bytes(), addressWithPort.address().size());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw NetworkException("Invalid network mode for setNativeFromAddress");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
inline bool invalidSocketDescriptor(SOCKET socket) {
|
||||
return socket == INVALID_SOCKET;
|
||||
}
|
||||
#else
|
||||
inline bool invalidSocketDescriptor(int socket) {
|
||||
return socket < 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct SocketImpl {
|
||||
SocketImpl() {
|
||||
socketDesc = 0;
|
||||
}
|
||||
|
||||
void setSockOpt(int level, int optname, const void* optval, socklen_t len) {
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
int ret = ::setsockopt(socketDesc, level, optname, (const char*)optval, len);
|
||||
#else
|
||||
int ret = ::setsockopt(socketDesc, level, optname, optval, len);
|
||||
#endif
|
||||
if (ret < 0)
|
||||
throw NetworkException(strf("setSockOpt failed to set %d, %d: %s", level, optname, netErrorString()));
|
||||
}
|
||||
|
||||
#ifdef STAR_SYSTEM_FAMILY_WINDOWS
|
||||
SOCKET socketDesc;
|
||||
#else
|
||||
int socketDesc;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue