From c00f4e15ae715be72517920ee80494f894e339ee Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 1 Jul 2021 22:10:46 -0500 Subject: [PATCH] Use poll() instead of SO_RCVTIMEO for RTSP timeout support poll() is more portable than SO_RCVTIMEO --- src/PlatformSockets.c | 18 ------------------ src/PlatformSockets.h | 1 - src/RtspConnection.c | 17 ++++++++++++++++- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/PlatformSockets.c b/src/PlatformSockets.c index 13fce7e..01c0c10 100644 --- a/src/PlatformSockets.c +++ b/src/PlatformSockets.c @@ -77,24 +77,6 @@ int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs) { #endif } -void setRecvTimeout(SOCKET s, int timeoutSec) { -#ifdef __WIIU__ - // timeouts aren't supported on Wii U -#else -#if defined(LC_WINDOWS) - int val = timeoutSec * 1000; -#else - struct timeval val; - val.tv_sec = timeoutSec; - val.tv_usec = 0; -#endif - - if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&val, sizeof(val)) < 0) { - Limelog("setsockopt(SO_RCVTIMEO) failed: %d\n", (int)LastSocketError()); - } -#endif -} - int pollSockets(struct pollfd* pollFds, int pollFdsCount, int timeoutMs) { #if defined(LC_WINDOWS) || defined(__vita__) // We could have used WSAPoll() but it has some nasty bugs diff --git a/src/PlatformSockets.h b/src/PlatformSockets.h index 9620874..605cb1e 100644 --- a/src/PlatformSockets.h +++ b/src/PlatformSockets.h @@ -99,7 +99,6 @@ int setSocketNonBlocking(SOCKET s, bool enabled); int recvUdpSocket(SOCKET s, char* buffer, int size, bool useSelect); void shutdownTcpSocket(SOCKET s); int setNonFatalRecvTimeoutMs(SOCKET s, int timeoutMs); -void setRecvTimeout(SOCKET s, int timeoutSec); void closeSocket(SOCKET s); bool isPrivateNetworkAddress(struct sockaddr_storage* address); int pollSockets(struct pollfd* pollFds, int pollFdsCount, int timeoutMs); diff --git a/src/RtspConnection.c b/src/RtspConnection.c index 64f6a1f..4c8f400 100644 --- a/src/RtspConnection.c +++ b/src/RtspConnection.c @@ -248,7 +248,6 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response if (sock == INVALID_SOCKET) { return ret; } - setRecvTimeout(sock, RTSP_TIMEOUT_SEC); serializedMessage = serializeRtspMessage(request, &messageLen); if (serializedMessage == NULL) { @@ -271,6 +270,8 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response offset = 0; responseBufferSize = 0; for (;;) { + struct pollfd pfd; + if (offset >= responseBufferSize) { responseBufferSize = offset + 16384; responseBuffer = extendBuffer(responseBuffer, responseBufferSize); @@ -280,6 +281,20 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response } } + pfd.fd = sock; + pfd.events = POLLIN; + err = pollSockets(&pfd, 1, RTSP_TIMEOUT_SEC * 1000); + if (err == 0) { + *error = ETIMEDOUT; + Limelog("RTSP request timed out\n"); + } + else if (err < 0) { + *error = LastSocketError(); + Limelog("Failed to wait for RTSP response: %d\n", *error); + goto Exit; + return false; + } + err = recv(sock, &responseBuffer[offset], responseBufferSize - offset, 0); if (err < 0) { // Error reading