mirror of
https://github.com/moonlight-stream/moonlight-common-c.git
synced 2026-02-16 02:21:07 +00:00
fix: use UDP connect to probe local address (#121)
This commit is contained in:
@@ -377,6 +377,19 @@ int LiStartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION stre
|
|||||||
ListenerCallbacks.stageFailed(STAGE_NAME_RESOLUTION, err);
|
ListenerCallbacks.stageFailed(STAGE_NAME_RESOLUTION, err);
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve LocalAddr by RemoteAddr.
|
||||||
|
{
|
||||||
|
SOCKADDR_LEN localAddrLen;
|
||||||
|
err = getLocalAddressByUdpConnect(&RemoteAddr, AddrLen, &LocalAddr, &localAddrLen);
|
||||||
|
if (err != 0) {
|
||||||
|
Limelog("failed to resolve local addr: %d\n", err);
|
||||||
|
ListenerCallbacks.stageFailed(STAGE_NAME_RESOLUTION, err);
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
LC_ASSERT(localAddrLen == AddrLen);
|
||||||
|
}
|
||||||
|
|
||||||
stage++;
|
stage++;
|
||||||
LC_ASSERT(stage == STAGE_NAME_RESOLUTION);
|
LC_ASSERT(stage == STAGE_NAME_RESOLUTION);
|
||||||
ListenerCallbacks.stageComplete(STAGE_NAME_RESOLUTION);
|
ListenerCallbacks.stageComplete(STAGE_NAME_RESOLUTION);
|
||||||
|
|||||||
@@ -568,6 +568,34 @@ Exit:
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getLocalAddressByUdpConnect(const struct sockaddr_storage* targetAddr, SOCKADDR_LEN targetAddrLen,
|
||||||
|
struct sockaddr_storage* localAddr, SOCKADDR_LEN* localAddrLen) {
|
||||||
|
SOCKET udpSocket;
|
||||||
|
|
||||||
|
udpSocket = createSocket(targetAddr->ss_family, SOCK_DGRAM, IPPROTO_UDP, false);
|
||||||
|
if (udpSocket == INVALID_SOCKET) {
|
||||||
|
return LastSocketError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(udpSocket, (struct sockaddr*)targetAddr, targetAddrLen) < 0) {
|
||||||
|
int err = LastSocketError();
|
||||||
|
Limelog("UDP connect() failed: %d\n", err);
|
||||||
|
closeSocket(udpSocket);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
*localAddrLen = sizeof(*localAddr);
|
||||||
|
if (getsockname(udpSocket, (struct sockaddr*)localAddr, localAddrLen) < 0) {
|
||||||
|
int err = LastSocketError();
|
||||||
|
Limelog("getsockname() failed: %d\n", err);
|
||||||
|
closeSocket(udpSocket);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeSocket(udpSocket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// See TCP_MAXSEG note in connectTcpSocket() above for more information.
|
// See TCP_MAXSEG note in connectTcpSocket() above for more information.
|
||||||
// TCP_NODELAY must be enabled on the socket for this function to work!
|
// TCP_NODELAY must be enabled on the socket for this function to work!
|
||||||
int sendMtuSafe(SOCKET s, char* buffer, int size) {
|
int sendMtuSafe(SOCKET s, char* buffer, int size) {
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ void addrToUrlSafeString(struct sockaddr_storage* addr, char* string, size_t str
|
|||||||
|
|
||||||
SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlocking);
|
SOCKET createSocket(int addressFamily, int socketType, int protocol, bool nonBlocking);
|
||||||
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec);
|
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec);
|
||||||
|
int getLocalAddressByUdpConnect(const struct sockaddr_storage* targetAddr, SOCKADDR_LEN targetAddrLen,
|
||||||
|
struct sockaddr_storage* localAddr, SOCKADDR_LEN* localAddrLen);
|
||||||
int sendMtuSafe(SOCKET s, char* buffer, int size);
|
int sendMtuSafe(SOCKET s, char* buffer, int size);
|
||||||
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize, int socketQosType);
|
SOCKET bindUdpSocket(int addressFamily, struct sockaddr_storage* localAddr, SOCKADDR_LEN addrLen, int bufferSize, int socketQosType);
|
||||||
int enableNoDelay(SOCKET s);
|
int enableNoDelay(SOCKET s);
|
||||||
|
|||||||
@@ -477,18 +477,6 @@ static bool transactRtspMessageTcp(PRTSP_MESSAGE request, PRTSP_MESSAGE response
|
|||||||
// Decrypt (if necessary) and deserialize the RTSP response
|
// Decrypt (if necessary) and deserialize the RTSP response
|
||||||
ret = unsealRtspMessage(responseBuffer, offset, response);
|
ret = unsealRtspMessage(responseBuffer, offset, response);
|
||||||
|
|
||||||
// Fetch the local address for this socket if it's not populated yet
|
|
||||||
if (LocalAddr.ss_family == 0) {
|
|
||||||
SOCKADDR_LEN addrLen = (SOCKADDR_LEN)sizeof(LocalAddr);
|
|
||||||
if (getsockname(sock, (struct sockaddr*)&LocalAddr, &addrLen) < 0) {
|
|
||||||
Limelog("Failed to get local address: %d\n", LastSocketError());
|
|
||||||
memset(&LocalAddr, 0, sizeof(LocalAddr));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LC_ASSERT(addrLen == AddrLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
if (serializedMessage != NULL) {
|
if (serializedMessage != NULL) {
|
||||||
free(serializedMessage);
|
free(serializedMessage);
|
||||||
|
|||||||
Reference in New Issue
Block a user