int32_t NTServerManager::NT_SendTo(void *Socket, const char *Buffer, int32_t BufferLength, int32_t Flags, const sockaddr *Peer, int32_t PeerLength) { IServer *Server = FindServerBySocket(Socket); int32_t BytesSent = -1; if (Server != nullptr) { // Emplace the server. Host_ConnectedSockets[Socket] = Server; memcpy(Server->LocalStorage, Peer, sizeof(sockaddr)); nDebugPrint("%s to \"%s\", %i bytes.", __func__, Server->Hostname, BufferLength); return Server->Platform_Send((uint8_t *)Buffer, BufferLength, Socket); } else { nDebugPrint("%s via %p, %i bytes.", __func__, Socket, BufferLength); return sendto((SOCKET)Socket, Buffer, BufferLength, Flags, Peer, PeerLength); } }
int32_t NTServerManager::NT_CloseSocket(void *Socket) { IServer *Server = FindServerBySocket(Socket); if (Server != nullptr) { nDebugPrint("%s for server \"%s\"", __func__, Server->Hostname); Host_ConnectedSockets.erase(Socket); Server->Platform_Disconnect(Socket); } return closesocket((SOCKET)Socket); }
int32_t NTServerManager::NT_Connect(void *Socket, const sockaddr *Address, int32_t AddressLength) { if (AddressLength == sizeof(sockaddr_in)) { sockaddr_in *IPAddress = (sockaddr_in *)Address; IServer *Server = FindServerByAddress(IPAddress->sin_addr.s_addr); // Connect to a local server. if (Server != nullptr) { Host_ConnectedSockets[Socket] = Server; Server->Platform_Connect(Socket, (void *)Address, AddressLength); if (!Host_SocketBlockStatus[Socket]) { return 0; } } // Replace the port if it's on localhost. if (IPAddress->sin_addr.s_addr == inet_addr("127.0.0.1")) { auto Iterator = Host_ProxyPorts.find(ntohs(((sockaddr_in *)Address)->sin_port)); if (Iterator != Host_ProxyPorts.end()) { nDebugPrint("%s replaces port %u with %u", __func__, ntohs(((sockaddr_in *)Address)->sin_port), Iterator->second); ((sockaddr_in *)Address)->sin_port = htons(Iterator->second); } } nDebugPrint("%s to address %s:%u on socket %p", __func__, inet_ntoa(((sockaddr_in *)Address)->sin_addr), ntohs(((sockaddr_in *)Address)->sin_port), Socket); } return connect((SOCKET)Socket, Address, AddressLength); }
// Network helpers. void InitializeWinsock() { static bool WinsockInitialized = false; if (!WinsockInitialized) { WSADATA wsaData; int Result = WSAStartup(MAKEWORD(2, 2), &wsaData); const char *ErrorString; if (Result != 0) { switch (Result) { case WSASYSNOTREADY: ErrorString = "WSA system is not ready for networking."; break; case WSAVERNOTSUPPORTED: ErrorString = "WSA system does not support version (2.2)."; break; case WSAEINPROGRESS: ErrorString = "WSA is busy with a blocking socket."; break; case WSAEPROCLIM: ErrorString = "Too many processes are using WSA right now."; break; case WSAEFAULT: ErrorString = "Invalid argument data."; break; default: ErrorString = va("Unknown error %d.", Result); } nDebugPrint("WSA failed for reason: %s", ErrorString); } else { WinsockInitialized = true; } } }
int32_t NTServerManager::NT_IOControlSocket(void *Socket, uint32_t Command, u_long *ArgumentPointer) { const char *ReadableCommand = "UNKNOWN"; switch (Command) { case FIONBIO: ReadableCommand = "FIONBIO"; // Set the blocking status. Host_SocketBlockStatus[Socket] = *ArgumentPointer == 0; break; case FIONREAD: ReadableCommand = "FIONREAD"; break; case FIOASYNC: ReadableCommand = "FIOASYNC"; break; case SIOCSHIWAT: ReadableCommand = "SIOCSHIWAT"; break; case SIOCGHIWAT: ReadableCommand = "SIOCGHIWAT"; break; case SIOCSLOWAT: ReadableCommand = "SIOCSLOWAT"; break; case SIOCGLOWAT: ReadableCommand = "SIOCGLOWAT"; break; case SIOCATMARK: ReadableCommand = "SIOCATMARK"; break; } nDebugPrint("%s on socket %p with command \"%s\"", __func__, Socket, ReadableCommand); return ioctlsocket((SOCKET)Socket, Command, ArgumentPointer); }