int32_t OsNetworkReceive(THandle aHandle, uint8_t* aBuffer, uint32_t aBytes) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } SetFdNonBlocking(handle->iSocket); fd_set read; FD_ZERO(&read); FD_SET(handle->iPipe[0], &read); FD_SET(handle->iSocket, &read); fd_set error; FD_ZERO(&error); FD_SET(handle->iSocket, &error); int32_t received = TEMP_FAILURE_RETRY_2(recv(handle->iSocket, aBuffer, aBytes, MSG_NOSIGNAL), handle); if (received==-1 && errno==EWOULDBLOCK) { int32_t selectErr = TEMP_FAILURE_RETRY_2(select(nfds(handle), &read, NULL, &error, NULL), handle); if (selectErr > 0 && FD_ISSET(handle->iSocket, &read)) { received = TEMP_FAILURE_RETRY_2(recv(handle->iSocket, aBuffer, aBytes, MSG_NOSIGNAL), handle); } } SetFdBlocking(handle->iSocket); return received; }
int32_t OsNetworkReceiveFrom(THandle aHandle, uint8_t* aBuffer, uint32_t aBytes, TIpAddress* aAddress, uint16_t* aPort) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } struct sockaddr_in addr; sockaddrFromEndpoint(&addr, 0, 0); socklen_t addrLen = sizeof(addr); SetFdNonBlocking(handle->iSocket); fd_set read; FD_ZERO(&read); FD_SET(handle->iPipe[0], &read); FD_SET(handle->iSocket, &read); fd_set error; FD_ZERO(&error); FD_SET(handle->iSocket, &error); int32_t received = TEMP_FAILURE_RETRY_2(recvfrom(handle->iSocket, aBuffer, aBytes, MSG_NOSIGNAL, (struct sockaddr*)&addr, &addrLen), handle); if (received==-1 && errno==EWOULDBLOCK) { int32_t selectErr = TEMP_FAILURE_RETRY_2(select(nfds(handle), &read, NULL, &error, NULL), handle); if (selectErr > 0 && FD_ISSET(handle->iSocket, &read)) { received = TEMP_FAILURE_RETRY_2(recvfrom(handle->iSocket, aBuffer, aBytes, MSG_NOSIGNAL, (struct sockaddr*)&addr, &addrLen), handle); } } SetFdBlocking(handle->iSocket); *aAddress = addr.sin_addr.s_addr; *aPort = ntohs(addr.sin_port); return received; }
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; }
int32_t OsNetworkListen(THandle aHandle, uint32_t aSlots) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } int32_t err = listen(handle->iSocket, aSlots); 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 OsNetworkPort(THandle aHandle, uint32_t* aPort) { int32_t err; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } struct sockaddr_in addr; socklen_t len = sizeof(addr); err = getsockname(handle->iSocket, (struct sockaddr*)&addr, &len); if (err == 0) { uint16_t port = ntohs(addr.sin_port); *aPort = port; } return err; }
int32_t OsNetworkSend(THandle aHandle, const uint8_t* aBuffer, uint32_t aBytes) { int32_t sent = 0; int32_t bytes = 0; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } do { bytes = send(handle->iSocket, (const char*)aBuffer, aBytes, 0); if (bytes != -1) { sent += bytes; } } while(bytes != -1 && sent < (int32_t)aBytes); return sent; }
int32_t OsNetworkSend(THandle aHandle, const uint8_t* aBuffer, uint32_t aBytes) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } int32_t sent = 0; int32_t bytes = 0; do { bytes = TEMP_FAILURE_RETRY_2(send(handle->iSocket, &aBuffer[sent], aBytes-sent, MSG_NOSIGNAL), handle); if (bytes != -1) { sent += bytes; } } while(bytes != -1 && sent < (int32_t)aBytes); return sent; }
int32_t OsNetworkSendTo(THandle aHandle, const uint8_t* aBuffer, uint32_t aBytes, TIpAddress aAddress, uint16_t aPort) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } struct sockaddr_in addr; sockaddrFromEndpoint(&addr, aAddress, aPort); int32_t sent = 0; int32_t bytes = 0; do { bytes = TEMP_FAILURE_RETRY_2(sendto(handle->iSocket, &aBuffer[sent], aBytes-sent, MSG_NOSIGNAL, (struct sockaddr*)&addr, sizeof(addr)), handle); if (bytes != -1) { sent += bytes; } } while(bytes != -1 && sent < (int32_t)aBytes); return sent; }
int32_t OsNetworkSendTo(THandle aHandle, const uint8_t* aBuffer, uint32_t aBytes, TIpAddress aAddress, uint16_t aPort) { int32_t sent = 0; int32_t bytes = 0; struct sockaddr_in addr; OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } sockaddrFromEndpoint(&addr, aAddress, aPort); do { bytes = sendto(handle->iSocket, (const char*)aBuffer, aBytes, 0, (struct sockaddr*)&addr, sizeof(addr)); if (bytes != -1) { sent += bytes; } } while(bytes != -1 && sent < (int32_t)aBytes); return sent; }
THandle OsNetworkAccept(THandle aHandle, TIpAddress* aClientAddress, uint32_t* aClientPort) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; *aClientAddress = 0; *aClientPort = 0; if (SocketInterrupted(handle)) { return kHandleNull; } struct sockaddr_in addr; sockaddrFromEndpoint(&addr, 0, 0); socklen_t len = sizeof(addr); SetFdNonBlocking(handle->iSocket); fd_set read; FD_ZERO(&read); FD_SET(handle->iPipe[0], &read); FD_SET(handle->iSocket, &read); fd_set error; FD_ZERO(&error); FD_SET(handle->iSocket, &error); int32_t h = TEMP_FAILURE_RETRY_2(accept(handle->iSocket, (struct sockaddr*)&addr, &len), handle); if (h==-1 && errno==EWOULDBLOCK) { int32_t selectErr = TEMP_FAILURE_RETRY_2(select(nfds(handle), &read, NULL, &error, NULL), handle); if (selectErr > 0 && FD_ISSET(handle->iSocket, &read)) { h = TEMP_FAILURE_RETRY_2(accept(handle->iSocket, (struct sockaddr*)&addr, &len), handle); } } SetFdBlocking(handle->iSocket); if (h == -1) { return kHandleNull; } OsNetworkHandle* newHandle = CreateHandle(handle->iCtx, h); if (newHandle == NULL) { close(h); return kHandleNull; } *aClientAddress = addr.sin_addr.s_addr; *aClientPort = ntohs(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 adapterChangeObserverThread(void* aPtr) { InterfaceChangedObserver* observer = (InterfaceChangedObserver*) aPtr; OsNetworkHandle *handle = observer->netHnd; char buffer[4096]; struct nlmsghdr *nlh; int32_t len, ret; fd_set rfds,errfds; while (1) { if (SocketInterrupted(handle)) { return; } FD_ZERO(&rfds); FD_SET(handle->iPipe[0], &rfds); FD_SET(handle->iSocket, &rfds); FD_ZERO(&errfds); FD_SET(handle->iSocket, &errfds); ret = TEMP_FAILURE_RETRY_2(select(nfds(handle), &rfds, NULL, &errfds, NULL), handle); if ((ret > 0) && FD_ISSET(handle->iSocket, &rfds)) { nlh = (struct nlmsghdr *) buffer; if ((len = recv(handle->iSocket, nlh, 4096, 0)) > 0) { while (NLMSG_OK(nlh, len) && (nlh->nlmsg_type != NLMSG_DONE)) { if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR || nlh->nlmsg_type == RTM_NEWLINK) { observer->iCallback(observer->iArg); } nlh = NLMSG_NEXT(nlh, len); } } } } }
int32_t OsNetworkConnect(THandle aHandle, TIpAddress aAddress, uint16_t aPort, uint32_t aTimeoutMs) { OsNetworkHandle* handle = (OsNetworkHandle*)aHandle; if (SocketInterrupted(handle)) { return -1; } int32_t err = -1; SetFdNonBlocking(handle->iSocket); struct sockaddr_in addr; sockaddrFromEndpoint(&addr, aAddress, aPort); /* ignore err as we expect this to fail due to EINPROGRESS */ (void)connect(handle->iSocket, (struct sockaddr*)&addr, sizeof(addr)); fd_set read; FD_ZERO(&read); FD_SET(handle->iPipe[0], &read); fd_set write; FD_ZERO(&write); FD_SET(handle->iSocket, &write); fd_set error; FD_ZERO(&error); FD_SET(handle->iSocket, &error); struct timeval tv; tv.tv_sec = aTimeoutMs / 1000; tv.tv_usec = (aTimeoutMs % 1000) * 1000; int32_t selectErr = TEMP_FAILURE_RETRY_2(select(nfds(handle), &read, &write, &error, &tv), handle); if (selectErr > 0 && FD_ISSET(handle->iSocket, &write)) { err = 0; } SetFdBlocking(handle->iSocket); return err; }