How to create a socket connection over nat from public end - sockets

I feel this question is best started with a simplified version of the scenario.
Server A is connected to the public internet.
Server B is in a private Network and uses network address translation to connect to the internet.
I own both servers and can edit the software on them.
The ip addresses of the servers and the nat router are known to me.
Using Winsock, I need to create a connection between them. I know enough about winsock for this to be trivial if the connection is started from server B, but I need server A to start the connection.
I want to avoid using additional libraries if possible as it would appear to me that I only need to figure out what ip and port server A needs to use when starting the connection.
What additional information do I require, How do I acquire it, and How do I act upon the information.
note: I have investigated other similar questions, but none of them addressed this situation. I am not sure if this should have been asked on server fault or another site, but if so please say which one before flagging as "off topic" instead of closing the question wordlessly.

You need to setup port forwarding on the NAT device to the machine on the private network. Exact steps are device/manufacturer-specific, but here's the general idea:
Pick a port number, configure the NAT device so that connections to its public IP and that port are forwarded to the IP of your private server and the port where your application is listening.

Related

What does it mean to connect to a certain port?

For example, when you make an ssh connection, you are connected to port 22. What happens then? On a very high level brief overview, I know that if port 22 is open on the other end and if you can authenticate to it as a certain user, then you get a shell on that machine.
But I don't understand how ports tie into this model of services and connections to different services from remote machines? Why is there a need for so many specific ports running specific services? And what exactly happens when you try to connect to a port?
I hope this question isn't too confusing due to my naive understanding. Thanks.
Imagine your server as a house with 65536 doors. If you want to visit family "HTTP", you go to door 80. If you were to visit family "SMTP", you would visit door no. 25.
Technically, a port is just one of multiple possible endpoints for outgoing/incomming connections. Many of the port numbers are assigned to certain services by convention.
Opening/establishing a connection means (when the transport protocol is TCP, which are most of the “classical” services like HTTP, SMTP, etc.) that you are performing a TCP handshake. With UDP (used for things like streaming and VoIP), there's no handshake.
Unless you want to understand the deeper voodoo of IP networks, you could just say, that's about it. Nothing overly special.
TCP-IP ports on your machine are essentially a mechanism to get messages to the right endpoints.
Each of the possible 65536 ports (16 total bits) fall under certain categories as designated by the Internet Assigned Numbers Authority (IANA).
But I don't understand how ports tie into this model of services and
connections to different services from remote machines? Why is there a
need for so many specific ports running specific services?
...
And what exactly happens when you try to connect to a port?
Think of it this way: How many applications on your computer communicate with other machines? Web browser, e-mail client, SSH client, online games, etc. Not to mention all of the stuff running under the hood.
Now think: how many physical ports do you have on your machine? Most desktop machines have one. Occasionally two or three. If a single application had to take complete control over your network interface nothing else would be able to use it! So TCP ports are a way of turning 1 connection into 65536 connections.
For example, when you make an ssh connection, you are connected to
port 22. What happens then?
Think of it like sending a package. Your SSH client in front of you needs to send information to a process running on the other machine. So you supply the destination address in the form of "user#[ip or hostname]" (so that it knows which machine on the network to send it to), and "port 22" (so it gets to the right application running on the machine). Your application then packs up a TCP parcel and stamps a destination and a return address and sends it to the network.
The network finds the destination computer and delivers the package. So now it's at the right machine, but it still needs to get to the right application. What do you think would happen if your SSH packet got delivered to an e-mail client? That's what the port number is for. It effectively tells your computer's local TCP mailman where to make the final delivery. Then the application does whatever it needs to with the data (such as verify authentication) and sends a response packet using your machine's return address. The back and forth continues as long as the connection is active.
Hope that helps. :)
The port is meant to allow applications on TCP/IP to exchange data. Each machine on the internet has one single address which is its IP. The port allows different applications on one machine to send and receive data with multiple servers on the network/internet. Common application like ftp and http servers communicate on default ports like 21 and 80 unless network administrators change those default ports for security reasons

Communicating between networks using sockets

I have a question about network connections among computers.
I've made some applications where messages pass through the Internet (via sockets) to make a connection between two devices. However, a strong condition is that two devices must be connected to the same network.
Can anyone give me a trick how to create a communication using sockets between two computers even if they are connected to different netwkorks?
Thank you in advance.
Here is a great tutorial on how to use sockets and general networking
(in java) http://www.thenewboston.org/watch.php?cat=25&number=38
In order to communicate between two diffrent networks over the internet, you will need to do something called port forwarding. What that does is that when your public IP of your network receives a packet with a spesific port number. The router knows where to send that packet to which local IP.
If you dont port forward and receive some data. The router doesent know where to send the packet. Therefore it discards it, which means others wont be able to connect to you.
You will only need to port forward the network with your server (using the example i linked). How you do that is by logging in to your router, and say that a port which the server uses gets forwarded to the IP of the PC hosting the server.
On the other network (client) you will need to change the IP address of which the client shall connect to. That IP address needs to be your public IP of your server's network. You can find that by connecting to the server's network and go to: http://www.whatsmyip.org/ . Keep in mind that public IP addresses may change over time.
Hope this helped!
-Kad

Why can't my socket programs connect to the internet?

I have begun my first course on networking this semester.
My problem is that whenever I try to connect my socket to a host outside my LAN,
network unreachable error is returned. Whether they be BSD sockets or Java sockets.
Moreover, my nmap probes also return the same error.
Once I asked a similar question here about ping probes and the answer was that my LAN proxy is rejecting ICMP requests. But there are no ICMP requests in establishing TCP connections right?
Why, on the other hand, my browser can connect to any host... although that it uses the same proxy...
Also,(please pardon me for this long doubt) when I give host name as www.google.com in my sockets, "unknown host" is returned. But my browser happily recognizes the same host.
Thank you in advance...
import java.net.*;
import java.io.*;
class Whois {
public static void main(String args[]) throws Exception{
int c;
Socket s=new Socket(args[0],Integer.parseInt((args[1])));
InputStream in=s.getInputStream();
while( (c=in.read()) != -1) {
System.out.print((char) c);
}
s.close();
}
}
Unfortunately, there may be many reasons for this behavior.
My best shot is that you're behind a firewall that's blocking any connections that are not going to port 80. In this case, you may try to connect with your program to the same network, but port 80.
Not sure why you wouldn't get name resolution for google. I'm guessing it's a bug in your code, but can't tell for sure.
Hope it helps.
Investigate and understand your network setup. How are you connected to the internet? Your workstation probably has a default route pointing to some machine again probably doing Network Address Translation (NAT) and/or running a firewall and maybe that proxy server. Find out how you do name resolution (DNS). One you figure these out you might find what you need to do to connect outside.
On the other hand, errors in the code we don't see in the question are also likely :)
There is likely a firewall that is blocking all connections to outside hosts, and an internal DNS server that does not lookup external hostnames. THis is why your socket programs can neither lookup outside hostnames nor connect to outside services.
The same restriction applies to your browser; it's just that your browser is set up to use a proxy server. This means that the browser isn't directly looking up outside hostnames or connecting to outside hosts - it is only looking up the proxy name and making TCP connections to the proxy server. The proxy then is doing the hostname lookups and making the TCP connections to the outside world, on behalf of your browser.

Peer to peer over 3G

Hey I'm trying to get a CFStream connection going over 3G. I can get it working over wifi using the host name, but when I try to connect directly to the ip address it fails.
Is there a guide out there on how to connect over 3G?
Thanks
ASH
You can use NAT traversal in some cases. This is not a guaranteed method and depends on the type of NAT so you will still need a relay server if you want to guarantee connectivity.
A general rule is if both clients are behind symmetric NATs then a relay server is required.
If only one NAT is symmetric then STUN, ICE, methods can be helpful in establishing P2P connections.
The following might help you:
Interactive Connectivity Establishment see en.wikipedia.org/wiki/Interactive_Connectivity_Establishment
PJNATH Open source project for NAT traversal in SIP/VoIP solutions see PJSIP.ORG
When you are connected to 3G then you are usually behind a router that implements some 'NAT' scheme. This means that your iPhone gets a private internal IP address on the inside (the 3G network) and a shared 'real' public IP address on the outside (the Internet).
This is all fine when you are just a client connecting to services on the Internet, but it will fail horribly when you try to connect to other clients in the same situation.
There is no simple solution for this. Programs like Skype work around this problem by using intermediate servers with public IP addresses that can relay network traffic between hosts behind such 'NATted' networks.

connecting to a private ip

I want to connect to a system which is behind a router. I know the public address of the router as well as the private ip (fixed always) of the system. How do i establish socket connection with the private ip?
This is why some people say that they are behind a "firewall", when they are behind a router. The Evil Viruses Of The Internet are not able to exploit any software on a computer behind a router (provided that the router admin didn't configure it in the funny way, for example by enabling DMZ).
You still have some options:
Talk to the router admin and make him forward a port for You
Take the router out and put Your "target" computer where Your router was, or enable DMZ (this only makes sense if there was only one computer behind the router). Warrning: install a firewall on the target computer first!
Turn the socket 180 degrees. Make the computer behind a router establish the connection to the server that has a public IP address
Use something like UPnP, if Your router supports it
Get a dedicated IP address for Your computer and configure router to switch all traffic to this IP address to Your computer (this is similar to DMZ, but would work if You have more than one computer behind the router). Warrning: install a firewall on the target computer first!
Use NAT traversal. There is a very good article on the subject here. Simplified version is that client establishes connection to some remote server. The server can see the opened port number on the client's router and this port is assigned to the client's machine, so it (or some another computer sharing this information) may establish connection to that port and reach the client's application. Warrning: this doesn't work with all routers. Some routers just won't let this happen.
The simplest thing is probably to forward the port from the system you want to connect to through the router.
This is more a question of configuration of the router as opposed to your actual program. If the router isn't configured to forward traffic to the private system, there's no way to force it to connect you - rather, the private system would have to open the connection on its own.
Strictly speaking, the answer to your question is "you can't". You can however enable DNAT (Destination Network Address Translation) on your router. You connect to a certain port on the router, and it forwards the connection to the internal ip. The internal ip (and port) are configured in the router settings and are not known by the connecting client.