UDP NAT Traversal - c++

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 :)

Related

C++ UDP Socket not working to send back from server to client after receiving first packets from client

Writing a UDP client-server app in C++ (done that lots of times before in many languages in the past 15 years), but somehow this one is not working correctly.
I cannot post actual code nor minimal reproducible app at the moment but I am willing to pay for live help if anyone is available to help solve this quickly with screensharing.
I think this is a particularity with C++ sockets and the way I am using them in this specific app which is quite complex.
Basically the issue is that the packets sent from the server to the client are not received by the client, only when said client is on a separate nat.
When both in same local networking and using their local IP, everything works as expected.
Here is what I am doing :
Client sendto(...) packets through UDP to the server using a specific server host and port 12345 (and keeps sending these non-stop)
On another thread, client bind(...) on port 12345 and "0.0.0.0" and tries to poll() and recvfrom() in a loop (poll always returns 0 here when client is on a separate nat)
Server bind() on port 12345 and "0.0.0.0" then poll() and recvfrom() in a loop
Upon receiving the first UDP message from a client, it starts a thread for sending
UDP messages back to the client on a new socket, using the
sockaddr_in that it got from the recvfrom() to pass in the sendto() commands.
Result : Server perfectly receives ALL messages from all clients, and sends all messages back to all clients, but any client that is not on the same NAT will never receive any messages (poll() always returns 0).
As far as I understand it, when the client sends a UDP message to the server on a specific remote port (12345 in this case), it will punch a hole in its NAT so that it can receive messages back from the remote server on that port...
I tested five different client network configurations :
Local network with the server, using local IP addresses (WORKS)
Local network with the server while client is using a VPN thus going through a remote NAT (DOES NOT WORK)
Local network with the server but client is using the WAN ip address to connect to the server (DOES NOT WORK)
Client at an actual remote network from a friend's connection, behind a router (DOES NOT WORK)
Client going through a wifi hotspot created using my phone (DOES NOT WORK)
For all tests above, the server was correctly receiving all communications from clients.
I also tried forcing the port to 12345 for the sendto() instead of using the sockaddr_in as set from recvfrom(), same issue.
Am I doing anything wrong ?
If you want to help but need to see actual code, I can do that live with screen sharing and I will pay for the help.
Thanks.
Also, if anyone can point me to a great site where I can pay for VERY QUICK help, please let me know, I don't even bother searching google because I really want actual advice from people who tried these services, not ads trying to rip me off...
Only the original receiver socket is allowed to reply to the client, because it's the client request that opens the port in the NAT. So either use the same socket in the server to receive and reply, or get the port that the second server socket was bound to and transfer it with an initial message through the original server port, so that A can send to it and punch the hole.
It looks so strange to create two half duplex sockets when a socket is a full duplex communication object that I'd go with the first option.

C++ sockets: communication between PCs over internet

I'm writing a program on Windows using winsocks that can send messages to another computer. The client connects with the server in the other computer and begin exchanging data.
It works fine on my local network using local addresses(192.168.1.*), but I can't communicate with public addresses (216.185.45.129); not even my own. I can successfully connect to a website on port 80, but not to my laptop at home using its public IP address, regardless of what ports I use (unreserved ports).
So I did research online and the only solution that seems to work is port forwarding.
-But is there absolutely no other way to achieve this?
-How do other programs like Teamviewer connect to other computers on the network then?
-Is there an already open but typically unused port that I can use?
-At the very least, can I forward the ports on my router but not have the client do anything? Or maybe have my program forward the ports automatically.
The main problem is, that every router is using NAT to distinguish different computer in your lokal network against the WAN. He need to do this, because you got only one IP in the internet, but several devices in your home. To archive this, he uses groups of ports. That means, if you use to send maybe from port 2048 to a webserver in internet with two devices, the router gives one device another port (like 2049). The response has the Port of the requester, so the router can map it back. Unfortunately most router always map ports so you never now which port you have from the internet side.
There are two common ways to work around and archive your goal.
Port Fowarding
You can force most router not to map special ports but bind them to unique MAC addresses. You can use UPNP to config most router to do that, but I do not recommend that for security reasons and also it does not work in many enviroments where Router do not allow UPNP manipulation.
Most router have port forwarding abilities for gaming reasons (mostly it is used in P2P networks)
It works with TCP and UDP.
NAT Traversal
The common way is NAT traversal, also known as NAT hole punching. I will describe it in short for UDP. You can find a wiki explanation here for TCP and for UDP here. Unfortunately you need a server in the internet both clients can reach. Here the steps:
Both clients contact the server. The server now know IP and PORT of both clients.
Server send back the information to the clients.
Both(!) clients send now packages to each other on the known address.
It is necessary that both client send a UDP package and have to accept that the first package get lost. The reason is the router. Most router only accept packages from a source on a mapped PORT if a client has send a package to that source before.
UPDATE
Regarding to a comment of Remy Lebau I changed the Firewall piercing part to NAT Traversal as it was partly wrong.

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.

Find all clients in network

I'm writing client-server application and I need my server to find all clients in some network. I've already found some info here: Discovering clients on a wifi network, but I still don't understand how to implement this. Maybe somebody can say where I can find some code examples.
Thanks in advance.
PS. Working on c++, windows.
Generally TCP/IP is used as a communication protocol between client and server. For Windows platform Winsock library is used to implement TCP/IP. The server binds and listens on a port for incoming connections. Just like a webserver like stackoverflow listens by default on port 80 and then client (browsers) connects to it.
Here is a link to start. Here is sample
Normally all the client connects to server which listens on a well defined port. The server is only one hence the IP address and port is well know to all the client and hence they can connect to it.
In you case you want your server to have ablity to discover all the clients in the network. To achieve this the server needs to broadcast to network some message. The client will receive this message and will respond to the server that they are available on such IP and they can connect to server or provide additional information to server. Normally instead of broadcast, multicast is used which is limited broadcast. All the clients and server will subscribe to the multicast group which is a special kind of IP address. When server send a message to this multicast address all the client, which are subscribers of this address will receive this message and can respond back. Here is a sample
Edit: you can also use boost lib to implement multicast: sender eg., receiver eg.