Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
cuteant committed Sep 28, 2020
1 parent 9c2175d commit 50bb5fd
Show file tree
Hide file tree
Showing 29 changed files with 464 additions and 40 deletions.
8 changes: 4 additions & 4 deletions src/DotNetty.NetUV/Handles/Pipe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal Pipe(LoopContext loop, bool ipc = false)

public int GetSendBufferSize()
{
if (Platform.IsWindows)
if (PlatformApi.IsWindows)
{
ThrowHelper.ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(HandleType);
}
Expand All @@ -42,7 +42,7 @@ public int SetSendBufferSize(int value)
{
if ((uint)value > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_PositiveOrZero(value, ExceptionArgument.value); }

if (Platform.IsWindows)
if (PlatformApi.IsWindows)
{
ThrowHelper.ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(HandleType);
}
Expand All @@ -52,7 +52,7 @@ public int SetSendBufferSize(int value)

public int GetReceiveBufferSize()
{
if (Platform.IsWindows)
if (PlatformApi.IsWindows)
{
ThrowHelper.ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(HandleType);
}
Expand All @@ -64,7 +64,7 @@ public int SetReceiveBufferSize(int value)
{
if ((uint)value > SharedConstants.TooBigOrNegative) { ThrowHelper.ThrowArgumentException_PositiveOrZero(value, ExceptionArgument.value); }

if (Platform.IsWindows)
if (PlatformApi.IsWindows)
{
ThrowHelper.ThrowPlatformNotSupportedException_handle_type_send_buffer_size_setting_not_supported_on_Windows(HandleType);
}
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetty.NetUV/Handles/Tty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public override void OnRead(Action<Tty, IStreamReadCompletion> onRead)

public Tty Mode(TtyMode mode)
{
if (mode == TtyMode.IO && !Platform.IsUnix)
if (mode == TtyMode.IO && !PlatformApi.IsUnix)
{
ThrowHelper.ThrowArgumentException_TtyMode_is_Unix_only(mode);
}
Expand Down
37 changes: 37 additions & 0 deletions src/DotNetty.NetUV/Internal/ThrowHelper.Libuv.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@

using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using DotNetty.NetUV.Handles;
using DotNetty.NetUV.Native;
using DotNetty.NetUV.Channels;
Expand Down Expand Up @@ -50,5 +52,40 @@ InvalidOperationException GetInvalidOperationException()
return new InvalidOperationException($"Invalid {nameof(LoopExecutor)} state {executionState}");
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ThrowInvalidOperationException_Dispatch()
{
throw GetInvalidOperationException();

static InvalidOperationException GetInvalidOperationException()
{
return new InvalidOperationException("No pipe connections to dispatch handles.");
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal static uint ThrowInvalidOperationException_Dispatch(AddressFamily addressFamily)
{
throw GetInvalidOperationException();
InvalidOperationException GetInvalidOperationException()
{
return new InvalidOperationException($"Address family : {addressFamily} platform : {RuntimeInformation.OSDescription} not supported");
}
}

#region -- SocketException --

[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ThrowSocketException(int errorCode)
{
throw GetSocketException();
SocketException GetSocketException()
{
return new SocketException(errorCode);
}
}

#endregion
}
}
2 changes: 1 addition & 1 deletion src/DotNetty.NetUV/Native/NativeHandles.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ internal unsafe IPEndPoint GetIPEndPoint()
var port = ((int)(_field0 & 0x00FF0000) >> 8) | (int)((_field0 & 0xFF000000) >> 24);

int family = (int)_field0;
if (Platform.IsDarwin)
if (PlatformApi.IsDarwin)
{
// see explaination in example 4
family >>= 8;
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetty.NetUV/Native/NativeRequests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ internal struct uv_getaddrinfo_t
[StructLayout(LayoutKind.Sequential)]
internal struct addrinfo
{
private static readonly bool s_isWindows = Platform.IsWindows;
private static readonly bool s_isWindows = PlatformApi.IsWindows;

public readonly int ai_flags;
public readonly int ai_family; // AF_INET or AF_INET6
Expand Down
2 changes: 1 addition & 1 deletion src/DotNetty.NetUV/Native/NativeStreams.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace DotNetty.NetUV.Native
[StructLayout(LayoutKind.Sequential)]
internal struct uv_buf_t
{
private static readonly bool IsWindows = Platform.IsWindows;
private static readonly bool IsWindows = PlatformApi.IsWindows;
private static readonly int Size = IntPtr.Size;

/*
Expand Down
110 changes: 110 additions & 0 deletions src/DotNetty.NetUV/Native/PlatformApi.Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Copyright (c) The DotNetty Project (Microsoft). All rights reserved.
*
* https://github.com/azure/dotnetty
*
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*
* Copyright (c) 2020 The Dotnetty-Span-Fork Project ([email protected]) All rights reserved.
*
* https://github.com/cuteant/dotnetty-span-fork
*
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/

namespace DotNetty.NetUV.Native
{
using System;
using System.Net.Sockets;
using DotNetty.NetUV.Handles;

static partial class PlatformApi
{
const int AF_INET6_LINUX = 10;
const int AF_INET6_OSX = 30;

internal static uint GetAddressFamily(AddressFamily addressFamily)
{
// AF_INET 2
if (addressFamily == AddressFamily.InterNetwork || IsWindows)
{
return (uint)addressFamily;
}

if (IsLinux)
{
return AF_INET6_LINUX;
}

if (IsDarwin)
{
return AF_INET6_OSX;
}

return ThrowHelper.ThrowInvalidOperationException_Dispatch(addressFamily);
}

internal static bool GetReuseAddress(IInternalScheduleHandle handle)
{
IntPtr socketHandle = GetSocketHandle(handle);

if (IsWindows)
{
return WindowsApi.GetReuseAddress(socketHandle);
}
return UnixApi.GetReuseAddress(socketHandle);
}

internal static void SetReuseAddress(IInternalScheduleHandle handle, int value)
{
IntPtr socketHandle = GetSocketHandle(handle);
if (IsWindows)
{
WindowsApi.SetReuseAddress(socketHandle, value);
}
else
{
UnixApi.SetReuseAddress(socketHandle, value);
}
}

internal static bool GetReusePort(IInternalScheduleHandle handle)
{
if (IsWindows) { return GetReuseAddress(handle); }

IntPtr socketHandle = GetSocketHandle(handle);
return UnixApi.GetReusePort(socketHandle);
}

internal static void SetReusePort(IInternalScheduleHandle handle, int value)
{
IntPtr socketHandle = GetSocketHandle(handle);
// Ignore SO_REUSEPORT on Windows because it is controlled
// by SO_REUSEADDR
if (IsWindows) { return; }

UnixApi.SetReusePort(socketHandle, value);
}

static IntPtr GetSocketHandle(IInternalScheduleHandle handle)
{
IntPtr socket = IntPtr.Zero;
NativeMethods.GetFileDescriptor(handle.InternalHandle, ref socket);
return socket;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ namespace DotNetty.NetUV.Native
using System.Net.Sockets;
using System.Runtime.InteropServices;

internal static class Platform
internal static partial class PlatformApi
{
static Platform()
static PlatformApi()
{
IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
Expand Down
128 changes: 128 additions & 0 deletions src/DotNetty.NetUV/Native/UnixApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright 2012 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Copyright (c) The DotNetty Project (Microsoft). All rights reserved.
*
* https://github.com/azure/dotnetty
*
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*
* Copyright (c) 2020 The Dotnetty-Span-Fork Project ([email protected]) All rights reserved.
*
* https://github.com/cuteant/dotnetty-span-fork
*
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/

namespace DotNetty.NetUV.Native
{
using System;
using System.Net.Sockets;
using System.Runtime.InteropServices;

static class UnixApi
{
#pragma warning disable IDE1006 // 命名样式
[DllImport("libc", SetLastError = true)]
static extern int setsockopt(int socket, int level, int option_name, IntPtr option_value, uint option_len);

[DllImport("libc", SetLastError = true)]
static extern unsafe int getsockopt(int socket, int level, int option_name, byte* optionValue, int* optionLen);
#pragma warning restore IDE1006 // 命名样式

const int SOL_SOCKET_LINUX = 0x0001;
const int SO_REUSEADDR_LINUX = 0x0002;
const int SO_REUSEPORT_LINUX = 0x000f;

const int SOL_SOCKET_OSX = 0xffff;
const int SO_REUSEADDR_OSX = 0x0004;
const int SO_REUSEPORT_OSX = 0x0200;

internal static unsafe bool GetReuseAddress(IntPtr socket)
{
int value = 0;
int status = 0;
int optLen = sizeof(int);
if (PlatformApi.IsLinux)
{
status = getsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEADDR_LINUX, (byte*)&value, &optLen);
}
else if (PlatformApi.IsDarwin)
{
status = getsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEADDR_OSX, (byte*)&value, &optLen);
}
if (status != 0)
{
ThrowHelper.ThrowSocketException(Marshal.GetLastWin32Error());
}

return value != 0;
}

internal static unsafe void SetReuseAddress(IntPtr socket, int value)
{
int status = 0;
if (PlatformApi.IsLinux)
{
status = setsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEADDR_LINUX, (IntPtr)(&value), sizeof(int));
}
else if (PlatformApi.IsDarwin)
{
status = setsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEADDR_OSX, (IntPtr)(&value), sizeof(int));
}
if (status != 0)
{
ThrowHelper.ThrowSocketException(Marshal.GetLastWin32Error());
}
}

internal static unsafe bool GetReusePort(IntPtr socket)
{
int value = 0;
int status = 0;
int optLen = sizeof(int);
if (PlatformApi.IsLinux)
{
status = getsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEPORT_LINUX, (byte*)&value, &optLen);
}
else if (PlatformApi.IsDarwin)
{
status = getsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEPORT_OSX, (byte*)&value, &optLen);
}
if (status != 0)
{
ThrowHelper.ThrowSocketException(Marshal.GetLastWin32Error());
}
return value != 0;
}

internal static unsafe void SetReusePort(IntPtr socket, int value)
{
int status = 0;
if (PlatformApi.IsLinux)
{
status = setsockopt(socket.ToInt32(), SOL_SOCKET_LINUX, SO_REUSEPORT_LINUX, (IntPtr)(&value), sizeof(int));
}
else if (PlatformApi.IsDarwin)
{
status = setsockopt(socket.ToInt32(), SOL_SOCKET_OSX, SO_REUSEPORT_OSX, (IntPtr)(&value), sizeof(int));
}
if (status != 0)
{
ThrowHelper.ThrowSocketException(Marshal.GetLastWin32Error());
}
}
}
}
Loading

0 comments on commit 50bb5fd

Please sign in to comment.