Zenilogix
Zenilogix

Reputation: 1403

Overcoming network filtering issues when using UDP broadcast/multicast for simple service discovery

I am working on a service discovery implementation in C#. In an attempt to get around some issues, I have implemented both broadcast and multicast, simplified to the snippets shown.

Client side broadcast:

var requestData = new byte[]{ /* Whatever */}

// Configure broadcast
var ipBroadcastEndPoint = new IPEndPoint(IPAddress.Broadcast, 12301);
var broadcastServerEp = new IPEndPoint(IPAddress.Any, 0);

var broadcastClient = new UdpClient {EnableBroadcast = true};
broadcastClient.Client.Bind(_broadcastServerEp);

// Send a request:
broadcastClient.Send(requestData, requestData.Length, ipBroadcastEndPoint);

// Listen for a reply:
var broadcastserverEp = new IPEndPoint(IPAddress.Any, 0);
var broadcastserverResponseData = broadcastClient.Receive(ref broadcastserverEp);

Client side multicast:

var requestData = new byte[]{ /* Whatever */}

// Configure multicast
var ipMulticastEndPoint = new IPEndPoint(IPAddress.Parse("239.255.255.253"), 12302);
var multicastServerEp = new IPEndPoint(IPAddress.Any, 0);

var multicastClient = new UdpClient(AddressFamily.InterNetwork);
multicastClient.JoinMulticastGroup(IPAddress.Parse("239.255.255.253"), 32);
multicastClient.Client.Bind(_multicastServerEp);

// Send a request:
multicastClient.Send(requestData, requestData.Length, ipMulticastEndPoint);

// Listen for a reply:
var multicastserverEp = new IPEndPoint(IPAddress.Any, 0);
var multicastserverResponseData = multicastClient.Receive(ref multicastserverEp);

Server side broadcast:

// Listen for broadcast
Task.Run(() =>
{
    var broadcastServer = new UdpClient(12301);
    while(/**/)
    {
        var broadcastclientEp = new IPEndPoint(IPAddress.Any, 0);
        var broadcastclientRequestData = broadcastServer.Receive(ref broadcastclientEp);

        // Reply to broadcast:
        var responseData = new byte[]{ /* Whatever */}
        broadcastServer.Send(responseData, responseData.Length, broadcastclientEp);
    }
}

Server side multicast:

// Listen for multicast
Task.Run(() =>
{
    var multicastServer = new UdpClient(12302);
    multicastServer.JoinMulticastGroup(IPAddress.Parse("239.255.255.253"));
    while(/**/)
    {
        var multicastclientEp = new IPEndPoint(IPAddress.Any, 0);
        var multicastclientRequestData = multicastServer.Receive(ref multicastclientEp);

        // Reply to multicast:
        var responseData = new byte[]{ /* Whatever */}
        multicastServer.Send(responseData, responseData.Length, multicastclientEp);
    }
}

If both client and server components are running on the same computer, both broadcast and multicast work as expected.

If both client and server components are on different computers in the same subnet, broadcast works, multicast works in one direction only (two computers in a given WLAN topology, multicast works when one of them is in the server role, but not the other way around).

If both client and server components are on different subnets in the same corporate network, neither broadcast or multicast works.

I'd like to get this to work reliably across subnets. From what I've learned so far, I know broadcast won't work, but multicast should.

Is there some magic to the selection of multicast addresses and/or port numbers? In other words, are there specific addresses and ports I should or should not be using for it to work reliably regardless of network topology? Are there address/port combinations which are customarily filtered or customarily kept open? Are there any configuration options I have overlooked?

Upvotes: 0

Views: 394

Answers (1)

dbush
dbush

Reputation: 224532

Allowing multicast traffic to pass between subnets is controlled entirely by the routers between those subnets.

The routers need to be configured to either with static multicast routes, or to accept IGMP messages from hosts to set up multicast groups as they are joined.

Upvotes: 0

Related Questions