+ * \param Connection TCP Connection pointer
+ * \param Header TCP Packet pointer
+ * \param Length Length of the packet
+ */
+void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length)
+{
+ tTCPStoredPacket *pkt;
+ int dataLen;
+
+ if(Header->Flags & TCP_FLAG_SYN) {
+ Connection->NextSequenceRcv = ntohl(Header->SequenceNumber) + 1;
+ }
+
+ if( Connection->State == TCP_ST_SYN_SENT )
+ {
+ if( (Header->Flags & (TCP_FLAG_SYN|TCP_FLAG_ACK)) == (TCP_FLAG_SYN|TCP_FLAG_ACK) ) {
+
+ 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_ACK;
+ Header->DataOffset = (sizeof(tTCPHeader)/4) << 4;
+ Log_Log("TCP", "ACKing SYN-ACK");
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ Connection->State = TCP_ST_OPEN;
+ }
+ }
+
+ // Get length of data
+ dataLen = Length - (Header->DataOffset>>4)*4;
+ Log_Log("TCP", "HandleConnectionPacket - dataLen = %i", dataLen);
+
+ if(Header->Flags & TCP_FLAG_ACK) {
+ // TODO: Process an ACKed Packet
+ Log_Log("TCP", "Conn %p, Packet 0x%x ACKed", Connection, Header->AcknowlegementNumber);
+ }
+
+ // TODO: Check what to do here
+ if(Header->Flags & TCP_FLAG_FIN) {
+ if( Connection->State == TCP_ST_FIN_SENT ) {
+ Connection->State = TCP_ST_FINISHED;
+ return ;
+ }
+ else {
+ Connection->State = TCP_ST_FINISHED;
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->Flags = TCP_FLAG_ACK;
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ return ;
+ }
+ }
+
+ if(dataLen == 0) {
+ Log_Log("TCP", "Empty Packet");
+ return ;
+ }
+
+ // NOTES:
+ // Flags
+ // PSH - Has Data?
+ // /NOTES
+
+ // Allocate and fill cached packet
+ pkt = malloc( dataLen + sizeof(tTCPStoredPacket) );
+ pkt->Next = NULL;
+ pkt->Sequence = ntohl(Header->SequenceNumber);
+ pkt->Length = dataLen;
+ memcpy(pkt->Data, (Uint8*)Header + (Header->DataOffset>>4)*4, dataLen);
+
+ // Is this packet the next expected packet?
+ // TODO: Fix this to check if the packet is in the window.
+ if( pkt->Sequence != Connection->NextSequenceRcv )
+ {
+ tTCPStoredPacket *tmp, *prev = NULL;
+
+ Log_Log("TCP", "Out of sequence packet (0x%08x != 0x%08x)",
+ pkt->Sequence, Connection->NextSequenceRcv);
+
+ // No? Well, let's cache it and look at it later
+ LOCK( &Connection->lFuturePackets );
+ for(tmp = Connection->FuturePackets;
+ tmp;
+ prev = tmp, tmp = tmp->Next)
+ {
+ if(tmp->Sequence > pkt->Sequence) break;
+ }
+ if(prev)
+ prev->Next = pkt;
+ else
+ Connection->FuturePackets = pkt;
+ pkt->Next = tmp;
+ RELEASE( &Connection->lFuturePackets );
+ }
+ else
+ {
+ // 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