* Acess2 IP Stack
* - TCP Handling
*/
-#define DEBUG 1
+#define DEBUG 0
#include "ipstack.h"
#include "ipv4.h"
#include "ipv6.h"
#define TCP_DACK_THRESHOLD 4096
#define TCP_DACK_TIMEOUT 100
-#define TCP_DEBUG 1 // Set to non-0 to enable TCP packet logging
+#define TCP_DEBUG 0 // Set to non-0 to enable TCP packet logging
// === PROTOTYPES ===
void TCP_Initialise(void);
void TCP_SendPacket(tTCPConnection *Conn, tTCPHeader *Header, size_t DataLen, const void *Data);
void TCP_int_SendPacket(tInterface *Interface, const void *Dest, tTCPHeader *Header, size_t Length, const void *Data);
void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
+void TCP_IPError(tInterface *Interface, tIPErrorMode Mode, const void *Address, int Length, const void *Buffer);
int TCP_INT_HandleServerPacket(tInterface *Interface, tTCPListener *Server, const void *Address, tTCPHeader *Header, size_t Length);
int TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length);
int TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length);
};
tVFS_NodeType gTCP_ClientNodeType = {
.TypeName = "TCP Client/Connection",
+ .Flags = VFS_NODETYPEFLAG_STREAM,
.Read = TCP_Client_Read,
.Write = TCP_Client_Write,
.IOCtl = TCP_Client_IOCtl,
giTCP_NextOutPort += rand()%128;
IPStack_AddFile(&gTCP_ServerFile);
IPStack_AddFile(&gTCP_ClientFile);
- IPv4_RegisterCallback(IP4PROT_TCP, TCP_GetPacket);
+ IPv4_RegisterCallback(IP4PROT_TCP, TCP_GetPacket, TCP_IPError);
IPv6_RegisterCallback(IP4PROT_TCP, TCP_GetPacket);
}
}
}
+void TCP_IPError(tInterface *Interface, tIPErrorMode Mode, const void *Address, int Length, const void *Buffer)
+{
+ if( Length < sizeof(tTCPHeader) ) return ;
+
+ const tTCPHeader *hdr = Buffer;
+
+ // TODO: Handle errors for server connections
+
+ for( tTCPConnection *conn = gTCP_OutbountCons; conn; conn = conn->Next )
+ {
+ if(conn->Interface != Interface)
+ continue;
+ if(conn->RemotePort != ntohs(hdr->SourcePort))
+ continue;
+ if( IPStack_CompareAddress(conn->Interface->Type, &conn->RemoteIP, Address, -1) == 0 )
+ continue ;
+
+ // Mark an error on the interface
+ VFS_MarkError(&conn->Node, 1);
+ return ;
+ }
+}
+
/*
* Handle packets in LISTEN state
*/
conn->LastACKSequence = ntohl( Header->SequenceNumber );
conn->Node.ImplInt = Server->NextID ++;
+ conn->Node.Size = -1;
// Hmm... Theoretically, this lock will never have to wait,
// as the interface is locked to the watching thread, and this
conn->LocalPort = -1;
conn->RemotePort = -1;
+ conn->Node.Size = -1;
conn->Node.ReferenceCount = 1;
conn->Node.ImplPtr = conn;
conn->Node.NumACLs = 1;
TCP_SendPacket( Connection, packet, Length, Data );
+ // TODO: Start a retransmit time (if data is not ACKed in x seconds, send again)
+
Connection->NextSequenceSend += Length;
}