Simulating multicasting on loopback interface - ruby

I'm writing a network application in ruby which should use UDP multicasting.
My problem is that I want to run multiple instances for testing purposes on localhost, but multicasting only works if I bind the socket to the real network interface.
Is there some way to enable multicasting for the loopback interface, so that all the 127.0.0.x get the message I send?
Currently I enable multicasting with:
ip = IPAddr.new('234.56.78.9').hton + IPAddr.new('0.0.0.0').hton
socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP,ip)
#socket.bind '127.0.0.1',1234 ##does not receive multicast :(
socket.bind '0.0.0.0',1234
Also, I noticed that if I e.g. bind the socket to 127.0.0.4 and send a message, in the packet the source ip is 127.0.0.1 anyway... is there a way to set the source IP so it shows the same IP I bound the socket to?

Solaris allows you to use multicast on the loopback device. For other operating systems you can enable IP_MULTICAST_LOOP on the sender (Unix) or the receiver (Windows) for similar effect.

Related

Does Loopback able to support all TCP/IP protocols

Does a Windows loopback adapter supports ACD and duplicate IPs. Say we have a code that supports full TCP stack and we bridge the program to loopback using PCAP.
If in case I set both the address same - is it the right way to test ACD? Do we need always wired devices to test ACD?

Why is IP_MULTICAST_IF and IPV6_MULTICAST_IF needed?

Say for example, my machine is multi-homed and has two network interfaces:
Wireless LAN adapter WiFi : Ip: 10.20.19.140
Ethernet adapter Ethernet: Ip: 10.20.19.154
I create two UDP sockets one listening on (1) and other on (2). The i am assuming the interface is already assigned, then why do i need IP_MULTICAST_IF and IPV6_MULTICAST_IF?
The IP_MULTICAST_IF or IPV6_MULTICAST_IF settings tell your socket which interface to send its multicast packets on. It's a separate, independent setting from the interface that you bound your socket to with bind(), since bind() controls which interface(s) the socket receives multicast packets from.
(Granted, the BSD sockets API implementers could have made the assumption that a socket would always want to send packets out over the same interface it receives packets on, but that would make a number of use cases more difficult; for example, if you are using a single socket to receive multicast packets from all interfaces (via INADDR_ANY), then when sending a packet using that socket you'd still need a way to specify which multicast interface you want that packet to be sent over)

PF_PACKET socket and 'Port unreachable' ICMP messages

My application needs to receive UDP packets from multiple destination ports (this is a bonafide application and not a sniffer). Therefore, I have chosen to use a PF_PACKET socket and to do port filtering at the application level.
Here's how I create the socket:
int g_rawSocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
I am correctly receiving UDP packets. However, the kernel on which the application runs is sending ICMP packets of type 'Destination unreachable' and code 'Port unreachable' to the remote device that is sending packets to my app. I guess that this is because I have not bound a port number to the socket. However, I wonder if it is appropriate to use bind with a PF_PACKET socket, especially as I need to bind multiple ports to it, which I guess is not possible.
Any comments please?
No, it can't be bound to a specific port, since it's working on a lower level than the Transport (UDP/TCP) layer. However, you could open and listen to all sockets, using regular UDP (AF_INET/SOCK_DGRAM) sockets and select for example and as far as I know you can bind and listen to as many sockets as you want, as long as you don't exceed the limits of open file descriptors for your process.
I have also done the same thing in my application.
in my case i have created sockets as many i need & bind them with the particular port. but i m not listening to any socket. so i created one raw socket
int sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
& then received all the traffic without any ICMP.
So i think u have to bind all the ports to avoid ICMP either you have to some kernel hacking as stoping or removing the code for ICMP in the linux-kernel code & build it again

UDP listening socket stops listening after network configuration changes

I have a UDP socket listening in a port for broadcast transmissions and it is working fine.
However, when I hibernate and resume the OS (Windows 7), the socket just stops receving data (and I can see that there is data arriving using Wireshark).
This also happens if I change any network settings like, change my IP address, disable and enable the network adapter.
The OS seems to disable all network adapters when hibernating and to re-enable them when it is resumed.
select just returns 0 (timeout) which is no different than when I'm not receiving any data. I could not find any references to this behavior anywhere.
If I close the socket and recreate it, it starts to work again.
My TCP listening sockets still working fine after resuming the OS.
Any ideas on how detect and correct this situation?
EDIT: It still receiving directly addresses data just fine, it just does not receive brodcast transmissions anymore.
EDIT2: Just discovered that if I write to the socket (send a dummy packet to anywhere) it starts to work again...
I think your code does not explicitly binds the socket to "0.0.0.0" address. So when you do sentto it binds the interface IP which is available at that time. When this IP is changed or interface is disabled, this socket will be reset by the TCP/IP stack. In your TCP socket, you should have bound to "0.0.0.0" address so it will always listen for connection independent of any IP/interface changes. You can make your udp socket also bound to "0.0.0.0" before sending any data on it. This will make it work even after hibernation or IP changes.

Cannot bind to multicast address (Windows)

I am trying to write an application that listens to a number of multicast groups using Windows sockets.
The problem I'm running in to is that when I go to bind the socket, if I try to bind to the multicast group address and port this fails with WSAEADDRNOTAVAIL. If I instead bind to INADDR_ANY and the port, then I can still receive other unrelated traffic destined for the same port.
When I implemented the same thing in Linux, I didn't have any issues binding to the multicast address (in fact, I saw it recommended several places to avoid getting unrelated traffic for the port).
Is this just not available with Windows sockets? I assume I could filter traffic myself by using WSARecvFrom and peeking at the headers, but I'd rather a simple solution if one exists.
Also, this is running on Windows Server 2008.
While the doc for bind() does not say that this unsupported, it does say in the remarks:
For multicast operations, the
preferred method is to call the bind
function to associate a socket with a
local IP address and then join the
multicast group....
Maybe this scheme will yield better results?

Resources