Skip to content

Commit e2322af

Browse files
matantsachclaude
andauthored
Fix UdpClient.EnableBroadcast not preventing broadcast sends (#124482)
## Summary Fixes #118055 `UdpClient.CheckForBroadcast()` unconditionally auto-enables the `Broadcast` socket option when sending to `IPAddress.Broadcast`, even when the user has explicitly set `EnableBroadcast = false`. This PR makes `CheckForBroadcast()` respect the user's explicit choice. ## Changes - Added `_isBroadcastSetByUser` field to track whether `EnableBroadcast` has been explicitly set by the user - Modified `CheckForBroadcast()` to skip auto-enable when the user has explicitly set `EnableBroadcast` - Backward-compatible: auto-enable behavior is preserved when users have not explicitly set the property **Note:** The pre-existing `_isBroadcast` flag is not reset when the `Client` socket is replaced via the property setter. The new `_isBroadcastSetByUser` flag follows this same pattern for consistency. Resetting state on socket replacement could be a follow-up improvement. ## Testing - `EnableBroadcast_ExplicitlyDisabled_NotAutoEnabled` — verifies that explicitly disabling broadcast prevents auto-enable on broadcast send - `EnableBroadcast_ExplicitlyEnabledThenDisabled_NotAutoEnabled` — verifies the toggle case (enable → disable) also prevents auto-enable - `EnableBroadcast_NotExplicitlySet_AutoEnabled` — verifies backward compatibility: auto-enable still works when the user hasn't set the property --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b954bd7 commit e2322af

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ public bool EnableBroadcast
171171
set
172172
{
173173
_clientSocket.EnableBroadcast = value;
174+
_isBroadcastSetByUser = true;
174175
}
175176
}
176177

@@ -247,14 +248,18 @@ protected virtual void Dispose(bool disposing)
247248
}
248249

249250
private bool _isBroadcast;
251+
private bool _isBroadcastSetByUser;
250252
private void CheckForBroadcast(IPAddress ipAddress)
251253
{
252254
// Here we check to see if the user is trying to use a Broadcast IP address
253255
// we only detect IPAddress.Broadcast (which is not the only Broadcast address)
254256
// and in that case we set SocketOptionName.Broadcast on the socket to allow its use.
255257
// if the user really wants complete control over Broadcast addresses they need to
256258
// inherit from UdpClient and gain control over the Socket and do whatever is appropriate.
257-
if (_clientSocket != null && !_isBroadcast && IsBroadcast(ipAddress))
259+
//
260+
// If the user has explicitly set EnableBroadcast, we respect their choice
261+
// and do not auto-enable broadcast.
262+
if (_clientSocket != null && !_isBroadcast && !_isBroadcastSetByUser && IsBroadcast(ipAddress))
258263
{
259264
// We need to set the Broadcast socket option.
260265
// Note that once we set the option on the Socket we never reset it.

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,55 @@ public void EnableBroadcast_Roundtrips()
320320
}
321321
}
322322

323+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))]
324+
[InlineData(false)]
325+
[InlineData(true)]
326+
public void EnableBroadcast_ExplicitlyDisabled_NotAutoEnabled(bool setTrueFirst)
327+
{
328+
using (var udpClient = new UdpClient())
329+
{
330+
if (setTrueFirst) udpClient.EnableBroadcast = true;
331+
udpClient.EnableBroadcast = false;
332+
333+
// Sending to a broadcast address should not auto-enable
334+
// broadcast when the user explicitly disabled it.
335+
// The send may throw SocketException on platforms that reject
336+
// broadcast sends when the socket option is not set.
337+
try
338+
{
339+
udpClient.Send(new byte[1], 1, new IPEndPoint(IPAddress.Broadcast, UnusedPort));
340+
}
341+
catch (SocketException)
342+
{
343+
}
344+
345+
Assert.False(udpClient.EnableBroadcast);
346+
}
347+
}
348+
349+
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsMultithreadingSupported))]
350+
public void EnableBroadcast_NotExplicitlySet_AutoEnabled()
351+
{
352+
using (var udpClient = new UdpClient())
353+
{
354+
Assert.False(udpClient.EnableBroadcast);
355+
356+
// When the user hasn't explicitly set EnableBroadcast,
357+
// sending to a broadcast address should auto-enable it
358+
// (preserving backward-compatible behavior).
359+
try
360+
{
361+
udpClient.Send(new byte[1], 1, new IPEndPoint(IPAddress.Broadcast, UnusedPort));
362+
}
363+
catch (SocketException)
364+
{
365+
return; // Platform doesn't support broadcast sends; skip assertion.
366+
}
367+
368+
Assert.True(udpClient.EnableBroadcast);
369+
}
370+
}
371+
323372
[PlatformSpecific(TestPlatforms.Windows)] // ExclusiveAddressUse is Windows-specific
324373
[Fact]
325374
public void ExclusiveAddressUse_Roundtrips()

0 commit comments

Comments
 (0)