From 47820c35bdb50e6092fd061b0eb38db648c0e8f7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 22 Oct 2014 21:48:52 -0400 Subject: [PATCH] Send TCP messages in a single call to send() because GFE can't handle receiving messages in fragments --- limelight-common/ControlStream.c | 24 +++++++++++++----------- limelight-common/InputStream.c | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/limelight-common/ControlStream.c b/limelight-common/ControlStream.c index 87131bf..9b6f369 100644 --- a/limelight-common/ControlStream.c +++ b/limelight-common/ControlStream.c @@ -88,7 +88,7 @@ static PNVCTL_PACKET_HEADER readNvctlPacket(void) { memcpy(fullPacket, &staticHeader, sizeof(staticHeader)); if (staticHeader.payloadLength != 0) { - err = recv(ctlSock, (char*) (fullPacket + 1), staticHeader.payloadLength, 0); + err = recv(ctlSock, (char*) (fullPacket + 1), staticHeader.payloadLength, 0); if (err != staticHeader.payloadLength) { free(fullPacket); return NULL; @@ -99,21 +99,23 @@ static PNVCTL_PACKET_HEADER readNvctlPacket(void) { } static int sendMessageAndForget(short ptype, short paylen, const void* payload) { - NVCTL_PACKET_HEADER header; + PNVCTL_PACKET_HEADER packet; SOCK_RET err; - header.type = ptype; - header.payloadLength = paylen; - err = send(ctlSock, (char*) &header, sizeof(header), 0); - if (err != sizeof(header)) { + packet = malloc(sizeof(*packet) + paylen); + if (packet == NULL) { return 0; } - if (payload != NULL) { - err = send(ctlSock, payload, paylen, 0); - if (err != paylen) { - return 0; - } + packet->type = ptype; + packet->payloadLength = paylen; + memcpy(&packet[1], payload, paylen); + + err = send(ctlSock, (char*) packet, sizeof(*packet) + paylen, 0); + free(packet); + + if (err != sizeof(*packet)) { + return 0; } return 1; diff --git a/limelight-common/InputStream.c b/limelight-common/InputStream.c index 49517ee..f36f69d 100644 --- a/limelight-common/InputStream.c +++ b/limelight-common/InputStream.c @@ -87,6 +87,7 @@ void destroyInputStream(void) { initialized = 0; } +#define OAES_DATA_OFFSET 32 static void inputSendThreadProc(void* context) { SOCK_RET err; PPACKET_HOLDER holder; @@ -114,21 +115,20 @@ static void inputSendThreadProc(void* context) { } // The first 32-bytes of the output are internal OAES stuff that we want to ignore - encryptedSize -= 32; + encryptedSize -= OAES_DATA_OFFSET; - // Send the encrypted length first + // Overwrite the last 4 bytes before the encrypted data with the length so + // we can send the message all at once. GFE can choke if it gets the header + // before the rest of the message. encryptedLengthPrefix = htonl((unsigned long) encryptedSize); - err = send(inputSock, (const char*) &encryptedLengthPrefix, sizeof(encryptedLengthPrefix), 0); - if (err <= 0) { - Limelog("Input thread terminating #3\n"); - listenerCallbacks->connectionTerminated(err); - return; - } + memcpy(&encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)], + &encryptedLengthPrefix, sizeof(encryptedLengthPrefix)); // Send the encrypted payload - err = send(inputSock, (const char*) &encryptedBuffer[32], encryptedSize, 0); + err = send(inputSock, (const char*) &encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)], + encryptedSize + sizeof(encryptedLengthPrefix), 0); if (err <= 0) { - Limelog("Input thread terminating #4\n"); + Limelog("Input thread terminating #3\n"); listenerCallbacks->connectionTerminated(err); return; }