#include "Flatline.h" #include "Flatline_Server.h" #define TRACK_PACKETS /*thread */int UDPServer_Socket = 0; unsigned char NetUDPServer_Listen(uint16_t port, unsigned char (*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; } } unsigned char NetUDPServer_Send(sockaddr* address, char* 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, sockaddr_in* address) { int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 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; return sock; } int NetTCPSocket_Create(uint16_t port, sockaddr_in* address) { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); unsigned long nonBlocking = 0; 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 = 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; return sock; } void NetUDPSocket_Close(int socket) { closesocket(socket); } int NetUDPSocket_Send(int socket, const sockaddr* address, char* data, int datalen) { //currently only protects against duplicate packets. int addr_size; int sent_bytes; #if 0 //#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); } sent_bytes = sendto(socket, data, datalen, 0, address, addr_size); if(sent_bytes == SOCKET_ERROR) { NetCatchError(); } return sent_bytes; } #ifdef TRACK_PACKETS uint32_t last_packet = -1; #endif unsigned char 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; } } *datalen = msg_size; return true; } DWORD WINAPI StartServer(void* lol){ if(NetPlatform_Initalize() && FlatlineInitialize()) { FLrServer_Run(); } return 0; } DWORD WINAPI StartClient(void* lol){ //NetPlatform_Initalize(); if(FlatlineInitialize()) { 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 }