IPStack - Fixed invalid window size in outgoing TCP packets
[tpg/acess2.git] / Modules / IPStack / tcp.c
index cedb8ce..68e72d7 100644 (file)
@@ -18,7 +18,7 @@
 #define TCP_RECIEVE_BUFFER_SIZE        0x4000
 
 // === PROTOTYPES ===
-void   TCP_Initialise();
+void   TCP_Initialise(void);
 void   TCP_StartConnection(tTCPConnection *Conn);
 void   TCP_SendPacket(tTCPConnection *Conn, size_t Length, tTCPHeader *Data);
 void   TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
@@ -62,8 +62,9 @@ Uint32        gaTCP_PortBitmap[0x800];
  * 
  * Registers the client and server files and the GetPacket callback
  */
-void TCP_Initialise()
+void TCP_Initialise(void)
 {
+       giTCP_NextOutPort += rand()%32;
        IPStack_AddFile(&gTCP_ServerFile);
        IPStack_AddFile(&gTCP_ClientFile);
        IPv4_RegisterCallback(IP4PROT_TCP, TCP_GetPacket);
@@ -354,9 +355,10 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                // - Handle State changes
                //
                if( Header->Flags & TCP_FLAG_FIN ) {
-                       Log_Log("TCP", "Conn %p closed, recieved FIN, acknowledging", Connection);
+                       Log_Log("TCP", "Conn %p closed, recieved FIN", Connection);
                        VFS_MarkError(&Connection->Node, 1);
                        Connection->State = TCP_ST_CLOSE_WAIT;
+//                     Header->Flags &= ~TCP_FLAG_FIN;
                        // CLOSE WAIT requires the client to close (or does it?)
                        #if 0
                        
@@ -411,6 +413,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        // 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.
+                       // - Meh, no real issue, as the cache shouldn't be that large
                        TCP_INT_UpdateRecievedFromFuture(Connection);
                
                        // ACK Packet
@@ -520,7 +523,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        // ACK Packet
                        Header->DestPort = Header->SourcePort;
                        Header->SourcePort = htons(Connection->LocalPort);
-                       Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+                       Header->AcknowlegementNumber = Header->SequenceNumber;
                        Header->SequenceNumber = htonl(Connection->NextSequenceSend);
                        Header->WindowSize = htons(TCP_WINDOW_SIZE);
                        Header->Flags = TCP_FLAG_ACK;
@@ -546,7 +549,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                        // Send ACK
                        Header->DestPort = Header->SourcePort;
                        Header->SourcePort = htons(Connection->LocalPort);
-                       Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+                       Header->AcknowlegementNumber = Header->SequenceNumber;
                        Header->SequenceNumber = htonl(Connection->NextSequenceSend);
                        Header->WindowSize = htons(TCP_WINDOW_SIZE);
                        Header->Flags = TCP_FLAG_ACK;
@@ -600,9 +603,7 @@ void TCP_INT_AppendRecieved(tTCPConnection *Connection, tTCPStoredPacket *Pkt)
        
        RingBuffer_Write( Connection->RecievedBuffer, Pkt->Data, Pkt->Length );
 
-       #if USE_SELECT
        VFS_MarkAvaliable(&Connection->Node, 1);
-       #endif
        
        Mutex_Release( &Connection->lRecievedPackets );
 }
@@ -1017,7 +1018,7 @@ Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buff
        while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
                Threads_Yield();
        
-       // If the conneciton is not nope, then clean out the recieved buffer
+       // If the conneciton is not open, then clean out the recieved buffer
        if( conn->State != TCP_ST_OPEN )
        {
                Mutex_Acquire( &conn->lRecievedPackets );
@@ -1035,7 +1036,7 @@ Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buff
        }
        
        // Wait
-       VFS_SelectNode(Node, VFS_SELECT_READ, NULL, "TCP_Client_Read");
+       VFS_SelectNode(Node, VFS_SELECT_READ|VFS_SELECT_ERROR, NULL, "TCP_Client_Read");
        
        // Lock list and read as much as possible (up to `Length`)
        Mutex_Acquire( &conn->lRecievedPackets );
@@ -1064,7 +1065,7 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, void *Dat
        packet->SourcePort = htons(Connection->LocalPort);
        packet->DestPort = htons(Connection->RemotePort);
        packet->DataOffset = (sizeof(tTCPHeader)/4)*16;
-       packet->WindowSize = TCP_WINDOW_SIZE;
+       packet->WindowSize = htons(TCP_WINDOW_SIZE);
        
        packet->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
        packet->SequenceNumber = htonl(Connection->NextSequenceSend);
@@ -1091,6 +1092,11 @@ Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
        
        ENTER("pNode XOffset XLength pBuffer", Node, Offset, Length, Buffer);
        
+//     #if DEBUG
+//     Debug_HexDump("TCP_Client_Write: Buffer = ",
+//             Buffer, Length);
+//     #endif
+       
        // Check if connection is open
        while( conn->State == TCP_ST_SYN_RCVD || conn->State == TCP_ST_SYN_SENT )
                Threads_Yield();
@@ -1117,7 +1123,7 @@ Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buf
                TCP_INT_SendDataPacket(conn, len, Buffer);
                
                Buffer += len;
-               rem += len;
+               rem -= len;
        } while( rem > 0 );
        
        LEAVE('i', Length);
@@ -1147,6 +1153,7 @@ void TCP_StartConnection(tTCPConnection *Conn)
        
        Conn->NextSequenceSend ++;
        Conn->State = TCP_ST_SYN_SENT;
+
        return ;
 }
 
@@ -1203,7 +1210,18 @@ int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data)
                if(conn->RemotePort == -1)
                        LEAVE_RET('i', 0);
 
-               TCP_StartConnection(conn);
+               {
+                       tTime   timeout_end = now() + conn->Interface->TimeoutDelay;
+       
+                       TCP_StartConnection(conn);
+                       // TODO: Wait for connection to open
+                       while( conn->State == TCP_ST_SYN_SENT && timeout_end > now() ) {
+                               Threads_Yield();
+                       }
+                       if( conn->State == TCP_ST_SYN_SENT )
+                               LEAVE_RET('i', 0);
+               }
+
                LEAVE_RET('i', 1);
        
        // Get recieve buffer length
@@ -1230,7 +1248,7 @@ void TCP_Client_Close(tVFS_Node *Node)
                
                packet.AcknowlegementNumber = 0;
                packet.SequenceNumber = htonl(conn->NextSequenceSend);
-               packet.Flags = TCP_FLAG_FIN|TCP_FLAG_ACK;
+               packet.Flags = TCP_FLAG_FIN;
                
                TCP_SendPacket( conn, sizeof(tTCPHeader), &packet );
        }
@@ -1238,7 +1256,7 @@ void TCP_Client_Close(tVFS_Node *Node)
        switch( conn->State )
        {
        case TCP_ST_CLOSE_WAIT:
-               conn->State = TCP_ST_CLOSED;
+               conn->State = TCP_ST_LAST_ACK;
                break;
        case TCP_ST_OPEN:
                conn->State = TCP_ST_FIN_WAIT1;

UCC git Repository :: git.ucc.asn.au