Joining RTP multicast from the source - c++

This computer is taking SDI video as input and giving RTP stream as output. There is no problem joining this rtp multicast from another computer on the same network but if I run my software on the SDI to RTP machine, I can't get any packets. There is no problem joining multicast but it acts like there are no packets.
We have 2 identical networks, I tried both, no success. I also tried some other software like VLC to see if they can get any packets and it seems they don't have any problem at all. I checked resource monitor and saw that these software are listening ports without giving a local ip address. I am always setting computers local ip address before joining any multicast stream to select the network ( there are 2 )

For jrtplib you need to set acceptOwnPackets before creating a session
RTPSessionParams rtp_sp;
rtp_sp.SetAcceptOwnPackets( TRUE );

Related

Computers on LAN do not consistently receive a UDP broadcast to 255.255.255.255 using boost::asio C++

I am quite new to network programming, but nonetheless I am working on a personal project that requires interfacing between two computers on the LAN.
For all of my networking needs, I am using boost.
Since computers running my software on the LAN do not know one another's IP addresses, the program immediately sends a UDP broadcast to 255.255.255.255. Another computer listens on the port 25566. If a computer receives a broadcast, it replies with another broadcast to ensure that the other connects via a TCP connection in the appropriate manner.
I have a laptop, and a desktop, both running Linux. If I test the code (two instances of the same thing) on the same machine, everything works flawlessly. However, a problem arises when I run one instance on the laptop, and another on the desktop. Two scenarios happen:
The first - I run one instance of the program on the Desktop computer. It sends a "Hello" message to check if another instance is running anywhere else on the LAN. Since there is no other instance running, it receives no response. Several seconds later, after the desktop instance sets itself up, I start an instance of the program on the laptop. The laptop broadcasts a "Hello" message as well. However, this is where the problem kicks in. When the laptop is the one sending the "Hello" message, there is only about a 10% chance that the desktop program (already running) actually receives it. I monitored the network with Wireshark on the desktop machine, and, again, Wireshark only picks up the broadcast from the laptop 10% of the time. However, if I run Wireshark on the laptop that is sending the "Hello" broadcast, Wireshark picks it up every single time.
The second - This is similar to the first, except the laptop runs the program first. I then start the desktop instance several seconds later. However, when the desktop broadcasts "Hello" the laptop receives the broadcast about 95% of the time (in contrast to 10% of the time when the roles are reversed). The laptop then responds with a "Configure" broadcast. The desktop then receives the "Configure" broadcast nearly 100% of the time. I confirmed the 95% receive rate with Wireshark again.
I am certain there is no problem with my program ignoring these packets. However, something is happening in the network where the broadcast packets are ignored or filtered. What I find particularly strange is how the desktop program only receives the "Hello" message 10% of the time in scenario 1, but receives the "Configure" message 100% of the time in scenario 2. If something strange was happening that prevented packets from reaching the desktop, woulden't both of those percentages be roughly equal?
Here is some of the code that I run to setup the necessary sockets:
broadcast_socket = new udp::socket(*ioservice); //Set up the socket that broadcasts the message
listen_socket = new udp::socket(*ioservice); //Set up the socket on port 25565 that listens for a broadcast
//Set up the ioservice...
error_code e1, e2;
broadcast_socket->open(udp::v4(), e1); //Actually open the sockets
listen_socket->open(udp::v4(), e2);
//Do some error code checking...
listen_endpoint = udp::endpoint(ip::address_v4::any(), port); //Get endpoint for port 25566 (listen_endpoint becomes 0.0.0.0:25566 after this call)
listen_socket->set_option(udp::socket::reuse_address(true));
listen_socket->bind(listen_endpoint);
broadcast_socket->set_option(udp::socket::reuse_address(true));
broadcast_socket->set_option(socket_base::broadcast(true));
broadcast_endpoint = udp::endpoint(ip::address_v4::broadcast(), port); //Get the broadcast_endpoint (returns 255.255.255.255)
Here is the code I use to receive broadcasted messages:
error_code ec;
size_t available_bytes = listen_socket->available(ec); //See if data is available
size_t read_bytes = 0;
char buffer[1024];
if(available_bytes > 0 && !ec){
read_bytes = listen_socket->receive_from(boost::asio::buffer(buffer, (available_bytes < sizeof(buffer) ? available_bytes : sizeof(buffer))), listen_endpoint);
read_data.append(buffer, read_bytes); //Append to a string for later processing
}
And finally, here is how I send data:
std::string payload = "Some payload stuff goes here";
broadcast_socket->send_to(boost::asio::buffer(payload, payload.size()), broadcast_endpoint); //Broadcasts to the broadcast_endpoint (255.255.255.255) which was determined earlier
So essentially my question is, why does some of my broadcasts not get through?
Thanks
EDIT:
Also, I forgot to mention that each computer receives its OWN broadcast every single time. So I think its a problem with the network, and not my code.
UDP is not guaranteed to deliver. That's part of the properties of the protocol.
The fact that you can observe the behaviour with Wireshark confirms that it has little to do with Boost.
Using 255.255.255.255 is a blunt weapon and it is limited:
Setting all the bits of an IP address to one, or 255.255.255.255, forms the limited broadcast address. Sending a UDP datagram to this address delivers the message to any host on the local network segment. Because routers never forward messages sent to this address, only hosts on the network segment receive the broadcast message.
You can be more targeted by using the subnet mask:
Broadcasts can be directed to specific portions of a network by setting all bits of the host identifier. For example, to send a broadcast to all hosts on the network identified by IP addresses starting with 192.168.1, use the address 192.168.1.255.
This heightens the chance that the router will know where to send the packet (I'm not a network engineer, so I'm not sure about the implementation details).
Enter Multicast Groups:
Unlike broadcast transmission (which is used on some local area networks), multicast clients receive a stream of packets only if they have previously elect to do so (by joining the specific multicast group address). Membership of a group is dynamic and controlled by the receivers (in turn informed by the local client applications).
(source: http://www.erg.abdn.ac.uk/users/gorry/course/intro-pages/uni-b-mcast.html)
This is more likely to fit your application. You'll have to select a good group endpoint depending on the network configuration, so it's slightly more involved.
Yet, you'll have support of all modern router hardware/software to ensure delivery to the interested parties (only).

TCP streams on iOS don't show up on a wireless network

I am trying to send and receive TCP streams from an iPad via a wireless connection to a laptop. I create sockets with boost::asio. This project is a port of a data streaming library that I maintain that works quite well on Windows, OSX, and Linux.
I can get the app to send and receive streams to/from other computers on a wired LAN when I run it on the simulator. But, when I target the device itself, I can't see any streams.
As I say, I am communicating via wireless between an iPad and a laptop. I create a wireless network on the laptop and then give the iPad a static IP. The connection appears to be fine, because I can ping the iPad with no packet loss. I have also tried connecting the devices by putting them on the same wireless LAN (although I'm not supposed to use wireless routers at work) and this also does not work.
According to apple, setting up streams like this with NSStream will just work. Maybe there is some permissions magic happening under the hood that I am not doing with my calls to boost::asio functions. In any case, I can't see the streams.
Actually, it turns out the only thing that was wrong was that I needed to set up my routing table so that it pointed multicast to the wireless card:
> sudo route -nv add -net 224.0.0.183 -interface en1
I got the IP from inspecting packets in wireshark -- it is the address that my device is multicasting to in my laptop. Sending works (from device to laptop), receiving is still silent though. This may be something else that needs to be set int the routing table (I really don't understand much at all about multicasting) or else I can fiddle with some config settings with my library.

how to get IP address of a computers that is directly connected to my PC

I'm trying to write a function that can get me the IP adress (and the name of the device as bonus) of devices that are in my network, the network is gonna be a direct connection between two computers using Ethernet cable or creating an access point (using wi-fi)
I tried to search about how to do it but it seems like I need to listen to the network or something which seems to be difficult.
hope you can guide me to what I should do or read to get started.
Note: I'm using Windows on both computers.
Edited:
P.S: I need the IP Address so I can send a message to the other computer using winsock in a Client/Server program I wrote.
can't I make the server send its IP to the client or the opposite ?
If your software is running on both machines, you can have one (or both) machines send out a particular broadcast (or, if you prefer, multicast) UDP packet on a specific port. Your program should also be listening on that same port. When it receives that packet (using recvfrom()), recvfrom()'s fifth argument will contain the IP address of the machine that sent the packet, i.e. the IP address you want.
(If OTOH your software is not running on the remote machine, you'll need to use some more general-purpose discovery mechanism such as mDNS or LLDP -- hopefully you won't have to do that, though, as it's a good deal more complicated)

Qt5 Bind TCP Socket on Multihomed Network

I am having troubling using the new bind feature of the QTcpSocket class in Qt5. Any help figuring this out would be appreciated.
I have a multihomed server that contains two NICs each with a separate IP address. I have setup routing on the servers so that sending from the source address is sent out of the appropriate NIC regardless of the target remote address. That is, sending from x.x.x.0 goes out over eth0 and x.x.x.1 goes out over eth1 regardless of who the data is being sent to. These NICs are connected via ethernet to long range Wifi links that are then connected to a switch. These wifi links act as a transparent bridge and can rather be seen as two ethernet cables (but they are limited in bandwidth). The switch is then connected to a computer. The goal is to transfer data between the server and the computer, and to use the two wifi links in parallel to increase bandwidth. Although the server is physically a server, the software has the computer running as the software server (as others connect to it). That is, the physical server (software client) opens TCP sockets and attempts to connect to the listening computer (software server).
I use the bind feature of Qt5 to bind one TCP socket to the eth0 IP address and bind another TCP socket to the eth1 IP address. I have verified this works with other programs like PING or file transfer via SCP. See http://qt-project.org/doc/qt-5.0/qtnetwork/qabstractsocket.html#bind
When I call bind the call succeeds and subsequent requests for the local IP address returns the correct value. E.g. socket->bind(ip) returns true and then socket->localAddress() equals ip. However, when I call connectToHost the localAddress is lost when it starts the connection attempt and after connecting it has a different localAddress that is not the one I wanted it to have.
Can anyone shed light into what is going on? I am trying to avoid rewriting the software to reverse the roles of software client / server as these programs are quite big. Thanks for the help.
There is an open bug on this in the Qt project bug tracker.

UDP NAT Traversal

I have a PC and a phone and I am trying to set up bi-directional communication between the 2 over 3G.
On the PC end I have full control over the NAT. So I have port mapped incoming communications on my specific port to the PC on my desk.
I then send to our PC network's outside IP address with my specific port.
I see the packets arrive at my PC, which is perfect. So now I want to send back a communication from the PC to the phone. I have got the address and port via a "recvfrom" and i then do a sendto back across to the address and port that I received the data from.
However this data is then not being received by the phone. I assume the incoming communication is not getting re-directed by the NAT box on the mobile providers network.
Why is this? I thought seeing as I've initiated communication from the phone that I should be able to go back along that route to communicate with the phone?
So, how do I get this working?
Any thoughts appreciated!
Well I did figure out what I was doing wrong. I was communicating from the phone to the PC's port "x" and then trying to go back the other way on port "y". Using the same port for both ways allowed communication to occur :)