I have a program that broadcast UDP to my local network, and one host device would read this message and function upon it perfectly.
Now I want to do this job remotely, knowing that where is the reciever host I have a public static IP provided by the ISP, and for example I'm out side this network and I want to broadcast this UDP traffic to it through the Internet, is there any possible routing configuration that would allow this trafic to reach the local network and just explode there ?
And if not. Is there any other way that can make this trafic, instead of broadcasting to be directed to this receiver host directly ? That would require then only some port forwarding in my static ip router.
By RFC, broadcasts cannot be forwarded by routers. Plus, several ISP will filter out such packets anyway. Broadcasts are limited to the local subnet only.
I suggest you look into multicast instead.
Related
In the WebRTC signalling process, I have to find my own public IP address with my port by doing a request to a STUN server. But does it really need to be this complex?
Couldn't I just send a request to the router of my subnet and get its IP address and the port it opened for me? Or even better, I store directly my public address in my computer and the router notifies me whenever it changes. The browser would give an API to get this public address directly. No need to use a STUN server. Why don't we do this instead?
Thank you for your help.
These are all great questions.
Couldn't I just send a request to the router of my subnet and get its IP address and the port it opened for me?
There's an old protocol called uPnP that will dynamically open a port mapping for you - provided the router supports it. A lot of routers used to support it. Not sure how standard it is now.
Even if routers were intelligent and there was a standard signaling mechanism in place, STUN (or something equivalent for STUN is still needed) for the following scenario.
Carrier NAT is when your ISP is sharing a public IP address with multiple routers. That is, your router's public IP address as configured by the ISP when it starts, is really just another private IP address. Upstream, there's a "bigger router" that is sharing the public IPv4 address with multiple other customers. That is, your PC might think it's IP address is 192.16.1.2, and your router reports that it's own IP address is 10.0.0.2. And the actual public IP address, 1.2.3.4, is shared with other customers. STUN solves this problem because the outbound packet to the public STUN server will go through both NATs - creating port mappings along the way.
Or even better, I store directly my public address in my computer and the router notifies me whenever it changes
Because establishing an effective P2P/WebRTC connection is more than knowing your public IP Address. It also involves knowing what "port" to use as well. While most routers will attempt to preserve the local port of the socket the client PC is using in the mapping (e.g. 10.0.0.2:9876 maps to 1.2.3.4:9876). This isn't always the case - another node could be using port 9876 on your network and/or many NATs just pick a randomly available port for the mapping. At the end of the day, you have to signal to the other side of your P2P/WebRTC connection "which IP" and "which port" to use.
The browser would give an API to get this public address directly.
There are plenty of sites such as whatismyipaddress.com that will tell you your IP address. But if there's a HTTP proxy server involved (explicitly configured on the PC or silently deployed on the network), the web service will only see the proxy IP address. Further HTTP(S) is a TCP based protocol. STUN and WebRTC are UDP based.
I understand the purpose of STUN and TURN servers and their use in WebRTC, but I don't fully get:
If I as a WebRTC client have already logged in to use the WebRTC service, wouldn't this service already have my public IP address? Why does it need to be found a second time by the STUN server?
Short answer: Because Proxies and NATs.
Lots of reasons:
The web server knows your public IP address for the established TCP connection, but for the subsequent P2P communications over UDP, it doesn't know how your local NAT will map the port (or which port its using).
You could be on a network in which all HTTP/HTTPS traffic goes over a proxy. Hence, the WebRTC service only knows the address of your proxy.
The WebRTC service itself could have a front end load balancer. Hence, it only knows the IP address of the load balancer.
The two endpoints attempting to do a WebRTC session may actually be behind the same NAT. Hence, the public IP address isn't as useful.
But the primary reason is around port prediction as discussed in #1 above. Address exchange over ICE or WebRTC involves not just exchanging IP Addresses, but also, UDP ports as well. Even if the web server knows the client's actual IP address, the web server can not infer what UDP port it will use for media traffic.
I have made an UDP client server program in java. It is working well in localhost and in the same router/ network.
But when I am running my UDP server program in my laptop connected to internet and running my UDP client program in my lab (on different network), then it is not working.
Is there any way to send UDP datagram over the network from one system to another?
Yes, in theory it should be working just the same. It's still IP.
In reality, routers with NAT exist. For example, if you address an UDP packet to your home PC's public IP address, it actually is addressed at your router. The router does not know which local IP he should address the packet to and discards the packet.
The solution: Configure UDP port forwardings for routers on both ends.
I am trying to write code on OSX in c (can use objective-c too if easier) to determine if multicast is enabled on the current machine (router the machine is connected to). To do this I am trying the following steps:
Open a port and send data over multicast.
Listen for responses on all active adapters.
Filter out the 'loopback' adapter.
If no replies, multicast is likely disabled.
Being new to network programming, I don't understand how I would get a response from any active adapters by sending out random data, unless I had software installed on the machines that were listening. Is there a certain multicast IP reserved that will always elicit a response, or is there a better way to go about doing this?
To determine if a machine has IP multicast addresses active (which is what I think you mean by "multicast is enabled"), look at the routing table and see if you find one or more IP v4 addresses in the range 224.0.0.0 to 239.255.255.255.
Multicast is implemented by DHCP, which is not your local computer. DHCP allocates addresses whihc correspond to multiple clients that are connected to that DHCP server. When you craft a multicast message, you send it to this DHCP server, which then takes the packet, finds the clients who are mapped to that multicast address, and then send it in a special packet that routers automatically duplicate (so if you have 2 people part of the group connected to 1 router, and that router is connected to another router (called router 2), router 2 won't send two packets, it will send one, and then router 1 will send two copies to its clients. The purpose of this is to speed up delievery time and not send duplicate data). As far as the clients, the clients aren't "set up" to allow multicast, but rather the router sets them up, and the rest is transparent to the client. The way you would have to find out if a client is connected to a multicast group, is to see if the DHCP server has created a multicast group, and then find the computer names from the IP addresses that are mapped to the multicast group.
By listening to all active adapters, you're not going to get anything but packets, which aren't going to tell you if its part of a multicast network, since they're going to look like every other packet (since the router will change the multicast address to YOUR ip address before you even see the packet). That's the beauty of multicast.
I am working on a C++ server/.NET client applications couple in which my server (which runs the c++ on linux) broadcasts a message to show it's alive to the whole network and my .NET program listens for packets and parses to get the uptime of the server.
As I have read, to send a regular UDP broadcast to the broadcast address, I simply have to send a packet to 192.168.0.255 (in my case 192.168.2.255) or 255.255.255.255. Is this right? Can I use the same port address? Are there any other necessities?
I understand the fact that if my .NET program listens on that particular address it is possible to receive packets from other applications than my C++ server program. Is there any method of "signing" the packet on the C++ server-side in order for my .NET program to read the header of the packet and see that it is (almost) the one I am looking for?
Regardless of the language you are using, here is my answer:
Regarding the broadcast IP addresses, both addresses are broadcast addresses but the limited broadcast address (which is 255.255.255.255) won't be forwarded by routers. It is better to use the subnet-directed broadcast address (192.168.2.255).
In order to send/receive a broadcast address, you need to define your broadcast address (broadcast IP address and port number). For example: 192.168.2.255 and port number 3000. The client applications (the senders) MUST enable SO_BROADCAST socket option as follows:
int enabled = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &enabled, sizeof(enabled));
where sockfd is the socket descriptor.
The server application will listen on a specific port number (port 3000). Normally, the server will respond to each request using unicast message.
There will be no conflict as long as no application is listening on the same port number. Your server will not run if another application is listening on the same port unless you enabled SO_REUSEADDRESS socket option. However, if there is a conflict, then your signiture is depending on your protocol (message format). So, check the message format and reject the message if it does not follow the message format defined by your application protocol.
For client applications, the received packet is unicast (unless you have another design). So, no conflict at this side.
You also have to enable the SO_BROADCAST socket option in C++ to send broadcast traffic, or you'll get a permission denied error:
int broadcastPermission = 1;
setsockopt(socketDescriptor, SOL_SOCKET, SO_BROADCAST, (void*)&broadcastPermission, sizeof(broadcastPermission))
If your .NET program listens for broadcast traffic, it will receive any and all broadcast traffic on the network sent on that port, including traffic not sent by your server. You could put a "marker" in the payload of the broadcast messages sent by your server. This way, your .NET program could distinguish which ones it cares about.
Beyond that, I would recommend using multicast instead of broadcast. Broadcast traffic is usually restricted to hosts on the same subnet. In layman's terms, if you have a router in your network, a host on side A of the router will not see broadcast traffic sent by a host on side B (and vice versa) because the router "blocks" it. Routers will almost always forward multicast traffic if a host has joined the multicast group.