1
+ /*
2
+ * Copyright 2012 The Netty Project
3
+ *
4
+ * The Netty Project licenses this file to you under the Apache License,
5
+ * version 2.0 (the "License"); you may not use this file except in compliance
6
+ * with the License. You may obtain a copy of the License at:
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ * License for the specific language governing permissions and limitations
14
+ * under the License.
15
+ *
16
+ * Copyright (c) The DotNetty Project (Microsoft). All rights reserved.
17
+ *
18
+ * https://github.com/azure/dotnetty
19
+ *
20
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
21
+ *
22
+ * Copyright (c) 2020 The Dotnetty-Span-Fork Project ([email protected] ) All rights reserved.
23
+ *
24
+ * https://github.com/cuteant/dotnetty-span-fork
25
+ *
26
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
27
+ */
28
+
29
+ namespace DotNetty . NetUV . Native
30
+ {
31
+ using System ;
32
+ using System . Net . Sockets ;
33
+ using System . Runtime . InteropServices ;
34
+
35
+ static class UnixApi
36
+ {
37
+ #pragma warning disable IDE1006 // 命名样式
38
+ [ DllImport ( "libc" , SetLastError = true ) ]
39
+ static extern int setsockopt ( int socket , int level , int option_name , IntPtr option_value , uint option_len ) ;
40
+
41
+ [ DllImport ( "libc" , SetLastError = true ) ]
42
+ static extern unsafe int getsockopt ( int socket , int level , int option_name , byte * optionValue , int * optionLen ) ;
43
+ #pragma warning restore IDE1006 // 命名样式
44
+
45
+ const int SOL_SOCKET_LINUX = 0x0001 ;
46
+ const int SO_REUSEADDR_LINUX = 0x0002 ;
47
+ const int SO_REUSEPORT_LINUX = 0x000f ;
48
+
49
+ const int SOL_SOCKET_OSX = 0xffff ;
50
+ const int SO_REUSEADDR_OSX = 0x0004 ;
51
+ const int SO_REUSEPORT_OSX = 0x0200 ;
52
+
53
+ internal static unsafe bool GetReuseAddress ( IntPtr socket )
54
+ {
55
+ int value = 0 ;
56
+ int status = 0 ;
57
+ int optLen = sizeof ( int ) ;
58
+ if ( PlatformApi . IsLinux )
59
+ {
60
+ status = getsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_LINUX , SO_REUSEADDR_LINUX , ( byte * ) & value , & optLen ) ;
61
+ }
62
+ else if ( PlatformApi . IsDarwin )
63
+ {
64
+ status = getsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_OSX , SO_REUSEADDR_OSX , ( byte * ) & value , & optLen ) ;
65
+ }
66
+ if ( status != 0 )
67
+ {
68
+ ThrowHelper . ThrowSocketException ( Marshal . GetLastWin32Error ( ) ) ;
69
+ }
70
+
71
+ return value != 0 ;
72
+ }
73
+
74
+ internal static unsafe void SetReuseAddress ( IntPtr socket , int value )
75
+ {
76
+ int status = 0 ;
77
+ if ( PlatformApi . IsLinux )
78
+ {
79
+ status = setsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_LINUX , SO_REUSEADDR_LINUX , ( IntPtr ) ( & value ) , sizeof ( int ) ) ;
80
+ }
81
+ else if ( PlatformApi . IsDarwin )
82
+ {
83
+ status = setsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_OSX , SO_REUSEADDR_OSX , ( IntPtr ) ( & value ) , sizeof ( int ) ) ;
84
+ }
85
+ if ( status != 0 )
86
+ {
87
+ ThrowHelper . ThrowSocketException ( Marshal . GetLastWin32Error ( ) ) ;
88
+ }
89
+ }
90
+
91
+ internal static unsafe bool GetReusePort ( IntPtr socket )
92
+ {
93
+ int value = 0 ;
94
+ int status = 0 ;
95
+ int optLen = sizeof ( int ) ;
96
+ if ( PlatformApi . IsLinux )
97
+ {
98
+ status = getsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_LINUX , SO_REUSEPORT_LINUX , ( byte * ) & value , & optLen ) ;
99
+ }
100
+ else if ( PlatformApi . IsDarwin )
101
+ {
102
+ status = getsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_OSX , SO_REUSEPORT_OSX , ( byte * ) & value , & optLen ) ;
103
+ }
104
+ if ( status != 0 )
105
+ {
106
+ ThrowHelper . ThrowSocketException ( Marshal . GetLastWin32Error ( ) ) ;
107
+ }
108
+ return value != 0 ;
109
+ }
110
+
111
+ internal static unsafe void SetReusePort ( IntPtr socket , int value )
112
+ {
113
+ int status = 0 ;
114
+ if ( PlatformApi . IsLinux )
115
+ {
116
+ status = setsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_LINUX , SO_REUSEPORT_LINUX , ( IntPtr ) ( & value ) , sizeof ( int ) ) ;
117
+ }
118
+ else if ( PlatformApi . IsDarwin )
119
+ {
120
+ status = setsockopt ( socket . ToInt32 ( ) , SOL_SOCKET_OSX , SO_REUSEPORT_OSX , ( IntPtr ) ( & value ) , sizeof ( int ) ) ;
121
+ }
122
+ if ( status != 0 )
123
+ {
124
+ ThrowHelper . ThrowSocketException ( Marshal . GetLastWin32Error ( ) ) ;
125
+ }
126
+ }
127
+ }
128
+ }
0 commit comments