private static void setConnectionForWait(TCPConnection connection) { connection.State = TCPConnectionState.TIME_WAIT; if (connection.Type == TCPConnectionType.CONNECTION) { TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor)); buf->Size = 0; buf->Type = TCPPacketDescriptorTypes.CLOSE; buf->Data = null; buf->xid = 0; connection.ReceiveQueue.Push(buf); } else { /** * We need to remove the key here! */ /** * put RESET in QUEUE */ TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor)); buf->Size = 0; buf->Type = TCPPacketDescriptorTypes.CLOSE; buf->Data = null; buf->xid = connection.XID; connection.BaseConnection.ReceiveQueue.Push(buf); connection.BaseConnection.Clients.Remove(connection.XID); } }
/// <summary> /// Read from TCP connection /// </summary> /// <param name="buffer"></param> /// <param name="size"></param> /// <returns></returns> public static unsafe uint readImpl(Node node, uint offset, uint size, byte[] buffer) { TCPSocketDevice socket = (TCPSocketDevice)node.Cookie; if (!socket.m_ipSpecified) { return(0); } /** * Create entry */ TCPPacketDescriptor *entry = TCP.Read(socket.Connection); if (entry == null) { return(0); } /** * Check size of packet */ int totalSize = entry->Size + sizeof(TCPPacketSmallDescriptor); if (size > totalSize) { size = (uint)totalSize; } uint remaining = size; int entrySize = (int)size; /** * Copy descriptor */ if (size > sizeof(TCPPacketSmallDescriptor)) { entrySize = sizeof(TCPPacketSmallDescriptor); } Memory.Memcpy(Util.ObjectToVoidPtr(buffer), entry, entrySize); remaining -= (uint)entrySize; if (remaining > 0) { /** * Copy data */ Memory.Memcpy((byte *)Util.ObjectToVoidPtr(buffer) + entrySize, entry->Data, entrySize); } Heap.Free(entry); return(size); }
/// <summary> /// Syn received /// </summary> /// <param name="con"></param> /// <param name="buffer"></param> private unsafe static void SynReceivedHandler(TCPConnection con, byte *buffer) { TCPHeader *header = (TCPHeader *)buffer; /** * ACK received? */ if ((header->Flags & (FLAG_ACK)) > 0) { con.SequenceNumber = Byte.ReverseBytes(Byte.ReverseBytes(con.SequenceNumber) + 1); con.State = TCPConnectionState.ESTABLISHED; /** * Do we need to notify we have a new connection? */ if (con.Type == TCPConnectionType.CHILD_CONNECTION) { /** * Put ACCEPT in queue */ TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor)); buf->Size = 4; buf->Type = TCPPacketDescriptorTypes.ACCEPT; buf->Data = (byte *)Heap.Alloc(4); buf->xid = con.XID; for (int i = 0; i < 4; i++) { buf->Data[i] = con.IP[i]; } con.BaseConnection.ReceiveQueue.Push(buf); } } else { // Failed? } }
/// <summary> /// Established handler /// </summary> /// <param name="connection"></param> /// <param name="sourceIP"></param> /// <param name="buffer"></param> /// <param name="size"></param> private static unsafe void EstablishedHandler(TCPConnection connection, byte[] sourceIP, byte *buffer, uint size) { TCPHeader *header = (TCPHeader *)buffer; /** * * Possible flags: * - PUSH * - FIN */ if ((header->Flags & (FLAG_FIN | FLAG_ACK)) == (FLAG_FIN | FLAG_ACK)) { connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1); SendPacket(connection.IP, connection.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), connection.InPort, connection.DestPort, FLAG_ACK, null, 0); setConnectionForWait(connection); } else if ((header->Flags & FLAG_FIN) > 0) { /** * Todo: We need acknowledge our application here with status CLOSE_WAIT, for now we shift over to the LAST_ACK state */ connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1); connection.State = TCPConnectionState.LAST_ACK; SendPacket(connection.IP, connection.SequenceNumber, Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + 1), connection.InPort, connection.DestPort, FLAG_ACK, null, 0); Sleep(300); SendPacket(connection.IP, connection.SequenceNumber, 0x00, connection.InPort, connection.DestPort, FLAG_FIN, null, 0); } if ((header->Flags & FLAG_PSH) > 0) { int sizePacket = (int)size - sizeof(TCPHeader); /** * Push packet in Queue */ TCPPacketDescriptor *buf = (TCPPacketDescriptor *)Heap.Alloc(sizeof(TCPPacketDescriptor)); buf->Size = sizePacket; buf->Type = TCPPacketDescriptorTypes.RECEIVE; buf->Data = (byte *)Heap.Alloc(sizePacket); buf->xid = connection.XID; Memory.Memcpy(buf->Data, buffer + sizeof(TCPHeader), sizePacket); Queue queue = connection.ReceiveQueue; /** * Is this a connection or a member? */ if (connection.Type != TCPConnectionType.CONNECTION) { queue = connection.BaseConnection.ReceiveQueue; } queue.Push(buf); connection.AcknowledgeNumber = Byte.ReverseBytes(Byte.ReverseBytes(header->Sequence) + (uint)sizePacket); SendPacket(connection.IP, connection.SequenceNumber, connection.AcknowledgeNumber, connection.InPort, connection.DestPort, FLAG_ACK, null, 0); } else { } }