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;
#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
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]);
// 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)
{
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
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];
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;
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);
}
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)
{
*/
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;
{
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);
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);