int32_t OsNetworkReceive(THandle aHandle, uint8_t* aBuffer, uint32_t aBytes) { int32_t received; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; WSAEVENT event; HANDLE handles[2]; DWORD ret; if (SocketInterrupted(handle)) { return -1; } event = WSACreateEvent(); if (NULL == event) { return -1; } if (0 != WSAEventSelect(handle->iSocket, event, FD_READ|FD_CLOSE)) { WSACloseEvent(event); return -1; } received = recv(handle->iSocket, (char*)aBuffer, aBytes, 0); if (SOCKET_ERROR==received && WSAEWOULDBLOCK==WSAGetLastError()) { handles[0] = event; handles[1] = handle->iEvent; ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, INFINITE, FALSE); if (WAIT_OBJECT_0 == ret) { received = recv(handle->iSocket, (char*)aBuffer, aBytes, 0); } } SetSocketBlocking(handle->iSocket); WSACloseEvent(event); return received; }
int32_t OsNetworkConnect(THandle aHandle, TIpAddress aAddress, uint16_t aPort, uint32_t aTimeoutMs) { int32_t err = -1; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; struct sockaddr_in addr; WSAEVENT event; HANDLE handles[2]; DWORD ret; if (SocketInterrupted(handle)) { return -1; } event = WSACreateEvent(); if (NULL == event) { return -1; } if (0 != WSAEventSelect(handle->iSocket, event, FD_CONNECT|FD_WRITE)) { WSACloseEvent(event); return -1; } sockaddrFromEndpoint(&addr, aAddress, aPort); (void)connect(handle->iSocket, (struct sockaddr*)&addr, sizeof(addr)); handles[0] = event; handles[1] = handle->iEvent; ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, aTimeoutMs, FALSE); if (WAIT_OBJECT_0 == ret) { err = 0; } SetSocketBlocking(handle->iSocket); WSACloseEvent(event); return err; }
THandle OsNetworkAccept(THandle aHandle, TIpAddress* aClientAddress, uint32_t* aClientPort) { SOCKET h; OsNetworkHandle* newHandle; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; WSAEVENT event; HANDLE handles[2]; DWORD ret; struct sockaddr_in addr; socklen_t len = sizeof(addr); *aClientAddress = 0; *aClientPort = 0; if (SocketInterrupted(handle)) { return kHandleNull; } sockaddrFromEndpoint(&addr, 0, 0); event = WSACreateEvent(); if (NULL == event) { return kHandleNull; } if (0 != WSAEventSelect(handle->iSocket, event, FD_ACCEPT|FD_CLOSE)) { WSACloseEvent(event); return kHandleNull; } h = accept(handle->iSocket, (struct sockaddr*)&addr, &len); if (INVALID_SOCKET==h && WSAEWOULDBLOCK==WSAGetLastError()) { handles[0] = event; handles[1] = handle->iEvent; ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, INFINITE, FALSE); if (WAIT_OBJECT_0 == ret) { h = accept(handle->iSocket, (struct sockaddr*)&addr, &len); } } SetSocketBlocking(handle->iSocket); WSACloseEvent(event); if (INVALID_SOCKET == h) { return kHandleNull; } newHandle = CreateHandle(handle->iCtx, h); if (NULL == newHandle) { return kHandleNull; } *aClientAddress = addr.sin_addr.s_addr; *aClientPort = SwapEndian16(addr.sin_port); return (THandle)newHandle; }
int32_t OsNetworkReceiveFrom(THandle aHandle, uint8_t* aBuffer, uint32_t aBytes, TIpAddress* aAddress, uint16_t* aPort) { int32_t received; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; struct sockaddr_in addr; int len = sizeof(addr); WSAEVENT event; HANDLE handles[2]; DWORD ret; if (SocketInterrupted(handle)) { return -1; } sockaddrFromEndpoint(&addr, 0, 0); event = WSACreateEvent(); if (NULL == event) { return -1; } if (0 != WSAEventSelect(handle->iSocket, event, FD_READ|FD_CLOSE)) { WSACloseEvent(event); return -1; } received = recvfrom(handle->iSocket, (char*)aBuffer, aBytes, 0, (struct sockaddr*)&addr, &len); if (SOCKET_ERROR==received && WSAEWOULDBLOCK==WSAGetLastError()) { handles[0] = event; handles[1] = handle->iEvent; ret = WSAWaitForMultipleEvents(2, &handles[0], FALSE, INFINITE, FALSE); if (WAIT_OBJECT_0 == ret) { received = recvfrom(handle->iSocket, (char*)aBuffer, aBytes, 0, (struct sockaddr*)&addr, &len); } } SetSocketBlocking(handle->iSocket); WSACloseEvent(event); *aAddress = addr.sin_addr.s_addr; *aPort = SwapEndian16(addr.sin_port); return received; }
void OsNetworkSetInterfaceChangedObserver(InterfaceListChanged aCallback, void* aArg) { if (NULL != gInterfaceChangeObserver) { return; } gInterfaceChangeObserver = (InterfaceChangeObserver*)malloc(sizeof(*gInterfaceChangeObserver)); if (NULL == gInterfaceChangeObserver) { return; } gInterfaceChangeObserver->iSocket = socket(AF_INET, SOCK_DGRAM, 0); SetSocketBlocking(gInterfaceChangeObserver->iSocket); gInterfaceChangeObserver->iEvent = WSACreateEvent(); gInterfaceChangeObserver->iShutdownEvent = WSACreateEvent(); gInterfaceChangeObserver->iCallback = aCallback; gInterfaceChangeObserver->iArg = aArg; gInterfaceChangeObserver->iShutdown = 0; gInterfaceChangeObserver->iSem = CreateSemaphore(NULL, 0, INT32_MAX, NULL); (void)WSAEventSelect(gInterfaceChangeObserver->iSocket, gInterfaceChangeObserver->iEvent, FD_ADDRESS_LIST_CHANGE); (void)CreateThread(NULL, 16*1024, (LPTHREAD_START_ROUTINE)&interfaceChangeThread, gInterfaceChangeObserver, 0, NULL); }
void OsNetworkSetInterfaceChangedObserver(OsContext* aContext, InterfaceListChanged aCallback, void* aArg) { InterfaceChangeObserver* icobs; if (NULL != aContext->iInterfaceChangeObserver) { return; } icobs = (InterfaceChangeObserver*)malloc(sizeof(InterfaceChangeObserver)); if (NULL == icobs) { return; } icobs->iSocket = socket(AF_INET, SOCK_DGRAM, 0); SetSocketBlocking(icobs->iSocket); icobs->iEvent = WSACreateEvent(); icobs->iShutdownEvent = WSACreateEvent(); icobs->iCallback = aCallback; icobs->iArg = aArg; icobs->iShutdown = 0; icobs->iSem = CreateSemaphore(NULL, 0, INT32_MAX, NULL); (void)WSAEventSelect(icobs->iSocket, icobs->iEvent, FD_ADDRESS_LIST_CHANGE); (void)CreateThread(NULL, 16*1024, (LPTHREAD_START_ROUTINE)&interfaceChangeThread, icobs, 0, NULL); aContext->iInterfaceChangeObserver = icobs; }