Permalink
Browse files

Merge pull request #2047 from esdrubal/socketreuse

[System] Fix TCP socket reuse.
  • Loading branch information...
esdrubal committed Sep 17, 2015
2 parents ff17686 + 59c7265 commit 07bae963aea19bb6c293ad3176c3f707ac94d2a2
Showing with 62 additions and 2 deletions.
  1. +61 −1 mcs/class/System/Test/System.Net.Sockets/SocketTest.cs
  2. +1 −1 mono/io-layer/sockets.c
@@ -9,8 +9,10 @@
//
using System;
using System.Linq;
using System.Collections;
using System.Threading;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;
using NUnit.Framework;
@@ -3476,7 +3478,65 @@ public void UdpDoubleBind ()
ss.Close ();
s.Close ();
}
static bool supportsTcpReuse = false;
static bool supportsTcpReuseSet = false;
static bool SupportsTcpReuse ()
{
if (supportsTcpReuseSet)
return supportsTcpReuse;
if (Path.DirectorySeparatorChar == '/') {
/*
* On UNIX OS
* Multiple threads listening to the same address and port are not possible
* before linux 3.9 kernel, where the socket option SO_REUSEPORT was introduced.
*/
Regex reg = new Regex(@"^#define\s*SO_REUSEPORT");
foreach (string directory in Directory.GetDirectories ("/usr/include")) {
var f = Directory.GetFiles (directory, "socket.h").SingleOrDefault ();
if (f != null && File.ReadLines (f).Any (l => reg.Match (l).Success)) {
supportsTcpReuse = true;
break;
}
}
} else {
supportsTcpReuse = true;
}
supportsTcpReuseSet = true;
return supportsTcpReuse;
}
// Test case for bug #31557
[Test]
public void TcpDoubleBind ()
{
using (Socket s = new Socket (AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp))
using (Socket ss = new Socket (AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp)) {
s.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
s.Bind (new IPEndPoint (IPAddress.Any, 12345));
s.Listen(1);
ss.SetSocketOption (SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
Exception ex = null;
try {
ss.Bind (new IPEndPoint (IPAddress.Any, 12345));
ss.Listen(1);
} catch (SocketException e) {
ex = e;
}
Assert.AreEqual (SupportsTcpReuse (), ex == null);
}
}
[Test]
[Category ("NotOnMac")]
public void ConnectedProperty ()
View
@@ -733,7 +733,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
socklen_t type_len = sizeof (type);
if (!getsockopt (fd, level, SO_TYPE, &type, &type_len)) {
if (type == SOCK_DGRAM)
if (type == SOCK_DGRAM || type == SOCK_STREAM)
setsockopt (fd, level, SO_REUSEPORT, tmp_val, optlen);
}
}

0 comments on commit 07bae96

Please sign in to comment.