From 22e0880ebcad2d12c5f7eb012c0707a531a37ae2 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 7 Nov 2023 12:28:23 +0100 Subject: [PATCH 01/27] =?UTF-8?q?=E2=9C=A8=20Implement=20plug=20for=20TcpC?= =?UTF-8?q?lient,=20TcpListener=20and=20NetworkStream?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/Sockets/NetworkStreamImpl.cs | 34 +++++ .../System/Net/Sockets/SocketImpl.cs | 128 ++++++++++++++++++ .../System/Net/Sockets/TcpClientImpl.cs | 30 ++++ .../System/Net/Sockets/TcpListenerImpl.cs | 30 ++++ 4 files changed, 222 insertions(+) create mode 100644 source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs new file mode 100644 index 0000000000..7b00d5ecb0 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net.Sockets +{ + [Plug(Target = typeof(NetworkStream))] + public static class NetworkStreamImpl + { + public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + + public static void Flush(NetworkStream aThis) + { + throw new NotImplementedException(); + } + + public static void Dispose(NetworkStream aThis) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs new file mode 100644 index 0000000000..a70eb32af3 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net.Sockets +{ + [Plug(Target = typeof(Socket))] + public static class SocketImpl + { + public static void Dispose(Socket aThis) + { + throw new NotImplementedException(); + } + + public static void Dispose(Socket aThis, bool disposing) + { + throw new NotImplementedException(); + } + + #region Plugs + + public static bool AcceptAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool AcceptAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool ConnectAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool ConnectAsync(Socket aThis, object e, bool userSocket, bool saeaCancelable) + { + throw new NotImplementedException(); + } + + public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType, object e) + { + throw new NotImplementedException(); + } + + public static void CancelConnectAsync(object e) + { + throw new NotImplementedException(); + } + + public static bool DisconnectAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool DisconnectAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool ReceiveAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool ReceiveAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool ReceiveFromAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool ReceiveFromAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool ReceiveMessageFromAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool ReceiveMessageFromAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool SendAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool SendAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool SendPacketsAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool SendPacketsAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + public static bool SendToAsync(Socket aThis, object e) + { + throw new NotImplementedException(); + } + + public static bool SendToAsync(Socket aThis, object e, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + #endregion + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs new file mode 100644 index 0000000000..2331b05db4 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net.Sockets +{ + [Plug(Target = typeof(TcpClient))] + public static class TcpClientImpl + { + public static int get_ReceiveBufferSize(TcpClient aThis) + { + throw new NotImplementedException(); + } + + public static NetworkStream GetStream(TcpClient aThis) + { + throw new NotImplementedException(); + } + + public static void Dispose(TcpClient aThis) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs new file mode 100644 index 0000000000..a1d1eb7c87 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net.Sockets +{ + [Plug(Target = typeof(TcpListener))] + public static class TcpListenerImpl + { + public static void Ctor(TcpListener aThis, IPAddress localaddr, int port) + { + throw new NotImplementedException(); + } + + public static void Start(TcpListener aThis) + { + throw new NotImplementedException(); + } + + public static TcpClient AcceptTcpClient(TcpListener aThis) + { + throw new NotImplementedException(); + } + } +} From 89ac855411bae3d04585bb4a98716d2e5ee1923b Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 7 Nov 2023 17:08:28 +0100 Subject: [PATCH 02/27] =?UTF-8?q?=E2=9C=A8=20Implement=20plugs=20for=20Tcp?= =?UTF-8?q?Listener?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OverlappedValueTaskSourceImpl.cs | 19 +++ .../System/Threading/OverlappedImpl.cs | 20 ++++ .../Net/Sockets/SocketAsyncEventArgsImpl.cs | 20 ++++ .../System/Net/Sockets/SocketImpl.cs | 109 ------------------ .../Threading/PreAllocatedOverlappedImpl.cs | 20 ++++ 5 files changed, 79 insertions(+), 109 deletions(-) create mode 100644 source/Cosmos.Core_Plugs/Microsoft/OverlappedValueTaskSourceImpl.cs create mode 100644 source/Cosmos.Core_Plugs/System/Threading/OverlappedImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/Net/Sockets/SocketAsyncEventArgsImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/Threading/PreAllocatedOverlappedImpl.cs diff --git a/source/Cosmos.Core_Plugs/Microsoft/OverlappedValueTaskSourceImpl.cs b/source/Cosmos.Core_Plugs/Microsoft/OverlappedValueTaskSourceImpl.cs new file mode 100644 index 0000000000..c545959e85 --- /dev/null +++ b/source/Cosmos.Core_Plugs/Microsoft/OverlappedValueTaskSourceImpl.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.Core_Plugs.Microsoft +{ + [Plug("Microsoft.Win32.SafeHandles.SafeFileHandle+OverlappedValueTaskSource, System.Private.CoreLib", IsOptional = true)] + public static class OverlappedValueTaskSourceImpl + { + [PlugMethod(Signature = "System_Void__Microsoft_Win32_SafeHandles_SafeFileHandle_OverlappedValueTaskSource__cctor__")] + public static void Cctor() + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.Core_Plugs/System/Threading/OverlappedImpl.cs b/source/Cosmos.Core_Plugs/System/Threading/OverlappedImpl.cs new file mode 100644 index 0000000000..3cbafb2be1 --- /dev/null +++ b/source/Cosmos.Core_Plugs/System/Threading/OverlappedImpl.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.Core_Plugs.System.Threading +{ + [Plug(TargetName = "System.Threading.Overlapped, System.Private.CoreLib")] + class OverlappedImpl + { + [PlugMethod(Signature = "System_Void__System_Threading_Overlapped_Free_System_Threading_NativeOverlapped__")] + public unsafe static void Free(NativeOverlapped* a) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketAsyncEventArgsImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketAsyncEventArgsImpl.cs new file mode 100644 index 0000000000..a380e79934 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketAsyncEventArgsImpl.cs @@ -0,0 +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 IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net.Sockets +{ + [Plug(Target = typeof(SocketAsyncEventArgs))] + public static class SocketAsyncEventArgsImpl + { + public static void Cctor() + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index a70eb32af3..1a7d336016 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -15,114 +15,5 @@ public static void Dispose(Socket aThis) { throw new NotImplementedException(); } - - public static void Dispose(Socket aThis, bool disposing) - { - throw new NotImplementedException(); - } - - #region Plugs - - public static bool AcceptAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool AcceptAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool ConnectAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool ConnectAsync(Socket aThis, object e, bool userSocket, bool saeaCancelable) - { - throw new NotImplementedException(); - } - - public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType, object e) - { - throw new NotImplementedException(); - } - - public static void CancelConnectAsync(object e) - { - throw new NotImplementedException(); - } - - public static bool DisconnectAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool DisconnectAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool ReceiveAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool ReceiveAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool ReceiveFromAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool ReceiveFromAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool ReceiveMessageFromAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool ReceiveMessageFromAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool SendAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool SendAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool SendPacketsAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool SendPacketsAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - public static bool SendToAsync(Socket aThis, object e) - { - throw new NotImplementedException(); - } - - public static bool SendToAsync(Socket aThis, object e, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - - #endregion } } diff --git a/source/Cosmos.System2_Plugs/System/Threading/PreAllocatedOverlappedImpl.cs b/source/Cosmos.System2_Plugs/System/Threading/PreAllocatedOverlappedImpl.cs new file mode 100644 index 0000000000..b627b0ddb9 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Threading/PreAllocatedOverlappedImpl.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Threading +{ + [Plug(Target = typeof(PreAllocatedOverlapped))] + public static class PreAllocatedOverlappedImpl + { + [PlugMethod(Signature = "System_Void__System_Threading_PreAllocatedOverlapped_System_Threading_IDeferredDisposable_OnFinalRelease_System_Boolean_")] + public static void OnFinalRelease(SocketAsyncEventArgs aThis, bool disposed) + { + throw new NotImplementedException(); + } + } +} From 87a11ecd5fbfb0e89c54b9bf492f46b0e444a3b1 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 7 Nov 2023 17:18:26 +0100 Subject: [PATCH 03/27] =?UTF-8?q?=E2=9C=A8=20Implement=20Stream=20plugs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/IO/StreamImpl.cs | 24 +++++++++++++++++++ .../System/Net/Sockets/NetworkStreamImpl.cs | 5 ---- 2 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs diff --git a/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs b/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs new file mode 100644 index 0000000000..47a7a467ba --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.IO +{ + [Plug(Target = typeof(Stream))] + public static class StreamImpl + { + public static void Dispose(Stream aThis) + { + throw new NotImplementedException(); + } + + public static void Dispose(Stream aThis, bool disposing) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 7b00d5ecb0..7a8ddeeb9c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -25,10 +25,5 @@ public static void Flush(NetworkStream aThis) { throw new NotImplementedException(); } - - public static void Dispose(NetworkStream aThis) - { - throw new NotImplementedException(); - } } } From 3a35ed9c214384d7ef5099fec4d4b883340007e4 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 7 Nov 2023 17:29:48 +0100 Subject: [PATCH 04/27] =?UTF-8?q?=F0=9F=90=9B=20Stream=20read=20plug=20doe?= =?UTF-8?q?s=20not=20work?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs b/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs index 47a7a467ba..80d1d8b9de 100644 --- a/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs @@ -11,6 +11,11 @@ namespace Cosmos.System_Plugs.System.IO [Plug(Target = typeof(Stream))] public static class StreamImpl { + public static int Read(Stream aThis, Span buffer) + { + throw new NotImplementedException(); + } + public static void Dispose(Stream aThis) { throw new NotImplementedException(); From f33a693b5195f2e3f38be127a6427f0f3979067e Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Wed, 8 Nov 2023 15:45:37 +0100 Subject: [PATCH 05/27] =?UTF-8?q?=F0=9F=94=A5=20Remove=20useless=20Stream?= =?UTF-8?q?=20plug=20+=20implement=20shutdown=20plug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Interop/WinsockImpl.cs | 16 ++++++++++ .../System/IO/StreamImpl.cs | 29 ------------------- 2 files changed, 16 insertions(+), 29 deletions(-) create mode 100644 source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs delete mode 100644 source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs diff --git a/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs b/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs new file mode 100644 index 0000000000..a20c5fedee --- /dev/null +++ b/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs @@ -0,0 +1,16 @@ +using IL2CPU.API.Attribs; +using System; +using System.Net.Sockets; + +namespace Cosmos.Core_Plugs.Interop +{ + [Plug("Interop+Winsock, System.Net.Sockets", IsOptional = true)] + class WinsockImpl + { + [PlugMethod(Signature = "System_Net_Sockets_SocketError__Interop_Winsock_shutdown_System_Net_Sockets_SafeSocketHandle__System_Int32_")] + public static SocketError shutdown(SafeSocketHandle socketHandle, int how) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs b/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs deleted file mode 100644 index 80d1d8b9de..0000000000 --- a/source/Cosmos.System2_Plugs/System/IO/StreamImpl.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using System.Text; -using System.Threading.Tasks; -using IL2CPU.API.Attribs; - -namespace Cosmos.System_Plugs.System.IO -{ - [Plug(Target = typeof(Stream))] - public static class StreamImpl - { - public static int Read(Stream aThis, Span buffer) - { - throw new NotImplementedException(); - } - - public static void Dispose(Stream aThis) - { - throw new NotImplementedException(); - } - - public static void Dispose(Stream aThis, bool disposing) - { - throw new NotImplementedException(); - } - } -} From e4f3e64b6c249738fccefe49fdfe22116e28ec3a Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Wed, 8 Nov 2023 16:37:11 +0100 Subject: [PATCH 06/27] =?UTF-8?q?=E2=9C=A8=20Implement=20Socket=20plugs=20?= =?UTF-8?q?+=20needed=20stuff?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cosmos.Core_Plugs/Interop/Advapi32Impl.cs | 6 +++++ .../Cosmos.Core_Plugs/Interop/Kernel32Impl.cs | 12 +++++++++ .../Cosmos.Core_Plugs/Interop/WinsockImpl.cs | 25 +++++++++++++++++++ .../Interop/WinsockImpl.cs | 8 +++++- .../System/IO/RandomAccessImpl.cs | 19 ++++++++++++++ .../System/Net/Sockets/SocketImpl.cs | 15 +++++++++++ 6 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs create mode 100644 source/Cosmos.System2_Plugs/System/IO/RandomAccessImpl.cs diff --git a/source/Cosmos.Core_Plugs/Interop/Advapi32Impl.cs b/source/Cosmos.Core_Plugs/Interop/Advapi32Impl.cs index 802e3f6b14..131ace453d 100644 --- a/source/Cosmos.Core_Plugs/Interop/Advapi32Impl.cs +++ b/source/Cosmos.Core_Plugs/Interop/Advapi32Impl.cs @@ -94,5 +94,11 @@ public static int RegEnumKeyEx(object aSafeRegistryHandle, int aInt, char[] aCha { throw new NotImplementedException(); } + + [PlugMethod(Signature = "System_Int32__Interop_Advapi32_EventSetInformation_System_Int64__Interop_Advapi32_EVENT_INFO_CLASS__System_Void___System_UInt32_")] + public static unsafe int EventSetInformation(long registrationHandle, object informationClass, void* eventInformation, uint informationLength) + { + throw new NotImplementedException(); + } } } diff --git a/source/Cosmos.Core_Plugs/Interop/Kernel32Impl.cs b/source/Cosmos.Core_Plugs/Interop/Kernel32Impl.cs index 6beed11788..da871c5fab 100644 --- a/source/Cosmos.Core_Plugs/Interop/Kernel32Impl.cs +++ b/source/Cosmos.Core_Plugs/Interop/Kernel32Impl.cs @@ -133,5 +133,17 @@ public static unsafe int WriteFile(global::System.Runtime.InteropServices.SafeHa { throw new NotImplementedException(); } + + [PlugMethod(Signature = "System_Int32__Interop_Kernel32_ReadFile_System_Runtime_InteropServices_SafeHandle__System_Byte___System_Int32___System_Int32__System_Threading_NativeOverlapped__")] + public static unsafe int ReadFile(global::System.Runtime.InteropServices.SafeHandle aSafeHandle, byte* aBytePtr, int aInt, ref int aRefInt, global::System.Threading.NativeOverlapped* aNativeOverlappedPtr) + { + throw new NotImplementedException(); + } + + [PlugMethod(Signature = "System_Void__Interop_Kernel32_GetSystemInfo__Interop_Kernel32_SYSTEM_INFO_")] + public static unsafe void GetSystemInfo(object lpSystemInfo) + { + throw new NotImplementedException(); + } } } diff --git a/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs b/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs new file mode 100644 index 0000000000..a2ac900b1f --- /dev/null +++ b/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs @@ -0,0 +1,25 @@ +using IL2CPU.API.Attribs; +using System; +using System.Net.Sockets; + +namespace Cosmos.Core_Plugs.Interop +{ + [Plug("Interop+Winsock, System.Net.Sockets", IsOptional = true)] + public static unsafe class WinsockImpl + { + public static SocketError shutdown(SafeSocketHandle socketHandle, int how) + { + throw new NotImplementedException(); + } + + public static int recv(SafeSocketHandle socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags) + { + throw new NotImplementedException(); + } + + public static int send(SafeSocketHandle socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags) + { + throw new NotImplementedException(); + } + } +} diff --git a/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs b/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs index a20c5fedee..06d51de990 100644 --- a/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs +++ b/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs @@ -5,12 +5,18 @@ namespace Cosmos.Core_Plugs.Interop { [Plug("Interop+Winsock, System.Net.Sockets", IsOptional = true)] - class WinsockImpl + public static unsafe class WinsockImpl { [PlugMethod(Signature = "System_Net_Sockets_SocketError__Interop_Winsock_shutdown_System_Net_Sockets_SafeSocketHandle__System_Int32_")] public static SocketError shutdown(SafeSocketHandle socketHandle, int how) { throw new NotImplementedException(); } + + [PlugMethod(Signature = "System_Net_Sockets_SocketError__Interop_Winsock_shutdown_System_Net_Sockets_SafeSocketHandle__System_Int32_")] + public static int recv(SafeSocketHandle socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags) + { + throw new NotImplementedException(); + } } } diff --git a/source/Cosmos.System2_Plugs/System/IO/RandomAccessImpl.cs b/source/Cosmos.System2_Plugs/System/IO/RandomAccessImpl.cs new file mode 100644 index 0000000000..ef4d18da6e --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/IO/RandomAccessImpl.cs @@ -0,0 +1,19 @@ +using IL2CPU.API.Attribs; +using Microsoft.Win32.SafeHandles; + +namespace Cosmos.System_Plugs.System.IO +{ + [Plug(typeof(RandomAccess))] + public static class RandomAccessImpl + { + public static int ReadAtOffset(SafeFileHandle handle, Span buffer, long fileOffset) + { + throw new NotImplementedException(); + } + + public static int WriteAtOffset(SafeFileHandle handle, ReadOnlySpan buffer, long fileOffset) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 1a7d336016..b704948075 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -11,6 +11,21 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(Socket))] public static class SocketImpl { + public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags socketFlags) + { + throw new NotImplementedException(); + } + + public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) + { + throw new NotImplementedException(); + } + + public static void Close(Socket aThis, int timeout) + { + throw new NotImplementedException(); + } + public static void Dispose(Socket aThis) { throw new NotImplementedException(); From 0022a591f24cf7e6bc2f85b059e9e466ff85c6cc Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Wed, 8 Nov 2023 17:30:36 +0100 Subject: [PATCH 07/27] =?UTF-8?q?=E2=9C=A8=20Start=20work=20on=20Socket=20?= =?UTF-8?q?+=20TcpListener=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/IPAddressImpl.cs | 24 +++++++++++++++ .../System/Net/Sockets/SocketImpl.cs | 10 +++++++ .../System/Net/Sockets/TcpListenerImpl.cs | 30 ++++++++++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs new file mode 100644 index 0000000000..b3aeb3e0d0 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using IL2CPU.API.Attribs; + +namespace Cosmos.System_Plugs.System.Net +{ + [Plug(Target = typeof(IPAddress))] + public static class IPAddressImpl + { + public static void Ctor(IPAddress aThis, ReadOnlySpan address, [FieldAccess(Name = "System.Net.IPAddress System.Net.IPAddress.Any")] ref IPAddress aAny) + { + Cosmos.HAL.Global.debugger.Send("IPAddress - ctor."); + + + + Cosmos.HAL.Global.debugger.Send("IPAddress - aAny set."); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index b704948075..4cfa746b36 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -11,6 +11,16 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(Socket))] public static class SocketImpl { + public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) + { + Cosmos.HAL.Global.debugger.Send("Socket - ctor."); + } + + public static Socket Accept(Socket aThis) + { + throw new NotImplementedException(); + } + public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags socketFlags) { throw new NotImplementedException(); diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs index a1d1eb7c87..6bf3b0b2a7 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -12,9 +12,37 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(TcpListener))] public static class TcpListenerImpl { + private static Socket? _serverSocket; + private static IPEndPoint _serverSocketEP; + + public static void Ctor(TcpListener aThis, IPEndPoint localEP) + { + if (localEP == null) + { + throw new ArgumentNullException(nameof(localEP)); + } + _serverSocketEP = localEP; + _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + } + public static void Ctor(TcpListener aThis, IPAddress localaddr, int port) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("TcpListener - ctor."); + + if (localaddr == null) + { + throw new ArgumentNullException(nameof(localaddr)); + } + + Cosmos.HAL.Global.debugger.Send("TcpListener - localaddr ok."); + + _serverSocketEP = new IPEndPoint(localaddr, port); + + Cosmos.HAL.Global.debugger.Send("TcpListener - _serverSocketEP ok."); + + _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + + Cosmos.HAL.Global.debugger.Send("TcpListener - _serverSocket ok."); } public static void Start(TcpListener aThis) From 313543f4107b0b2ebb564f66ef2b20cb66c1e0a7 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 9 Nov 2023 06:38:10 +0100 Subject: [PATCH 08/27] =?UTF-8?q?=E2=9C=A8=20IPAdress=20plug=20base=20impl?= =?UTF-8?q?emented?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/IPAddressImpl.cs | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index b3aeb3e0d0..607f736e1c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -12,13 +12,42 @@ namespace Cosmos.System_Plugs.System.Net [Plug(Target = typeof(IPAddress))] public static class IPAddressImpl { - public static void Ctor(IPAddress aThis, ReadOnlySpan address, [FieldAccess(Name = "System.Net.IPAddress System.Net.IPAddress.Any")] ref IPAddress aAny) + private const int IPv4AddressBytes = 4; + private const int IPv6AddressBytes = 16; + private static uint PrivateAddress; + + public static uint get_PrivateAddress() { - Cosmos.HAL.Global.debugger.Send("IPAddress - ctor."); + return PrivateAddress; + } + + public static void set_PrivateAddress(uint address) + { + PrivateAddress = address; + } + public static void Ctor(IPAddress aThis, ReadOnlySpan address) + { + Cosmos.HAL.Global.debugger.Send("IPAddress - ctor."); + if (address.Length == IPv4AddressBytes) + { + PrivateAddress = (uint)(address[0] << 24 | address[1] << 16 | address[2] << 8 | address[3]); + } + else if (address.Length == IPv6AddressBytes) + { + throw new NotImplementedException("IPv6 not supported yet!"); + } + else + { + throw new ArgumentException("Bad IP address format", nameof(address)); + } - Cosmos.HAL.Global.debugger.Send("IPAddress - aAny set."); + Cosmos.HAL.Global.debugger.Send("IPAddress - " + address[0] + "." + address[1] + "." + address[2] + "." + address[3] + " set."); + } + + public static void Ctor(IPAddress aThis, ReadOnlySpan address, long scopeId) + { } } } From 382e34838476a3941a51f1be61072863d6750ea9 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 9 Nov 2023 07:37:50 +0100 Subject: [PATCH 09/27] =?UTF-8?q?=E2=9C=A8=20Implement=20TcpListener.Accep?= =?UTF-8?q?tTcpClient?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cosmos.Core_Plugs/Interop/WinsockImpl.cs | 5 +++++ source/Cosmos.System2/Network/IPv4/Address.cs | 2 +- .../System/Net/Sockets/SocketImpl.cs | 8 ++++++- .../System/Net/Sockets/TcpClientImpl.cs | 10 +++++++++ .../System/Net/Sockets/TcpListenerImpl.cs | 22 +++++++++++++++++-- 5 files changed, 43 insertions(+), 4 deletions(-) diff --git a/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs b/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs index a2ac900b1f..7b6fd32126 100644 --- a/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs +++ b/source/Cosmos.Core_Plugs/Interop/WinsockImpl.cs @@ -21,5 +21,10 @@ public static int send(SafeSocketHandle socketHandle, byte* pinnedBuffer, int le { throw new NotImplementedException(); } + + public static int bind(SafeSocketHandle socketHandle, byte[] socketAddress, int socketAddressSize) + { + throw new NotImplementedException(); + } } } diff --git a/source/Cosmos.System2/Network/IPv4/Address.cs b/source/Cosmos.System2/Network/IPv4/Address.cs index c48b91099e..9d1d3c3828 100644 --- a/source/Cosmos.System2/Network/IPv4/Address.cs +++ b/source/Cosmos.System2/Network/IPv4/Address.cs @@ -161,7 +161,7 @@ public byte[] ToByteArray() /// /// Convert this address to a 32-bit number. /// - private uint ToUInt32() + public uint ToUInt32() { return (uint)((Parts[0] << 24) | (Parts[1] << 16) | (Parts[2] << 8) | (Parts[3] << 0)); } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 4cfa746b36..e4a0be6b02 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -11,6 +11,11 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(Socket))] public static class SocketImpl { + public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType) + { + Cosmos.HAL.Global.debugger.Send("Socket - ctor."); + } + public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) { Cosmos.HAL.Global.debugger.Send("Socket - ctor."); @@ -18,7 +23,8 @@ public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType so public static Socket Accept(Socket aThis) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("Socket - Accept."); + return null; } public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags socketFlags) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 2331b05db4..adf2e7b8cc 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -12,6 +12,16 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(TcpClient))] public static class TcpClientImpl { + public static void Ctor(TcpClient aThis) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); + } + + public static void Ctor(TcpClient aThis, Socket acceptedSocket) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); + } + public static int get_ReceiveBufferSize(TcpClient aThis) { throw new NotImplementedException(); diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs index 6bf3b0b2a7..261ef01673 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -15,6 +15,8 @@ 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) @@ -23,6 +25,7 @@ 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) @@ -42,17 +45,32 @@ 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) { - throw new NotImplementedException(); + tcpListener.Start(); } public static TcpClient AcceptTcpClient(TcpListener aThis) { - throw new NotImplementedException(); + if (!tcpListener.IsListening()) + { + throw new InvalidOperationException("TcpListener not active."); + } + + Cosmos.HAL.Global.debugger.Send("TcpListener - accepting client."); + + var client = tcpListener.AcceptTcpClient(); + + Cosmos.HAL.Global.debugger.Send("TcpListener - AcceptTcpClient ok."); + + var realClient = new TcpClient(); + realClient.Client = _serverSocket; + return realClient; } } } From 62117a4971d5afd1dbeb62862b6863bfad8e167b Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 9 Nov 2023 21:00:20 +0100 Subject: [PATCH 10/27] =?UTF-8?q?=E2=9C=A8=20Implement=20TCP=20Socket=20Bi?= =?UTF-8?q?nd=20Listen=20Accept=20Close?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 14 +-- .../System/Net/IPAddressImpl.cs | 7 ++ .../System/Net/IPEndPointImpl.cs | 37 ++++++ .../System/Net/Sockets/SocketImpl.cs | 105 +++++++++++++++++- .../System/Net/Sockets/TcpClientImpl.cs | 16 ++- .../System/Net/Sockets/TcpListenerImpl.cs | 28 ++--- 6 files changed, 177 insertions(+), 30 deletions(-) create mode 100644 source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index 2506c53f9f..d2de247bc8 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -184,7 +184,7 @@ public static ushort GetDynamicPort(int tries = 10) /// /// A list of currently active connections. /// - internal static List Connections; + public static List Connections; /// /// String / enum correspondance (used for debugging) @@ -248,7 +248,7 @@ internal static Tcp GetConnection(ushort localPort, ushort remotePort, Address l /// /// If a connection is found that matches the local and remote ports and addresses, it will be removed from the list of connections. /// - 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++) { @@ -280,14 +280,14 @@ internal static void RemoveConnection(ushort localPort, ushort remotePort, Addre /// /// The connection Transmission Control Block. /// - internal TransmissionControlBlock TCB { get; set; } + public TransmissionControlBlock TCB { get; set; } #endregion /// /// The RX buffer queue. /// - internal Queue RxBuffer; + public Queue RxBuffer; /// /// The connection status. @@ -714,7 +714,7 @@ private void WaitAndClose() /// /// Waits for a new TCP connection status. /// - internal bool WaitStatus(Status status, int timeout) + public bool WaitStatus(Status status, int timeout) { int second = 0; int _deltaT = 0; @@ -737,7 +737,7 @@ internal bool WaitStatus(Status status, int timeout) /// /// Waits for a new TCP connection status (blocking). /// - internal bool WaitStatus(Status status) + public bool WaitStatus(Status status) { while (Status != status); @@ -747,7 +747,7 @@ internal bool WaitStatus(Status status) /// /// Sends an empty packet. /// - 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)); } diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 607f736e1c..430fa9973d 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -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 address) { Cosmos.HAL.Global.debugger.Send("IPAddress - ctor."); diff --git a/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs new file mode 100644 index 0000000000..5821229885 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs @@ -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."); + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index e4a0be6b02..f03117c963 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -1,9 +1,10 @@ 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 @@ -11,6 +12,9 @@ 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."); @@ -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(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 buffer, SocketFlags socketFlags) @@ -37,14 +95,51 @@ public static int Receive(Socket aThis, Span 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); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index adf2e7b8cc..003c7d3c2c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -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) @@ -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"); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs index 261ef01673..5e0bf26c6e 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -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) @@ -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) @@ -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; } } From 6f4593969032c0fc45ffd7eedfcdc1d26a099463 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Thu, 9 Nov 2023 21:12:25 +0100 Subject: [PATCH 11/27] =?UTF-8?q?=F0=9F=A5=85=20Throw=20Socket=20errors=20?= =?UTF-8?q?if=20not=20TCP=20stream?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/Sockets/SocketImpl.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index f03117c963..a67b19e921 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -17,14 +17,34 @@ public static class SocketImpl public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType) { + CheckSocket(aThis, socketType, protocolType); + Cosmos.HAL.Global.debugger.Send("Socket - ctor."); } public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) { + CheckSocket(aThis, socketType, protocolType); + Cosmos.HAL.Global.debugger.Send("Socket - ctor."); } + public static void CheckSocket(Socket aThis, SocketType socketType, ProtocolType protocolType) + { + if (socketType != SocketType.Stream) + { + throw new NotImplementedException("Only stream sockets implemented."); + } + if (protocolType == ProtocolType.Udp) + { + throw new NotImplementedException("Only TCP sockets supported. UDP Coming soon ;)"); + } + else if (protocolType != ProtocolType.Tcp) + { + throw new NotImplementedException("Only TCP sockets supported."); + } + } + public static void Bind(Socket aThis, EndPoint localEP) { Cosmos.HAL.Global.debugger.Send("Socket - Bind."); From be9427e984b823c8d70946964d3d87df38e8def2 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Fri, 10 Nov 2023 16:50:15 +0100 Subject: [PATCH 12/27] =?UTF-8?q?=E2=9C=A8=20Implement=20Socket.Receive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 4 +- .../System/Net/Sockets/NetworkStreamImpl.cs | 43 ++++++++++++++- .../System/Net/Sockets/SocketImpl.cs | 52 ++++++++++++++++++- .../System/Net/Sockets/TcpClientImpl.cs | 22 ++++++-- 4 files changed, 113 insertions(+), 8 deletions(-) diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index d2de247bc8..e4c33b4560 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -189,7 +189,7 @@ public static ushort GetDynamicPort(int tries = 10) /// /// String / enum correspondance (used for debugging) /// - internal static readonly string[] Table; + public static readonly string[] Table; static Tcp() { @@ -297,7 +297,7 @@ public static void RemoveConnection(ushort localPort, ushort remotePort, Address /// /// The received data buffer. /// - internal byte[] Data { get; set; } + public byte[] Data { get; set; } public Tcp(ushort localPort, ushort remotePort, Address localIp, Address remoteIp) { diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 7a8ddeeb9c..af59a28b18 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -11,9 +11,48 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(NetworkStream))] public static class NetworkStreamImpl { - public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count) + public static void Ctor(NetworkStream aThis, Socket socket, FileAccess access, bool ownsSocket, + [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket, + [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._ownsSocket")] ref bool _ownsSocket, + [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._readable")] ref bool _readable, + [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._writeable")] ref bool _writeable + ) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("NetworkStream - ctor."); + + if (socket == null) + { + throw new ArgumentNullException(nameof(socket)); + } + if (!socket.Connected) + { + throw new IOException("Socket not connected."); + } + + _streamSocket = socket; + _ownsSocket = ownsSocket; + + switch (access) + { + case FileAccess.Read: + _readable = true; + break; + case FileAccess.Write: + _writeable = true; + break; + case FileAccess.ReadWrite: + default: // assume FileAccess.ReadWrite + _readable = true; + _writeable = true; + break; + } + } + + public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket) + { + Cosmos.HAL.Global.debugger.Send("NetworkStream - Read."); + + return _streamSocket.Receive(buffer, offset, count, 0); } public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index a67b19e921..5b80fac53c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -45,6 +45,22 @@ public static void CheckSocket(Socket aThis, SocketType socketType, ProtocolType } } + public static bool get_Connected(Socket aThis) + { + Cosmos.HAL.Global.debugger.Send("Socket - get_Connected."); + + Cosmos.HAL.Global.debugger.Send("Socket - StateMachine.Status=" + Tcp.Table[(int)StateMachine.Status] ); + + return StateMachine.Status == Status.ESTABLISHED; + } + + public static bool Poll(Socket aThis, int microSeconds, SelectMode mode) + { + Cosmos.HAL.Global.debugger.Send("Socket - Poll."); + + return StateMachine.Status == Status.ESTABLISHED; + } + public static void Bind(Socket aThis, EndPoint localEP) { Cosmos.HAL.Global.debugger.Send("Socket - Bind."); @@ -112,7 +128,41 @@ public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags sock public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("Socket - Receive Span."); + + return 0; + } + + public static int Receive(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) + { + Cosmos.HAL.Global.debugger.Send("Socket - Receive byte[]."); + + while (StateMachine.Data == null || StateMachine.Data.Length == 0) + { + if (StateMachine.Status != Status.ESTABLISHED) + { + throw new Exception("Client must be connected before receiving data."); + } + } + + StateMachine.RxBuffer.Dequeue(); + + // Copy received buffer data in buffer arg + Cosmos.HAL.Global.debugger.Send("Socket - Receive StateMachine.Data.Length=" + StateMachine.Data.Length); + Cosmos.HAL.Global.debugger.Send("Socket - Receive size=" + size); + int bytesToCopy = Math.Min(StateMachine.Data.Length, size); + Cosmos.HAL.Global.debugger.Send("Socket - Receive bytesToCopy=" + bytesToCopy); + Buffer.BlockCopy(StateMachine.Data, 0, buffer, offset, bytesToCopy); + Cosmos.HAL.Global.debugger.Send("Socket - Receive copied to buffer"); + + // Update buffer data by deleting read data + byte[] remainingData = new byte[StateMachine.Data.Length - bytesToCopy]; + Buffer.BlockCopy(StateMachine.Data, bytesToCopy, remainingData, 0, remainingData.Length); + StateMachine.Data = remainingData; + + Cosmos.HAL.Global.debugger.Send("Socket - Receive moved data."); + + return bytesToCopy; } public static void Close(Socket aThis) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 003c7d3c2c..a7ee302cd5 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -28,12 +28,28 @@ public static void Ctor(TcpClient aThis, Socket acceptedSocket, [FieldAccess(Nam public static int get_ReceiveBufferSize(TcpClient aThis) { - throw new NotImplementedException(); + //TODO implement Socket.SetSocketOption Socket.GetSocketOption + return 8192; } - public static NetworkStream GetStream(TcpClient aThis) + public static NetworkStream GetStream(TcpClient aThis, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket, + [FieldAccess(Name = "System.Net.Sockets.NetworkStream System.Net.Sockets.TcpClient._dataStream")] ref NetworkStream _dataStream) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("TcpClient - GetStream"); + + if (_clientSocket == null) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - GetStream _clientSocket null"); + throw new NullReferenceException(); + } + if (_dataStream == null) + { + _dataStream = new NetworkStream(_clientSocket, true); + } + + Cosmos.HAL.Global.debugger.Send("TcpClient - Created network stream"); + + return _dataStream; } public static void Dispose(TcpClient aThis, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket) From bce8f13e650dc9fb5110d3a9934139b9fd421d63 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Fri, 10 Nov 2023 17:10:17 +0100 Subject: [PATCH 13/27] =?UTF-8?q?=F0=9F=90=9B=20Fix=20NetworkStream=20disp?= =?UTF-8?q?ose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/Sockets/NetworkStreamImpl.cs | 10 ++++++++++ .../System/Net/Sockets/SocketImpl.cs | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index af59a28b18..64a4a1b7db 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -64,5 +64,15 @@ public static void Flush(NetworkStream aThis) { throw new NotImplementedException(); } + + public static void Dispose(NetworkStream aThis) + { + Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose."); + } + + public static void Dispose(NetworkStream aThis, bool disposing) + { + Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose."); + } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 5b80fac53c..70c4c3c56f 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -141,7 +141,8 @@ public static int Receive(Socket aThis, byte[] buffer, int offset, int size, Soc { if (StateMachine.Status != Status.ESTABLISHED) { - throw new Exception("Client must be connected before receiving data."); + Cosmos.HAL.Global.debugger.Send("Socket - Client must be connected before receiving data.."); + return 0; } } From 6179d929589e817bb5c43416f23d9bf09d57cac5 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Fri, 10 Nov 2023 17:22:12 +0100 Subject: [PATCH 14/27] =?UTF-8?q?=E2=9C=A8=20Implement=20Socket.Send?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/Sockets/NetworkStreamImpl.cs | 6 ++- .../System/Net/Sockets/SocketImpl.cs | 40 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 64a4a1b7db..a0b93e28a8 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -55,9 +55,11 @@ public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count return _streamSocket.Receive(buffer, offset, count, 0); } - public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count) + public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket) { - throw new NotImplementedException(); + Cosmos.HAL.Global.debugger.Send("NetworkStream - Write."); + + return _streamSocket.Send(buffer, offset, count, 0); } public static void Flush(NetworkStream aThis) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 70c4c3c56f..5b6cded0e1 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -4,6 +4,9 @@ using System.Net; using System.Net.Sockets; using System.Text; +using Cosmos.System.Helpers; +using Cosmos.System.Network.IPv4; +using Cosmos.System.Network; using Cosmos.System.Network.IPv4.TCP; using IL2CPU.API.Attribs; @@ -119,6 +122,8 @@ public static void Start(Socket aThis) public static void Connect(Socket aThis, IPAddress address, int port) { Cosmos.HAL.Global.debugger.Send("Socket - Connect."); + + throw new NotImplementedException(); } public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags socketFlags) @@ -126,6 +131,41 @@ public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags sock throw new NotImplementedException(); } + public static int Send(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) + { + if (StateMachine.RemoteEndPoint.Address == null || StateMachine.RemoteEndPoint.Port == 0) + { + throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); + } + if (StateMachine.Status != Status.ESTABLISHED) + { + throw new Exception("Client must be connected before sending data."); + } + if (buffer.Length > 536) + { + var chunks = ArrayHelper.ArraySplit(buffer, 536); + + for (int i = 0; i < chunks.Length; i++) + { + var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, i == chunks.Length - 2 ? (byte)(Flags.PSH | Flags.ACK) : (byte)Flags.ACK, StateMachine.TCB.SndWnd, 0, chunks[i]); + OutgoingBuffer.AddPacket(packet); + NetworkStack.Update(); + + StateMachine.TCB.SndNxt += (uint)chunks[i].Length; + } + } + else + { + var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, (byte)(Flags.PSH | Flags.ACK), StateMachine.TCB.SndWnd, 0, data); + OutgoingBuffer.AddPacket(packet); + NetworkStack.Update(); + + StateMachine.TCB.SndNxt += (uint)buffer.Length; + } + + return 0; + } + public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) { Cosmos.HAL.Global.debugger.Send("Socket - Receive Span."); From 48d8a9820e95ba72829c721293c6030793ad0053 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Sun, 3 Dec 2023 23:46:58 +0100 Subject: [PATCH 15/27] =?UTF-8?q?=F0=9F=90=9B=20Fix=20closing=20connection?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 22 ++- .../System/Net/IPAddressImpl.cs | 5 + .../System/Net/IPEndPointImpl.cs | 5 + .../System/Net/Sockets/NetworkStreamImpl.cs | 27 +++- .../System/Net/Sockets/SocketImpl.cs | 126 +++++++++++++++--- .../System/Net/Sockets/TcpClientImpl.cs | 56 +++++++- .../System/Net/Sockets/TcpListenerImpl.cs | 5 + 7 files changed, 219 insertions(+), 27 deletions(-) diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index e4c33b4560..65dab5a6c5 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -294,6 +294,11 @@ public static void RemoveConnection(ushort localPort, ushort remotePort, Address /// public Status Status; + /// + /// Check send data confirmation. + /// + public bool WaitingSendAck = false; + /// /// The received data buffer. /// @@ -330,9 +335,13 @@ internal void ReceiveData(TCPPacket packet) } else { + Cosmos.HAL.Global.debugger.Send("Tcp - Received TCP"); + // Check sequence number and segment data. if (TCB.RcvNxt <= packet.SequenceNumber && packet.SequenceNumber + packet.TCP_DataLength < TCB.RcvNxt + TCB.RcvWnd) { + Cosmos.HAL.Global.debugger.Send("Tcp - Received TCP ok."); + switch (Status) { case Status.SYN_RECEIVED: @@ -359,7 +368,7 @@ internal void ReceiveData(TCPPacket packet) case Status.TIME_WAIT: break; default: - NetworkStack.Debugger.Send("Unknown TCP connection state."); + NetworkStack.Debugger.Send("Unknown TCP connection state = " + (int)Status); break; } } @@ -547,6 +556,8 @@ public void ProcessEstablished(TCPPacket packet) { if (packet.ACK) { + Cosmos.HAL.Global.debugger.Send("Tcp - Received ACK"); + if (TCB.SndUna < packet.AckNumber && packet.AckNumber <= TCB.SndNxt) { TCB.SndUna = packet.AckNumber; @@ -595,12 +606,19 @@ public void ProcessEstablished(TCPPacket packet) return; } + if (WaitingSendAck) + { + Cosmos.HAL.Global.debugger.Send("Tcp - WaitingSendAck = false"); + + WaitingSendAck = false; + } + if (packet.TCP_DataLength > 0 && packet.SequenceNumber >= TCB.RcvNxt) //packet sequencing { TCB.RcvNxt += packet.TCP_DataLength; Data = ArrayHelper.Concat(Data, packet.TCP_Data); - } + } } if (packet.RST) { diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 430fa9973d..0ad0ff3d88 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -26,6 +26,11 @@ public static void set_PrivateAddress(uint address) PrivateAddress = address; } + public static void CCtor(IPAddress aThis) + { + Cosmos.HAL.Global.debugger.Send("IPAddress - cctor."); + } + public static void Ctor(IPAddress aThis, long address) { Cosmos.HAL.Global.debugger.Send("IPAddress - ctor long."); diff --git a/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs index 5821229885..43ae11a531 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs @@ -12,6 +12,11 @@ namespace Cosmos.System_Plugs.System.Net [Plug(Target = typeof(IPEndPoint))] public static class IPEndPointImpl { + public static void CCtor(IPEndPoint aThis) + { + Cosmos.HAL.Global.debugger.Send("IPEndPoint - cctor."); + } + 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) { diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index a0b93e28a8..2479f7ba9b 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -11,8 +11,14 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(NetworkStream))] public static class NetworkStreamImpl { + private static Socket _streamSocket; + + public static void CCtor(NetworkStream aThis) + { + Cosmos.HAL.Global.debugger.Send("NetworkStream - cctor."); + } + public static void Ctor(NetworkStream aThis, Socket socket, FileAccess access, bool ownsSocket, - [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._ownsSocket")] ref bool _ownsSocket, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._readable")] ref bool _readable, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._writeable")] ref bool _writeable @@ -48,14 +54,14 @@ public static void Ctor(NetworkStream aThis, Socket socket, FileAccess access, b } } - public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket) + public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count) { Cosmos.HAL.Global.debugger.Send("NetworkStream - Read."); return _streamSocket.Receive(buffer, offset, count, 0); } - public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.NetworkStream._streamSocket")] ref Socket _streamSocket) + public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count) { Cosmos.HAL.Global.debugger.Send("NetworkStream - Write."); @@ -67,14 +73,25 @@ public static void Flush(NetworkStream aThis) throw new NotImplementedException(); } + public static void Close(NetworkStream aThis) + { + Cosmos.HAL.Global.debugger.Send("NetworkStream - Close"); + + _streamSocket.Close(); + } + public static void Dispose(NetworkStream aThis) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose."); + Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose 1."); + + _streamSocket.Close(); } public static void Dispose(NetworkStream aThis, bool disposing) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose."); + Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose 2."); + + _streamSocket.Close(); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 5b6cded0e1..36f2fd1323 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -5,8 +5,6 @@ using System.Net.Sockets; using System.Text; using Cosmos.System.Helpers; -using Cosmos.System.Network.IPv4; -using Cosmos.System.Network; using Cosmos.System.Network.IPv4.TCP; using IL2CPU.API.Attribs; @@ -18,6 +16,14 @@ public static class SocketImpl private static Tcp StateMachine; private static IPEndPoint EndPoint = null; + private static EndPoint _localEndPoint; + private static EndPoint _remoteEndPoint; + + public static void CCtor(Socket aThis) + { + Cosmos.HAL.Global.debugger.Send("Socket - cctor."); + } + public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType) { CheckSocket(aThis, socketType, protocolType); @@ -78,22 +84,30 @@ public static void Listen(Socket aThis) 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) + public static Socket Accept(Socket aThis) { Cosmos.HAL.Global.debugger.Send("Socket - Accept."); if (StateMachine == null) { - throw new Exception("The TcpListener is not started."); + Cosmos.HAL.Global.debugger.Send("The TcpListener is not started"); + + Start(aThis); } + Cosmos.HAL.Global.debugger.Send("Socket - Accept 1."); + if (StateMachine.Status == Status.CLOSED) // if TcpListener already accepted client, remove old one. { + Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.1"); Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); + Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.2"); Start(aThis); + Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.3"); } + Cosmos.HAL.Global.debugger.Send("Socket - Accept 2."); + while (StateMachine.WaitStatus(Status.ESTABLISHED) != true); Cosmos.HAL.Global.debugger.Send("Socket - Accepted."); @@ -133,39 +147,90 @@ public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags sock public static int Send(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) { + Cosmos.HAL.Global.debugger.Send("Socket - Send."); + if (StateMachine.RemoteEndPoint.Address == null || StateMachine.RemoteEndPoint.Port == 0) { + Cosmos.HAL.Global.debugger.Send("Socket - Must establish a default remote host by calling Connect() before using this Send() overload."); + throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); } if (StateMachine.Status != Status.ESTABLISHED) { + Cosmos.HAL.Global.debugger.Send("Socket - Client must be connected before sending data.."); + throw new Exception("Client must be connected before sending data."); } - if (buffer.Length > 536) + + if (offset < 0 || size < 0 || (offset + size) > buffer.Length) + { + Cosmos.HAL.Global.debugger.Send("Socket - Invalid offset or size"); + + throw new ArgumentOutOfRangeException("Invalid offset or size"); + } + + int bytesSent = 0; + + if (size > 536) // why 536bytes chunk size?? { - var chunks = ArrayHelper.ArraySplit(buffer, 536); + Cosmos.HAL.Global.debugger.Send("Socket - chunked"); + + byte[] data = new byte[size]; + Buffer.BlockCopy(buffer, offset, data, 0, size); + + var chunks = ArrayHelper.ArraySplit(data, 536); for (int i = 0; i < chunks.Length; i++) { - var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, i == chunks.Length - 2 ? (byte)(Flags.PSH | Flags.ACK) : (byte)Flags.ACK, StateMachine.TCB.SndWnd, 0, chunks[i]); - OutgoingBuffer.AddPacket(packet); - NetworkStack.Update(); + var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, i == chunks.Length - 1 ? (byte)(Flags.PSH | Flags.ACK) : (byte)Flags.ACK, StateMachine.TCB.SndWnd, 0, chunks[i]); + Cosmos.System.Network.IPv4.OutgoingBuffer.AddPacket(packet); + Cosmos.System.Network.NetworkStack.Update(); StateMachine.TCB.SndNxt += (uint)chunks[i].Length; } + + Cosmos.HAL.Global.debugger.Send("Socket - packed sent"); + + StateMachine.WaitingSendAck = true; + + bytesSent = size; } else { + Cosmos.HAL.Global.debugger.Send("Socket - not chunked"); + + byte[] data = new byte[size]; + Buffer.BlockCopy(buffer, offset, data, 0, size); + + Cosmos.HAL.Global.debugger.Send("Socket - data copied chunked"); + var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, (byte)(Flags.PSH | Flags.ACK), StateMachine.TCB.SndWnd, 0, data); - OutgoingBuffer.AddPacket(packet); - NetworkStack.Update(); - StateMachine.TCB.SndNxt += (uint)buffer.Length; + Cosmos.HAL.Global.debugger.Send("Socket - packed created"); + + Cosmos.System.Network.IPv4.OutgoingBuffer.AddPacket(packet); + + Cosmos.HAL.Global.debugger.Send("Socket - packed queued"); + + Cosmos.System.Network.NetworkStack.Update(); + + Cosmos.HAL.Global.debugger.Send("Socket - packed sent"); + + StateMachine.TCB.SndNxt += (uint)size; + + StateMachine.WaitingSendAck = true; + + bytesSent = size; } - return 0; + while (StateMachine.WaitingSendAck == true) { } + + Cosmos.HAL.Global.debugger.Send("Socket - Send ok bytesSent=" + bytesSent); + + return bytesSent; } + public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) { Cosmos.HAL.Global.debugger.Send("Socket - Receive Span."); @@ -219,7 +284,38 @@ public static void Close(Socket aThis, int timeout) if (StateMachine == null) { - throw new Exception("The Socket is not started."); + Cosmos.HAL.Global.debugger.Send("The Socket is not started."); + + return; + } + + if (StateMachine.Status == Status.CLOSED) + { + Cosmos.HAL.Global.debugger.Send("Socket - TCP already closing or closed."); + + Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); + + Cosmos.HAL.Global.debugger.Send("Socket - TCP removed TCP connection."); + + StateMachine = null; + + return; + } + else if (StateMachine.Status == Status.CLOSING || StateMachine.Status == Status.CLOSE_WAIT) + { + Cosmos.HAL.Global.debugger.Send("Socket - TCP already closing or closed wait."); + + while (StateMachine.WaitStatus(Status.CLOSED) != true) ; + + Cosmos.HAL.Global.debugger.Send("Socket - TCP CLOSED."); + + Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); + + Cosmos.HAL.Global.debugger.Send("Socket - TCP removed TCP connection wait."); + + StateMachine = null; + + return; } if (StateMachine.Status == Status.LISTEN) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index a7ee302cd5..f4c51283ad 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -12,12 +12,20 @@ namespace Cosmos.System_Plugs.System.Net.Sockets [Plug(Target = typeof(TcpClient))] public static class TcpClientImpl { + private static Socket _clientSocket; + private static NetworkStream _dataStream; + + public static void CCtor(TcpClient aThis) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); + } + public static void Ctor(TcpClient aThis) { Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); } - public static void Ctor(TcpClient aThis, Socket acceptedSocket, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket) + public static void Ctor(TcpClient aThis, Socket acceptedSocket) { Cosmos.HAL.Global.debugger.Send("TcpClient - ctor socket."); @@ -26,14 +34,23 @@ public static void Ctor(TcpClient aThis, Socket acceptedSocket, [FieldAccess(Nam Cosmos.HAL.Global.debugger.Send("TcpClient - ctor socket " + (acceptedSocket.RemoteEndPoint as IPEndPoint).Port + ":" + (acceptedSocket.RemoteEndPoint as IPEndPoint).Port); } + public static void set_Client(TcpClient aThis, Socket value) + { + _clientSocket = value; + } + + public static Socket get_Client(TcpClient aThis) + { + return _clientSocket; + } + public static int get_ReceiveBufferSize(TcpClient aThis) { //TODO implement Socket.SetSocketOption Socket.GetSocketOption return 8192; } - public static NetworkStream GetStream(TcpClient aThis, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket, - [FieldAccess(Name = "System.Net.Sockets.NetworkStream System.Net.Sockets.TcpClient._dataStream")] ref NetworkStream _dataStream) + public static NetworkStream GetStream(TcpClient aThis) { Cosmos.HAL.Global.debugger.Send("TcpClient - GetStream"); @@ -52,13 +69,42 @@ public static NetworkStream GetStream(TcpClient aThis, [FieldAccess(Name = "Syst return _dataStream; } - public static void Dispose(TcpClient aThis, [FieldAccess(Name = "System.Net.Sockets.Socket System.Net.Sockets.TcpClient._clientSocket")] ref Socket _clientSocket) + public static void Close(TcpClient aThis) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose"); + Cosmos.HAL.Global.debugger.Send("TcpClient - Close"); _clientSocket.Close(); Cosmos.HAL.Global.debugger.Send("TcpClient - Closed"); } + + public static void Dispose(TcpClient aThis, bool disposing) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2"); + + IDisposable dataStream = _dataStream; + if (dataStream != null) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.1"); + + dataStream.Dispose(); + + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.2"); + } + else + { + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.3"); + Socket socket = _clientSocket; + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.4"); + if (socket != null) + { + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.5"); + socket.Close(); + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.6"); + } + } + + Cosmos.HAL.Global.debugger.Send("TcpClient - Closed"); + } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs index 5e0bf26c6e..5335ea3f6d 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -15,6 +15,11 @@ public static class TcpListenerImpl private static Socket? _serverSocket; private static IPEndPoint _serverSocketEP; + public static void CCtor(TcpListener aThis) + { + Cosmos.HAL.Global.debugger.Send("TcpListener - cctor."); + } + public static void Ctor(TcpListener aThis, IPEndPoint localEP) { if (localEP == null) From ff3ebd4eda9398694b23e7f70c833bdac6a4a202 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Mon, 4 Dec 2023 09:51:09 +0100 Subject: [PATCH 16/27] =?UTF-8?q?=E2=9C=A8=20Implement=20Socket.Send=20ack?= =?UTF-8?q?=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 7 ---- .../System/Net/Sockets/SocketImpl.cs | 33 ++++++++++++---- .../System/Net/Sockets/TcpClientImpl.cs | 38 ++++++++----------- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index 65dab5a6c5..b049376515 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -606,13 +606,6 @@ public void ProcessEstablished(TCPPacket packet) return; } - if (WaitingSendAck) - { - Cosmos.HAL.Global.debugger.Send("Tcp - WaitingSendAck = false"); - - WaitingSendAck = false; - } - if (packet.TCP_DataLength > 0 && packet.SequenceNumber >= TCB.RcvNxt) //packet sequencing { TCB.RcvNxt += packet.TCP_DataLength; diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 36f2fd1323..4246274aca 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -149,16 +149,15 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket { Cosmos.HAL.Global.debugger.Send("Socket - Send."); + if (StateMachine.RemoteEndPoint.Address == null || StateMachine.RemoteEndPoint.Port == 0) { Cosmos.HAL.Global.debugger.Send("Socket - Must establish a default remote host by calling Connect() before using this Send() overload."); - throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); } if (StateMachine.Status != Status.ESTABLISHED) { Cosmos.HAL.Global.debugger.Send("Socket - Client must be connected before sending data.."); - throw new Exception("Client must be connected before sending data."); } @@ -171,7 +170,7 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket int bytesSent = 0; - if (size > 536) // why 536bytes chunk size?? + if (size > 536) // why 536 bytes for chunks size?? { Cosmos.HAL.Global.debugger.Send("Socket - chunked"); @@ -187,12 +186,13 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket Cosmos.System.Network.NetworkStack.Update(); StateMachine.TCB.SndNxt += (uint)chunks[i].Length; + bytesSent += chunks[i].Length; + + WaitAck(); } Cosmos.HAL.Global.debugger.Send("Socket - packed sent"); - StateMachine.WaitingSendAck = true; - bytesSent = size; } else @@ -221,15 +221,34 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket StateMachine.WaitingSendAck = true; bytesSent = size; - } - while (StateMachine.WaitingSendAck == true) { } + WaitAck(); + } Cosmos.HAL.Global.debugger.Send("Socket - Send ok bytesSent=" + bytesSent); + return bytesSent; } + private static void WaitAck() + { + bool ackReceived = false; + uint expectedAckNumber = StateMachine.TCB.SndNxt; + + while (!ackReceived) + { + if (StateMachine.TCB.SndUna >= expectedAckNumber) + { + Cosmos.HAL.Global.debugger.Send("ACK okay"); + + ackReceived = true; + } + } + + Cosmos.HAL.Global.debugger.Send("Socket - Send ackReceived"); + } + public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) { diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index f4c51283ad..724973b6fd 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -17,7 +17,7 @@ public static class TcpClientImpl public static void CCtor(TcpClient aThis) { - Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); + Cosmos.HAL.Global.debugger.Send("TcpClient - cctor."); } public static void Ctor(TcpClient aThis) @@ -44,6 +44,11 @@ public static Socket get_Client(TcpClient aThis) return _clientSocket; } + public static void set_Client(TcpClient aThis, Socket socket) + { + _clientSocket = socket; + } + public static int get_ReceiveBufferSize(TcpClient aThis) { //TODO implement Socket.SetSocketOption Socket.GetSocketOption @@ -69,42 +74,29 @@ public static NetworkStream GetStream(TcpClient aThis) return _dataStream; } - public static void Close(TcpClient aThis) - { - Cosmos.HAL.Global.debugger.Send("TcpClient - Close"); - - _clientSocket.Close(); - - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed"); - } - public static void Dispose(TcpClient aThis, bool disposing) { Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2"); - IDisposable dataStream = _dataStream; - if (dataStream != null) + if (_dataStream != null) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.1"); + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.1"); - dataStream.Dispose(); + _dataStream.Dispose(); - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.2"); + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.2"); } else { - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.3"); - Socket socket = _clientSocket; - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.4"); - if (socket != null) + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.4"); + if (_clientSocket != null) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.5"); - socket.Close(); - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed 2.6"); + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.5"); + _clientSocket.Close(); } } - Cosmos.HAL.Global.debugger.Send("TcpClient - Closed"); + Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 3"); } } } From ad9bd567648e19678ebc957461363379867f42cd Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Mon, 4 Dec 2023 09:53:46 +0100 Subject: [PATCH 17/27] =?UTF-8?q?=F0=9F=90=9B=20Fix=20build=20(multiple=20?= =?UTF-8?q?set=5FClient)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 724973b6fd..2833914fa3 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -44,11 +44,6 @@ public static Socket get_Client(TcpClient aThis) return _clientSocket; } - public static void set_Client(TcpClient aThis, Socket socket) - { - _clientSocket = socket; - } - public static int get_ReceiveBufferSize(TcpClient aThis) { //TODO implement Socket.SetSocketOption Socket.GetSocketOption From 4fe451542718340a01269cc2371b9827423c92f5 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Mon, 4 Dec 2023 16:35:57 +0100 Subject: [PATCH 18/27] =?UTF-8?q?=F0=9F=90=9B=20Fix=20stack=20corruption?= =?UTF-8?q?=20(wrong=20plug=20return=20type)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/Sockets/NetworkStreamImpl.cs | 4 ++-- .../Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 2479f7ba9b..2dc7294fa5 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -61,11 +61,11 @@ public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count return _streamSocket.Receive(buffer, offset, count, 0); } - public static int Write(NetworkStream aThis, byte[] buffer, int offset, int count) + public static void Write(NetworkStream aThis, byte[] buffer, int offset, int count) { Cosmos.HAL.Global.debugger.Send("NetworkStream - Write."); - return _streamSocket.Send(buffer, offset, count, 0); + _streamSocket.Send(buffer, offset, count, 0); } public static void Flush(NetworkStream aThis) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 4246274aca..390e418c0c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -261,6 +261,13 @@ public static int Receive(Socket aThis, byte[] buffer, int offset, int size, Soc { Cosmos.HAL.Global.debugger.Send("Socket - Receive byte[]."); + if (offset < 0 || size < 0 || (offset + size) > buffer.Length) + { + Cosmos.HAL.Global.debugger.Send("Socket - Invalid offset or size"); + + throw new ArgumentOutOfRangeException("Invalid offset or size"); + } + while (StateMachine.Data == null || StateMachine.Data.Length == 0) { if (StateMachine.Status != Status.ESTABLISHED) From 6fc41c40b10c97684441d2f7a81c1e2e7f04f8ac Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Mon, 4 Dec 2023 16:51:46 +0100 Subject: [PATCH 19/27] =?UTF-8?q?=F0=9F=94=A5=20Remove=20useless=20debug?= =?UTF-8?q?=20logs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dotnet TcpListener working like a charm! --- source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 8 -- .../System/Net/IPAddressImpl.cs | 15 +-- .../System/Net/IPEndPointImpl.cs | 13 -- .../System/Net/Sockets/NetworkStreamImpl.cs | 21 +--- .../System/Net/Sockets/SocketImpl.cs | 115 +++--------------- .../System/Net/Sockets/TcpClientImpl.cs | 24 ---- .../System/Net/Sockets/TcpListenerImpl.cs | 20 +-- 7 files changed, 22 insertions(+), 194 deletions(-) diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index b049376515..8324e0b2e9 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -256,8 +256,6 @@ public static void RemoveConnection(ushort localPort, ushort remotePort, Address { Connections.RemoveAt(i); - NetworkStack.Debugger.Send("Connection removed!"); - return; } } @@ -335,13 +333,9 @@ internal void ReceiveData(TCPPacket packet) } else { - Cosmos.HAL.Global.debugger.Send("Tcp - Received TCP"); - // Check sequence number and segment data. if (TCB.RcvNxt <= packet.SequenceNumber && packet.SequenceNumber + packet.TCP_DataLength < TCB.RcvNxt + TCB.RcvWnd) { - Cosmos.HAL.Global.debugger.Send("Tcp - Received TCP ok."); - switch (Status) { case Status.SYN_RECEIVED: @@ -556,8 +550,6 @@ public void ProcessEstablished(TCPPacket packet) { if (packet.ACK) { - Cosmos.HAL.Global.debugger.Send("Tcp - Received ACK"); - if (TCB.SndUna < packet.AckNumber && packet.AckNumber <= TCB.SndNxt) { TCB.SndUna = packet.AckNumber; diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 0ad0ff3d88..8c4989a2df 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -26,36 +26,27 @@ public static void set_PrivateAddress(uint address) PrivateAddress = address; } - public static void CCtor(IPAddress aThis) - { - Cosmos.HAL.Global.debugger.Send("IPAddress - cctor."); - } - 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 address) { - Cosmos.HAL.Global.debugger.Send("IPAddress - ctor."); - if (address.Length == IPv4AddressBytes) { PrivateAddress = (uint)(address[0] << 24 | address[1] << 16 | address[2] << 8 | address[3]); } else if (address.Length == IPv6AddressBytes) { + Cosmos.HAL.Global.debugger.Send("IPv6 not supported yet!"); throw new NotImplementedException("IPv6 not supported yet!"); } else { - throw new ArgumentException("Bad IP address format", nameof(address)); + Cosmos.HAL.Global.debugger.Send("Bad IP address format"); + throw new ArgumentException("Bad IP address format"); } - - Cosmos.HAL.Global.debugger.Send("IPAddress - " + address[0] + "." + address[1] + "." + address[2] + "." + address[3] + " set."); } public static void Ctor(IPAddress aThis, ReadOnlySpan address, long scopeId) diff --git a/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs index 43ae11a531..0d6d0d9ae1 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPEndPointImpl.cs @@ -12,31 +12,18 @@ namespace Cosmos.System_Plugs.System.Net [Plug(Target = typeof(IPEndPoint))] public static class IPEndPointImpl { - public static void CCtor(IPEndPoint aThis) - { - Cosmos.HAL.Global.debugger.Send("IPEndPoint - cctor."); - } - 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."); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 2dc7294fa5..2c0a8f9e0a 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -13,25 +13,22 @@ public static class NetworkStreamImpl { private static Socket _streamSocket; - public static void CCtor(NetworkStream aThis) - { - Cosmos.HAL.Global.debugger.Send("NetworkStream - cctor."); - } - public static void Ctor(NetworkStream aThis, Socket socket, FileAccess access, bool ownsSocket, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._ownsSocket")] ref bool _ownsSocket, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._readable")] ref bool _readable, [FieldAccess(Name = "System.Boolean System.Net.Sockets.NetworkStream._writeable")] ref bool _writeable ) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - ctor."); - if (socket == null) { + Cosmos.HAL.Global.debugger.Send("NetworkStream - socket is null."); + throw new ArgumentNullException(nameof(socket)); } if (!socket.Connected) { + Cosmos.HAL.Global.debugger.Send("NetworkStream - socket is not connected."); + throw new IOException("Socket not connected."); } @@ -56,15 +53,11 @@ public static void Ctor(NetworkStream aThis, Socket socket, FileAccess access, b public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Read."); - return _streamSocket.Receive(buffer, offset, count, 0); } public static void Write(NetworkStream aThis, byte[] buffer, int offset, int count) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Write."); - _streamSocket.Send(buffer, offset, count, 0); } @@ -75,22 +68,16 @@ public static void Flush(NetworkStream aThis) public static void Close(NetworkStream aThis) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Close"); - _streamSocket.Close(); } public static void Dispose(NetworkStream aThis) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose 1."); - _streamSocket.Close(); } public static void Dispose(NetworkStream aThis, bool disposing) { - Cosmos.HAL.Global.debugger.Send("NetworkStream - Dispose 2."); - _streamSocket.Close(); } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 390e418c0c..60787c118c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -19,111 +19,83 @@ public static class SocketImpl private static EndPoint _localEndPoint; private static EndPoint _remoteEndPoint; - public static void CCtor(Socket aThis) - { - Cosmos.HAL.Global.debugger.Send("Socket - cctor."); - } - public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType) { CheckSocket(aThis, socketType, protocolType); - - Cosmos.HAL.Global.debugger.Send("Socket - ctor."); } public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType) { CheckSocket(aThis, socketType, protocolType); - - Cosmos.HAL.Global.debugger.Send("Socket - ctor."); } public static void CheckSocket(Socket aThis, SocketType socketType, ProtocolType protocolType) { if (socketType != SocketType.Stream) { + Cosmos.HAL.Global.debugger.Send("Socket - Only stream sockets implemented."); + throw new NotImplementedException("Only stream sockets implemented."); } if (protocolType == ProtocolType.Udp) { + Cosmos.HAL.Global.debugger.Send("Socket - Only TCP sockets supported. UDP Coming soon ;)"); + throw new NotImplementedException("Only TCP sockets supported. UDP Coming soon ;)"); } else if (protocolType != ProtocolType.Tcp) { + Cosmos.HAL.Global.debugger.Send("Socket - Only TCP sockets supported."); + throw new NotImplementedException("Only TCP sockets supported."); } } public static bool get_Connected(Socket aThis) { - Cosmos.HAL.Global.debugger.Send("Socket - get_Connected."); - - Cosmos.HAL.Global.debugger.Send("Socket - StateMachine.Status=" + Tcp.Table[(int)StateMachine.Status] ); - return StateMachine.Status == Status.ESTABLISHED; } public static bool Poll(Socket aThis, int microSeconds, SelectMode mode) { - Cosmos.HAL.Global.debugger.Send("Socket - Poll."); - return StateMachine.Status == Status.ESTABLISHED; } 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); + Start(); } public static Socket Accept(Socket aThis) { - Cosmos.HAL.Global.debugger.Send("Socket - Accept."); - if (StateMachine == null) { - Cosmos.HAL.Global.debugger.Send("The TcpListener is not started"); + Cosmos.HAL.Global.debugger.Send("The TcpListener is not started, starting..."); - Start(aThis); + Start(); } - Cosmos.HAL.Global.debugger.Send("Socket - Accept 1."); - if (StateMachine.Status == Status.CLOSED) // if TcpListener already accepted client, remove old one. { - Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.1"); Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); - Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.2"); - Start(aThis); - Cosmos.HAL.Global.debugger.Send("Socket - Accept 1.3"); + Start(); } - Cosmos.HAL.Global.debugger.Send("Socket - Accept 2."); - 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) + private static void Start() { StateMachine = new((ushort)EndPoint.Port, 0, Cosmos.System.Network.IPv4.Address.Zero, Cosmos.System.Network.IPv4.Address.Zero); StateMachine.RxBuffer = new Queue(8); @@ -147,9 +119,6 @@ public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags sock public static int Send(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) { - Cosmos.HAL.Global.debugger.Send("Socket - Send."); - - if (StateMachine.RemoteEndPoint.Address == null || StateMachine.RemoteEndPoint.Port == 0) { Cosmos.HAL.Global.debugger.Send("Socket - Must establish a default remote host by calling Connect() before using this Send() overload."); @@ -164,7 +133,6 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket if (offset < 0 || size < 0 || (offset + size) > buffer.Length) { Cosmos.HAL.Global.debugger.Send("Socket - Invalid offset or size"); - throw new ArgumentOutOfRangeException("Invalid offset or size"); } @@ -172,8 +140,6 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket if (size > 536) // why 536 bytes for chunks size?? { - Cosmos.HAL.Global.debugger.Send("Socket - chunked"); - byte[] data = new byte[size]; Buffer.BlockCopy(buffer, offset, data, 0, size); @@ -191,31 +157,17 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket WaitAck(); } - Cosmos.HAL.Global.debugger.Send("Socket - packed sent"); - bytesSent = size; } else { - Cosmos.HAL.Global.debugger.Send("Socket - not chunked"); - byte[] data = new byte[size]; Buffer.BlockCopy(buffer, offset, data, 0, size); - Cosmos.HAL.Global.debugger.Send("Socket - data copied chunked"); - var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, (byte)(Flags.PSH | Flags.ACK), StateMachine.TCB.SndWnd, 0, data); - - Cosmos.HAL.Global.debugger.Send("Socket - packed created"); - Cosmos.System.Network.IPv4.OutgoingBuffer.AddPacket(packet); - - Cosmos.HAL.Global.debugger.Send("Socket - packed queued"); - Cosmos.System.Network.NetworkStack.Update(); - Cosmos.HAL.Global.debugger.Send("Socket - packed sent"); - StateMachine.TCB.SndNxt += (uint)size; StateMachine.WaitingSendAck = true; @@ -225,9 +177,6 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket WaitAck(); } - Cosmos.HAL.Global.debugger.Send("Socket - Send ok bytesSent=" + bytesSent); - - return bytesSent; } @@ -240,31 +189,22 @@ private static void WaitAck() { if (StateMachine.TCB.SndUna >= expectedAckNumber) { - Cosmos.HAL.Global.debugger.Send("ACK okay"); - ackReceived = true; } } - - Cosmos.HAL.Global.debugger.Send("Socket - Send ackReceived"); } public static int Receive(Socket aThis, Span buffer, SocketFlags socketFlags) { - Cosmos.HAL.Global.debugger.Send("Socket - Receive Span."); - - return 0; + return Receive(aThis, buffer.ToArray(), 0, buffer.Length, socketFlags); } public static int Receive(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) { - Cosmos.HAL.Global.debugger.Send("Socket - Receive byte[]."); - if (offset < 0 || size < 0 || (offset + size) > buffer.Length) { - Cosmos.HAL.Global.debugger.Send("Socket - Invalid offset or size"); - + Cosmos.HAL.Global.debugger.Send("Socket - Receive Invalid offset or size"); throw new ArgumentOutOfRangeException("Invalid offset or size"); } @@ -279,66 +219,42 @@ public static int Receive(Socket aThis, byte[] buffer, int offset, int size, Soc StateMachine.RxBuffer.Dequeue(); - // Copy received buffer data in buffer arg - Cosmos.HAL.Global.debugger.Send("Socket - Receive StateMachine.Data.Length=" + StateMachine.Data.Length); - Cosmos.HAL.Global.debugger.Send("Socket - Receive size=" + size); int bytesToCopy = Math.Min(StateMachine.Data.Length, size); - Cosmos.HAL.Global.debugger.Send("Socket - Receive bytesToCopy=" + bytesToCopy); Buffer.BlockCopy(StateMachine.Data, 0, buffer, offset, bytesToCopy); - Cosmos.HAL.Global.debugger.Send("Socket - Receive copied to buffer"); - // Update buffer data by deleting read data byte[] remainingData = new byte[StateMachine.Data.Length - bytesToCopy]; Buffer.BlockCopy(StateMachine.Data, bytesToCopy, remainingData, 0, remainingData.Length); StateMachine.Data = remainingData; - Cosmos.HAL.Global.debugger.Send("Socket - Receive moved data."); - return bytesToCopy; } public static void Close(Socket aThis) { - Cosmos.HAL.Global.debugger.Send("Socket - Closing."); - Close(aThis, 5000); } public static void Close(Socket aThis, int timeout) { - Cosmos.HAL.Global.debugger.Send("Socket - Closing with timeout " + timeout); - if (StateMachine == null) { - Cosmos.HAL.Global.debugger.Send("The Socket is not started."); - return; } if (StateMachine.Status == Status.CLOSED) { - Cosmos.HAL.Global.debugger.Send("Socket - TCP already closing or closed."); - Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); - Cosmos.HAL.Global.debugger.Send("Socket - TCP removed TCP connection."); - StateMachine = null; return; } else if (StateMachine.Status == Status.CLOSING || StateMachine.Status == Status.CLOSE_WAIT) { - Cosmos.HAL.Global.debugger.Send("Socket - TCP already closing or closed wait."); - while (StateMachine.WaitStatus(Status.CLOSED) != true) ; - Cosmos.HAL.Global.debugger.Send("Socket - TCP CLOSED."); - Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); - Cosmos.HAL.Global.debugger.Send("Socket - TCP removed TCP connection wait."); - StateMachine = null; return; @@ -346,15 +262,11 @@ public static void Close(Socket aThis, int timeout) 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++; @@ -363,6 +275,7 @@ public static void Close(Socket aThis, int timeout) if (StateMachine.WaitStatus(Status.CLOSED, 5000) == false) { + Cosmos.HAL.Global.debugger.Send("Socket - Close Failed to close TCP connection!"); throw new Exception("Failed to close TCP connection!"); } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 2833914fa3..0b1bdd0d95 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -15,23 +15,13 @@ public static class TcpClientImpl private static Socket _clientSocket; private static NetworkStream _dataStream; - public static void CCtor(TcpClient aThis) - { - Cosmos.HAL.Global.debugger.Send("TcpClient - cctor."); - } - public static void Ctor(TcpClient aThis) { - Cosmos.HAL.Global.debugger.Send("TcpClient - ctor."); } public static void Ctor(TcpClient aThis, Socket acceptedSocket) { - 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 void set_Client(TcpClient aThis, Socket value) @@ -52,8 +42,6 @@ public static int get_ReceiveBufferSize(TcpClient aThis) public static NetworkStream GetStream(TcpClient aThis) { - Cosmos.HAL.Global.debugger.Send("TcpClient - GetStream"); - if (_clientSocket == null) { Cosmos.HAL.Global.debugger.Send("TcpClient - GetStream _clientSocket null"); @@ -64,34 +52,22 @@ public static NetworkStream GetStream(TcpClient aThis) _dataStream = new NetworkStream(_clientSocket, true); } - Cosmos.HAL.Global.debugger.Send("TcpClient - Created network stream"); - return _dataStream; } public static void Dispose(TcpClient aThis, bool disposing) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2"); - if (_dataStream != null) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.1"); - _dataStream.Dispose(); - - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.2"); } else { - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.4"); if (_clientSocket != null) { - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 2.5"); _clientSocket.Close(); } } - - Cosmos.HAL.Global.debugger.Send("TcpClient - Dispose 3"); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs index 5335ea3f6d..d3346bb72c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpListenerImpl.cs @@ -15,11 +15,6 @@ public static class TcpListenerImpl private static Socket? _serverSocket; private static IPEndPoint _serverSocketEP; - public static void CCtor(TcpListener aThis) - { - Cosmos.HAL.Global.debugger.Send("TcpListener - cctor."); - } - public static void Ctor(TcpListener aThis, IPEndPoint localEP) { if (localEP == null) @@ -32,22 +27,14 @@ public static void Ctor(TcpListener aThis, IPEndPoint localEP) public static void Ctor(TcpListener aThis, IPAddress localaddr, int port) { - Cosmos.HAL.Global.debugger.Send("TcpListener - ctor."); - if (localaddr == null) { + Cosmos.HAL.Global.debugger.Send("TcpListener - Ctor localaddr == null"); throw new ArgumentNullException(nameof(localaddr)); } - Cosmos.HAL.Global.debugger.Send("TcpListener - localaddr ok."); - _serverSocketEP = new IPEndPoint(localaddr, port); - - Cosmos.HAL.Global.debugger.Send("TcpListener - _serverSocketEP ok."); - _serverSocket = new Socket(_serverSocketEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - - Cosmos.HAL.Global.debugger.Send("TcpListener - _serverSocket ok."); } public static void Start(TcpListener aThis) @@ -67,12 +54,7 @@ public static void Start(TcpListener aThis) public static TcpClient AcceptTcpClient(TcpListener aThis) { - Cosmos.HAL.Global.debugger.Send("TcpListener - accepting client."); - Socket acceptedSocket = _serverSocket!.Accept(); - - Cosmos.HAL.Global.debugger.Send("TcpListener - socket accepted."); - var realClient = new TcpClient(); realClient.Client = acceptedSocket; return realClient; From 069069fb11636d4a2741e07cd06db313dfc38900 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Mon, 4 Dec 2023 17:30:46 +0100 Subject: [PATCH 20/27] =?UTF-8?q?=E2=9C=A8=20Begin=20TCPClient=20connect?= =?UTF-8?q?=20impl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/Cosmos.System2/Network/IPv4/Address.cs | 12 +++++ .../Cosmos.System2/Network/IPv4/EndPoint.cs | 11 +++++ .../System/Net/Sockets/SocketImpl.cs | 49 +++++++++++++++++-- .../System/Net/Sockets/TcpClientImpl.cs | 22 +++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/source/Cosmos.System2/Network/IPv4/Address.cs b/source/Cosmos.System2/Network/IPv4/Address.cs index 9d1d3c3828..ac4004a7bd 100644 --- a/source/Cosmos.System2/Network/IPv4/Address.cs +++ b/source/Cosmos.System2/Network/IPv4/Address.cs @@ -35,6 +35,18 @@ public class Address : IComparable /// public static readonly Address Broadcast = new(255, 255, 255, 255); + /// + /// Create new instance of the class, with specified IP address. + /// + /// Adress + public Address(uint address) + { + Parts[0] = (byte)((address >> 24) & 0xFF); + Parts[1] = (byte)((address >> 16) & 0xFF); + Parts[2] = (byte)((address >> 8) & 0xFF); + Parts[3] = (byte)(address & 0xFF); + } + /// /// Create new instance of the class, with specified IP address. /// diff --git a/source/Cosmos.System2/Network/IPv4/EndPoint.cs b/source/Cosmos.System2/Network/IPv4/EndPoint.cs index 34f11411dd..b9d6be4407 100644 --- a/source/Cosmos.System2/Network/IPv4/EndPoint.cs +++ b/source/Cosmos.System2/Network/IPv4/EndPoint.cs @@ -28,6 +28,17 @@ public EndPoint(Address addr, ushort port) Port = port; } + /// + /// Initializes a new instance of the class. + /// + /// The IPv4 address. + /// The port. + public EndPoint(uint addr, ushort port) + { + Address = new Address(addr); + Port = port; + } + public override string ToString() { return Address.ToString() + ":" + Port.ToString(); diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 60787c118c..6003a785af 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -105,16 +105,59 @@ private static void Start() Tcp.Connections.Add(StateMachine); } + private static uint ConvertIPAddressToUInt32(IPAddress ip) + { + byte[] bytes = ip.GetAddressBytes(); + return (uint)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]); + } + public static void Connect(Socket aThis, IPAddress address, int port) { - Cosmos.HAL.Global.debugger.Send("Socket - Connect."); + if (StateMachine.Status == Status.ESTABLISHED) + { + throw new Exception("Client must be closed before setting a new connection."); + } + + StateMachine.RemoteEndPoint.Address = new Cosmos.System.Network.IPv4.Address(ConvertIPAddressToUInt32(address)); + StateMachine.LocalEndPoint.Address = Cosmos.System.Network.Config.IPConfig.FindNetwork(StateMachine.RemoteEndPoint.Address); + StateMachine.RemoteEndPoint.Port = (ushort)port; + + _remoteEndPoint = new IPEndPoint(StateMachine.RemoteEndPoint.Address.ToUInt32(), StateMachine.RemoteEndPoint.Port); + _localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port); - throw new NotImplementedException(); + //Generate Random Sequence Number + var rnd = new Random(); + var SequenceNumber = (uint)(rnd.Next(0, Int32.MaxValue) << 32) | (uint)rnd.Next(0, Int32.MaxValue); + + //Fill TCB + StateMachine.TCB.SndUna = SequenceNumber; + StateMachine.TCB.SndNxt = SequenceNumber; + StateMachine.TCB.SndWnd = Tcp.TcpWindowSize; + StateMachine.TCB.SndUp = 0; + StateMachine.TCB.SndWl1 = 0; + StateMachine.TCB.SndWl2 = 0; + StateMachine.TCB.ISS = SequenceNumber; + + StateMachine.TCB.RcvNxt = 0; + StateMachine.TCB.RcvWnd = Tcp.TcpWindowSize; + StateMachine.TCB.RcvUp = 0; + StateMachine.TCB.IRS = 0; + + Tcp.Connections.Add(StateMachine); + + StateMachine.SendEmptyPacket(Flags.SYN); + + StateMachine.Status = Status.SYN_SENT; + + if (StateMachine.WaitStatus(Status.ESTABLISHED, 5) == false) + { + throw new Exception("Failed to open TCP connection!"); + } } public static int Send(Socket aThis, ReadOnlySpan buffer, SocketFlags socketFlags) { - throw new NotImplementedException(); + return Send(aThis, buffer.ToArray(), 0, buffer.Length, socketFlags); ; } public static int Send(Socket aThis, byte[] buffer, int offset, int size, SocketFlags socketFlags) diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 0b1bdd0d95..16b1698fec 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -40,6 +40,28 @@ public static int get_ReceiveBufferSize(TcpClient aThis) return 8192; } + public static void Connect(TcpClient aThis, string hostname, int port, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) + { + _clientSocket.Connect(IPAddress.Parse(hostname), port); + _active = true; + } + + public static void Connect(TcpClient aThis, IPAddress address, int port, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) + { + _clientSocket.Connect(address, port); + _active = true; + } + + public static void Connect(TcpClient aThis, IPEndPoint remoteEP, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) + { + throw new NotImplementedException(); + } + + public static void Connect(TcpClient aThis, IPAddress[] ipAddresses, int port) + { + throw new NotImplementedException(); + } + public static NetworkStream GetStream(TcpClient aThis) { if (_clientSocket == null) From c6bb978dca61da2cb36522a043a7e20e57ee0085 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 08:30:01 +0100 Subject: [PATCH 21/27] =?UTF-8?q?=E2=9C=A8=20TCPClient=20connect=20local?= =?UTF-8?q?=20port=20generation=20+=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/IPAddressImpl.cs | 51 +++++++++++++++++-- .../System/Net/Sockets/SocketImpl.cs | 31 +++++++++-- .../System/Net/Sockets/TcpClientImpl.cs | 8 ++- 3 files changed, 83 insertions(+), 7 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 8c4989a2df..7903553ec0 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -26,6 +26,10 @@ public static void set_PrivateAddress(uint address) PrivateAddress = address; } + public static void CCtor(IPAddress aThis) + { + } + public static void Ctor(IPAddress aThis, long address) { PrivateAddress = (uint)address; @@ -33,14 +37,25 @@ public static void Ctor(IPAddress aThis, long address) public static void Ctor(IPAddress aThis, ReadOnlySpan address) { + Ctor(aThis, address.ToArray()); + } + + public static void Ctor(IPAddress aThis, ReadOnlySpan address, long scopeId) + { + Ctor(aThis, address.ToArray()); + } + + public static void Ctor(IPAddress aThis, byte[] address) + { + Cosmos.HAL.Global.debugger.Send(address[0] + "." + address[1] + "." + address[2] + "." + address[3]); + if (address.Length == IPv4AddressBytes) { - PrivateAddress = (uint)(address[0] << 24 | address[1] << 16 | address[2] << 8 | address[3]); + PrivateAddress = (uint)((address[0] << 24) | (address[1] << 16) | (address[2] << 8) | (address[3] << 0)); } else if (address.Length == IPv6AddressBytes) { Cosmos.HAL.Global.debugger.Send("IPv6 not supported yet!"); - throw new NotImplementedException("IPv6 not supported yet!"); } else { @@ -49,8 +64,38 @@ public static void Ctor(IPAddress aThis, ReadOnlySpan address) } } - public static void Ctor(IPAddress aThis, ReadOnlySpan address, long scopeId) + public static IPAddress Parse(string address) + { + string[] fragments = address.Split('.'); + if (fragments.Length == 4) + { + try + { + var addressArray = new byte[4]; + addressArray[0] = byte.Parse(fragments[0]); + addressArray[1] = byte.Parse(fragments[1]); + addressArray[2] = byte.Parse(fragments[2]); + addressArray[3] = byte.Parse(fragments[3]); + + Cosmos.HAL.Global.debugger.Send(fragments[0] + "." + fragments[1] + "." + fragments[2] + "." + fragments[3]); + Cosmos.HAL.Global.debugger.Send(addressArray[0] + "." + addressArray[1] + "." + addressArray[2] + "." + addressArray[3]); + + return new IPAddress(addressArray); + } + catch + { + return null; + } + } + else + { + return null; + } + } + + public static string ToString(IPAddress aThis) { + return (byte)(PrivateAddress >> 24) + "." + (byte)(PrivateAddress >> 16 & 0xff) + "." + (byte)(PrivateAddress >> 8 & 0xff) + "." + (byte)(PrivateAddress & 0xff); } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 6003a785af..18a18194a7 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -5,6 +5,7 @@ using System.Net.Sockets; using System.Text; using Cosmos.System.Helpers; +using Cosmos.System.Network.Config; using Cosmos.System.Network.IPv4.TCP; using IL2CPU.API.Attribs; @@ -19,6 +20,9 @@ public static class SocketImpl private static EndPoint _localEndPoint; private static EndPoint _remoteEndPoint; + private const int MinPort = 49152; + private const int MaxPort = 65535; + public static void Ctor(Socket aThis, SocketType socketType, ProtocolType protocolType) { CheckSocket(aThis, socketType, protocolType); @@ -111,20 +115,41 @@ private static uint ConvertIPAddressToUInt32(IPAddress ip) return (uint)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]); } + public static int GetRandomPort() + { + Random random = new Random(); + return random.Next(MinPort, MaxPort + 1); + } + public static void Connect(Socket aThis, IPAddress address, int port) { + Start(); + + Cosmos.HAL.Global.debugger.Send("Connect - start okay"); + Cosmos.HAL.Global.debugger.Send("address - " + address.ToString()); + Cosmos.HAL.Global.debugger.Send("port - " + port); + if (StateMachine.Status == Status.ESTABLISHED) { throw new Exception("Client must be closed before setting a new connection."); } - StateMachine.RemoteEndPoint.Address = new Cosmos.System.Network.IPv4.Address(ConvertIPAddressToUInt32(address)); - StateMachine.LocalEndPoint.Address = Cosmos.System.Network.Config.IPConfig.FindNetwork(StateMachine.RemoteEndPoint.Address); + StateMachine.RemoteEndPoint.Address = Cosmos.System.Network.IPv4.Address.Parse(EndPoint.Address.ToString()); StateMachine.RemoteEndPoint.Port = (ushort)port; + StateMachine.LocalEndPoint.Address = NetworkConfiguration.CurrentAddress; + StateMachine.LocalEndPoint.Port = (ushort)GetRandomPort(); - _remoteEndPoint = new IPEndPoint(StateMachine.RemoteEndPoint.Address.ToUInt32(), StateMachine.RemoteEndPoint.Port); + Cosmos.HAL.Global.debugger.Send("StateMachine.RemoteEndPoint.Address=" + StateMachine.RemoteEndPoint.Address.ToString()); + Cosmos.HAL.Global.debugger.Send("StateMachine.LocalEndPoint.Address=" + StateMachine.LocalEndPoint.Address.ToString()); + + _remoteEndPoint = new IPEndPoint(address, StateMachine.RemoteEndPoint.Port); _localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port); + Cosmos.HAL.Global.debugger.Send("_remoteEndPoint=" + _remoteEndPoint.ToString()); + Cosmos.HAL.Global.debugger.Send("_localEndPoint=" + _localEndPoint.ToString()); + + Cosmos.HAL.Global.debugger.Send("Connect - endpoints okay."); + //Generate Random Sequence Number var rnd = new Random(); var SequenceNumber = (uint)(rnd.Next(0, Int32.MaxValue) << 32) | (uint)rnd.Next(0, Int32.MaxValue); diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 16b1698fec..1a37f9c9b6 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -42,7 +42,13 @@ public static int get_ReceiveBufferSize(TcpClient aThis) public static void Connect(TcpClient aThis, string hostname, int port, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) { - _clientSocket.Connect(IPAddress.Parse(hostname), port); + var address = IPAddress.Parse(hostname); + var endpoint = new IPEndPoint(address, port); + + Cosmos.HAL.Global.debugger.Send("address - " + address.ToString()); + _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _clientSocket.Bind(endpoint); + _clientSocket.Connect(address, port); _active = true; } From 4465eb6fe36b9771b42510eea0d0efc262933ef2 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 10:44:01 +0100 Subject: [PATCH 22/27] =?UTF-8?q?=E2=9C=A8=20TCPClient=20works!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../System/Net/IPAddressImpl.cs | 23 ++++++++--------- .../System/Net/Sockets/SocketImpl.cs | 25 +++++-------------- .../System/Net/Sockets/TcpClientImpl.cs | 3 +-- 3 files changed, 17 insertions(+), 34 deletions(-) diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 7903553ec0..3c451ee61c 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -16,16 +16,21 @@ public static class IPAddressImpl private const int IPv6AddressBytes = 16; private static uint PrivateAddress; - public static uint get_PrivateAddress() + public static uint get_PrivateAddress(IPAddress aThis) { return PrivateAddress; } - public static void set_PrivateAddress(uint address) + public static void set_PrivateAddress(IPAddress aThis, uint address) { PrivateAddress = address; } + public static AddressFamily get_AddressFamily(IPAddress aThis) + { + return AddressFamily.InterNetwork; + } + public static void CCtor(IPAddress aThis) { } @@ -47,11 +52,11 @@ public static void Ctor(IPAddress aThis, ReadOnlySpan address, long scopeI public static void Ctor(IPAddress aThis, byte[] address) { - Cosmos.HAL.Global.debugger.Send(address[0] + "." + address[1] + "." + address[2] + "." + address[3]); - if (address.Length == IPv4AddressBytes) { - PrivateAddress = (uint)((address[0] << 24) | (address[1] << 16) | (address[2] << 8) | (address[3] << 0)); + PrivateAddress = (uint)((address[0] << 0) | (address[1] << 8) | (address[2] << 16) | (address[3] << 24)); + + Cosmos.HAL.Global.debugger.Send("Ctor address=" + aThis.ToString()); } else if (address.Length == IPv6AddressBytes) { @@ -77,9 +82,6 @@ public static IPAddress Parse(string address) addressArray[2] = byte.Parse(fragments[2]); addressArray[3] = byte.Parse(fragments[3]); - Cosmos.HAL.Global.debugger.Send(fragments[0] + "." + fragments[1] + "." + fragments[2] + "." + fragments[3]); - Cosmos.HAL.Global.debugger.Send(addressArray[0] + "." + addressArray[1] + "." + addressArray[2] + "." + addressArray[3]); - return new IPAddress(addressArray); } catch @@ -92,10 +94,5 @@ public static IPAddress Parse(string address) return null; } } - - public static string ToString(IPAddress aThis) - { - return (byte)(PrivateAddress >> 24) + "." + (byte)(PrivateAddress >> 16 & 0xff) + "." + (byte)(PrivateAddress >> 8 & 0xff) + "." + (byte)(PrivateAddress & 0xff); - } } } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index 18a18194a7..e3fb0a0562 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -17,8 +17,8 @@ public static class SocketImpl private static Tcp StateMachine; private static IPEndPoint EndPoint = null; - private static EndPoint _localEndPoint; - private static EndPoint _remoteEndPoint; + private static IPEndPoint _localEndPoint; + private static IPEndPoint _remoteEndPoint; private const int MinPort = 49152; private const int MaxPort = 65535; @@ -125,12 +125,9 @@ public static void Connect(Socket aThis, IPAddress address, int port) { Start(); - Cosmos.HAL.Global.debugger.Send("Connect - start okay"); - Cosmos.HAL.Global.debugger.Send("address - " + address.ToString()); - Cosmos.HAL.Global.debugger.Send("port - " + port); - if (StateMachine.Status == Status.ESTABLISHED) { + Cosmos.HAL.Global.debugger.Send("Socket - Client must be closed before setting a new connection.."); throw new Exception("Client must be closed before setting a new connection."); } @@ -139,20 +136,12 @@ public static void Connect(Socket aThis, IPAddress address, int port) StateMachine.LocalEndPoint.Address = NetworkConfiguration.CurrentAddress; StateMachine.LocalEndPoint.Port = (ushort)GetRandomPort(); - Cosmos.HAL.Global.debugger.Send("StateMachine.RemoteEndPoint.Address=" + StateMachine.RemoteEndPoint.Address.ToString()); - Cosmos.HAL.Global.debugger.Send("StateMachine.LocalEndPoint.Address=" + StateMachine.LocalEndPoint.Address.ToString()); - _remoteEndPoint = new IPEndPoint(address, StateMachine.RemoteEndPoint.Port); _localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port); - Cosmos.HAL.Global.debugger.Send("_remoteEndPoint=" + _remoteEndPoint.ToString()); - Cosmos.HAL.Global.debugger.Send("_localEndPoint=" + _localEndPoint.ToString()); - - Cosmos.HAL.Global.debugger.Send("Connect - endpoints okay."); - //Generate Random Sequence Number - var rnd = new Random(); - var SequenceNumber = (uint)(rnd.Next(0, Int32.MaxValue) << 32) | (uint)rnd.Next(0, Int32.MaxValue); + Random rnd = new(); + var SequenceNumber = (uint)(rnd.Next(0, int.MaxValue) << 32) | (uint)rnd.Next(0, int.MaxValue); //Fill TCB StateMachine.TCB.SndUna = SequenceNumber; @@ -169,12 +158,10 @@ public static void Connect(Socket aThis, IPAddress address, int port) StateMachine.TCB.IRS = 0; Tcp.Connections.Add(StateMachine); - StateMachine.SendEmptyPacket(Flags.SYN); - StateMachine.Status = Status.SYN_SENT; - if (StateMachine.WaitStatus(Status.ESTABLISHED, 5) == false) + if (StateMachine.WaitStatus(Status.ESTABLISHED, 5000) == false) { throw new Exception("Failed to open TCP connection!"); } diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index 1a37f9c9b6..cfb2dbb115 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -36,8 +36,7 @@ public static Socket get_Client(TcpClient aThis) public static int get_ReceiveBufferSize(TcpClient aThis) { - //TODO implement Socket.SetSocketOption Socket.GetSocketOption - return 8192; + return Cosmos.System.Network.IPv4.TCP.Tcp.TcpWindowSize; } public static void Connect(TcpClient aThis, string hostname, int port, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) From 6e776ad5e234474afcaaa7cab9adda9051e185c8 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 11:00:02 +0100 Subject: [PATCH 23/27] =?UTF-8?q?=F0=9F=93=9D=20Update=20TCP=20documentati?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/articles/Kernel/Network.md | 133 ++++++++++++++++++++++---------- 1 file changed, 94 insertions(+), 39 deletions(-) diff --git a/Docs/articles/Kernel/Network.md b/Docs/articles/Kernel/Network.md index ccc5558f67..1628ac14b9 100644 --- a/Docs/articles/Kernel/Network.md +++ b/Docs/articles/Kernel/Network.md @@ -28,40 +28,112 @@ using(var xClient = new DHCPClient()) } ``` -## TCP -Like UDP, TCP has to create a client and call Connect() to specify the remote machine address before sending or receiving data. - -Server : +## UDP +Before playing with packets, we have to create a client and call Connect() to specify the remote machine address. After that the client will be able to send or listen for data. ```csharp -using(var xServer = new TcpListener(4242)) +using(var xClient = new UdpClient(4242)) { - /** Start server **/ - xServer.Start(); - - /** Accept incoming TCP connection **/ - var client = xServer.AcceptTcpClient(); //blocking - - /** Stop server **/ - xServer.Stop(); + xClient.Connect(new Address(192, 168, 1, 70), 4242); /** Send data **/ - client.Send(Encoding.ASCII.GetBytes(message)); + xClient.Send(Encoding.ASCII.GetBytes(message)); + + /** Receive data **/ + var endpoint = new EndPoint(Address.Zero, 0); + var data = xClient.Receive(ref endpoint); //set endpoint to remote machine IP:port + var data2 = xClient.NonBlockingReceive(ref endpoint); //retrieve receive buffer without waiting } ``` -Client : +## TCP +Unlike UDP, TCP is plugged with the dotnet framework. You won't have to use Cosmos.System.Network.IPv4.TCP but System.Net.Sockets and System.Net. You can setup TCP network streams using TcpListener, TcpClient and NetworkStream, don't use the Stream class unless you know what you do. + +Server: ```csharp -using(var xClient = new TcpClient(4242)) +using System.Text; +using System.Net.Sockets; +using System.Net; + +class TcpServer { - xClient.Connect(new Address(192, 168, 1, 70), 4242); + private TcpListener tcpListener; + private int port; + + public TcpServer(int port) + { + this.port = port; + var address = IPAddress.Any; + this.tcpListener = new TcpListener(address, port); + } + + public void Start() + { + this.tcpListener.Start(); + + while (true) + { + /** Wait for new connections **/ + TcpClient client = this.tcpListener.AcceptTcpClient(); + HandleClientComm(client); + client.Close(); + } + } + + private void HandleClientComm(TcpClient client) + { + NetworkStream stream = client.GetStream(); + + byte[] buffer = new byte[client.ReceiveBufferSize]; + int bytesRead; + + while (true) + { + bytesRead = 0; + + /** Receive data **/ + bytesRead = stream.Read(buffer, 0, buffer.Length); // Blocks until a client sends a message + + if (bytesRead == 0) // The client has disconnected from the server + { + break; + } + + string received = Encoding.ASCII.GetString(buffer, 0, bytesRead); + + /** Send data **/ + byte[] response = Encoding.ASCII.GetBytes("ok"); + stream.Write(response, 0, response.Length); + + // stream.Flush(); useless for now + } + stream.Close(); + } +} +``` - /** Send data **/ - xClient.Send(Encoding.ASCII.GetBytes(message)); +Client : +```csharp +string serverIp = "192.168.1.63"; +int serverPort = 1312; +using(TcpClient client = new TcpClient()) +{ + /**Connect to server **/ + client.Connect(serverIp, serverPort); + NetworkStream stream = client.GetStream(); + + /** Send data **/ + string messageToSend = "Hello from CosmosOS!"; + byte[] dataToSend = Encoding.ASCII.GetBytes(messageToSend); + stream.Write(dataToSend, 0, dataToSend.Length); + /** Receive data **/ - var endpoint = new EndPoint(Address.Zero, 0); - var data = xClient.Receive(ref endpoint); //set endpoint to remote machine IP:port - var data2 = xClient.NonBlockingReceive(ref endpoint); //retrieve receive buffer without waiting + byte[] receivedData = new byte[client.ReceiveBufferSize]; + int bytesRead = stream.Read(receivedData, 0, receivedData.Length); + string receivedMessage = Encoding.ASCII.GetString(receivedData, 0, bytesRead); + + /** Close data stream **/ + stream.Close(); } ``` @@ -96,23 +168,6 @@ using(var xServer = new FtpServer(fs, "0:\\")) } ``` -## UDP -Before playing with packets, we have to create a client and call Connect() to specify the remote machine address. After that the client will be able to send or listen for data. -```csharp -using(var xClient = new UdpClient(4242)) -{ - xClient.Connect(new Address(192, 168, 1, 70), 4242); - - /** Send data **/ - xClient.Send(Encoding.ASCII.GetBytes(message)); - - /** Receive data **/ - var endpoint = new EndPoint(Address.Zero, 0); - var data = xClient.Receive(ref endpoint); //set endpoint to remote machine IP:port - var data2 = xClient.NonBlockingReceive(ref endpoint); //retrieve receive buffer without waiting -} -``` - ## ICMP For ICMP, we will only be able to send an ICMP echo to a distant machine and wait for its response. If another machine sends us an ICMP echo, Cosmos will automatically handle the request and reply. ```csharp From f3fca0a1166b7d97e2a6fc0b88de592e1a55e913 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 11:06:47 +0100 Subject: [PATCH 24/27] =?UTF-8?q?=F0=9F=93=9D=20Update=20Network.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Docs/articles/Kernel/Network.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Docs/articles/Kernel/Network.md b/Docs/articles/Kernel/Network.md index 1628ac14b9..d169383655 100644 --- a/Docs/articles/Kernel/Network.md +++ b/Docs/articles/Kernel/Network.md @@ -6,7 +6,7 @@ All protocols here don't necessary support every feature described by their RFC Each protocol has a Client class which can be used to receive and send data. If a Receive() method is blocking, the method will timeout after 5 seconds or use the value optionally set by parameter. Please note that all finished connections should be closed using Close(). -Cosmos Network Stack won't use Classes and Functions that are under .NET Core. Everything described here will be under: +The Cosmos Network Stack mainly not uses classes and functions that are under .NET Core (except TCP). Everything described here will be under: ```csharp using Cosmos.System.Network; ``` @@ -28,6 +28,11 @@ using(var xClient = new DHCPClient()) } ``` +### Get local IP address +```csharp +Console.WriteLine(NetworkConfiguration.CurrentAddress.ToString()); +``` + ## UDP Before playing with packets, we have to create a client and call Connect() to specify the remote machine address. After that the client will be able to send or listen for data. ```csharp @@ -46,7 +51,7 @@ using(var xClient = new UdpClient(4242)) ``` ## TCP -Unlike UDP, TCP is plugged with the dotnet framework. You won't have to use Cosmos.System.Network.IPv4.TCP but System.Net.Sockets and System.Net. You can setup TCP network streams using TcpListener, TcpClient and NetworkStream, don't use the Stream class unless you know what you do. +Unlike UDP, TCP is plugged with the dotnet framework. You won't have to use Cosmos.System.Network but System.Net.Sockets and System.Net. You can setup TCP network streams using TcpListener, TcpClient and NetworkStream, don't use the Stream class unless you know what you do. Server: ```csharp @@ -196,9 +201,4 @@ using(var xClient = new DnsClient()) /** Receive DNS Response **/ Address destination = xClient.Receive(); //can set a timeout value } - ``` -## Get local IP address -```csharp -Console.WriteLine(NetworkConfiguration.CurrentAddress.ToString()); -``` \ No newline at end of file From c7b70e15ed4f17c4022869d8122f61805b86b0ff Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 11:43:34 +0100 Subject: [PATCH 25/27] =?UTF-8?q?=F0=9F=94=A5=20Clean=20up=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Network/IPv4/TCP/TCPClient.cs | 261 ------------------ source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs | 7 - .../Network/IPv4/TCP/TcpListener.cs | 139 ---------- .../Interop/WinsockImpl.cs | 22 -- .../System/Net/IPAddressImpl.cs | 4 +- .../System/Net/Sockets/SocketImpl.cs | 19 +- 6 files changed, 3 insertions(+), 449 deletions(-) delete mode 100644 source/Cosmos.System2/Network/IPv4/TCP/TCPClient.cs delete mode 100644 source/Cosmos.System2/Network/IPv4/TCP/TcpListener.cs delete mode 100644 source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs diff --git a/source/Cosmos.System2/Network/IPv4/TCP/TCPClient.cs b/source/Cosmos.System2/Network/IPv4/TCP/TCPClient.cs deleted file mode 100644 index 87a990b9c8..0000000000 --- a/source/Cosmos.System2/Network/IPv4/TCP/TCPClient.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Collections.Generic; -using Cosmos.System.Helpers; -using Cosmos.System.Network.Config; - -namespace Cosmos.System.Network.IPv4.TCP -{ - /// - /// Represents a TCP client. Used to manage the TCP connection to a server. - /// - public class TcpClient : IDisposable - { - /// - /// The TCP state machine. - /// - public Tcp StateMachine; - - /// - /// Initializes a new instance of the class. - /// - /// Thrown on fatal error. - /// Thrown if TcpClient with localPort 0 exists. - public TcpClient() : this(Tcp.GetDynamicPort()) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The TCP state machine. - /// Thrown on fatal error. - /// Thrown if localPort already exists. - internal TcpClient(Tcp stateMachine) - { - StateMachine = stateMachine; - } - - /// - /// Initializes a new instance of the class. - /// - /// The local port. - /// Thrown on fatal error. - /// Thrown if localPort already exists. - internal TcpClient(int localPort) - { - StateMachine = new((ushort)localPort, 0, Address.Zero, Address.Zero); - StateMachine.RxBuffer = new Queue(8); - StateMachine.Status = Status.CLOSED; - } - - /// - /// Initializes a new instance of the class. - /// - /// Destination address. - /// Destination port. - /// Thrown on fatal error. - /// Thrown if TcpClient with localPort 0 exists. - public TcpClient(Address dest, int destPort) - : this(Tcp.GetDynamicPort()) - { - StateMachine.RemoteEndPoint.Address = dest; - StateMachine.RemoteEndPoint.Port = (ushort)destPort; - } - - /// - /// Connects the client to the given server. - /// - /// Destination address. - /// Destination port. - /// Thrown if TCP Status is not CLOSED. - public void Connect(Address dest, int destPort, int timeout = 5000) - { - if (StateMachine.Status == Status.ESTABLISHED) - { - throw new Exception("Client must be closed before setting a new connection."); - } - - StateMachine.RemoteEndPoint.Address = dest; - StateMachine.LocalEndPoint.Address = IPConfig.FindNetwork(dest); - StateMachine.RemoteEndPoint.Port = (ushort)destPort; - - //Generate Random Sequence Number - var rnd = new Random(); - var SequenceNumber = (uint)(rnd.Next(0, Int32.MaxValue) << 32) | (uint)rnd.Next(0, Int32.MaxValue); - - //Fill TCB - StateMachine.TCB.SndUna = SequenceNumber; - StateMachine.TCB.SndNxt = SequenceNumber; - StateMachine.TCB.SndWnd = Tcp.TcpWindowSize; - StateMachine.TCB.SndUp = 0; - StateMachine.TCB.SndWl1 = 0; - StateMachine.TCB.SndWl2 = 0; - StateMachine.TCB.ISS = SequenceNumber; - - StateMachine.TCB.RcvNxt = 0; - StateMachine.TCB.RcvWnd = Tcp.TcpWindowSize; - StateMachine.TCB.RcvUp = 0; - StateMachine.TCB.IRS = 0; - - Tcp.Connections.Add(StateMachine); - - StateMachine.SendEmptyPacket(Flags.SYN); - - StateMachine.Status = Status.SYN_SENT; - - if (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) == false) - { - throw new Exception("Failed to open TCP connection!"); - } - } - - /// - /// Closes the connection. - /// - /// Thrown on fatal error. - /// Thrown if TCP Status is CLOSED. - public void Close() - { - if (StateMachine.Status == Status.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); - } - - /// - /// Sends data to the connected server. - /// - /// Data array to send. - /// Thrown if destination is null or destinationPort is 0. - /// Thrown on fatal error. - /// Thrown if data array length is greater than Int32.MaxValue. - /// Thrown on IO error. - /// Thrown if TCP Status is not ESTABLISHED. - public void Send(byte[] data) - { - if (StateMachine.RemoteEndPoint.Address == null || StateMachine.RemoteEndPoint.Port == 0) - { - throw new InvalidOperationException("Must establish a default remote host by calling Connect() before using this Send() overload"); - } - if (StateMachine.Status != Status.ESTABLISHED) - { - throw new Exception("Client must be connected before sending data."); - } - if (data.Length > 536) - { - var chunks = ArrayHelper.ArraySplit(data, 536); - - for (int i = 0; i < chunks.Length; i++) - { - var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, i == chunks.Length - 2 ? (byte)(Flags.PSH | Flags.ACK) : (byte)Flags.ACK, StateMachine.TCB.SndWnd, 0, chunks[i]); - OutgoingBuffer.AddPacket(packet); - NetworkStack.Update(); - - StateMachine.TCB.SndNxt += (uint)chunks[i].Length; - } - } - else - { - var packet = new TCPPacket(StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address, StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.TCB.SndNxt, StateMachine.TCB.RcvNxt, 20, (byte)(Flags.PSH | Flags.ACK), StateMachine.TCB.SndWnd, 0, data); - OutgoingBuffer.AddPacket(packet); - NetworkStack.Update(); - - StateMachine.TCB.SndNxt += (uint)data.Length; - } - } - - /// - /// Receives data from the end-point. - /// - /// Source end point. - /// Thrown on fatal error. - /// Thrown if TCP Status is not ESTABLISHED. - public byte[] NonBlockingReceive(ref EndPoint source) - { - if (StateMachine.Status != Status.ESTABLISHED) - { - throw new Exception("Client must be connected before receiving data."); - } - - if (StateMachine.RxBuffer.Count < 1) - { - return null; - } - - var packet = StateMachine.RxBuffer.Dequeue(); - source.Address = packet.SourceIP; - source.Port = packet.SourcePort; - - var tmp = StateMachine.Data; - StateMachine.Data = null; - return tmp; - } - - /// - /// Receives data from the end-point. - /// - /// Source end point. - /// Thrown on fatal error. - /// Thrown if TCP Status is not ESTABLISHED. - public byte[] Receive(ref EndPoint source) - { - while (StateMachine.RxBuffer.Count < 1) - { - if (StateMachine.Status != Status.ESTABLISHED) - { - throw new Exception("Client must be connected before receiving data."); - } - } - - var packet = StateMachine.RxBuffer.Dequeue(); - source.Address = packet.SourceIP; - source.Port = packet.SourcePort; - - var tmp = StateMachine.Data; - StateMachine.Data = null; - return tmp; - } - - /// - /// Gets the remote hosts end-point (IP address and port). - /// - public EndPoint RemoteEndPoint => StateMachine.RemoteEndPoint; - - /// - /// Gets the remote hosts end-point (IP address and port). - /// - public EndPoint LocalEndPoint => StateMachine.LocalEndPoint; - - /// - /// Returns a value whether the TCP client is connected to a remote host. - /// - public bool IsConnected() - { - return StateMachine.Status == Status.ESTABLISHED; - } - - /// - /// Returns a value whether the TCP client is closed - /// - public bool IsClosed() - { - return StateMachine.Status == Status.CLOSED; - } - - public void Dispose() - { - Close(); - } - } -} diff --git a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs index 8324e0b2e9..349b2dea56 100644 --- a/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs +++ b/source/Cosmos.System2/Network/IPv4/TCP/Tcp.cs @@ -292,11 +292,6 @@ public static void RemoveConnection(ushort localPort, ushort remotePort, Address /// public Status Status; - /// - /// Check send data confirmation. - /// - public bool WaitingSendAck = false; - /// /// The received data buffer. /// @@ -401,8 +396,6 @@ public void ProcessListen(TCPPacket packet) } else if (packet.FIN) { - Status = Status.CLOSED; - NetworkStack.Debugger.Send("TCP connection closed! (FIN received on LISTEN state)"); } else if (packet.ACK) diff --git a/source/Cosmos.System2/Network/IPv4/TCP/TcpListener.cs b/source/Cosmos.System2/Network/IPv4/TCP/TcpListener.cs deleted file mode 100644 index 30e8d831ff..0000000000 --- a/source/Cosmos.System2/Network/IPv4/TCP/TcpListener.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Cosmos.System.Network.IPv4.TCP -{ - /// - /// Used to manage a TCP connection to a client. - /// - public class TcpListener : IDisposable - { - private readonly ushort localPort; - - /// - /// The TCP state machine. - /// - internal Tcp StateMachine; - - /// - /// Initializes a new instance of the class. - /// - /// Local address. - /// Local port. - /// Thrown on fatal error. - /// Thrown if localPort already exists. - public TcpListener(ushort localPort) - { - this.localPort = localPort; - } - - /// - /// Receives a instance from the remote host. - /// - /// The accepted . - /// Thrown if TcpListener not started. - public TcpClient AcceptTcpClient(int timeout = -1) - { - 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(); - } - - if (timeout == -1) - { - while (StateMachine.WaitStatus(Status.ESTABLISHED) != true); - } - else - { - while (StateMachine.WaitStatus(Status.ESTABLISHED, timeout) != true); - } - - return new TcpClient(StateMachine); - } - - /// - /// Starts listening for new TCP connections. - /// - /// Thrown on fatal error. - /// Thrown on IO error. - public void Start() - { - StateMachine = new(localPort, 0, Address.Zero, Address.Zero); - StateMachine.RxBuffer = new Queue(8); - StateMachine.LocalEndPoint.Port = localPort; - StateMachine.Status = Status.LISTEN; - - Tcp.Connections.Add(StateMachine); - } - - /// - /// Stops listening for new TCP connections. - /// - /// Thrown on fatal error. - /// Thrown on IO error. - /// Thrown if TcpListener not started. - public void Stop() - { - if (StateMachine == null) - { - throw new Exception("The TcpListener is not started."); - } - - if (StateMachine.Status == Status.LISTEN) - { - Tcp.RemoveConnection(StateMachine.LocalEndPoint.Port, StateMachine.RemoteEndPoint.Port, StateMachine.LocalEndPoint.Address, StateMachine.RemoteEndPoint.Address); - StateMachine = null; - } - else if (StateMachine.Status == Status.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); - } - } - - /// - /// Returns a value whether the TCP server is waiting for a connection - /// - public bool IsListening() - { - return StateMachine.Status == Status.LISTEN; - } - - /// - /// Returns a value whether the TCP server is connected to a remote host. - /// - public bool IsConnected() - { - return StateMachine.Status == Status.ESTABLISHED; - } - - /// - /// Returns a value whether the TCP server is closed - /// - public bool IsClosed() - { - return StateMachine == null || StateMachine.Status == Status.CLOSED; - } - - public void Dispose() - { - Stop(); - } - } -} diff --git a/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs b/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs deleted file mode 100644 index 06d51de990..0000000000 --- a/source/Cosmos.System2_Plugs/Interop/WinsockImpl.cs +++ /dev/null @@ -1,22 +0,0 @@ -using IL2CPU.API.Attribs; -using System; -using System.Net.Sockets; - -namespace Cosmos.Core_Plugs.Interop -{ - [Plug("Interop+Winsock, System.Net.Sockets", IsOptional = true)] - public static unsafe class WinsockImpl - { - [PlugMethod(Signature = "System_Net_Sockets_SocketError__Interop_Winsock_shutdown_System_Net_Sockets_SafeSocketHandle__System_Int32_")] - public static SocketError shutdown(SafeSocketHandle socketHandle, int how) - { - throw new NotImplementedException(); - } - - [PlugMethod(Signature = "System_Net_Sockets_SocketError__Interop_Winsock_shutdown_System_Net_Sockets_SafeSocketHandle__System_Int32_")] - public static int recv(SafeSocketHandle socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags) - { - throw new NotImplementedException(); - } - } -} diff --git a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs index 3c451ee61c..6565af1f1b 100644 --- a/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/IPAddressImpl.cs @@ -55,12 +55,10 @@ public static void Ctor(IPAddress aThis, byte[] address) if (address.Length == IPv4AddressBytes) { PrivateAddress = (uint)((address[0] << 0) | (address[1] << 8) | (address[2] << 16) | (address[3] << 24)); - - Cosmos.HAL.Global.debugger.Send("Ctor address=" + aThis.ToString()); } else if (address.Length == IPv6AddressBytes) { - Cosmos.HAL.Global.debugger.Send("IPv6 not supported yet!"); + //do nothing } else { diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs index e3fb0a0562..0757cd5946 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/SocketImpl.cs @@ -33,7 +33,7 @@ public static void Ctor(Socket aThis, AddressFamily addressFamily, SocketType so CheckSocket(aThis, socketType, protocolType); } - public static void CheckSocket(Socket aThis, SocketType socketType, ProtocolType protocolType) + private static void CheckSocket(Socket aThis, SocketType socketType, ProtocolType protocolType) { if (socketType != SocketType.Stream) { @@ -93,7 +93,6 @@ public static Socket Accept(Socket aThis) while (StateMachine.WaitStatus(Status.ESTABLISHED) != true); _remoteEndPoint = new IPEndPoint(StateMachine.RemoteEndPoint.Address.ToUInt32(), StateMachine.RemoteEndPoint.Port); - _localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port); return aThis; @@ -109,18 +108,6 @@ private static void Start() Tcp.Connections.Add(StateMachine); } - private static uint ConvertIPAddressToUInt32(IPAddress ip) - { - byte[] bytes = ip.GetAddressBytes(); - return (uint)(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3]); - } - - public static int GetRandomPort() - { - Random random = new Random(); - return random.Next(MinPort, MaxPort + 1); - } - public static void Connect(Socket aThis, IPAddress address, int port) { Start(); @@ -134,7 +121,7 @@ public static void Connect(Socket aThis, IPAddress address, int port) StateMachine.RemoteEndPoint.Address = Cosmos.System.Network.IPv4.Address.Parse(EndPoint.Address.ToString()); StateMachine.RemoteEndPoint.Port = (ushort)port; StateMachine.LocalEndPoint.Address = NetworkConfiguration.CurrentAddress; - StateMachine.LocalEndPoint.Port = (ushort)GetRandomPort(); + StateMachine.LocalEndPoint.Port = Tcp.GetDynamicPort(); _remoteEndPoint = new IPEndPoint(address, StateMachine.RemoteEndPoint.Port); _localEndPoint = new IPEndPoint(StateMachine.LocalEndPoint.Address.ToUInt32(), StateMachine.LocalEndPoint.Port); @@ -225,8 +212,6 @@ public static int Send(Socket aThis, byte[] buffer, int offset, int size, Socket StateMachine.TCB.SndNxt += (uint)size; - StateMachine.WaitingSendAck = true; - bytesSent = size; WaitAck(); From 51bb237e33caeb5e93e406ad7e3fab26277d28e4 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 11:50:25 +0100 Subject: [PATCH 26/27] =?UTF-8?q?=E2=9C=85=20Remove=20TCP=20test=20for=20n?= =?UTF-8?q?ow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/Kernels/NetworkTest/Kernel.cs | 42 ++----------------- .../Cosmos.System2/Network/NetworkDebugger.cs | 21 ++++++---- 2 files changed, 17 insertions(+), 46 deletions(-) diff --git a/Tests/Kernels/NetworkTest/Kernel.cs b/Tests/Kernels/NetworkTest/Kernel.cs index 22bd4c8502..458995f888 100644 --- a/Tests/Kernels/NetworkTest/Kernel.cs +++ b/Tests/Kernels/NetworkTest/Kernel.cs @@ -11,6 +11,8 @@ using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; using System; using System.Collections.Generic; +using System.Net; +using System.Net.Sockets; using System.Text; using Sys = Cosmos.System; @@ -152,43 +154,7 @@ private void TestDhcpConnection() private void TestTcpConnection() { - Global.debugger.Send("Creating TCP client..."); - - using (var xClient = new TcpClient()) - { - Assert.IsTrue(xClient.IsClosed(), "TCP connexion created."); - - xClient.Connect(new Address(127, 0, 0, 1), 12345); - Assert.IsTrue(xClient.IsConnected(), "TCP connexion established."); - - var endpoint = new EndPoint(Address.Zero, 0); - var data = xClient.Receive(ref endpoint); - Assert.AreEqual(Encoding.ASCII.GetString(data), "Hello from the testrunner!", "TCP receive works"); - - xClient.Send(Encoding.ASCII.GetBytes(NetworkConfiguration.CurrentAddress.ToString())); - - xClient.Send(Encoding.ASCII.GetBytes("cosmos is the best operating system uwu")); - var data2 = xClient.Receive(ref endpoint); - Assert.AreEqual(Encoding.ASCII.GetString(data2), "COSMOS IS THE BEST OPERATING SYSTEM UWU", "TCP send works"); - - string baseMessage = "This is a long TCP message for sequencing test..."; - string paddedMessage = baseMessage.PadRight(6000, '.'); - xClient.Send(Encoding.ASCII.GetBytes(paddedMessage)); - - var data3 = xClient.Receive(ref endpoint); - Assert.AreEqual(data3.Length, 6000, "TCP paquet sequencing works."); - } - - Global.debugger.Send("Creating TCP server..."); - - using (var xServer = new TcpListener(4343)) - { - xServer.Start(); - Assert.IsTrue(xServer.IsListening(), "TCP server is listening."); - - var client = xServer.AcceptTcpClient(); //blocking - Assert.IsTrue(xServer.IsConnected(), "Received new client! TCP connexion established."); - } + } private void TestDnsConnection() @@ -222,7 +188,7 @@ private void TestIcmpConnection() xClient.SendEcho(); - var endpoint = new EndPoint(Address.Zero, 0); + var endpoint = new Sys.Network.IPv4.EndPoint(Address.Zero, 0); int time = xClient.Receive(ref endpoint); Assert.IsFalse(time == -1, "ICMP echo works"); diff --git a/source/Cosmos.System2/Network/NetworkDebugger.cs b/source/Cosmos.System2/Network/NetworkDebugger.cs index 564e1f1666..e13a28cb41 100644 --- a/source/Cosmos.System2/Network/NetworkDebugger.cs +++ b/source/Cosmos.System2/Network/NetworkDebugger.cs @@ -1,8 +1,8 @@ using System; +using System.Net; +using System.Net.Sockets; using System.Text; using Cosmos.System.Network.Config; -using Cosmos.System.Network.IPv4; -using Cosmos.System.Network.IPv4.TCP; using Con = System.Console; namespace Cosmos.System.Network @@ -13,12 +13,13 @@ namespace Cosmos.System.Network public class NetworkDebugger { private readonly TcpListener listener; + private NetworkStream stream; private TcpClient client; /// /// The remote host IP address. /// - public Address Ip { get; set; } + public IPAddress Ip { get; set; } /// /// The port to use. @@ -32,7 +33,7 @@ public class NetworkDebugger public NetworkDebugger(int port) { Port = port; - listener = new TcpListener((ushort)port); + listener = new TcpListener(IPAddress.Any, (ushort)port); } /// @@ -40,11 +41,11 @@ public NetworkDebugger(int port) /// /// IP Address of the remote debugger. /// Port used for TCP connection. - public NetworkDebugger(Address ip, int port) + public NetworkDebugger(IPAddress ip, int port) { Ip = ip; Port = port; - client = new TcpClient(port); + client = new TcpClient(new IPEndPoint(Ip, port)); } /// @@ -57,13 +58,15 @@ public void Start() listener.Start(); Con.WriteLine("Waiting for remote debugger connection at " + NetworkConfiguration.CurrentAddress.ToString() + ":" + Port); - client = listener.AcceptTcpClient(); //blocking + client = listener.AcceptTcpClient(); } else if (listener == null) { client.Connect(Ip, Port); } + stream = client.GetStream(); + Send("--- Cosmos Network Debugger ---"); Send("Debugger connected!"); } @@ -74,7 +77,8 @@ public void Start() /// Text to send to the debugger. public void Send(string message) { - client.Send(Encoding.ASCII.GetBytes("[" + DateTime.Now.ToString("HH:mm:ss") + "] - " + message + "\r\n")); + byte[] dataToSend = Encoding.ASCII.GetBytes("[" + DateTime.Now.ToString("HH:mm:ss") + "] - " + message + "\r\n"); + stream.Write(dataToSend, 0, dataToSend.Length); } /// @@ -84,6 +88,7 @@ public void Stop() { Con.WriteLine("Closing Debugger connection"); Send("Closing..."); + stream.Close(); client.Close(); } } From 4b4e809d2f217700073cc972303ec892301e2030 Mon Sep 17 00:00:00 2001 From: valentinbreiz Date: Tue, 5 Dec 2023 13:20:25 +0100 Subject: [PATCH 27/27] =?UTF-8?q?=E2=9C=85=20Update=20TCP=20tests=20+=20Fi?= =?UTF-8?q?x=20NetworkStream=20Write?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/Kernels/NetworkTest/Kernel.cs | 52 ++++++++++++++++++- .../System/Net/Sockets/NetworkStreamImpl.cs | 5 ++ .../System/Net/Sockets/TcpClientImpl.cs | 5 +- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Tests/Kernels/NetworkTest/Kernel.cs b/Tests/Kernels/NetworkTest/Kernel.cs index 458995f888..04e0f7122b 100644 --- a/Tests/Kernels/NetworkTest/Kernel.cs +++ b/Tests/Kernels/NetworkTest/Kernel.cs @@ -154,7 +154,57 @@ private void TestDhcpConnection() private void TestTcpConnection() { - + Global.debugger.Send("Creating TCP client..."); + + using (var xClient = new TcpClient()) + { + Global.debugger.Send("Creating IPAddress..."); + var address = new IPAddress(new byte[] { 127, 0, 0, 1 }); + Global.debugger.Send("Connecting to TCP server..."); + xClient.Connect(address, 12345); + Global.debugger.Send("TcpClient connected."); + NetworkStream stream = xClient.GetStream(); + Assert.IsTrue(xClient.Connected, "TCP connexion established."); + + byte[] receivedData = new byte[xClient.ReceiveBufferSize]; + int bytesRead = stream.Read(receivedData, 0, receivedData.Length); + string receivedMessage = Encoding.ASCII.GetString(receivedData, 0, bytesRead); + Assert.AreEqual(receivedMessage, "Hello from the testrunner!", "TCP receive works"); + + Global.debugger.Send("TcpClient sending IP " + NetworkConfiguration.CurrentAddress.ToString()); + stream.Write(Encoding.ASCII.GetBytes(NetworkConfiguration.CurrentAddress.ToString())); + Global.debugger.Send("TcpClient IP sent"); + + // Envoyer un message au serveur + string messageToSend = "cosmos is the best operating system uwu"; + byte[] dataToSend = Encoding.ASCII.GetBytes(messageToSend); + Global.debugger.Send("Sending: " + messageToSend); + stream.Write(dataToSend, 0, dataToSend.Length); + + byte[] receivedData2 = new byte[xClient.ReceiveBufferSize]; + int bytesRead2 = stream.Read(receivedData2, 0, receivedData2.Length); + string receivedMessage2 = Encoding.ASCII.GetString(receivedData2, 0, bytesRead2); + Assert.AreEqual(receivedMessage2, "COSMOS IS THE BEST OPERATING SYSTEM UWU", "TCP send works"); + + string baseMessage = "This is a long TCP message for sequencing test..."; + string paddedMessage = baseMessage.PadRight(6000, '.'); + stream.Write(Encoding.ASCII.GetBytes(paddedMessage)); + Global.debugger.Send("Sent long data packet."); + + byte[] receivedData3 = new byte[xClient.ReceiveBufferSize]; + int bytesRead3 = stream.Read(receivedData3, 0, receivedData3.Length); + Assert.AreEqual(bytesRead3, 6000, "TCP paquet sequencing works."); + + stream.Close(); + } + + Global.debugger.Send("Creating TCP server..."); + + var xServer = new TcpListener(IPAddress.Any, 4343); + xServer.Start(); + + var client = xServer.AcceptTcpClient(); //blocking + Assert.IsTrue(client.Connected, "Received new client! TCP connexion established."); } private void TestDnsConnection() diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs index 2c0a8f9e0a..940d34a269 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/NetworkStreamImpl.cs @@ -56,6 +56,11 @@ public static int Read(NetworkStream aThis, byte[] buffer, int offset, int count return _streamSocket.Receive(buffer, offset, count, 0); } + public static void Write(NetworkStream aThis, ReadOnlySpan buffer) + { + Write(aThis, buffer.ToArray(), 0, buffer.Length); + } + public static void Write(NetworkStream aThis, byte[] buffer, int offset, int count) { _streamSocket.Send(buffer, offset, count, 0); diff --git a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs index cfb2dbb115..b70121e4fa 100644 --- a/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs +++ b/source/Cosmos.System2_Plugs/System/Net/Sockets/TcpClientImpl.cs @@ -44,7 +44,6 @@ public static void Connect(TcpClient aThis, string hostname, int port, [FieldAcc var address = IPAddress.Parse(hostname); var endpoint = new IPEndPoint(address, port); - Cosmos.HAL.Global.debugger.Send("address - " + address.ToString()); _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _clientSocket.Bind(endpoint); _clientSocket.Connect(address, port); @@ -53,6 +52,10 @@ public static void Connect(TcpClient aThis, string hostname, int port, [FieldAcc public static void Connect(TcpClient aThis, IPAddress address, int port, [FieldAccess(Name = "System.Boolean System.Net.Sockets.TcpClient._active")] ref bool _active) { + var endpoint = new IPEndPoint(address, port); + + _clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + _clientSocket.Bind(endpoint); _clientSocket.Connect(address, port); _active = true; }