+ // Ooh, Goodie! Add it to the recieved list
+ TCP_INT_AppendRecieved(Connection, pkt);
+ free(pkt);
+ Log_Log("TCP", "0x%08x += %i", Connection->NextSequenceRcv, dataLen);
+ Connection->NextSequenceRcv += dataLen;
+
+ // TODO: This should be moved out of the watcher thread,
+ // so that a single lost packet on one connection doesn't cause
+ // all connections on the interface to lag.
+ TCP_INT_UpdateRecievedFromFuture(Connection);
+
+ // ACK Packet
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->WindowSize = htons(TCP_WINDOW_SIZE);
+ Header->Flags &= TCP_FLAG_SYN; // Eliminate all flags save for SYN
+ Header->Flags |= TCP_FLAG_ACK; // Add ACK
+ Log_Log("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ //Connection->NextSequenceSend ++;
+ }
+}
+
+/**
+ * \brief Appends a packet to the recieved list
+ * \param Connection Connection structure
+ * \param Pkt Packet structure on heap
+ */
+void TCP_INT_AppendRecieved(tTCPConnection *Connection, tTCPStoredPacket *Pkt)
+{
+ LOCK( &Connection->lRecievedPackets );
+ if(Connection->RecievedBuffer->Length + Pkt->Length > Connection->RecievedBuffer->Space )
+ {
+ Log_Error("TCP", "Buffer filled, packet dropped (%s)",
+ // TCP_INT_DumpConnection(Connection)
+ ""
+ );
+ return ;
+ }
+
+ RingBuffer_Write( Connection->RecievedBuffer, Pkt->Data, Pkt->Length );
+
+ RELEASE( &Connection->lRecievedPackets );
+}
+
+/**
+ * \brief Updates the connections recieved list from the future list
+ * \param Connection Connection structure
+ *
+ * Updates the recieved packets list with packets from the future (out
+ * of order) packets list that are now able to be added in direct
+ * sequence.
+ */
+void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection)
+{
+ tTCPStoredPacket *pkt, *prev;
+ for(;;)
+ {
+ prev = NULL;
+ // Look for the next expected packet in the cache.
+ LOCK( &Connection->lFuturePackets );
+ for(pkt = Connection->FuturePackets;
+ pkt && pkt->Sequence < Connection->NextSequenceRcv;
+ prev = pkt, pkt = pkt->Next);
+
+ // If we can't find the expected next packet, stop looking
+ if(!pkt || pkt->Sequence > Connection->NextSequenceRcv) {
+ RELEASE( &Connection->lFuturePackets );
+ return;