#include "Flatline.h" #include "Flatline_Server.h" #define TRACK_PACKETS /*thread */int UDPServer_Socket = 0; bool NetUDPServer_Listen(uint16_t port, bool (*packet_callback)(char* data, int datalen, int from)) { sockaddr_in address; UDPServer_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (UDPServer_Socket < 0) { DDrConsole_PrintF("could not create socket"); return false; } memset(&address, 0, sizeof(sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(port); if (bind(UDPServer_Socket, (sockaddr*)&address, sizeof(sockaddr_in)) < 0) { DDrConsole_PrintF("could not bind port %d", port); closesocket(UDPServer_Socket); return false; } else { char data[65537] = {0}; sockaddr_in from; int recvlen; FLrServer_Initialize(); for (;;) { int fromlen = sizeof(sockaddr_in); memset(&from, 0, sizeof(sockaddr_in)); recvlen = recvfrom(UDPServer_Socket, data, 65537 - 1, 0, (sockaddr*)&from, (void*)&fromlen); if (!packet_callback(data, recvlen, ntohl(from.sin_addr.s_addr))) break; } closesocket(UDPServer_Socket); return true; } } bool NetUDPServer_Send(sockaddr* address, flatline_packet* data, int datalen) { //DDrConsole_PrintF("Sending data size %u to %s on socket %i", datalen, inet_ntoa( ((sockaddr_in*)address)->sin_addr ), UDPServer_Socket); data->FLATLINE = *(int*)"FLATLINE"; return NetUDPSocket_Send(UDPServer_Socket, address, data, datalen); } int client_sock = 0; sockaddr_in client_address; int NetUDPSocket_Create(uint16_t port) { int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in address; unsigned long nonBlocking = 1; if (sock < 0) { DDrConsole_PrintF("could not create socket"); return -1; } memset(&client_address, 0, sizeof(sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(port); if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0) { DDrConsole_PrintF("could not bind port %d", port); return false; } if (ioctlsocket(sock, FIONBIO, &nonBlocking)) { DDrConsole_PrintF("failed to set non-blocking socket"); return false; } client_sock = sock; client_address = address; return sock; } int NetTCPSocket_Create(uint16_t port) { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in address; unsigned long nonBlocking = 1; if (sock < 0) { DDrConsole_PrintF("could not create socket"); return -1; } memset(&client_address, 0, sizeof(sockaddr_in)); address.sin_family = AF_INET; address.sin_addr.s_addr = htonl(INADDR_ANY); address.sin_port = htons(port); if (bind(sock, (sockaddr*)&address, sizeof(sockaddr_in)) < 0) { DDrConsole_PrintF("could not bind port %d", port); return false; } if (ioctlsocket(sock, FIONBIO, &nonBlocking)) { DDrConsole_PrintF("failed to set non-blocking socket"); return false; } client_sock = sock; client_address = address; return sock; } void NetUDPSocket_Close(int socket) { closesocket(socket); } int NetUDPSocket_Send(int socket, const sockaddr* address, flatline_packet* data, int datalen) { //currently only protects against duplicate packets. int addr_size; #ifdef TRACK_PACKETS static uint32_t packet_index = 0; packet_index = (packet_index + 1); data->packet_index = packet_index; #endif data->FLATLINE = *(int*)"FLATLINE"; switch (address->sa_family) { case AF_INET: addr_size = sizeof(sockaddr_in); break; case AF_INET6: addr_size = sizeof(sockaddr_in6); break; default: addr_size = sizeof(sockaddr_storage); } return sendto(socket, data, datalen, 0, address, addr_size); } #ifdef TRACK_PACKETS uint32_t last_packet = -1; #endif bool NetUDPSocket_Recieve(int socket, sockaddr_storage* address, char* data, uint16_t* datalen) { int address_size = sizeof(sockaddr_storage); uint32_t msg_size = recvfrom(socket, data, 1400, 0, (SOCKADDR *)address, &address_size); if (msg_size == 0) return false; else if (msg_size == SOCKET_ERROR) { int errorno = WSAGetLastError(); if (errorno == WSAEWOULDBLOCK) return false; //no packets. else { //DDrConsole_PrintF("Packet type %i", ((flatline_packet*)data)->id); NetCatchError(); return false; } } /* #ifdef TRACK_PACKETS if(client_connected && !server_started) { uint32_t index_mkr = ((flatline_packet*)(data))->packet_index; //fancy way of checking if index_mkr is on one side of the max size of an int and last_packet is on the other if( ((index_mkr - last_packet < 0x80000000) && (index_mkr > last_packet)) //if it is, subtract half the size of an int from each. ^_^ || ((index_mkr - 0x80000000) > (last_packet - 0x80000000) ) ) { return false; } else { last_packet = index_mkr; } } #endif */ *datalen = msg_size; return true; } DWORD WINAPI StartServer(void* lol){ NetPlatform_Initalize(); FLrServer_Run(); return 0; } DWORD WINAPI StartClient(void* lol){ //NetPlatform_Initalize(); FLrClient_Run((flatline_packet*)lol); return 0; } void NetCatchError(){ char Message[1024]; int errorno = WSAGetLastError(); if(errno == WSAEWOULDBLOCK) { return; } #ifdef WIN32 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) Message, 1024, NULL); DDrConsole_Print(Message); #endif }