From bbf15af8370064b0f1dbcd994fb6fd65255dc3c9 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 26 Oct 2023 01:15:27 -0500 Subject: [PATCH] Revert "Use connected datagram sockets for audio and video" This causes problems on multi-homed GFE and Sunshine (prior to v0.21) hosts because audio and video data can be sent back from an address different than the one we used as our original destination address. This reverts commit c13f4a323fc5d25bf9e1d18ac8166d6b5fad22b8. --- src/AudioStream.c | 18 +++++++++--------- src/PlatformSockets.c | 17 ----------------- src/PlatformSockets.h | 1 - src/VideoStream.c | 19 ++++++++----------- 4 files changed, 17 insertions(+), 38 deletions(-) diff --git a/src/AudioStream.c b/src/AudioStream.c index 680241d..a8a60c0 100644 --- a/src/AudioStream.c +++ b/src/AudioStream.c @@ -37,6 +37,12 @@ typedef struct _QUEUED_AUDIO_PACKET { static void AudioPingThreadProc(void* context) { char legacyPingData[] = { 0x50, 0x49, 0x4E, 0x47 }; + LC_SOCKADDR saddr; + + LC_ASSERT(AudioPortNumber != 0); + + memcpy(&saddr, &RemoteAddr, sizeof(saddr)); + SET_PORT(&saddr, AudioPortNumber); // We do not check for errors here. Socket errors will be handled // on the read-side in ReceiveThreadProc(). This avoids potential @@ -48,10 +54,10 @@ static void AudioPingThreadProc(void* context) { pingCount++; AudioPingPayload.sequenceNumber = BE32(pingCount); - send(rtpSocket, (char*)&AudioPingPayload, sizeof(AudioPingPayload), 0); + sendto(rtpSocket, (char*)&AudioPingPayload, sizeof(AudioPingPayload), 0, (struct sockaddr*)&saddr, AddrLen); } else { - send(rtpSocket, legacyPingData, sizeof(legacyPingData), 0); + sendto(rtpSocket, legacyPingData, sizeof(legacyPingData), 0, (struct sockaddr*)&saddr, AddrLen); } PltSleepMsInterruptible(&udpPingThread, 500); @@ -92,15 +98,9 @@ int notifyAudioPortNegotiationComplete(void) { return LastSocketFail(); } - // Connect our audio socket to the target address and port - int err = connectUdpSocket(rtpSocket, &RemoteAddr, AddrLen, AudioPortNumber); - if (err != 0) { - return err; - } - // We may receive audio before our threads are started, but that's okay. We'll // drop the first 1 second of audio packets to catch up with the backlog. - err = PltCreateThread("AudioPing", AudioPingThreadProc, NULL, &udpPingThread); + int err = PltCreateThread("AudioPing", AudioPingThreadProc, NULL, &udpPingThread); if (err != 0) { return err; } diff --git a/src/PlatformSockets.c b/src/PlatformSockets.c index a1bcc98..af71fb0 100644 --- a/src/PlatformSockets.c +++ b/src/PlatformSockets.c @@ -317,23 +317,6 @@ SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCK return s; } -int connectUdpSocket(SOCKET s, struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port) { - int err; - LC_SOCKADDR saddr; - - LC_ASSERT(port != 0); - - memcpy(&saddr, dstaddr, addrlen); - SET_PORT(&saddr, port); - err = connect(s, (struct sockaddr*)&saddr, addrlen); - if (err < 0) { - Limelog("connect() failed for UDP socket: %d\n", (int)LastSocketError()); - return LastSocketFail(); - } - - return 0; -} - int setSocketNonBlocking(SOCKET s, bool enabled) { #if defined(__vita__) int val = enabled ? 1 : 0; diff --git a/src/PlatformSockets.h b/src/PlatformSockets.h index 6bbe277..10df63e 100644 --- a/src/PlatformSockets.h +++ b/src/PlatformSockets.h @@ -88,7 +88,6 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string, size_t str SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlocking); SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec); -int connectUdpSocket(SOCKET s, struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port); int sendMtuSafe(SOCKET s, char* buffer, int size); SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize); int enableNoDelay(SOCKET s); diff --git a/src/VideoStream.c b/src/VideoStream.c index 2089e0d..e1f3e65 100644 --- a/src/VideoStream.c +++ b/src/VideoStream.c @@ -50,6 +50,12 @@ void destroyVideoStream(void) { // UDP Ping proc static void VideoPingThreadProc(void* context) { char legacyPingData[] = { 0x50, 0x49, 0x4E, 0x47 }; + LC_SOCKADDR saddr; + + LC_ASSERT(VideoPortNumber != 0); + + memcpy(&saddr, &RemoteAddr, sizeof(saddr)); + SET_PORT(&saddr, VideoPortNumber); // We do not check for errors here. Socket errors will be handled // on the read-side in ReceiveThreadProc(). This avoids potential @@ -61,10 +67,10 @@ static void VideoPingThreadProc(void* context) { pingCount++; VideoPingPayload.sequenceNumber = BE32(pingCount); - send(rtpSocket, (char*)&VideoPingPayload, sizeof(VideoPingPayload), 0); + sendto(rtpSocket, (char*)&VideoPingPayload, sizeof(VideoPingPayload), 0, (struct sockaddr*)&saddr, AddrLen); } else { - send(rtpSocket, legacyPingData, sizeof(legacyPingData), 0); + sendto(rtpSocket, legacyPingData, sizeof(legacyPingData), 0, (struct sockaddr*)&saddr, AddrLen); } PltSleepMsInterruptible(&udpPingThread, 500); @@ -268,15 +274,6 @@ int startVideoStream(void* rendererContext, int drFlags) { return LastSocketError(); } - // Connect our video socket to the target address and port - LC_ASSERT(VideoPortNumber != 0); - err = connectUdpSocket(rtpSocket, &RemoteAddr, AddrLen, VideoPortNumber); - if (err != 0) { - VideoCallbacks.cleanup(); - closeSocket(rtpSocket); - return err; - } - VideoCallbacks.start(); err = PltCreateThread("VideoRecv", VideoReceiveThreadProc, NULL, &receiveThread);