X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FModules%2FIPStack%2Ftcp.c;h=aa951689eb318a27c8e81817362a6540fd255782;hb=015f48988e0ff398409d71dfc692005ab439490a;hp=8b4f99db58cb1bab2bb7090a08850a5c6ebdde91;hpb=bd912eb789383ceabf98c361e75c49dbab630ace;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/IPStack/tcp.c b/KernelLand/Modules/IPStack/tcp.c index 8b4f99db..aa951689 100644 --- a/KernelLand/Modules/IPStack/tcp.c +++ b/KernelLand/Modules/IPStack/tcp.c @@ -37,13 +37,13 @@ Uint16 TCP_GetUnusedPort(); // --- Server tVFS_Node *TCP_Server_Init(tInterface *Interface); int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]); -tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name); +tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name, Uint Flags); int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data); void TCP_Server_Close(tVFS_Node *Node); // --- Client tVFS_Node *TCP_Client_Init(tInterface *Interface); -size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer); -size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer); +size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags); +size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags); int TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data); void TCP_Client_Close(tVFS_Node *Node); // --- Helpers @@ -350,7 +350,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head // Get length of data dataLen = Length - (Header->DataOffset>>4)*4; LOG("dataLen = %i", dataLen); -// Log_Debug("TCP", "State %i, dataLen = %x", Connection->State, dataLen); + Log_Debug("TCP", "State %i, dataLen = %x", Connection->State, dataLen); // // State Machine @@ -368,14 +368,6 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head if( Header->Flags & TCP_FLAG_SYN ) { Connection->NextSequenceRcv ++; - 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; - TCP_SendPacket( Connection, Header, 0, NULL ); if( Header->Flags & TCP_FLAG_ACK ) { @@ -388,6 +380,14 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head Log_Log("TCP", "ACKing SYN"); Connection->State = TCP_ST_SYN_RCVD; } + 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; + TCP_SendPacket( Connection, Header, 0, NULL ); } break; @@ -426,12 +426,15 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head } Connection->NextSequenceRcv ++; // TODO: Is this right? (empty packet counts as one byte) Log_Log("TCP", "Empty Packet, inc and ACK the current sequence number"); + TCP_INT_SendACK(Connection); + #if 0 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, Header, 0, NULL ); + #endif return ; } @@ -442,7 +445,7 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head sequence_num = ntohl(Header->SequenceNumber); - LOG("TCP", "0x%08x <= 0x%08x < 0x%08x", + LOG("0x%08x <= 0x%08x < 0x%08x", Connection->NextSequenceRcv, ntohl(Header->SequenceNumber), Connection->NextSequenceRcv + TCP_WINDOW_SIZE @@ -947,7 +950,7 @@ int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]) * \param Node Server node * \param Name Hexadecimal ID of the node */ -tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name) +tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name, Uint Flags) { tTCPConnection *conn; tTCPListener *srv = Node->ImplPtr; @@ -1102,7 +1105,7 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface) * \note If \a Length is smaller than the size of the packet, the rest * of the packet's data will be discarded. */ -size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer) +size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer, Uint Flags) { tTCPConnection *conn = Node->ImplPtr; size_t len; @@ -1120,6 +1123,7 @@ size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe if( len == 0 ) { VFS_MarkAvaliable(Node, 0); + errno = 0; LEAVE('i', -1); return -1; } @@ -1129,7 +1133,17 @@ size_t TCP_Client_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffe } // Wait - VFS_SelectNode(Node, VFS_SELECT_READ|VFS_SELECT_ERROR, NULL, "TCP_Client_Read"); + { + tTime *timeout = NULL; + tTime timeout_zero = 0; + if( Flags & VFS_IOFLAG_NOBLOCK ) + timeout = &timeout_zero; + if( !VFS_SelectNode(Node, VFS_SELECT_READ|VFS_SELECT_ERROR, timeout, "TCP_Client_Read") ) { + errno = EWOULDBLOCK; + LEAVE('i', -1); + return -1; + } + } // Lock list and read as much as possible (up to `Length`) Mutex_Acquire( &conn->lRecievedPackets ); @@ -1179,7 +1193,7 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const voi /** * \brief Send some bytes on a connection */ -size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer) +size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer, Uint Flags) { tTCPConnection *conn = Node->ImplPtr; size_t rem = Length; @@ -1194,12 +1208,23 @@ size_t TCP_Client_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void // Don't allow a write to a closed connection if( conn->State > TCP_ST_OPEN ) { VFS_MarkError(Node, 1); + errno = 0; LEAVE('i', -1); return -1; } // Wait - VFS_SelectNode(Node, VFS_SELECT_WRITE|VFS_SELECT_ERROR, NULL, "TCP_Client_Write"); + { + tTime *timeout = NULL; + tTime timeout_zero = 0; + if( Flags & VFS_IOFLAG_NOBLOCK ) + timeout = &timeout_zero; + if( !VFS_SelectNode(Node, VFS_SELECT_WRITE|VFS_SELECT_ERROR, timeout, "TCP_Client_Write") ) { + errno = EWOULDBLOCK; + LEAVE('i', -1); + return -1; + } + } do { @@ -1354,7 +1379,8 @@ void TCP_Client_Close(tVFS_Node *Node) while( conn->State == TCP_ST_FIN_WAIT1 ) Threads_Yield(); break; default: - Log_Warning("TCP", "Unhandled connection state in TCP_Client_Close"); + Log_Warning("TCP", "Unhandled connection state %i in TCP_Client_Close", + conn->State); break; }