From: John Hodge Date: Thu, 26 Dec 2013 15:03:15 +0000 (+0800) Subject: Modules/IPStack - Fix page fault in TCP, quietened some things X-Git-Tag: rel0.15~30 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=9122d035c4337d33bf0cc2212eeade4e42a367a2;p=tpg%2Facess2.git Modules/IPStack - Fix page fault in TCP, quietened some things --- diff --git a/KernelLand/Modules/IPStack/arp.c b/KernelLand/Modules/IPStack/arp.c index c81f4c2a..5b9303b9 100644 --- a/KernelLand/Modules/IPStack/arp.c +++ b/KernelLand/Modules/IPStack/arp.c @@ -364,18 +364,18 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe switch( req4->SWSize ) { case 4: - Log_Debug("ARP", "ARP Request IPv4 Address %i.%i.%i.%i from %i.%i.%i.%i" - " (%02x:%02x:%02x:%02x:%02x:%02x)", - req4->DestIP.B[0], req4->DestIP.B[1], req4->DestIP.B[2], - req4->DestIP.B[3], - req4->SourceIP.B[0], req4->SourceIP.B[1], - req4->SourceIP.B[2], req4->SourceIP.B[3], - req4->SourceMac.B[0], req4->SourceMac.B[1], - req4->SourceMac.B[2], req4->SourceMac.B[3], - req4->SourceMac.B[4], req4->SourceMac.B[5]); iface = IPv4_GetInterface(Adapter, req4->DestIP, 0); if( iface ) { + Log_Debug("ARP", "ARP Request IPv4 Address %i.%i.%i.%i from %i.%i.%i.%i" + " (%02x:%02x:%02x:%02x:%02x:%02x)", + req4->DestIP.B[0], req4->DestIP.B[1], req4->DestIP.B[2], + req4->DestIP.B[3], + req4->SourceIP.B[0], req4->SourceIP.B[1], + req4->SourceIP.B[2], req4->SourceIP.B[3], + req4->SourceMac.B[0], req4->SourceMac.B[1], + req4->SourceMac.B[2], req4->SourceMac.B[3], + req4->SourceMac.B[4], req4->SourceMac.B[5]); ARP_UpdateCache4(req4->SourceIP, req4->SourceMac); req4->DestIP = req4->SourceIP; diff --git a/KernelLand/Modules/IPStack/ipv4.c b/KernelLand/Modules/IPStack/ipv4.c index 71a0533e..11cbc152 100644 --- a/KernelLand/Modules/IPStack/ipv4.c +++ b/KernelLand/Modules/IPStack/ipv4.c @@ -186,7 +186,8 @@ void IPv4_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buff // TODO: Handle packet fragmentation #if IPV4_TRACE - Log_Debug("IPv4", " From %i.%i.%i.%i to %i.%i.%i.%i", + Log_Debug("IPv4", "Proto 0x%x From %i.%i.%i.%i to %i.%i.%i.%i", + hdr->Protocol, hdr->Source.B[0], hdr->Source.B[1], hdr->Source.B[2], hdr->Source.B[3], hdr->Destination.B[0], hdr->Destination.B[1], hdr->Destination.B[2], hdr->Destination.B[3] ); diff --git a/KernelLand/Modules/IPStack/link.c b/KernelLand/Modules/IPStack/link.c index ac31ce2b..45311d0c 100644 --- a/KernelLand/Modules/IPStack/link.c +++ b/KernelLand/Modules/IPStack/link.c @@ -12,7 +12,7 @@ #include "include/adapters_int.h" // === CONSTANTS === -#define LINK_LOGPACKETS 1 +#define LINK_LOGPACKETS 0 #define VALIDATE_CHECKSUM 0 #define MAX_PACKET_SIZE 2048 diff --git a/KernelLand/Modules/IPStack/tcp.c b/KernelLand/Modules/IPStack/tcp.c index c10213c9..3d4978b4 100644 --- a/KernelLand/Modules/IPStack/tcp.c +++ b/KernelLand/Modules/IPStack/tcp.c @@ -11,7 +11,6 @@ #define USE_SELECT 1 #define HEXDUMP_INCOMING 0 #define HEXDUMP_OUTGOING 0 -#define CACHE_FUTURE_PACKETS_IN_BYTES 1 // Use a ring buffer to cache out of order packets #define TCP_MIN_DYNPORT 0xC000 #define TCP_MAX_HALFOPEN 1024 // Should be enough @@ -37,6 +36,7 @@ void TCP_INT_SendACK(tTCPConnection *Connection, const char *Reason); Uint16 TCP_GetUnusedPort(); int TCP_AllocatePort(Uint16 Port); int TCP_DeallocatePort(Uint16 Port); +tTCPConnection *TCP_int_CreateConnection(tInterface *Interface, enum eTCPConnectionState State); // --- Server tVFS_Node *TCP_Server_Init(tInterface *Interface); int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]); @@ -241,11 +241,9 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe // TODO: Check for halfopen max - conn = calloc(1, sizeof(tTCPConnection)); - conn->State = TCP_ST_SYN_RCVD; + conn = TCP_int_CreateConnection(Interface, TCP_ST_SYN_RCVD); conn->LocalPort = srv->Port; conn->RemotePort = ntohs(hdr->SourcePort); - conn->Interface = Interface; switch(Interface->Type) { @@ -253,17 +251,10 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe case 6: conn->RemoteIP.v6 = *(tIPv6*)Address; break; } - conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE ); - conn->NextSequenceRcv = ntohl( hdr->SequenceNumber ) + 1; conn->NextSequenceSend = rand(); - // Create node - conn->Node.NumACLs = 1; - conn->Node.ACLs = &gVFS_ACL_EveryoneRW; - conn->Node.ImplPtr = conn; conn->Node.ImplInt = srv->NextID ++; - conn->Node.Type = &gTCP_ClientNodeType; // TODO: Special type for the server end? // Hmm... Theoretically, this lock will never have to wait, // as the interface is locked to the watching thread, and this @@ -501,10 +492,9 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head Uint8 *dataptr = (Uint8*)Header + (Header->DataOffset>>4)*4; #if CACHE_FUTURE_PACKETS_IN_BYTES Uint32 index; - int i; index = sequence_num % TCP_WINDOW_SIZE; - for( i = 0; i < dataLen; i ++ ) + for( int i = 0; i < dataLen; i ++ ) { Connection->FuturePacketValidBytes[index/8] |= 1 << (index%8); Connection->FuturePacketData[index] = dataptr[i]; @@ -698,26 +688,29 @@ int TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection) { #if CACHE_FUTURE_PACKETS_IN_BYTES - int i, length = 0; - Uint32 index; - // Calculate length of contiguous bytes - length = Connection->HighestSequenceRcvd - Connection->NextSequenceRcv; - index = Connection->NextSequenceRcv % TCP_WINDOW_SIZE; - for( i = 0; i < length; i ++ ) + int length = Connection->HighestSequenceRcvd - Connection->NextSequenceRcv; + Uint32 index = Connection->NextSequenceRcv % TCP_WINDOW_SIZE; + for( int i = 0; i < length; i ++ ) { - if( Connection->FuturePacketValidBytes[i / 8] == 0xFF ) { - i += 7; index += 7; - continue; - } - else if( !(Connection->FuturePacketValidBytes[i / 8] & (1 << (i%8))) ) + int bit = index % 8; + Uint8 bitfield_byte = Connection->FuturePacketValidBytes[index / 8]; + if( (bitfield_byte & (1 << bit)) == 0 ) { + length = i; break; - - index ++; + } + + if( bitfield_byte == 0xFF ) { + int inc = 8 - bit; + i += inc - 1; + index += inc; + } + else { + index ++; + } if(index > TCP_WINDOW_SIZE) index -= TCP_WINDOW_SIZE; } - length = i; index = Connection->NextSequenceRcv % TCP_WINDOW_SIZE; @@ -797,7 +790,7 @@ void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection) SHORTREL( &Connection->lFuturePackets ); // Looks like we found one - TCP_INT_AppendRecieved(Connection, pkt); + TCP_INT_AppendRecieved(Connection, pkt->Data, pkt->Length); Connection->NextSequenceRcv += pkt->Length; free(pkt); } @@ -885,6 +878,38 @@ int TCP_DeallocatePort(Uint16 Port) return 1; } +tTCPConnection *TCP_int_CreateConnection(tInterface *Interface, enum eTCPConnectionState State) +{ + tTCPConnection *conn = calloc( sizeof(tTCPConnection) + TCP_WINDOW_SIZE + TCP_WINDOW_SIZE/8, 1 ); + + conn->State = State; + conn->Interface = Interface; + conn->LocalPort = -1; + conn->RemotePort = -1; + + conn->Node.ReferenceCount = 1; + conn->Node.ImplPtr = conn; + conn->Node.NumACLs = 1; + conn->Node.ACLs = &gVFS_ACL_EveryoneRW; + conn->Node.Type = &gTCP_ClientNodeType; + conn->Node.BufferFull = 1; // Cleared when connection opens + + conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE ); + #if 0 + conn->SentBuffer = RingBuffer_Create( TCP_SEND_BUFFER_SIZE ); + Semaphore_Init(conn->SentBufferSpace, 0, TCP_SEND_BUFFER_SIZE, "TCP SentBuffer", conn->Name); + #endif + + #if CACHE_FUTURE_PACKETS_IN_BYTES + // Future recieved data (ahead of the expected sequence number) + conn->FuturePacketData = (Uint8*)conn + sizeof(tTCPConnection); + conn->FuturePacketValidBytes = conn->FuturePacketData + TCP_WINDOW_SIZE; + #endif + + conn->DeferredACKTimer = Time_AllocateTimer( TCP_int_SendDelayedACK, conn); + return conn; +} + // --- Server tVFS_Node *TCP_Server_Init(tInterface *Interface) { @@ -1077,33 +1102,7 @@ void TCP_Server_Close(tVFS_Node *Node) */ tVFS_Node *TCP_Client_Init(tInterface *Interface) { - tTCPConnection *conn = calloc( sizeof(tTCPConnection) + TCP_WINDOW_SIZE + TCP_WINDOW_SIZE/8, 1 ); - - conn->State = TCP_ST_CLOSED; - conn->Interface = Interface; - conn->LocalPort = -1; - conn->RemotePort = -1; - - conn->Node.ReferenceCount = 1; - conn->Node.ImplPtr = conn; - conn->Node.NumACLs = 1; - conn->Node.ACLs = &gVFS_ACL_EveryoneRW; - conn->Node.Type = &gTCP_ClientNodeType; - conn->Node.BufferFull = 1; // Cleared when connection opens - - conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE ); - #if 0 - conn->SentBuffer = RingBuffer_Create( TCP_SEND_BUFFER_SIZE ); - Semaphore_Init(conn->SentBufferSpace, 0, TCP_SEND_BUFFER_SIZE, "TCP SentBuffer", conn->Name); - #endif - - #if CACHE_FUTURE_PACKETS_IN_BYTES - // Future recieved data (ahead of the expected sequence number) - conn->FuturePacketData = (Uint8*)conn + sizeof(tTCPConnection); - conn->FuturePacketValidBytes = conn->FuturePacketData + TCP_WINDOW_SIZE; - #endif - - conn->DeferredACKTimer = Time_AllocateTimer( TCP_int_SendDelayedACK, conn); + tTCPConnection *conn = TCP_int_CreateConnection(Interface, TCP_ST_CLOSED); SHORTLOCK(&glTCP_OutbountCons); conn->Next = gTCP_OutbountCons; @@ -1181,6 +1180,9 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const voi { char buf[sizeof(tTCPHeader)+Length]; tTCPHeader *packet = (void*)buf; + + // - Stop Delayed ACK timer (as this data packet ACKs) + Time_RemoveTimer(Connection->DeferredACKTimer); packet->SourcePort = htons(Connection->LocalPort); packet->DestPort = htons(Connection->RemotePort); @@ -1190,6 +1192,7 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const voi packet->AcknowlegementNumber = htonl(Connection->NextSequenceRcv); packet->SequenceNumber = htonl(Connection->NextSequenceSend); packet->Flags = TCP_FLAG_PSH|TCP_FLAG_ACK; // Hey, ACK if you can! + packet->UrgentPointer = 0; memcpy(packet->Options, Data, Length); diff --git a/KernelLand/Modules/IPStack/tcp.h b/KernelLand/Modules/IPStack/tcp.h index 42682ac7..dc7a0ffc 100644 --- a/KernelLand/Modules/IPStack/tcp.h +++ b/KernelLand/Modules/IPStack/tcp.h @@ -10,6 +10,8 @@ #include // tTimer #include // tSemaphore +#define CACHE_FUTURE_PACKETS_IN_BYTES 1 // Use a ring buffer to cache out of order packets? + typedef struct sTCPHeader tTCPHeader; typedef struct sTCPListener tTCPListener; typedef struct sTCPStoredPacket tTCPStoredPacket; @@ -151,7 +153,7 @@ struct sTCPConnection * \todo Convert this to a ring buffer and a bitmap of valid bytes * \{ */ - #if CACHE_FUTURE_PACKETS_OR_BYTES == bytes + #if CACHE_FUTURE_PACKETS_IN_BYTES Uint32 HighestSequenceRcvd; //!< Highest sequence number (within window) recieved Uint8 *FuturePacketData; //!< Future packet data (indexed by sequence number) Uint8 *FuturePacketValidBytes; //!< Valid byte bitmap (WINDOW_SIZE/8 bytes) diff --git a/KernelLand/Modules/IPStack/udp.c b/KernelLand/Modules/IPStack/udp.c index 8c5c6cae..325a09e8 100644 --- a/KernelLand/Modules/IPStack/udp.c +++ b/KernelLand/Modules/IPStack/udp.c @@ -38,7 +38,7 @@ tVFS_NodeType gUDP_NodeType = { .IOCtl = UDP_Channel_IOCtl, .Close = UDP_Channel_Close }; -tMutex glUDP_Channels; +tMutex glUDP_Channels; // TODO: Replace with a RWLock tUDPChannel *gpUDP_Channels; tMutex glUDP_Ports;