Establish peer-to-peer connection from behind NAT - c++

I need to make some general way for my own peer-to-peer UDP or TCP communication between my own clients over internet, without creating own server.
I cannot just use XMPP for the communication because file transmit are necessary.
Do I understand the possible sequence of actions correctly?
Connect to some (or any?) XMPP server, using prepared existing XMPP account
Search for another my own client connected to XMPP and connect to it.
Resolve an unique public global internet (IP?) address or ID for each client (how?)
Exchange these addresses between clients
Make direct connection possible by some actions with clients' NATs
Connect clients directly p2p to each other using received unique addresses
Disconnect from XMPP server
Communicate via my own p2p connection
If the sequence is correctly, what specific actions do I need to do to resolve unique addresses, and to make an UDP or TCP connection then? How that can be done on c++?
Edit.
I've found nice answer here: Programming P2P application

Your situation is close to WebRTC: peers need a way to 1) discover each other ("signaling"), 2) set up a direct connection through NAT if needed. (STUN/TURN)
See this WebRTC infrastructure overview for a start, and ask more specific follow-up questions later.

Related

Uniquely Identify UDP Connection - Multiple Connections from same IP

I'll start by saying that currently my server identifies based on sender IP, that is the IP of the client.
Now I am programming a game server (just for practice) and this got me thinking how do I uniquely identify a client if they are on the same IP. (Two players open a connection on the same machine / same network so the outward IP is the same).
I've searched for an answer both on google and here and gamedev.net but am unable to find what I am looking for, likely because I do not know the correct terms to query for.
Any guidance on this would be appreciated, especially in regards to efficiency and best practice.
Thanks.
There is no "connection" term in all stuff related to UDP, but it is common that an application that initiates a UDP socket maintains the same source port over the time, so you could identify it by source IP-port.
There is some stuff related to maintain communication between a client inside a NAT router (in NAT-UDP the client is the first host that send a UDP datagram to another host and trigger a new connection tracking entry) and a server.
This "connection tracking" is only for allow traffic from outside to inside, making a "temporal" relationship (with a timeout), that probably will not be used anymore (only once) sometimes.
If the server doesn't use the same destination port in outcoming datagram as source port in incoming one, the router won't send the datagram to the host inside NAT.
Best regards.

Establishing a websocket connection with another server

I'm working on embedding Mongoose into an application, and I need to be able to have the app connect to a server when it starts up. How can I do this? On GitHub, I see examples for receiving connections, but none on how to initialize a connection with another one. Any ideas?
Mongoose is a web server. It is designed to accept incoming connections, not make outgoing ones.
If you want to make outgoing connections, the way forward will depend on what you are connecting to and what protocol(s) it may use.
If you want to make outgoing http or https connections, you could use libcurl.
If some other protocol you may be able to find an appropriate library. Or, you can use operating system layer socket APIs to make your own connection, and implement whatever protocol is required on top of that. Here is an example for Linux, for example.

Redirect opened TCP connection

Is it possible to redirect an opened TCP connection to a third device?
For example I have two clients which are both connected to a central server. Both initiated the communication. They cannot accept any connections from outside the internet because the router's firewall is blocking them.
What if they want to connect to each other: is it possible to redirect the two connections with the server to become one peer-to-peer connection between the clients? (I have a feeling that this is not possible) My program allows that both devices can work as a TCP server, just firewalls are blocking them.
Currently I am using two solutions to communicate between the two clients. One is using UPnP port mappings, the other that messages sent to server are repeated and transmitted to the clients.
Is there any other solution? I am especially interested in methods which are using C++, Qt and Linux.
You cannot redirect already opened TCP connections to another device, because in this case the endpoints of the connection would need to change - but the endpoint (ip+port) is an essential part of the connection. So you could only transfer the data you received at the server from one connection to the other and back, or you could try to make the two parties connect directly to each other from start with TCP hole punching like mentioned in a comment already. But this will only work for simple NAT setups.
Simple port forwarding at the server will not work for already established connections, because you would have to rewrite not only sender and receiver of all packets (e.g. NAT) but also rewrite the sequence numbers etc so they match the other established connection. So you would need to do the forwarding in user space or inside the kernel at the connection level and not the packet level with techniques like socket splicing.

How to conect client to server through ad-hoc network by socket

I read similar posts here, but no one is really helpfull, so I ask same for Windows.
On server side we create ad-hoc network and connect to it using ad-hoc api, on client side we get enumeration of all available ad-hoc networks and connect to proper one.
Now on server side we just create listening socket, we don't need to specify any ip address.
But on client side we must know server ip address to create connection socket.
I know that socket layer is independent from higher level (ad-hoc), but it's not the answer. The goal: get ip address of server that created ad-hoc network on client that is currently connected to that network. I don't want to use other libraries like managed wi-fi.
Maybe there is some win api function to get list of ip addresses associated with ad-hoc network, some ip address range? I don't quite understand all specifics (and hardly will do, considering education process), so just point me in right direction. The language is not the matter, may it be C# or C++.
Thanks.

0MQ - get message ip

First, I want to give thanks for that amazing lib! I love it. A client is connecting himself to a server. The server should save the IP and do stuff with it later on (I really need the IP). I found that answer: http://lists.zeromq.org/pipermail/zeromq-dev/2010-September/006381.html but I don't understand how I get the IP out of the message (a XREP)... I think I am only able to read the ID, but the IP is managed internally by 0MQ. His second solution suggests to send the IP as part of the message, but I don't understand how to get the "public"-IP. I found that post: Get TCP address information in ZeroMQ
is pass bind a service to an ephemeral port, get a full connection endpoint ("tcp://ipaddress:port")
I don't get how this works. Does he mean something like a web-service?
In my opinion, it would be best to get the IP out of 0MQ (it has the IP already). I would even adjust 0MQ for that, if somebody could point to the place where the IP is saved, couldn't find it. The socket types are not that important, at the moment. I would prefer smth REQ-REP like. Thank you!
Summary:
TL;DR answer to your question is: you can't get IP address of the peer that sent a message, using ZeroMQ API.
Explanation:
ZeroMQ does not expose peer IP address because it is irrelevant for the message based communication that ZeroMQ is designed for. When it is possible for ZeroMQ to get IP address of client that is connecting to server (in example using method described here), it is useless. For a longer explanation here is how it works inside ZeroMQ and any other server implementation.
Server side of the connection does not handle connected clients by the means of the hashtable that maps IP to client, but by keeping track of connected "sockets" (socket descriptors) - when a server accepts (using accept()) a connection, it receives from operating system socket descriptor to use to communicate with connected peer. All server has to do is keep that descriptor around to read() from and write() to that client. Another client that connects to server receives another socket descriptor.
To summarize: even if ZeroMQ would be able to provide you with IP of connected peer, you should not depend on it. ZeroMQ hides from you connection management so you can focus on messaging. Connection management includes reconnections, which may result in a change of IP without changing the actual ZeroMQ socket connected on the other side.
So here's an example of why you might want to get the ip address a message was delivered from: we have a server whose job it is to synchronize updates onto occasionally-connected clients (think mobile devices here, though this is an extreme example of a mobile deivce.)
When the mobile unit comes onto the network, it sends a list of it's firmware files to the server via a dealer-router connection. The server has a list of all applicable firmware files; if the client needs an update it will initiate an update via a separate mechanism.
Since the IPs for the devices can (and do) change, we need to know the IP address associated with the mobile device FOR THIS CONNECTION, i.e. right now.
Yes, we absolutely can have the client send it's IP address in the message, but that's a waste of another n bytes of valuable satellite air time, and while not pure evil, is sure annoying. Zmq already has this information, if it didn't have it, it wouldn't be able to generate replies. The address is in the socket data, there's no reason the message couldn't (optionally, for all you guys who use wired networks and think disconnects are the exception) include a reference to the socket structure so you can get the address out of it. Other than pedantic religiosity, which is far too common in zmq.
The way ZeroMQ is designed there's no information provided on the remote IP. As far as I know you have to manage this through your application by sending that information as a message of some sort.
The messages themselves use an IP-agnostic ID which has more to do with the instance of ZeroMQ running than any particular interface. This is because there may be more than one transport method and interface connecting the two instances.