Windows Peer to Peer Global_ Group without third party ipv6 tunnel - c++

I have been trying to develop a peer to peer application that uses Micosoft's Peer to Peer Group library. Basing my work on the Creating a Group Chat Application acrticle on msdn. This works fine for local groups and will also work for global groups if I have a thrid party tunnel adapter installed such as the gogo6 client. However from a few things I have read it seems like I should be able to get things working through the Teredo tunnel adapter that comes built into Windows.
I have tried various things and can now access ipv6 only sites (eg ipv6.google.com) without the gogo6 tunnel running, but I can't seem to find any other peers in my global group through this method.
I have added a rule allowing trafic (including edge traversal) for the application in the Windows Firewall and also opened the following ports to incoming and outgoing trafic.
tcp 3587
udp 3540, 1900
From the samples I have read it seems like it should just work, but it doesn't. I did read that to use teredo in an application you had to specificaly enable it. The only way I have found to do this is when opening the socket, but the group api does all of that for you so I have no known way of controlling that.

Some Teredo clients are unreachable due to symmetric router problem. Teredo can work only behind 90% of routers. Gogo6 uses TSP which tunnels the packet to gogo6 infrastructure from where it reaches ipv6 internet.

I don't think Teredo supports IPv6 multicast. If the Peer to Peer Group library uses multicast under the hood, I think that's the problem. I could never find any confirmation that multicast is unsupported by Teredo; but in my own testing setsockopt(ADD_GROUP_MEMBERSHIP) would always fail when the interface ID was a Teredo interface.

Related

Connection from external computer to computer in local network

Currently in my chat p2p app, I need to open the port for other computers can connect to, but static ip is not allowed by the admin to open the port. Then I found a network programming exercise that seemed like a solution to this problem. The requirements are as follows:
"Write a program to test the UPnP protocol to
ADSL modem controller opens NAT gateway automatically.
In case you can not control the modem, find out and install a NAT Traversal technique to connect two clients in two NAT networks.
internet (use an intermediary server for primers
connect)."
Can anyone tell me what is an intermediate server for connection primitives?
Check https://www.noip.com/ :P. Maybe this can solve some of your problems ^^
You can simple setup DynDNS services. You will have one external domain name with any ip address.
But best way to setup SoftEther VPN solution. That can pass thought any NAT. You can keep your application server at the NAT subnetwork too. And that server will registered on common EtherVPN registry that allow connects from anywhere.
If you want smart solution embedded in your application. Please check similar solutions for VoIP communications. Like ICE, STUN, TURN. But that will not simple to implement.

C++ application: discover other IPs on LAN

I want to create a C++ application that can be used (in part) to communicate between users on a local area network using UDP. Each instance of the application will have a thread dedicated to listening for other instances of the application and broadcasting its presence to other instances.
Is there a reliable way to perform this type of broadcast/listening on the LAN using pure C++ and POSIX system calls? I know there's no generally reliable way to find all IPs on a LAN, but I assume this is only because other devices are not willing to respond to pings.
Don't re-invent the wheel. There are two existing technologies, that, when combined, solve your problem in a standardized, well-designed, proven manner:
RFC6762 mDNS (Multicast DNS) is a protocol that works almost exactly like DNS, except it works using IP multicast. Instead of sending your DNS request to a unicast address, you send your DNS request to a multicast group, and any member of that group can answer your request (so you may get multiple answers).
RFC6763 DNS-SD (DNS-based Service Discovery) is a way to encode Services as DNS entries, which allows you then to retrieve Services from DNS using specially encoded hostnames. (For example, looking up the hostname _ipp._tcp.example.com would return a list of all printers that support the Internet Printing Protocol over TCP within the domain example.com)
So, we have one protocol that allows us to ask DNS about Services, and we have one protocol that allows us to ask a group of hosts to answer DNS queries … when we put the two together, we get a way of asking hosts for services! The combination of those two protocols is sometimes called Zeroconf networking, and is already implemented in macOS, iOS, tvOS, and watchOS (where it is called Bonjour), Android, most Unices (via Avahi, a portable implementation of those two protocols), and many home devices such as TVs. E.g. Spotify Connect, ChromeCast, Philips Hue and many others are also based on it. It's how iTunes devices find each other on the local network, for example.
Unfortunately, support in Windows is still limited, at the moment it seems to only exist for Windows 10 apps implemented in ECMAScript. (However, nothing stops you from shipping your own implementation with your app, and AFAIK, both Avahi and Apple's mDNSResponder work on Windows.)
So, what you would basically do is to send an mDNS query to the mDNS multicast group and ask for _myprotocol._udp.local. Then, assuming that your application registers itself with the OS's mDNS service (i.e. Bonjour on macOS, Avahi on Unices, …), you would get back a list of all hosts on the local network that support your protocol.

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.

Connection to server while behind the rounter in WinSock2, C++

I'm writing a very simple server-client application in C++, using WinSocks.
When I set client's parameters as: resolveHost ("google.pl") for server's IP and 80 for port, I receive a html (with GET header).
When I run the server first (with port 10000) and then client (port 10000 IP inet_addr("127.0.0.1") it seems to works (I receive something).
But when I change the server's IP in client to inet_addr("188.246.158.171") (my IP for now, I don't have static IP, I've checked my actual IP with some website), it for sure DOES NOT works.
My computer is behind the router - can it be the problem?
If so, can I solve it in the way that don't requite any configuration to router (port forwarding etc.). Also, I don't want to make anything router's model-specific, so I intentionally haven't posted the model of my router ;)
Why I don't want to change configuration?
Because my application will be for "simple people". And simple people won't try to make configuration, and I won't require them to do so.
Also, many applications (on-line games for example) works fine with my router without any configuration - my application cannot be exception (by the example of other applications on my computer, I know it's possible and common to achieve it).
I use Visual Studio 2012, works on Windows 7 x64.
If you run a listening server behind a router, you must configure port forwarding rules on the router if you want outside clients to reach the server through the router. You cannot avoid that. However, if the router supports uPnP (Universal Plug and Play), your server code can configure port forwarding rules programmably, such as with Microsoft's IUPnPNAT interface. Otherwise, you have to use the router's own configuration software (usually an HTTP interface running on the router itself).
You also have to configure ports/permissions on a local firewall, if installed. Some firewalls have APIs for that, such as Microsoft's Firewall.
Online games and other peer-to-peer apps employ several NAT Traversal techniques to get around NATs, firewalls, etc. Hole Punching, Role Reversal, etc. Do some searches, information is readily available.

Communication between two computers without opening ports, using a third computer to set up the connection

Let's say I have a server, and two clients connected to it. (via TCP, but it doesn't matter)
My goal is to allow a direct connection between those two clients. This is to allow direct voice contact between two players, for example, or any other client plugin they may have installed which don't need server interaction (like playing some kind of random game between the two). The server can be there to help setting up the connection.
From duskwuff's answer, I got several leads:
http://en.wikipedia.org/wiki/STUN which describes an algorithm to do that, and
http://en.wikipedia.org/wiki/UDP_hole_punching
From those, I got more leads:
http://www.h-online.com/security/features/How-Skype-Co-get-round-firewalls-747197.html
http://nutss.gforge.cis.cornell.edu/stunt.php -- A possible STUN implementation with TCP
With time, I could surely work out something for my program. For now I'm using C++ and TCP (Qt Sockets or Boost sockets), but if needed I don't mind doing UDP in C and wrapping it.
The bounty is there for any programmer having experience with those in C and C++ that may give tips to make this easier, by linking to example programs, updated libraries, or any other useful information. A documented, flexible & working C++ TCP implementation would be the best but I'll take what I get!
Punching TCP holes in NAT is sometimes/often possible (it depends of the NAT behavior). This is not a simple subject to learn, but read the corresponding chapter about NAT traversal from Practical JXTA II (available online on Scribd) to understand the nature of the issues to solve.
Then, read this. It comes from the guy who wrote that: http://nutss.gforge.cis.cornell.edu/stunt.php (one of the links in your question).
I am not a C/C++ specialist, but the issues to solve are not language specific. As long as you have access to TCP from your code base, that's enough. Keep in mind that implementing UDP traversal is easier than TCP.
Hope these tips help.
P.S.: I am not aware of a C/C++ implementation of the solution. The code mentioned in Cornell's link is NOT operational as confirmed by the author. I tried to resuscitate it myself, but he let me know it was completely tweaked for research purposes and far from production ready.
I'm not aware of any way to reliably punch through firewalls for TCP, but there's a similar method for UDP traffic that's pretty well documented:
http://en.wikipedia.org/wiki/STUN
http://en.wikipedia.org/wiki/UDP_hole_punching
A few links to projects that might be of interest or helpful:
http://sourceforge.net/projects/stun/
http://udt.sourceforge.net/
http://www.telehash.org/
You're looking for rendezvous server for NAT hole punching: the server that is publicly accessible (not behind NAT/firewall or they are properly configured) to help computers behind NAT/firewall to establish peer-to-peer connection.
UDP is more popular in NAT punching because provides much better results than TCP. Clear and informative description of UDP NAT hole punching can be found here.
If you need reliable communication, you can use reliable protocols over UDP:
SCTP (libraries) - standardized one, or
one of many custom protocols, e.g. RakNet (I used this library, it's quite mature and feature-rich and has NAT punching implementation), Enet or many others (Q8)
Ephemeral ports won't magically eliminate the need to relay through the server, because they are only valid during the life of the session opened through a well known service port. Basically ephemeral ports depend on a server session.
You will need to use the server to relay communications between both clients, that is act as a proxy server. One option would be to setup a SSH tunnel through a SSH proxy server, with the added benefit of security.
Still this doesn't guarantee that the firewall won't block the connection. That depends on the firewall type and configuration. Most residential routers that act as firewalls, by default block all incoming connections. This is normally fine because most of the time the computers behind the firewall act only as clients, which initiate the connections to the outside. And this setup varies, because some restrict initiating connections only to well known service ports like HTTP, HTTPS, FTP, SFTP, SSH, etc., and if your proxy server uses a non-well-known-service port then the connection will be blocked.
But firewalls can be setup to block outgoing traffic also, this is most common in corporate networks, which don't even allow direct connections to web servers and route everything through proxy servers, in order to control resource usage.
You can also research on the use of UPnP to open ports dynamically.