Skip to content

Commit fecdb74

Browse files
authored
Relaxing IsConnected Check for Datagram Sockets (#87916)
* Relaxing IsConnected Check for Datagram Sockets * Adding Listener inside Test * Add relaxing to every Connect Path and invert condition to SocketType.Stream * Make test theory and pass ipv4 ipv6 data * Add LoopbacksAndAny * Fix forgotten usage of parameter * Handle OSX case * Review feedback
1 parent 9ffdb53 commit fecdb74

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -797,10 +797,7 @@ public void Connect(EndPoint remoteEP)
797797
throw new InvalidOperationException(SR.net_sockets_mustnotlisten);
798798
}
799799

800-
if (_isConnected)
801-
{
802-
throw new SocketException((int)SocketError.IsConnected);
803-
}
800+
ThrowIfConnectedStreamSocket();
804801

805802
ValidateBlockingMode();
806803

@@ -839,10 +836,7 @@ public void Connect(IPAddress address, int port)
839836
throw new ArgumentOutOfRangeException(nameof(port));
840837
}
841838

842-
if (_isConnected)
843-
{
844-
throw new SocketException((int)SocketError.IsConnected);
845-
}
839+
ThrowIfConnectedStreamSocket();
846840

847841
ValidateForMultiConnect(isMultiEndpoint: false); // needs to come before CanTryAddressFamily call
848842

@@ -902,10 +896,7 @@ public void Connect(IPAddress[] addresses, int port)
902896
throw new NotSupportedException(SR.net_invalidversion);
903897
}
904898

905-
if (_isConnected)
906-
{
907-
throw new SocketException((int)SocketError.IsConnected);
908-
}
899+
ThrowIfConnectedStreamSocket();
909900

910901
ValidateForMultiConnect(isMultiEndpoint: true); // needs to come before CanTryAddressFamily call
911902

@@ -2648,10 +2639,7 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan
26482639
throw new InvalidOperationException(SR.net_sockets_mustnotlisten);
26492640
}
26502641

2651-
if (_isConnected)
2652-
{
2653-
throw new SocketException((int)SocketError.IsConnected);
2654-
}
2642+
ThrowIfConnectedStreamSocket();
26552643

26562644
// Prepare SocketAddress.
26572645
EndPoint? endPointSnapshot = e.RemoteEndPoint;
@@ -3736,6 +3724,14 @@ private void ThrowIfDisposed()
37363724
ObjectDisposedException.ThrowIf(Disposed, this);
37373725
}
37383726

3727+
private void ThrowIfConnectedStreamSocket()
3728+
{
3729+
if (_isConnected && _socketType == SocketType.Stream)
3730+
{
3731+
throw new SocketException((int)SocketError.IsConnected);
3732+
}
3733+
}
3734+
37393735
private bool IsConnectionOriented => _socketType == SocketType.Stream;
37403736

37413737
internal static void SocketListDangerousReleaseRefs(IList? socketList, ref int refsAdded)

src/libraries/System.Net.Sockets/tests/FunctionalTests/Connect.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,21 @@ public async Task Connect_WithoutListener_ThrowSocketExceptionWithAppropriateInf
217217
Assert.Contains(a.LocalEndPoint.ToString(), ex.Message);
218218
}
219219
}
220+
221+
[Theory]
222+
[MemberData(nameof(LoopbacksAndAny))]
223+
public async Task Connect_DatagramSockets_DontThrowConnectedException_OnSecondAttempt(IPAddress listenAt, IPAddress secondConnection)
224+
{
225+
using Socket listener = new Socket(listenAt.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
226+
using Socket s = new Socket(listenAt.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
227+
listener.Bind(new IPEndPoint(listenAt, 0));
228+
229+
await ConnectAsync(s, new IPEndPoint(listenAt, ((IPEndPoint)listener.LocalEndPoint).Port));
230+
Assert.True(s.Connected);
231+
// According to the OSX man page, it's enough connecting to an invalid address to dissolve the connection. (0 port connection returns error on OSX)
232+
await ConnectAsync(s, new IPEndPoint(secondConnection, PlatformDetection.IsOSX ? 1 : 0));
233+
Assert.True(s.Connected);
234+
}
220235
}
221236

222237
public sealed class ConnectSync : Connect<SocketHelperArraySync>

src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,12 @@ public abstract class MemberDatas
598598
new object[] { IPAddress.Loopback, true },
599599
new object[] { IPAddress.Loopback, false },
600600
};
601+
602+
public static readonly object[][] LoopbacksAndAny = new object[][]
603+
{
604+
new object[] { IPAddress.IPv6Loopback, IPAddress.IPv6Any },
605+
new object[] { IPAddress.Loopback, IPAddress.Any },
606+
};
601607
}
602608

603609
//

0 commit comments

Comments
 (0)