- // 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->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 );
+ break;
+
+ // LAST-ACK - Waiting for the ACK of FIN (from CLOSE WAIT)
+ case TCP_ST_LAST_ACK:
+ if( Header->Flags & TCP_FLAG_ACK )
+ {
+ Connection->State = TCP_ST_FINISHED; // Connection completed
+ Log_Log("TCP", "LAST-ACK to CLOSED - Connection remote closed");
+ // TODO: Destrory the TCB
+ }
+ break;
+
+ // --- Local close States
+ case TCP_ST_FIN_WAIT1:
+ if( Header->Flags & TCP_FLAG_FIN )
+ {
+ Connection->State = TCP_ST_CLOSING;
+ Log_Debug("TCP", "Conn %p closed, sent FIN and recieved FIN", Connection);
+ VFS_MarkError(&Connection->Node, 1);
+
+ // ACK Packet
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = Header->SequenceNumber;
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->WindowSize = htons(TCP_WINDOW_SIZE);
+ Header->Flags = TCP_FLAG_ACK;
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ break ;
+ }
+
+ // TODO: Make sure that the packet is actually ACKing the FIN
+ if( Header->Flags & TCP_FLAG_ACK )
+ {
+ Connection->State = TCP_ST_FIN_WAIT2;
+ Log_Debug("TCP", "Conn %p closed, sent FIN ACKed", Connection);
+ VFS_MarkError(&Connection->Node, 1);
+ return ;
+ }
+ break;
+
+ case TCP_ST_FIN_WAIT2:
+ if( Header->Flags & TCP_FLAG_FIN )
+ {
+ Connection->State = TCP_ST_TIME_WAIT;
+ Log_Debug("TCP", "FIN sent and recieved, ACKing and going into TIME WAIT %p FINWAIT-2 -> TIME WAIT", Connection);
+ // Send ACK
+ Header->DestPort = Header->SourcePort;
+ Header->SourcePort = htons(Connection->LocalPort);
+ Header->AcknowlegementNumber = Header->SequenceNumber;
+ Header->SequenceNumber = htonl(Connection->NextSequenceSend);
+ Header->WindowSize = htons(TCP_WINDOW_SIZE);
+ Header->Flags = TCP_FLAG_ACK;
+ TCP_SendPacket( Connection, sizeof(tTCPHeader), Header );
+ }
+ break;
+
+ case TCP_ST_CLOSING:
+ // TODO: Make sure that the packet is actually ACKing the FIN
+ if( Header->Flags & TCP_FLAG_ACK )
+ {
+ Connection->State = TCP_ST_TIME_WAIT;
+ Log_Debug("TCP", "Conn %p CLOSING -> TIME WAIT", Connection);
+ VFS_MarkError(&Connection->Node, 1);
+ return ;
+ }
+ break;
+
+ // --- Closed (or near closed) states) ---
+ case TCP_ST_TIME_WAIT:
+ Log_Log("TCP", "Packets on Time-Wait, ignored");
+ break;
+
+ case TCP_ST_FINISHED:
+ Log_Log("TCP", "Packets when CLOSED, ignoring");
+ break;
+
+ //default:
+ // Log_Warning("TCP", "Unhandled TCP state %i", Connection->State);
+ // break;