In order for Udp multicast to work, router must support it? - router

I am wondering for the udp multicast to work, router must support it?

Multicast is based on dynamically generated trees that can (theoretically) span the entire internet. These multicast trees are based on two protocols:
IGMP: Internet Group Management Protocol. Used by receivers and users like me and you.
PIM: Protocol Independent Multicast. Used by routers to replicate and reroute the packets accordingly.
The client needs to be IGMP-compatible, and the routers need to be PIM-compatible.

To be precise, you will need a multicast router if you want the traffic to traverse different subnets. Normally you can expect multicast to work fine on your local subnet.
Side note, many layer 2-3 switches do not include multicast routing functionality, they can however forward to an external multicast router. Multicast routing can be enabled in CISCO routers, etc.

Related

How to implement multicast sockets in swift?

I'm writing a server that, among other things, needs to be constantly sending data in different multicast addresses. The packages being sent might be received by a client side (an app) which will be switching between the mentioned addresses.
I'm using Perfect (https://github.com/PerfectlySoft/Perfect) for writing the server side, however had no luck using the Perfect-Net module nor using CocoaAsyncSocket. How could i implement both the sender and the receiver using swift? Any could snippet would be really useful.
I've been reading about multicasting and when it comes to the receiver, i've notice that in most languages (i.e. java or c#) the receiver often indicates a port number and a multicast ip-address, but when is the connection with the server being made? When does the socket bind to the real server ip-address?
Thanks in advance
If we talk about the TCP/IP stack, only IP and UDP support broadcasts and multicasts. They're both connectionless, and this is why you see only sending and receiving to special multicast addresses, but no binds and connects. You see it in different languages because (a) protocols are language-agnostic and (b) most implementations put reasonable efforts in trying to be compatible with BSD sockets interface.
If you want that true multicast, you'll need to find a swift implementation of sockets that allow setting options. Usual names for this operation is setsockopt. Multicast sender side doesn't need anything beyond a basic UDP socket (I suggest using UDP, not IP), while sender needs to be added to a multicast group. This Python example pretty much describes it.
However, it's worth noting that routers don't route broadcasts and multicasts. Hence you cannot use it over internet. If you need to use internet in your project, I'd advise you to use TCP - or websockets if your clients are browsers - and send messages to "groups" of them manually.
I guess you actually want Perfect-Kafka or Perfect-Mosquitto - Message Queue which allows a server to publish live streams to the client side subscribers. Low-level sockets will not easily fulfill your requirement.

Can a UDP multicast server send packets outside LAN?

I'm in the process of making a multiplayer game, where the players' movements are sent over the network and their positions are stored in the server. I've been told that UDP would be best since it doesn't rely on constant connection and it won't matter if the client misses a packet. The clients could be on any router, not necessarily within the server's LAN.
Is it possible to set up a server that the clients can connect to that will send all of them periodic updates of the positions of nearby objects/players?
I don't want to have to send packets to each individual client, and I heard multicasting can solve this problem, but every example I've seen only sends packets over a local network. Can I multicast past routers, and if so, how can I do that in Java? (And explain it to me like I have no idea what I'm doing, which is mostly true)
Ex.
Server has IP address 71.10.200.133
Client A has IP address 38.49.339.293
Client B has IP address 37.28.487.388
...
Client Z has IP address 43.38.382.949
Client A sends an update about the player's position to Server
Server sends update to B-Z without iterating a packet to each individual client. How do I accomplish this (if it's possible)?
Multicasts will traverse a router if and only if the router allows it. Unless you're in control of all the routers between you and your clients, the answer to your question is 'no'.
Multicast packets are broadcasts, thus they reach each node on that subnet. For you to send a multicast packet out on the web is not an effecient nor smart way of sending data.
For LAN based traffic:
Multicast is fine
But, for internet traffic I would suggest making a:
UDPClient
or
TCPClient
for internet based traffic and possibly multicast for LAN based (to mix things up a bit).
For internet traffic: Keep in mind, clients will need to initiate the connection first since most routers (household) have a firewall blocking all NEW outside-to-in traffic. So create a socket to listen over a designated port/ports for any incoming connections and from there on use which ever method of packet broadcasting/sending you like
You do also have the option of using Multicast proxies or Layer 2 VPNs if you have the capabilities. L2TP, https://en.wikipedia.org/wiki/Layer_2_Tunneling_Protocol
A layer 2 VPN would relay unicast and multicast packets.
That would basically allow you to control the routers as EJP suggested above.
This questions also 3 year old so you've probably already figured a way to do it by now.

How to let different processes use different network interfaces?

I'm on the client side. There're multiple network interfaces. How can I let different processes use different network interfaces to communicate? Since I want to connect to the same server, routing seems not working here. Also, connect() doesn't have arguments to specify local address or interface as bind() does.
If your goal is to increase bandwidth to the server by using multiple network interfaces in parallel, then that's probably not something you can (or should) do at the application level. Instead, you should study up on Link Aggregation and then configure your computer and networking stack to use that. Once that is working properly, you will get the parallelization-speedup you want automatically, without the client application having to do anything special to enable it.
"The bind() system call is frequently misunderstood. It is used to
bind to a particular IP address. Only packets destined to that IP
address will be received, and any transmitted packets will carry that
IP address as their source. bind() does not control anything about the
routing of transmitted packets. So for example, if you bound to the IP
address of eth0 but you send a packet to a destination where the
kernel's best route goes out eth1, it will happily send the packet out
eth1 with the source IP address of eth0. This is perfectly valid for
TCP/IP, where packets can traverse unrelated networks on their way to
the destination."
More info e.g. here.
That's why you probably misunderstand bind() call.
The appropriate way to bind to physical topology (to some specific interface) is to use SO_BINDTODEVICE socket option. This is done by setsockopt() call.
Source Policy Routing might be helpful.
Try the following steps:
Use iptables to give packets from different process with different marks.
Use iproute2 to route packets with different marks to different table.
In different table, set the default route to different uplink.
The whole process require certain amount of understanding about linux networking.
Here is an example shows how to route all traffic for a user through one specific uplink: http://www.niftiestsoftware.com/2011/08/28/making-all-network-traffic-for-a-linux-user-use-a-specific-network-interface/
You could try follow similar approach by running different process with different user and route traffic from one user to one uplink.
Also you could let processes communicate with the server with different port and mark the traffic by port.

Coordinating peer-to-peer messages using multicast, how to get receiving IP?

I have been working on a local LAN service which uses a multicast port to coordinate several machines. Each machine listens on the multicast port for instructions, and when a certain instruction is received, will send messages directly to other machines.
In other words the multicast port is used to coordinate peer-to-peer UDP messaging.
In practice this works quite well but there is a lingering issue related to correctly setting up these peer-to-peer transmissions. Basically, each machine needs to announce on the multicast port its own IP address, so that other machines know where to send messages when they wish to start a P2P transmission.
I realize that in general the idea of identifying the local IP is not necessarily sensible, but I don't see any other way-- the local receiving IP must be announced one way or another. At least I am not working on the internet, so in general I won't need to worry about NATs, just need to identify the local LAN IP. (No more than 1 hop for the multicast packets is allowed.)
I wanted to, if possible, determine the IP passively, i.e., without sending any messages.
I have been using code that calls getifaddrs(), which returns a linked list of NICs on the machine, and I scan this list for non-zero IP addresses and choose the first one.
In general this has worked okay, but we have had issues where for example a machine with both a wired and wifi connection are active, it will identify the wrong one, and the only work-around we found was to turn off the wifi.
Now, I imagine that a more reliable solution would be to send a message to the multicast telling other machines to report back with the source address of the message; that might allow to identify which IP is actually visible to the other machines on the net. Alternatively maybe even just looking at the multicast loopback message would work.
What do you think, are there any passive solutions to identify which address to use? If not, what's the best active solution?
I'm using POSIX socket API from C. Must work on Linux, OS X, Windows. (For Windows I have been using GetAdapterAddresses().)
Your question about how to get the address so you can advertise it right is looking at it from the wrong side. It's a losing proposition to try to guess what your address is. Better for the other side to detect it itself.
When a listening machine receives a message, it is probably doing do using recvfrom(2). The fifth argument is a buffer into which the kernel will store the address of the peer, if the underlying protocol offers it. Since you are using IP/UDP, the buffer should get filled in with a sockaddr_in showing the IP address of the sender.
I'd use the address on the interface I use to send the announcement multicast message -- on the wired interface announce the wired address and on the wireless interface announce the wireless address.
When all the receivers live on the wired side, they will never see the message on the wireless network.
When there is a bridge between the wired and the wireless network, add a second step in discovery for round-trip time estimation, and include a unique host ID in the announcement packet, so multiple routes to the same host can be detected and the best one chosen.
Also, it may be a good idea to add a configuration option to limit the service to certain interfaces.

UDP multicast from specific network card

I'm looking for some networking gurus to help me with a problem. I have many computers running my software which uses UDP multicasting. This works fine if the computers are connected ONLY to one network (network A). My computer (which is also running said software) will listen on port XXXX for the multicasts. This computer has two network cards and when I connect it to another network, network B, my software goes haywire. The problem is that I do not know what network a given multicast came from. And if I send out a multicast, I cannot tell it to use network A instead of network B or vice versa.
My questions:
Is there a way to distinguish packets coming in from different networks??
Is there a way to send a multicast to network A and NOT network B?
I'm using C++ and Win32 sockets. Thanks to anyone that replies.
You should listen for multicast packets on one interface where you joined the group. You should explicitly set the interface used for sending the multicast packets (otherwise they are routed as everything else, default route, etc.). Both are accomplished via setsockopt calls. Here are some links for you:
Multicast programming - talks about setting "send" interface,
IP Multicast Extensions - talks about both "send" and "receive" interfaces.
Disclaimer: the links are admittedly Unix-centric, so your Windows mileage may vary :)
Working on a project with MC UDP on redundant NICs over the last year, we saw a similar problem. After battling it a bit with winsock, our ultimate solution was to prioritize traffic using the DOS command route
route add 224.x.x.x ... [desired gateway] METRIC 1
This ensured that the traffic only went out on the Interface we wanted.
I realize this might not be exactly what you want, but it could at least be a stopgap solution while you implement another fix.
On multihomed hosts you need to join the multicast group via all interfaces sequentially, or via all the ones you care about. If you are interested in network of origin you could use multiple M/C sockets, each bound to a different interface, same port, and each of them joined to the group; then the receiving socket itself tells you which network any incoming traffic comes from.