Usermode/telnetd - Hacking it up :) Needs _SysSpawn implemented to work
[tpg/acess2.git] / Modules / IPStack / tcp.c
index 3952d8e..1415dea 100644 (file)
@@ -26,7 +26,7 @@ void  TCP_StartConnection(tTCPConnection *Conn);
 void   TCP_SendPacket(tTCPConnection *Conn, size_t Length, tTCPHeader *Data);
 void   TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffer);
 void   TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length);
-void   TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length);
+int    TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length);
 void   TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection);
 Uint16 TCP_GetUnusedPort();
  int   TCP_AllocatePort(Uint16 Port);
@@ -40,7 +40,7 @@ void  TCP_Server_Close(tVFS_Node *Node);
 // --- Client
 tVFS_Node      *TCP_Client_Init(tInterface *Interface);
 Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
-Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer);
  int   TCP_Client_IOCtl(tVFS_Node *Node, int ID, void *Data);
 void   TCP_Client_Close(tVFS_Node *Node);
 // --- Helpers
@@ -49,6 +49,20 @@ void TCP_Client_Close(tVFS_Node *Node);
 // === TEMPLATES ===
 tSocketFile    gTCP_ServerFile = {NULL, "tcps", TCP_Server_Init};
 tSocketFile    gTCP_ClientFile = {NULL, "tcpc", TCP_Client_Init};
+tVFS_NodeType  gTCP_ServerNodeType = {
+       .TypeName = "TCP Server",
+       .ReadDir = TCP_Server_ReadDir,
+       .FindDir = TCP_Server_FindDir,
+       .IOCtl   = TCP_Server_IOCtl,
+       .Close   = TCP_Server_Close
+       };
+tVFS_NodeType  gTCP_ClientNodeType = {
+       .TypeName = "TCP Client/Connection",
+       .Read  = TCP_Client_Read,
+       .Write = TCP_Client_Write,
+       .IOCtl = TCP_Client_IOCtl,
+       .Close = TCP_Client_Close
+       };
 
 // === GLOBALS ===
  int   giTCP_NumHalfopen = 0;
@@ -135,17 +149,10 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
        tTCPListener    *srv;
        tTCPConnection  *conn;
 
-       Log_Log("TCP", "TCP_GetPacket: SourcePort = %i, DestPort = %i",
-               ntohs(hdr->SourcePort), ntohs(hdr->DestPort));
-/*
-       Log_Log("TCP", "TCP_GetPacket: SequenceNumber = 0x%x", ntohl(hdr->SequenceNumber));
-       Log_Log("TCP", "TCP_GetPacket: AcknowlegementNumber = 0x%x", ntohl(hdr->AcknowlegementNumber));
-       Log_Log("TCP", "TCP_GetPacket: DataOffset = %i", hdr->DataOffset >> 4);
-       Log_Log("TCP", "TCP_GetPacket: WindowSize = %i", htons(hdr->WindowSize));
-       Log_Log("TCP", "TCP_GetPacket: Checksum = 0x%x", htons(hdr->Checksum));
-       Log_Log("TCP", "TCP_GetPacket: UrgentPointer = 0x%x", htons(hdr->UrgentPointer));
-*/
-       Log_Log("TCP", "TCP_GetPacket: Flags = %s%s%s%s%s%s%s%s",
+       Log_Log("TCP", "TCP_GetPacket: <Local>:%i from [%s]:%i, Flags= %s%s%s%s%s%s%s%s",
+               ntohs(hdr->SourcePort),
+               IPStack_PrintAddress(Interface->Type, Address),
+               ntohs(hdr->DestPort),
                (hdr->Flags & TCP_FLAG_CWR) ? "CWR " : "",
                (hdr->Flags & TCP_FLAG_ECE) ? "ECE " : "",
                (hdr->Flags & TCP_FLAG_URG) ? "URG " : "",
@@ -183,8 +190,6 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        // Is this in an established connection?
                        for( conn = srv->Connections; conn; conn = conn->Next )
                        {
-                               Log_Log("TCP", "TCP_GetPacket: conn->Interface(%p) == Interface(%p)",
-                                       conn->Interface, Interface);
                                // Check that it is coming in on the same interface
                                if(conn->Interface != Interface)        continue;
 
@@ -235,9 +240,7 @@ void TCP_GetPacket(tInterface *Interface, void *Address, int Length, void *Buffe
                        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
                        conn->Node.ImplPtr = conn;
                        conn->Node.ImplInt = srv->NextID ++;
-                       conn->Node.Read = TCP_Client_Read;
-                       conn->Node.Write = TCP_Client_Write;
-                       //conn->Node.Close = TCP_SrvConn_Close;
+                       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
@@ -424,11 +427,15 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
                // Is this packet the next expected packet?
                if( sequence_num == Connection->NextSequenceRcv )
                {
+                        int    rv;
                        // Ooh, Goodie! Add it to the recieved list
-                       TCP_INT_AppendRecieved(Connection,
+                       rv = TCP_INT_AppendRecieved(Connection,
                                (Uint8*)Header + (Header->DataOffset>>4)*4,
                                dataLen
                                );
+                       if(rv != 0) {
+                               break;
+                       }
                        Log_Log("TCP", "0x%08x += %i", Connection->NextSequenceRcv, dataLen);
                        Connection->NextSequenceRcv += dataLen;
                        
@@ -619,16 +626,19 @@ void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Head
  * \param Data Packet contents
  * \param Length       Length of \a Data
  */
-void TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length)
+int TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length)
 {
        Mutex_Acquire( &Connection->lRecievedPackets );
+
        if(Connection->RecievedBuffer->Length + Length > Connection->RecievedBuffer->Space )
        {
-               Log_Error("TCP", "Buffer filled, packet dropped (%s)",
-               //      TCP_INT_DumpConnection(Connection)
-                       ""
+               VFS_MarkAvaliable(&Connection->Node, 1);
+               Log_Error("TCP", "Buffer filled, packet dropped (:%i) - %i + %i > %i",
+                       Connection->LocalPort, Connection->RecievedBuffer->Length, Length,
+                       Connection->RecievedBuffer->Space
                        );
-               return ;
+               Mutex_Release( &Connection->lRecievedPackets );
+               return 1;
        }
        
        RingBuffer_Write( Connection->RecievedBuffer, Data, Length );
@@ -636,6 +646,7 @@ void TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t
        VFS_MarkAvaliable(&Connection->Node, 1);
        
        Mutex_Release( &Connection->lRecievedPackets );
+       return 0;
 }
 
 /**
@@ -765,7 +776,7 @@ Uint16 TCP_GetUnusedPort()
 
        // Get Next outbound port
        ret = giTCP_NextOutPort++;
-       while( gaTCP_PortBitmap[ret/32] & (1 << (ret%32)) )
+       while( gaTCP_PortBitmap[ret/32] & (1UL << (ret%32)) )
        {
                ret ++;
                giTCP_NextOutPort++;
@@ -836,10 +847,7 @@ tVFS_Node *TCP_Server_Init(tInterface *Interface)
        srv->Node.ImplPtr = srv;
        srv->Node.NumACLs = 1;
        srv->Node.ACLs = &gVFS_ACL_EveryoneRW;
-       srv->Node.ReadDir = TCP_Server_ReadDir;
-       srv->Node.FindDir = TCP_Server_FindDir;
-       srv->Node.IOCtl = TCP_Server_IOCtl;
-       srv->Node.Close = TCP_Server_Close;
+       srv->Node.Type = &gTCP_ServerNodeType;
 
        SHORTLOCK(&glTCP_Listeners);
        srv->Next = gTCP_Listeners;
@@ -906,30 +914,43 @@ tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name)
         int    id = atoi(Name);
        
        ENTER("pNode sName", Node, Name);
-       
-       // Sanity Check
-       itoa(tmp, id, 16, 8, '0');
-       if(strcmp(tmp, Name) != 0) {
-               LOG("'%s' != '%s' (%08x)", Name, tmp, id);
-               LEAVE('n');
-               return NULL;
+
+       // Check for a non-empty name
+       if( Name[0] ) 
+       {       
+               // Sanity Check
+               itoa(tmp, id, 16, 8, '0');
+               if(strcmp(tmp, Name) != 0) {
+                       LOG("'%s' != '%s' (%08x)", Name, tmp, id);
+                       LEAVE('n');
+                       return NULL;
+               }
+               
+               Log_Debug("TCP", "srv->Connections = %p", srv->Connections);
+               Log_Debug("TCP", "srv->NewConnections = %p", srv->NewConnections);
+               Log_Debug("TCP", "srv->ConnectionsTail = %p", srv->ConnectionsTail);
+               
+               // Search
+               SHORTLOCK( &srv->lConnections );
+               for(conn = srv->Connections;
+                       conn;
+                       conn = conn->Next)
+               {
+                       LOG("conn->Node.ImplInt = %i", conn->Node.ImplInt);
+                       if(conn->Node.ImplInt == id)    break;
+               }
+               SHORTREL( &srv->lConnections );
        }
-       
-       Log_Debug("TCP", "srv->Connections = %p", srv->Connections);
-       Log_Debug("TCP", "srv->NewConnections = %p", srv->NewConnections);
-       Log_Debug("TCP", "srv->ConnectionsTail = %p", srv->ConnectionsTail);
-       
-       // Search
-       SHORTLOCK( &srv->lConnections );
-       for(conn = srv->Connections;
-               conn;
-               conn = conn->Next)
+       // Empty Name - Check for a new connection and if it's there, open it
+       else
        {
-               LOG("conn->Node.ImplInt = %i", conn->Node.ImplInt);
-               if(conn->Node.ImplInt == id)    break;
+               SHORTLOCK( &srv->lConnections );
+               conn = srv->NewConnections;
+               if( conn != NULL )
+                       srv->NewConnections = conn->Next;
+               SHORTREL( &srv->lConnections );
        }
-       SHORTREL( &srv->lConnections );
-       
+               
        // If not found, ret NULL
        if(!conn) {
                LOG("Connection %i not found", id);
@@ -1004,10 +1025,7 @@ tVFS_Node *TCP_Client_Init(tInterface *Interface)
        conn->Node.ImplPtr = conn;
        conn->Node.NumACLs = 1;
        conn->Node.ACLs = &gVFS_ACL_EveryoneRW;
-       conn->Node.Read = TCP_Client_Read;
-       conn->Node.Write = TCP_Client_Write;
-       conn->Node.IOCtl = TCP_Client_IOCtl;
-       conn->Node.Close = TCP_Client_Close;
+       conn->Node.Type = &gTCP_ClientNodeType;
 
        conn->RecievedBuffer = RingBuffer_Create( TCP_RECIEVE_BUFFER_SIZE );
        #if 0
@@ -1087,7 +1105,7 @@ Uint64 TCP_Client_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buff
 /**
  * \brief Send a data packet on a connection
  */
-void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, void *Data)
+void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const void *Data)
 {
        char    buf[sizeof(tTCPHeader)+Length];
        tTCPHeader      *packet = (void*)buf;
@@ -1116,7 +1134,7 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, void *Dat
 /**
  * \brief Send some bytes on a connection
  */
-Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+Uint64 TCP_Client_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, const void *Buffer)
 {
        tTCPConnection  *conn = Node->ImplPtr;
        size_t  rem = Length;

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