Skip to content

Commit faf2a3e

Browse files
Merge branch 'master' into ios_socket_fix
2 parents fa1d548 + 7274276 commit faf2a3e

File tree

7 files changed

+96
-38
lines changed

7 files changed

+96
-38
lines changed

LibSample/BroadcastTest.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,11 @@ public void Run()
112112
//Server
113113
_serverListener = new ServerListener();
114114

115-
NetManager server = new NetManager(_serverListener);
116-
server.BroadcastReceiveEnabled = true;
115+
NetManager server = new NetManager(_serverListener)
116+
{
117+
BroadcastReceiveEnabled = true,
118+
IPv6Enabled = IPv6Mode.DualMode
119+
};
117120
if (!server.Start(9050))
118121
{
119122
Console.WriteLine("Server start failed");
@@ -129,7 +132,8 @@ public void Run()
129132
{
130133
UnconnectedMessagesEnabled = true,
131134
SimulateLatency = true,
132-
SimulationMaxLatency = 1500
135+
SimulationMaxLatency = 1500,
136+
IPv6Enabled = IPv6Mode.DualMode
133137
};
134138
_clientListener1.Client = client1;
135139
if (!client1.Start())
@@ -144,7 +148,8 @@ public void Run()
144148
{
145149
UnconnectedMessagesEnabled = true,
146150
SimulateLatency = true,
147-
SimulationMaxLatency = 1500
151+
SimulationMaxLatency = 1500,
152+
IPv6Enabled = IPv6Mode.DualMode
148153
};
149154

150155
_clientListener2.Client = client2;

LibSample/HolePunchServerTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,23 +122,23 @@ public void Run()
122122

123123
_c1 = new NetManager(clientListener)
124124
{
125-
IPv6Enabled = false,
125+
IPv6Enabled = IPv6Mode.DualMode,
126126
NatPunchEnabled = true
127127
};
128128
_c1.NatPunchModule.Init(natPunchListener1);
129129
_c1.Start();
130130

131131
_c2 = new NetManager(clientListener)
132132
{
133-
IPv6Enabled = false,
133+
IPv6Enabled = IPv6Mode.DualMode,
134134
NatPunchEnabled = true
135135
};
136136
_c2.NatPunchModule.Init(natPunchListener2);
137137
_c2.Start();
138138

139139
_puncher = new NetManager(clientListener)
140140
{
141-
IPv6Enabled = false,
141+
IPv6Enabled = IPv6Mode.DualMode,
142142
NatPunchEnabled = true
143143
};
144144
_puncher.Start(ServerPort);

LiteNetLib/NetManager.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010

1111
namespace LiteNetLib
1212
{
13+
public enum IPv6Mode
14+
{
15+
Disabled,
16+
SeparateSocket,
17+
DualMode
18+
}
19+
1320
public sealed class NetPacketReader : NetDataReader
1421
{
1522
private NetPacket _packet;
@@ -284,7 +291,7 @@ private struct IncomingData
284291
/// <summary>
285292
/// IPv6 support
286293
/// </summary>
287-
public bool IPv6Enabled = true;
294+
public IPv6Mode IPv6Enabled = IPv6Mode.SeparateSocket;
288295

289296
/// <summary>
290297
/// First peer. Useful for Client mode

LiteNetLib/NetSocket.cs

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class UnitySocketFix : MonoBehaviour
2121
internal IPAddress BindAddrIPv4;
2222
internal IPAddress BindAddrIPv6;
2323
internal bool Reuse;
24-
internal bool IPv6;
24+
internal IPv6Mode IPv6;
2525
internal int Port;
2626
internal bool Paused;
2727
internal NetSocket Socket;
@@ -67,7 +67,7 @@ internal sealed class NetSocket
6767
private Thread _threadv6;
6868
private readonly INetSocketListener _listener;
6969
private const int SioUdpConnreset = -1744830452; //SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
70-
private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("FF02:0:0:0:0:0:0:1");
70+
private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("ff02::1");
7171
internal static readonly bool IPv6Support;
7272
#if UNITY_IOS && !UNITY_EDITOR
7373
private UnitySocketFix _unitySocketFix;
@@ -83,8 +83,19 @@ public void OnErrorRestore()
8383

8484
public short Ttl
8585
{
86-
get { return _udpSocketv4.Ttl; }
87-
set { _udpSocketv4.Ttl = value; }
86+
get
87+
{
88+
if (_udpSocketv4.AddressFamily == AddressFamily.InterNetworkV6)
89+
return (short)_udpSocketv4.GetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.HopLimit);
90+
return _udpSocketv4.Ttl;
91+
}
92+
set
93+
{
94+
if (_udpSocketv4.AddressFamily == AddressFamily.InterNetworkV6)
95+
_udpSocketv4.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.HopLimit, value);
96+
else
97+
_udpSocketv4.Ttl = value;
98+
}
8899
}
89100

90101
static NetSocket()
@@ -173,16 +184,21 @@ private void ReceiveLogic(object state)
173184
}
174185
}
175186

176-
public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool reuseAddress, bool ipv6)
187+
public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool reuseAddress, IPv6Mode ipv6Mode)
177188
{
178189
if (IsActive())
179190
return false;
191+
bool dualMode = ipv6Mode == IPv6Mode.DualMode && IPv6Support;
180192

181-
_udpSocketv4 = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
182-
if (!BindSocket(_udpSocketv4, new IPEndPoint(addressIPv4, port), reuseAddress))
193+
_udpSocketv4 = new Socket(
194+
dualMode ? AddressFamily.InterNetworkV6 : AddressFamily.InterNetwork,
195+
SocketType.Dgram,
196+
ProtocolType.Udp);
197+
198+
if (!BindSocket(_udpSocketv4, new IPEndPoint(dualMode ? addressIPv6 : addressIPv4, port), reuseAddress, ipv6Mode))
183199
return false;
184200

185-
LocalPort = ((IPEndPoint)_udpSocketv4.LocalEndPoint).Port;
201+
LocalPort = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port;
186202

187203
#if UNITY_IOS && !UNITY_EDITOR
188204
if (_unitySocketFix == null)
@@ -195,13 +211,15 @@ public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool re
195211
_unitySocketFix.BindAddrIPv6 = addressIPv6;
196212
_unitySocketFix.Reuse = reuseAddress;
197213
_unitySocketFix.Port = LocalPort;
198-
_unitySocketFix.IPv6 = ipv6;
214+
_unitySocketFix.IPv6 = ipv6Mode;
199215
}
200216
else
201217
{
202218
_unitySocketFix.Paused = false;
203219
}
204220
#endif
221+
if (dualMode)
222+
_udpSocketv6 = _udpSocketv4;
205223

206224
IsRunning = true;
207225
_threadv4 = new Thread(ReceiveLogic)
@@ -212,27 +230,13 @@ public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool re
212230
_threadv4.Start(_udpSocketv4);
213231

214232
//Check IPv6 support
215-
if (!IPv6Support || !ipv6)
233+
if (!IPv6Support || ipv6Mode != IPv6Mode.SeparateSocket)
216234
return true;
217235

218236
_udpSocketv6 = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
219237
//Use one port for two sockets
220-
if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort), reuseAddress))
238+
if (BindSocket(_udpSocketv6, new IPEndPoint(addressIPv6, LocalPort), reuseAddress, ipv6Mode))
221239
{
222-
try
223-
{
224-
#if !UNITY
225-
_udpSocketv6.SetSocketOption(
226-
SocketOptionLevel.IPv6,
227-
SocketOptionName.AddMembership,
228-
new IPv6MulticastOption(MulticastAddressV6));
229-
#endif
230-
}
231-
catch (Exception)
232-
{
233-
// Unity3d throws exception - ignored
234-
}
235-
236240
_threadv6 = new Thread(ReceiveLogic)
237241
{
238242
Name = "SocketThreadv6(" + LocalPort + ")",
@@ -244,7 +248,7 @@ public bool Bind(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool re
244248
return true;
245249
}
246250

247-
private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress)
251+
private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress, IPv6Mode ipv6Mode)
248252
{
249253
//Setup socket
250254
socket.ReceiveTimeout = 500;
@@ -276,7 +280,7 @@ private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress)
276280
}
277281
if (socket.AddressFamily == AddressFamily.InterNetwork)
278282
{
279-
socket.Ttl = NetConstants.SocketTTL;
283+
Ttl = NetConstants.SocketTTL;
280284

281285
#if NETSTANDARD || NETCOREAPP
282286
if(!RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
@@ -293,23 +297,57 @@ private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress)
293297
NetDebug.WriteError("[B]Broadcast error: {0}", e.SocketErrorCode);
294298
}
295299
}
300+
else //IPv6 specific
301+
{
302+
if (ipv6Mode == IPv6Mode.DualMode)
303+
{
304+
try
305+
{
306+
//Disable IPv6 only mode
307+
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, false);
308+
}
309+
catch(Exception e)
310+
{
311+
NetDebug.WriteError("[B]Bind exception (dualmode setting): {0}", e.ToString());
312+
}
313+
}
314+
}
296315

297316
//Bind
298317
try
299318
{
300319
socket.Bind(ep);
301320
NetDebug.Write(NetLogLevel.Trace, "[B]Successfully binded to port: {0}", ((IPEndPoint)socket.LocalEndPoint).Port);
321+
322+
//join multicast
323+
if (socket.AddressFamily == AddressFamily.InterNetworkV6)
324+
{
325+
try
326+
{
327+
#if !UNITY
328+
socket.SetSocketOption(
329+
SocketOptionLevel.IPv6,
330+
SocketOptionName.AddMembership,
331+
new IPv6MulticastOption(MulticastAddressV6));
332+
#endif
333+
}
334+
catch (Exception)
335+
{
336+
// Unity3d throws exception - ignored
337+
}
338+
}
302339
}
303340
catch (SocketException bindException)
304341
{
305342
switch (bindException.SocketErrorCode)
306343
{
307344
//IPv6 bind fix
308345
case SocketError.AddressAlreadyInUse:
309-
if (socket.AddressFamily == AddressFamily.InterNetworkV6)
346+
if (socket.AddressFamily == AddressFamily.InterNetworkV6 && ipv6Mode != IPv6Mode.DualMode)
310347
{
311348
try
312349
{
350+
//Set IPv6Only
313351
socket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, true);
314352
socket.Bind(ep);
315353
}
@@ -417,6 +455,9 @@ public void Close(bool suspend)
417455
_unitySocketFix = null;
418456
#endif
419457
}
458+
//cleanup dual mode
459+
if (_udpSocketv4 == _udpSocketv6)
460+
_udpSocketv6 = null;
420461

421462
if (_udpSocketv4 != null)
422463
_udpSocketv4.Close();

LiteNetLib/Utils/NtpRequest.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ private NtpRequest(IPEndPoint endPoint, Action<NtpPacket> onRequestComplete)
3737

3838
// Create and start socket
3939
_socket = new NetSocket(this);
40-
_socket.Bind(IPAddress.Any, IPAddress.IPv6Any, 0, false, endPoint.AddressFamily == AddressFamily.InterNetworkV6);
40+
_socket.Bind(
41+
IPAddress.Any,
42+
IPAddress.IPv6Any,
43+
0,
44+
false,
45+
endPoint.AddressFamily == AddressFamily.InterNetworkV6 ? IPv6Mode.SeparateSocket : IPv6Mode.Disabled);
4146
}
4247

4348
/// <summary>
512 Bytes
Binary file not shown.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ server.Start(9050 /* port */);
8989

9090
listener.ConnectionRequestEvent += request =>
9191
{
92-
if(server.PeersCount < 10 /* max connections */)
92+
if(server.ConnectedPeersCount < 10 /* max connections */)
9393
request.AcceptIfKey("SomeConnectionKey");
9494
else
9595
request.Reject();

0 commit comments

Comments
 (0)