X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Modules%2FIPStack%2Ftcp.c;h=1600bb46acd75e6f6b2f597c22f63af1233cb053;hb=9e4f0db5f7ccc535cb72d6ab2f96e201b050ef20;hp=cedb8ce7176d7575786ffbcb8bb420e4854296ad;hpb=de1db24a66d9dc40d9ab828683376851166340a0;p=tpg%2Facess2.git diff --git a/Modules/IPStack/tcp.c b/Modules/IPStack/tcp.c index cedb8ce7..1600bb46 100644 --- a/Modules/IPStack/tcp.c +++ b/Modules/IPStack/tcp.c @@ -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); @@ -89,7 +90,9 @@ void TCP_SendPacket( tTCPConnection *Conn, size_t Length, tTCPHeader *Data ) buf[2] = (htons(Length)<<16) | (6<<8) | 0; Data->Checksum = 0; memcpy( &buf[3], Data, Length ); - Data->Checksum = htons( IPv4_Checksum( buf, buflen ) ); + if(Length & 1) + ((Uint8*)buf)[12+Length] = 0; + Data->Checksum = htons( IPv4_Checksum( (Uint16*)buf, buflen/2 ) ); free(buf); IPv4_SendPacket(Conn->Interface, Conn->RemoteIP.v4, IP4PROT_TCP, 0, Length, Data); break; @@ -134,7 +137,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe { Log_Log("TCP", "TCP_GetPacket: SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber)); Debug_HexDump( - "[TCP ] Packet Data = ", + "TCP_GetPacket: Packet Data = ", (Uint8*)hdr + (hdr->DataOffset >> 4)*4, Length - (hdr->DataOffset >> 4)*4 ); @@ -354,9 +357,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 +415,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 +525,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 +551,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 +605,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 +1020,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 +1038,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 +1067,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); @@ -1073,8 +1076,7 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, void *Dat memcpy(packet->Options, Data, Length); Log_Debug("TCP", "Send sequence 0x%08x", Connection->NextSequenceSend); - Debug_HexDump("[TCP ] TCP_INT_SendDataPacket: Data = ", - Data, Length); + Debug_HexDump("TCP_INT_SendDataPacket: Data = ", Data, Length); TCP_SendPacket( Connection, sizeof(tTCPHeader)+Length, packet ); @@ -1091,6 +1093,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 +1124,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 +1154,7 @@ void TCP_StartConnection(tTCPConnection *Conn) Conn->NextSequenceSend ++; Conn->State = TCP_ST_SYN_SENT; + return ; } @@ -1203,7 +1211,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 +1249,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 +1257,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;