Send TCP messages in a single call to send() because GFE can't handle receiving messages in fragments

This commit is contained in:
Cameron Gutman 2014-10-22 21:48:52 -04:00
parent bc8275474f
commit 47820c35bd
2 changed files with 23 additions and 21 deletions

View File

@ -88,7 +88,7 @@ static PNVCTL_PACKET_HEADER readNvctlPacket(void) {
memcpy(fullPacket, &staticHeader, sizeof(staticHeader)); memcpy(fullPacket, &staticHeader, sizeof(staticHeader));
if (staticHeader.payloadLength != 0) { 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) { if (err != staticHeader.payloadLength) {
free(fullPacket); free(fullPacket);
return NULL; return NULL;
@ -99,21 +99,23 @@ static PNVCTL_PACKET_HEADER readNvctlPacket(void) {
} }
static int sendMessageAndForget(short ptype, short paylen, const void* payload) { static int sendMessageAndForget(short ptype, short paylen, const void* payload) {
NVCTL_PACKET_HEADER header; PNVCTL_PACKET_HEADER packet;
SOCK_RET err; SOCK_RET err;
header.type = ptype; packet = malloc(sizeof(*packet) + paylen);
header.payloadLength = paylen; if (packet == NULL) {
err = send(ctlSock, (char*) &header, sizeof(header), 0);
if (err != sizeof(header)) {
return 0; return 0;
} }
if (payload != NULL) { packet->type = ptype;
err = send(ctlSock, payload, paylen, 0); packet->payloadLength = paylen;
if (err != paylen) { memcpy(&packet[1], payload, paylen);
return 0;
} err = send(ctlSock, (char*) packet, sizeof(*packet) + paylen, 0);
free(packet);
if (err != sizeof(*packet)) {
return 0;
} }
return 1; return 1;

View File

@ -87,6 +87,7 @@ void destroyInputStream(void) {
initialized = 0; initialized = 0;
} }
#define OAES_DATA_OFFSET 32
static void inputSendThreadProc(void* context) { static void inputSendThreadProc(void* context) {
SOCK_RET err; SOCK_RET err;
PPACKET_HOLDER holder; 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 // 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); encryptedLengthPrefix = htonl((unsigned long) encryptedSize);
err = send(inputSock, (const char*) &encryptedLengthPrefix, sizeof(encryptedLengthPrefix), 0); memcpy(&encryptedBuffer[OAES_DATA_OFFSET - sizeof(encryptedLengthPrefix)],
if (err <= 0) { &encryptedLengthPrefix, sizeof(encryptedLengthPrefix));
Limelog("Input thread terminating #3\n");
listenerCallbacks->connectionTerminated(err);
return;
}
// Send the encrypted payload // 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) { if (err <= 0) {
Limelog("Input thread terminating #4\n"); Limelog("Input thread terminating #3\n");
listenerCallbacks->connectionTerminated(err); listenerCallbacks->connectionTerminated(err);
return; return;
} }