Skip to content

Commit

Permalink
✨ Implement TCP Socket Bind Listen Accept Close
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinbreiz committed Nov 9, 2023
1 parent 382e348 commit 62117a4
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 30 deletions.
14 changes: 7 additions & 7 deletions source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public static ushort GetDynamicPort(int tries = 10)
/// <summary>
/// A list of currently active connections.
/// </summary>
internal static List<Tcp> Connections;
public static List<Tcp> Connections;

/// <summary>
/// String / enum correspondance (used for debugging)
Expand Down Expand Up @@ -248,7 +248,7 @@ internal static Tcp GetConnection(ushort localPort, ushort remotePort, Address l
/// <remarks>
/// If a connection is found that matches the local and remote ports and addresses, it will be removed from the list of connections.
/// </remarks>
internal static void RemoveConnection(ushort localPort, ushort remotePort, Address localIp, Address remoteIp)
public static void RemoveConnection(ushort localPort, ushort remotePort, Address localIp, Address remoteIp)
{
for (int i = 0; i < Connections.Count; i++)
{
Expand Down Expand Up @@ -280,14 +280,14 @@ internal static void RemoveConnection(ushort localPort, ushort remotePort, Addre
/// <summary>
/// The connection Transmission Control Block.
/// </summary>
internal TransmissionControlBlock TCB { get; set; }
public TransmissionControlBlock TCB { get; set; }

#endregion

/// <summary>
/// The RX buffer queue.
/// </summary>
internal Queue<TCPPacket> RxBuffer;
public Queue<TCPPacket> RxBuffer;

/// <summary>
/// The connection status.
Expand Down Expand Up @@ -714,7 +714,7 @@ private void WaitAndClose()
/// <summary>
/// Waits for a new TCP connection status.
/// </summary>
internal bool WaitStatus(Status status, int timeout)
public bool WaitStatus(Status status, int timeout)
{
int second = 0;
int _deltaT = 0;
Expand All @@ -737,7 +737,7 @@ internal bool WaitStatus(Status status, int timeout)
/// <summary>
/// Waits for a new TCP connection status (blocking).
/// </summary>
internal bool WaitStatus(Status status)
public bool WaitStatus(Status status)
{
while (Status != status);

Expand All @@ -747,7 +747,7 @@ internal bool WaitStatus(Status status)
/// <summary>
/// Sends an empty packet.
/// </summary>
internal void SendEmptyPacket(Flags flag)
public void SendEmptyPacket(Flags flag)
{
SendPacket(new TCPPacket(LocalEndPoint.Address, RemoteEndPoint.Address, LocalEndPoint.Port, RemoteEndPoint.Port, TCB.SndNxt, TCB.RcvNxt, 20, (byte)flag, TCB.SndWnd, 0));
}
Expand Down
7 changes: 7 additions & 0 deletions source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public static void set_PrivateAddress(uint address)
PrivateAddress = address;
}

public static void Ctor(IPAddress aThis, long address)
{
Cosmos.HAL.Global.debugger.Send("IPAddress - ctor long.");

PrivateAddress = (uint)address;
}

public static void Ctor(IPAddress aThis, ReadOnlySpan<byte> address)
{
Cosmos.HAL.Global.debugger.Send("IPAddress - ctor.");
Expand Down
37 changes: 37 additions & 0 deletions source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using IL2CPU.API.Attribs;

namespace Cosmos.System_Plugs.System.Net
{
[Plug(Target = typeof(IPEndPoint))]
public static class IPEndPointImpl
{
public static void Ctor(IPEndPoint aThis, long address, int port, [FieldAccess(Name = "System.Net.IPAddress System.Net.IPEndPoint._address")] ref IPAddress _address,
[FieldAccess(Name = "System.Int32 System.Net.IPEndPoint._port")] ref int _port)
{
Cosmos.HAL.Global.debugger.Send("IPEndPoint - start 1.");

_address = new IPAddress(address);
_port = port;

Cosmos.HAL.Global.debugger.Send("IPEndPoint - ok.");
}

public static void Ctor(IPEndPoint aThis, IPAddress address, int port, [FieldAccess(Name = "System.Net.IPAddress System.Net.IPEndPoint._address")] ref IPAddress _address,
[FieldAccess(Name = "System.Int32 System.Net.IPEndPoint._port")] ref int _port)
{
Cosmos.HAL.Global.debugger.Send("IPEndPoint - start. 2");

_address = address;
_port = port;

Cosmos.HAL.Global.debugger.Send("IPEndPoint - ok.");
}
}
}
105 changes: 100 additions & 5 deletions source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Cosmos.System.Network.IPv4.TCP;
using IL2CPU.API.Attribs;

namespace Cosmos.System_Plugs.System.Net.Sockets
{
[Plug(Target = typeof(Socket))]
public static class SocketImpl
{
private static Tcp StateMachine;
private static IPEndPoint EndPoint = null;

public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType)
{
Cosmos.HAL.Global.debugger.Send("Socket - ctor.");
Expand All @@ -21,10 +25,64 @@ public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType so
Cosmos.HAL.Global.debugger.Send("Socket - ctor.");
}

public static Socket Accept(Socket aThis)
public static void Bind(Socket aThis, EndPoint localEP)
{
Cosmos.HAL.Global.debugger.Send("Socket - Bind.");

EndPoint = localEP as IPEndPoint;
}

public static void Listen(Socket aThis)
{
Cosmos.HAL.Global.debugger.Send("Socket - Bind.");

Start(aThis);
}

public static Socket Accept(Socket aThis, [FieldAccess(Name = "System.Net.EndPoint System.Net.Sockets.Socket._remoteEndPoint")] ref EndPoint _remoteEndPoint
, [FieldAccess(Name = "System.Net.EndPoint System.Net.Sockets.Socket._remoteEndPoint")] ref EndPoint _localEndPoint)
{
Cosmos.HAL.Global.debugger.Send("Socket - Accept.");
return null;

if (StateMachine == null)
{
throw new Exception("The TcpListener is not started.");
}

if (StateMachine.Status == Status.CLOSED) // if TcpListener already accepted client, remove old one.
{
Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address);
Start(aThis);
}

while (StateMachine.WaitStatus(Status.ESTABLISHED) != true);

Cosmos.HAL.Global.debugger.Send("Socket - Accepted.");

Cosmos.HAL.Global.debugger.Send("Socket - Ip is " + StateMachine.RemoteEndPoint.Address.ToString() + ":" + StateMachine.RemoteEndPoint.Port);

_remoteEndPoint = new IPEndPoint(StateMachine.RemoteEndPoint.Address.ToUInt32(), StateMachine.RemoteEndPoint.Port);

_localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port);

Cosmos.HAL.Global.debugger.Send("Socket - ok.");

return aThis;
}

public static void Start(Socket aThis)
{
StateMachine = new((ushort)EndPoint.Port, 0, Cosmos.System.Network.IPv4.Address.Zero, Cosmos.System.Network.IPv4.Address.Zero);
StateMachine.RxBuffer = new Queue<TCPPacket>(8);
StateMachine.LocalEndPoint.Port = (ushort)EndPoint.Port;
StateMachine.Status = Status.LISTEN;

Tcp.Connections.Add(StateMachine);
}

public static void Connect(Socket aThis, IPAddress address, int port)
{
Cosmos.HAL.Global.debugger.Send("Socket - Connect.");
}

public static int Send(Socket aThis, ReadOnlySpan<byte> buffer, SocketFlags socketFlags)
Expand All @@ -37,14 +95,51 @@ public static int Receive(Socket aThis, Span<byte> buffer, SocketFlags socketFla
throw new NotImplementedException();
}

public static void Close(Socket aThis)
{
Cosmos.HAL.Global.debugger.Send("Socket - Closing.");

Close(aThis, 5000);
}

public static void Close(Socket aThis, int timeout)
{
throw new NotImplementedException();
Cosmos.HAL.Global.debugger.Send("Socket - Closing with timeout " + timeout);

if (StateMachine == null)
{
throw new Exception("The Socket is not started.");
}

if (StateMachine.Status == Status.LISTEN)
{
Cosmos.HAL.Global.debugger.Send("Socket - Closing remove con");

Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address);
StateMachine = null;
}
else if (StateMachine.Status == Status.ESTABLISHED)
{
Cosmos.HAL.Global.debugger.Send("Socket - Closing ESTABLISHED");

StateMachine.SendEmptyPacket(Flags.FIN | Flags.ACK);

StateMachine.TCB.SndNxt++;

StateMachine.Status = Status.FIN_WAIT1;

if (StateMachine.WaitStatus(Status.CLOSED, 5000) == false)
{
throw new Exception("Failed to close TCP connection!");
}

Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address);
}
}

public static void Dispose(Socket aThis)
{
throw new NotImplementedException();
aThis.Close(5000);
}
}
}
16 changes: 12 additions & 4 deletions source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ public static void Ctor(TcpClient aThis)
Cosmos.HAL.Global.debugger.Send("TcpClient - ctor.");
}

public static void Ctor(TcpClient aThis, Socket acceptedSocket)
public static void Ctor(TcpClient aThis, Socket acceptedSocket, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket)
{
Cosmos.HAL.Global.debugger.Send("TcpClient - ctor.");
Cosmos.HAL.Global.debugger.Send("TcpClient - ctor socket.");

_clientSocket = acceptedSocket;

Cosmos.HAL.Global.debugger.Send("TcpClient - ctor socket " + (acceptedSocket.RemoteEndPoint as IPEndPoint).Port + ":" + (acceptedSocket.RemoteEndPoint as IPEndPoint).Port);
}

public static int get_ReceiveBufferSize(TcpClient aThis)
Expand All @@ -32,9 +36,13 @@ public static NetworkStream GetStream(TcpClient aThis)
throw new NotImplementedException();
}

public static void Dispose(TcpClient aThis)
public static void Dispose(TcpClient aThis, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket)
{
throw new NotImplementedException();
Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose");

_clientSocket.Close();

Cosmos.HAL.Global.debugger.Send("TcpClient - Closed");
}
}
}
28 changes: 14 additions & 14 deletions source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ public static class TcpListenerImpl
private static Socket? _serverSocket;
private static IPEndPoint _serverSocketEP;

private static Cosmos.System.Network.IPv4.TCP.TcpListener tcpListener;

public static void Ctor(TcpListener aThis, IPEndPoint localEP)
{
if (localEP == null)
Expand All @@ -25,7 +23,6 @@ public static void Ctor(TcpListener aThis, IPEndPoint localEP)
}
_serverSocketEP = localEP;
_serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tcpListener = new Cosmos.System.Network.IPv4.TCP.TcpListener((ushort)localEP.Port);
}

public static void Ctor(TcpListener aThis, IPAddress localaddr, int port)
Expand All @@ -45,31 +42,34 @@ public static void Ctor(TcpListener aThis, IPAddress localaddr, int port)

_serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

tcpListener = new Cosmos.System.Network.IPv4.TCP.TcpListener((ushort)port);

Cosmos.HAL.Global.debugger.Send("TcpListener - _serverSocket ok.");
}

public static void Start(TcpListener aThis)
{
tcpListener.Start();
}
_serverSocket!.Bind(_serverSocketEP);

public static TcpClient AcceptTcpClient(TcpListener aThis)
{
if (!tcpListener.IsListening())
try
{
throw new InvalidOperationException("TcpListener not active.");
_serverSocket.Listen();
}
catch (SocketException)
{
// aThis.Stop();
throw;
}
}

public static TcpClient AcceptTcpClient(TcpListener aThis)
{
Cosmos.HAL.Global.debugger.Send("TcpListener - accepting client.");

var client = tcpListener.AcceptTcpClient();
Socket acceptedSocket = _serverSocket!.Accept();

Cosmos.HAL.Global.debugger.Send("TcpListener - AcceptTcpClient ok.");
Cosmos.HAL.Global.debugger.Send("TcpListener - socket accepted.");

var realClient = new TcpClient();
realClient.Client = _serverSocket;
realClient.Client = acceptedSocket;
return realClient;
}
}
Expand Down

0 comments on commit 62117a4

Please sign in to comment.