Modules/IPStack - Add structure for propagating ICMP errors
[tpg/acess2.git] / KernelLand / Modules / IPStack / tcp.c
index 5c65a52..2854f30 100644 (file)
@@ -2,7 +2,7 @@
  * Acess2 IP Stack
  * - TCP Handling
  */
-#define DEBUG  1
+#define DEBUG  0
 #include "ipstack.h"
 #include "ipv4.h"
 #include "ipv6.h"
@@ -20,7 +20,7 @@
 #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);
@@ -28,6 +28,7 @@ void  TCP_StartConnection(tTCPConnection *Conn);
 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);
@@ -67,6 +68,7 @@ tVFS_NodeType gTCP_ServerNodeType = {
        };
 tVFS_NodeType  gTCP_ClientNodeType = {
        .TypeName = "TCP Client/Connection",
+       .Flags = VFS_NODETYPEFLAG_STREAM,
        .Read  = TCP_Client_Read,
        .Write = TCP_Client_Write,
        .IOCtl = TCP_Client_IOCtl,
@@ -93,7 +95,7 @@ void TCP_Initialise(void)
        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);
 }
 
@@ -303,6 +305,29 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        }
 }
 
+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
  */
@@ -345,6 +370,7 @@ int TCP_INT_HandleServerPacket(tInterface *Interface, tTCPListener *Server, cons
        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
@@ -899,6 +925,7 @@ tTCPConnection *TCP_int_CreateConnection(tInterface *Interface, enum eTCPConnect
        conn->LocalPort = -1;
        conn->RemotePort = -1;
 
+       conn->Node.Size = -1;
        conn->Node.ReferenceCount = 1;
        conn->Node.ImplPtr = conn;
        conn->Node.NumACLs = 1;
@@ -1264,6 +1291,8 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const voi
        
        TCP_SendPacket( Connection, packet, Length, Data );
        
+       // TODO: Start a retransmit time (if data is not ACKed in x seconds, send again)
+       
        Connection->NextSequenceSend += Length;
 }
 

UCC git Repository :: git.ucc.asn.au