C++ sockets: communication between PCs over internet - c++

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.

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.

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.

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.

Making my TCP server Internet-facing - where should I start?

I have written a client/server code.
The server program executes on a terminal which plainly receives text data from the client and the client is a GUI where in you could specify the IP address of the machine where the server would be running.
However this works only in a closed Network(LAN).
I have just learnt TCP IP and have written a few codes that run on a LAN.
I wanted to make this program work across the network(over the internet).
But I have some basic doubts like,does one need the permission of the local ISP for such programs to execute across the internet.Does it involve buying a domain or some kind of permissions?
Can some one please help me on,what should I be doing,or where should I start from?
Listener have to have IP port opened in some way. If you are behind router, you should set proper port forwarding on router and if ISP provides its own subnet, you should know how to setup such link. (i do not know what kind of tehnology ISP might use for this).
For beginning you do not need you own domain name but you should be able to address by ip. If you need domain, register own domain name or create subdomain for free (i was using http://freedns.afraid.org/ )
If your server is behind a router which creates a LAN, you have to configure the router that it will forward the packages from your client to the server.
You have to forward all the incoming packages at the specific port to the local ip of the server.

Windows Peer to Peer Global_ Group without third party ipv6 tunnel

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.