multicast interview questions
Top multicast frequently asked interview questions
How should I choose an IPv4 multicast address for my application's use? I may need more than one (a whole range perhaps ultimately) but just want to avoid conflicts with other applications.
- Packets will be entirely contained within an administrative domain, probably a LAN
- If several independent instances of my application are in use on the same network, they could each use their own multicast address - but if they don't, they will be able to coexist anyway, they'll just have a small amount of overhead ignoring each others' packets.
- My packets already contain a "magic number" to avoid problems
- I will be checking the originator address (which I know can be spoofed of course), TTL and other things to try to prevent unexpected packets mucking things up.
Ideas please :)
Currently I've just allocated an arbitrary one from the "local use" space, 239.255.42.99
Source: (StackOverflow)
We've run into a thorny problem. We are writing a c++ program that receives multicast UDP traffic. We're in the process of moving our applications to a different network environment and our operations team has requested that we support IGMPv3 membership announcements from our applications. Initial investigations indicate that Linux 2.6 kernels do support IGMPv3. Therefore, I'm puzzled that when we run tcpdump we see the following output traces:
[rtv@myhost]$ sudo /usr/sbin/tcpdump -i eth1.22 igmp
tcpdump: listening on eth1.22
00:20:09.007094 switch-a.stage > ALL-SYSTEMS.MCAST.NET: igmp query v2 [max resp time 20] [ttl 1]
00:20:09.241946 10.129.22.236 > 232.0.1.10: igmp v2 report 232.0.1.10 (DF) [tos 0xc0] [ttl 1]
00:20:10.472159 10.129.22.236 > 236.0.1.101: igmp v2 report 236.0.1.101 (DF) [tos 0xc0] [ttl 1]
44 packets received by filter
My understanding is that one could force the kernel to use a lower version of IGMP by specifying a non-zero value in the file /proc/sys/net/ipv4/conf/eth1.22/force_igmp_version; however, I've confirmed that the file has a zero value configuration.
Our application is using the following code to join the multicast group:
... joinMulticast(in_addr mcast_addr, in_addr interface_addr)
{
struct ip_mreq mcast_req;
mcast_req.imr_multiaddr.s_addr = mcast_addr;
mcast_req.imr_interface.s_addr = interface_addr;
int err = setsockopt(fFileDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(char*)&theMulti, sizeof(theMulti));
// handle errors etc.
// ...
}
Is there something extra that we need to include in the source program to force IGMPv3?
Source: (StackOverflow)
I need to send a broadcast datagram to all machine (servers) connected to my network.
I'm using NodeJS Multicast
Client
var dgram = require('dgram');
var message = new Buffer("Some bytes");
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 41234, "localhost");
// If I'm in the same machine 'localhost' works
// I need to do something 192.168.0.255 or 255.255.255
client.close();
Servers
var dgram = require("dgram");
var server = dgram.createSocket("udp4");
server.on("message", function (msg, rinfo) {
console.log("server got: " + msg + " from " +
rinfo.address + ":" + rinfo.port);
});
server.on("listening", function () {
var address = server.address();
console.log("server listening " + address.address + ":" + address.port);
});
server.bind(41234);
Thanks.
Source: (StackOverflow)
This question is similar to Using reliable multicast (Pragmatic General Multicast) not returning from accept, but my code is slightly different from its, so it may result in a different answer.
I am attempting to get a reliable-multicast server/client proof of concept setup.
The solution itself is a server/client connection. The client connects to the server via TCP/IP. The server then opens up a reliable multicast socket for the client to listen on. The client sends messages via TCP, and the server echoes it back via IPPROTO_RM
. The end goal is to have many clients connected to the server, all receiving every echoed message.
The example code is based off of this page.
I have set up my RM sockets similarly (see listings below). The TCP sockets are working fine. The problem is in the RM sockets. The server opens up the multicast socket, then binds
and connects
to the multicast address properly. The client, however, listens
correctly, but the call to accept
blocks forever.
Both client and server processes are running on the same host.
I have checked, and Multicasting support is installed on the host (Server 2008).
Update: I've noticed that sometimes the accept will return if I send some data down the socket from the sender's side first. This is not ideal, nor is it reliable.
Update: The signs are pointing to the switch. Seems like a little hub won't cut it. We had an hilarious incident which resulted in lost comms for the whole building.
Listings
Server creates and connects Multicast sender
short
Port = 0;
const char
*Address = "234.5.6.7";
SOCKET
RMSocket;
SOCKADDR_IN
LocalAddr,
SessionAddr;
RMSocket = socket(AF_INET, SOCK_RDM, IPPROTO_RM);
if (RMSocket == INVALID_SOCKET)
{
return Failed;
}
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons(0);
LocalAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if ( bind( RMSocket, (SOCKADDR*)&LocalAddr, sizeof(LocalAddr)) == SOCKET_ERROR )
{
return Failed;
}
SessionAddr.sin_family = AF_INET;
SessionAddr.sin_port = htons( Port );
SessionAddr.sin_addr.s_addr = inet_addr( Address );
if ( connect( RMSocket, (SOCKADDR*)&SessionAddr, sizeof(SessionAddr)) == SOCKET_ERROR )
{
return Failed;
}
return Success;
Client creates and accepts Multicast reader
short
Port = 0;
const char
*Address = "234.5.6.7";
SOCKADDR_IN
LocalAddr;
SOCKET
RMListener,
RMSocket;
RMListener = socket( AF_INET, SOCK_RDM, IPPROTO_RM );
if ( RMListener == INVALID_SOCKET )
{
return Failed;
}
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_port = htons( Port );
LocalAddr.sin_addr.s_addr = inet_addr( Address );
if ( bind( RMListener, (SOCKADDR*)&LocalAddr, sizeof(LocalAddr) ) )
{
return Failed;
}
if ( listen( RMListener, SOMAXCONN ) )
{
return Failed;
}
// BLOCKS HERE
RMSocket = accept( RMListener, NULL, NULL);
if ( RMSocket == INVALID_SOCKET )
{
return Failed;
}
return Success;
Source: (StackOverflow)
I am trying to modify a multicast listener / sender example to bind the UDP / multicast socket to a specific interface and not using the INADDR_ANY macro.
I possess the IPv4 address of the interface.
I tried the following, but the socket does not receive any UDP (unicast, broadcast, multicast) packets.
struct sockaddr_in addr;
int fd, nbytes;
socklen_t addrlen;
struct ip_mreq mreq;
// my_ipv4Addr equals current IP as String, e.g. "89.89.89.89"
// create what looks like an ordinary UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket");
exit(1);
}
// set up addresses
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
// [-] addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_addr.s_addr = inet_addr(my_ipv4Addr);
addr.sin_port = htons(port);
// bind socket
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
// use setsockopt() to request that the kernel join a multicast group
mreq.imr_multiaddr.s_addr = inet_addr(group);
// [-] mreq.imr_interface.s_addr = htonl(INADDR_ANY);
mreq.imr_interface.s_addr = inet_addr(my_ipv4Addr);
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))< 0) {
perror("setsockopt");
exit(1);
}
Edit:
Let me explain the purpose of my program. I am writing a little tool, which will check, if a network supports broadcast/multicast. Therefore I own a system with two interfaces and send via Interface1 a multicast Packet and try to receive it with Interface2. But: The packet shall go through the network, not the loopack device.
The idea is to block multicast-loopback on thread1/interface1 with:
u_char loop = 0;
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
And to listen on thread2/interface 2 interface-specific. Tcpdump shows, that the packets are arriving, but are dropped with my config above.
Source: (StackOverflow)
I have a java application which uses a few MulticastSocket instances to listen
to a few UDP multicast feeds. Each such socket is handled by a dedicated thread.
The thread reads each Datagram, parses it's content and writes to log (log4j) the packet's sequence id (long) and the timestamp the Datagram was received.
When I try to run 2 instances of the same application on a Windows Server 2008 R2,
with 2 * 6 cores and compare the 2 logs created by the 2 applications,
I notice that quite frequently the timing of the packets isn't the same.
Most packets are received by the 2 apps at the same time (milis), but frequently
there's a difference of about 1-7ms diff between the reception time of the same packet
by the 2 apps.
I tried allocating more buffers in the NIC, and also made the socket read buffer bigger.
In addition I tried minimizing GC runs and I also use -verbose:gc and can see
that GC times and the problematic timing diff does not occur at the same time.
This allows me to assume that my problem isn't GC related.
No drop packets problem was observed, and a bandwidth problem is not likely.
Ideas / Opinions are welcome.
Thanks.
Source: (StackOverflow)
I am trying to set up ehcache replication as documented here: http://ehcache.sourceforge.net/EhcacheUserGuide.html#id.s22.2
This is on a Windows machine but will ultimately run on Solaris in production.
The instructions say to set up a provider as follows:
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1,
multicastGroupPort=4446, timeToLive=32"/>
And a listener like this:
<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40001,
socketTimeoutMillis=2000"/>
My questions are:
Are the multicast IP address and port arbitrary (I know the address has to live within a specific range but do they have to be specific numbers)?
Do they need to be set up in some way by our system administrator (I am on an office network)?
I want to test it locally so am running two separate tomcat instances with the above config.
What do I need to change in each one? I know both the listeners can't listen on the same port - but what about the provider?
Also, are the listener ports arbitrary too?
I've tried setting it up as above but in my testing the caches don't appear to be replicated - the value added in one tomcat's cache is not present in the other cache.
Is there anything I can do to debug this situation (other than packet sniffing)?
Thanks in advance for any help, been tearing my hair out over this one!
Source: (StackOverflow)
I have a very simple wrapper for boost::asio sockets sending multicast messages:
// header
class MulticastSender
{
public:
/// Constructor
/// @param ip - The multicast address to broadcast on
/// @param port - The multicast port to broadcast on
MulticastSender(const String& ip, const UInt16 port);
/// Sends a multicast message
/// @param msg - The message to send
/// @param size - The size of the message (in bytes)
/// @return number of bytes sent
size_t send(const void* msg, const size_t size);
private:
boost::asio::io_service m_service;
boost::asio::ip::udp::endpoint m_endpoint;
boost::asio::ip::udp::socket m_socket;
};
// implementation
inline MulticastSender::MulticastSender(const String& ip, const UInt16 port) :
m_endpoint(boost::asio::ip::address_v4::from_string(ip), port),
m_socket(m_service, m_endpoint.protocol())
{
m_socket.set_option(boost::asio::socket_base::send_buffer_size(8 * 1024 * 1024));
m_socket.set_option(boost::asio::socket_base::broadcast(true));
m_socket.set_option(boost::asio::socket_base::reuse_address(true));
}
inline size_t MulticastSender::send(const void* msg, const size_t size)
{
try
{
return m_socket.send_to(boost::asio::buffer(msg, size), m_endpoint);
}
catch (const std::exception& e)
{
setError(e.what());
}
return 0;
}
// read and send a message
MulticastSender sender(ip, port);
while(readFile(&msg)) sender.send(&msg, sizeof(msg));
When compiled on Windows 7 using Visual Studio 2013, I get throughput of ~11 MB/s, on Ubuntu 14.04 ~100 MB/s. I added timers and was able to validate the send(...)
method is the culprit.
I tried with and without antivirus enabled, and tried disabling a few other services with no luck. Some I cannot disable due to permissions on the computer, like the firewall.
I assume there is a service on Windows running that is interfering, or my implementation is missing something that is effecting the application on Windows and not Linux.
Any ideas on what might be cauing this would be appreciated
Source: (StackOverflow)
Apple now requires iOS 9 apps to be IPv6 compliant. We're mostly OK, except for a bit of code which sends a UDP broadcast - this now fails in iOS 9.
Everything I read tells me that UDP multicast is the right way to do this in IPv6. I've found some example code, but it doesn't work on any version of iOS or Mac OS X I've tried.
This code is being called from a C/C++ lib inside our program - difficult to make a callback into Swift, Obj-C, Java, etc. And this code will be shared by a Mac OS X and Android version of our app. One would think it's possible to do IPv6 multicast in C in any POSIX environment!
In the sample below, execution succeeds up to the final sendto() call, which actually sends the UDP message. That sendto() fails, with errno set to EBROKENPIPE (22) after the failure.
My best guess is that I'm missing some required setsockopt() call, or am using the wrong multicast address. Right now, I'm stumped.
Here's the function call I'm making (to multicast "Is anybody out there?" on UDP port 4031):
char *msg = "Is anybody out there?";
err = multicast_udp_msg ( "FF01::1111", 4031, msg, strlen(msg) );
Here's the code that is being called:
// Multicasts a message on a specific UDP port.
// myhost - IPv6 address on which to multicast the message (i.e., ourself)
// port - UDP port on which to broadcast the mssage
// msg - message contents to broadcast
// msgsize - length of message in bytes
// Return value is zero if successful, or nonzero on error.
int multicast_udp_msg ( char *myhost, short port, char *msg, size_t msgsize )
{
int sockfd, n;
char service[16] = { 0 };
int err = 0;
struct addrinfo hints = { 0 }, *res, *ressave;
struct sockaddr_storage addr = { 0 };
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
sprintf ( service, "%hd", port );
n = getaddrinfo ( myhost, service, &hints, &res );
if ( n < 0 )
{
fprintf(stderr, "getaddrinfo error:: [%s]\n", gai_strerror(n));
return -1;
}
ressave = res;
sockfd = socket ( res->ai_family, res->ai_socktype, res->ai_protocol );
if ( sockfd >= 0 )
{
memcpy ( &addr, res->ai_addr, sizeof ( addr ) );
if ( joinGroup ( sockfd, 0, 8, &addr ) == 0 )
if ( bind ( sockfd, res->ai_addr, res->ai_addrlen ) == 0 )
if ( sendto ( sockfd, msg, msgsize, 0, (struct sockaddr *) &addr, sizeof ( addr ) ) < 0 )
err = errno;
close ( sockfd );
res = res->ai_next;
}
freeaddrinfo ( ressave );
return err;
}
int
joinGroup(int sockfd, int loopBack, int mcastTTL,
struct sockaddr_storage *addr)
{
int r1, r2, r3, retval;
retval=-1;
switch (addr->ss_family) {
case AF_INET: {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr=
((struct sockaddr_in *)addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr= INADDR_ANY;
r1= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
&loopBack, sizeof(loopBack));
if (r1<0)
perror("joinGroup:: IP_MULTICAST_LOOP:: ");
r2= setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IP_MULTICAST_TTL:: ");
r3= setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(const void *)&mreq, sizeof(mreq));
if (r3<0)
perror("joinGroup:: IP_ADD_MEMBERSHIP:: ");
} break;
case AF_INET6: {
struct ipv6_mreq mreq6;
memcpy(&mreq6.ipv6mr_multiaddr,
&(((struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(struct in6_addr));
mreq6.ipv6mr_interface= 0; // cualquier interfaz
r1= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
&loopBack, sizeof(loopBack));
if (r1<0)
perror("joinGroup:: IPV6_MULTICAST_LOOP:: ");
r2= setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&mcastTTL, sizeof(mcastTTL));
if (r2<0)
perror("joinGroup:: IPV6_MULTICAST_HOPS:: ");
r3= setsockopt(sockfd, IPPROTO_IPV6,
IPV6_JOIN_GROUP, &mreq6, sizeof(mreq6));
if (r3<0)
perror("joinGroup:: IPV6_ADD_MEMBERSHIP:: ");
} break;
default:
r1=r2=r3=-1;
}
if ((r1>=0) && (r2>=0) && (r3>=0))
retval=0;
return retval;
}
Thoughts welcome!
-Tim
Source: (StackOverflow)
If I want to test a set of multicast IP programs (sender/receiver) without having to set up the networking, can this be done on the same box? If so, what needs to be setup or done differently?
Source: (StackOverflow)
I'm looking at taking a set of objects, let's say there's 3 objects alive at the moment, which all implement a common interface, and then wrap those objects inside a fourth object, also implementing the same interface.
The fourth object's implementations of methods and properties would simply call the relevant bits on those 3 underlying objects. I know that there will be cases here where it won't make sense to do that, but this is for a service multicast architecture so there's already a good set of limitations in place.
My question is where to start. The generation of that fourth object should be done in memory, at runtime, so I'm thinking Reflection.Emit
, unfortunately I don't have enough experience with that to even know where to begin.
Do I have to construct an in-memory assembly? It sure looks that way, but I'd just like a quick pointer to where I should start.
Basically I'm looking at taking an interface, and a list of object instances all implementing that interface, and constructing a new object, also implementing that interface, which should "multicast" all method calls and property access to all the underlying objects, at least as much as possible. There will be heaps of problems with exceptions and such but I'll tackle those bits when I get to them.
This is for a service-oriented architecture, where I would like to have existing code that takes, as an example, a logger-service, to now access multiple logger services, without having to change the code that uses the services. Instead, I'd like to runtime-generate a logger-service-wrapper that internally simply calls the relevant methods on multiple underlying objects.
This is for .NET 3.5 and C#.
Source: (StackOverflow)
Im trying to write a server/service that broadcasts a message on the lan ever second or so, Kind of like a service discovery.
The message needs to be received by
multiple client programs that could be
on the same machine or different
machines. But there could be more than
one program on each machine running at
the same time.
Im using delphi7, with indy 9.0.18
where im stuck is if i should be using UDP(TIdUDPClient/Server) or IP MultiCast (TIdIPMCastClient/Server) or if its even possible...
Ive managed to get it to work with IP Multi Cast with one client per machine, but even after many trys with different bindings.. max/min ports etc, i cant seem to find a solution.
Source: (StackOverflow)
I'm trying to get udp multicast data using sockets and c++ (c). I have a server with 2 network cards so I need to bind socket to specific interface. Currently I'm testing on another server that has only one network card.
When I use INADDR_ANY I can see the udp data, when I bind to specific interface I don't see any data. Function inet_addr is not failing (I removed checking for return value for now).
Code is bellow.
On a server with one network card, my IP address is 10.81.128.44. I receive data when I run as:
./client 225.0.0.37 12346
This gives me no data:
./client 225.0.0.37 12346 10.81.128.44
Any suggestions? (Hope the code compiles, I removed comments ...)
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
#define HELLO_PORT 12345
#define HELLO_GROUP "225.0.0.37"
#define MSGBUFSIZE 256
int main(int argc, char *argv[])
{
string source_iface;
string group(HELLO_GROUP);
int port(HELLO_PORT);
if (!(argc < 2)) group = argv[1];
if (!(argc < 3)) port = atoi(argv[2]);
if (!(argc < 4)) source_iface = argv[3];
cout << "group: " << group << " port: " << port << " source_iface: " << source_iface << endl;
int fd;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(1);
}
u_int yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
{
perror("Reusing ADDR failed");
exit(1);
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = (source_iface.empty() ? htonl(INADDR_ANY) : inet_addr(source_iface.c_str()));
if (bind(fd,(struct sockaddr *)&addr, sizeof(addr)) < 0)
{
perror("bind");
exit(1);
}
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(group.c_str());
mreq.imr_interface.s_addr = (source_iface.empty() ? htonl(INADDR_ANY) : inet_addr(source_iface.c_str()));
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
{
perror("setsockopt");
exit(1);
}
socklen_t addrlen;
int nbytes;
char msgbuf[MSGBUFSIZE];
while (1)
{
memset(&msgbuf, 0, MSGBUFSIZE);
addrlen = sizeof(addr);
if ((nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0, (struct sockaddr *)&addr, &addrlen)) < 0)
{
perror("recvfrom");
exit(1);
}
cout.write(msgbuf, nbytes);
cout.flush();
}
return 0;
}
Thanks in advance ...
Source: (StackOverflow)