#ifdef _WIN32 #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0600 #endif #include #include #else #include #include #include #include #include #include #include #include #include #endif #include #include int checkError(int in) { // TODO: Print the error here. return in; } void startup() { #ifdef _WIN32 WSADATA d; if (WSAStartup(MAKEWORD(2, 2), &d)) { fprintf(stderr, "Failed to initialize.\n"); } #endif } int init(unsigned short localPort) { int socketID = checkError(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); if(socketID == -1) return -1; struct sockaddr_in bindingAddr; bindingAddr.sin_family = AF_INET; bindingAddr.sin_port = htons(localPort); bindingAddr.sin_addr.s_addr = INADDR_ANY; memset(&bindingAddr.sin_zero, 0, 8); if(checkError(bind(socketID, (const struct sockaddr*)&bindingAddr, sizeof(bindingAddr))) == -1) { #ifdef _WIN32 closesocket(socketID); #else close(socketID); #endif return -1; }; return socketID; } int deinit(int socketID) { #ifdef _WIN32 return checkError(closesocket(socketID)); #else return checkError(close(socketID)); #endif } int sendTo(int socketID, const char* data, uintptr_t size, uint32_t ip, uint16_t port) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = ip; memset(&addr.sin_zero, 0, 8); return checkError(sendto(socketID, data, size, 0, (const struct sockaddr*)&addr, sizeof(addr))); } intptr_t receiveFrom(int socketID, char* buffer, uintptr_t size, int timeout, uint32_t* resultIP, uint16_t* resultPort) { struct pollfd pfd = {.fd = socketID, .events = POLLIN}; #ifdef _WIN32 intptr_t result = checkError(WSAPoll(&pfd, 1, timeout)); #else intptr_t result = checkError(poll(&pfd, 1, timeout)); #endif if(result <= 0) return result; struct sockaddr_in address; uint32_t addrLen = sizeof(address); result = checkError(recvfrom(socketID, buffer, size, 0, (struct sockaddr *)&address, &addrLen)); *resultIP = address.sin_addr.s_addr; *resultPort = ntohs(address.sin_port); return result; } uint32_t resolveIP(const char* address) { struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; struct addrinfo* res; int result = getaddrinfo(address, NULL, &hints, &res); if(result != 0) { errno = result; return 0xffffffff; } uint32_t ip = ((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr; freeaddrinfo(res); return ip; } int getError() { return errno; }