I am required to implement a p2p communicator and read about nat hole punching. There are a few questions I don't quite understand:
Do I really require a server if I know the public IP address and destination of my peer?
In real life scenario, does it really work and what are some network policies that may cause it to fail
For Skype, why does it optionally also require 443 and 80 if theoretically works for any Ports?
The main purpose of a server is for helping to detect how private addresses are translated into public adresses, and this is only visible from outside the LAN.
Do I really require a server if I know the public IP address and destination of my peer?
No.
In real life scenario, does it really work and what are some network policies that may cause it to fail
Unless the port your are trying to reached is bloqued by a firewall, there should be no issue if you know the public address of your peer.
For Skype, why does it optionally also require 443 and 80 if theoretically works for any Ports?
Because those ports are usually open (i.e., not blocked by NATs/Firewall), while others are not necessarily open.
Related
Given the following scenario:
Computer A connects to a public server from behind a firewall.
Computer B connects to the same public server from behind a firewall.
Now, is there any way for Computer A to talk directly to Computer B using those outbound connections without sending all data through the server?
Can the server link those connections somehow?
Two peers, talking to each other, using outbound connections instead of dealing with inbound firewall issues.
Possible, yes. Easy, no.
At least one of the firewalls needs to be updated to forward a port on the external IP to a port on the machine behind it. The other machine can then connect to that port to open a bidirectional TCP/IP connection.
To accomplish this, you can make use of UPnP on the firewall to accomplish "hole punching" or "NAT traversal".
Once the firewall port is open, you forward that port number over the public server and pass it along with the public IP address already known to the server along to the other machine. It can now create the connection.
I don't think that it can be achieved mate. Unless you have access to the public server network and create a route to direct incoming A directly to the B and vice versa.
I've been investigating networking for use in a two-player game I'm writing, and I'm still not clear on when a device must have a port forwarded in order to communicate with the outside world.
From what I've seen in other games, port forwarding is always required in order to host a server, but is not required on the client. In addition, there are other situations, such as skype (which, to my understanding is ultimately client to client), where neither end must forward a port.
So my question is, in over-the-Internet communication, when is and isn't port forwarding necessary, and what steps can i take as a developer to make it so my users don't have to worry about it? Thanks in advance!
Port forwarding is needed when a machine on the Internet needs to initiate a connection to a machine that's behind a firewall or NAT router. If the connection is initiated by the machine behind the firewall, the firewall/router automatically recognizes the reply traffic and sends it to the machine that opened the connection.
But if a packet arrives on the external interface, and it's not a part of such a connection, the router needs to know what to do with it. By default, it will reject it. But if forwarding is configured for the port, that tells it what internal machine to send it to.
Put another way: you need port forwarding if you want to run a server behind the NAT firewall/router, you don't need it if you're just running a client.
There is reason why Skype don't (not always) need manual setting of port forwarding:
When you install Skype, a port above 1024 is chosen at random as the
port for incoming connections. You can configure Skype to use a
different port for incoming connections if you wish, but if you do,
you must open the alternative port manually.
If the port chosen for incoming connections becomes unavailable, by
default ports 80 and 443 will be used as alternatives. If another
application (such as Apache HTTP server or IIS) uses these ports, you
can either configure the application to use other ports, or you can
configure Skype to not use these ports.
Port forwarding is must if you host a server.
You can use same technique as Skype...
I am not sure if there is any other option...
Port forwarding (occurs) when a NAT, firewall or some other device blocks communication on all or some ports.
To answer your question as an example, most commercial routers use NAT to allow multiple people to use the same IP(As view from the outside world) provided by ISPs. Most ISP's use NAT to allow multiple customers to use the same IP(As viewed from the outside world). To get this to work, the NAT changes the internal IP and the port number of a communication to THE(there is only one for the entire sub network) external IP and a new port number. By doing this, the router/isp/ect can tell which internal IP and port each external communication goes to.
Anytime one of the computers communicating over the internet are behind a NAT, port forwarding is required. I'm sure there are way more situations than this, and the solution to each can be quite complicated. But this covers the vast majority.
I have an application that relies on IP addresses for communication (Domain names simply does not work. :(... )
Its function is to connect to its peer on the other machine and send data over after establishing trust. During the "trust establishing" phase they both exchange their IPs for future communication. They both are behind the two different firewalls and are NATted. One is in our NATted office network and other is in the cloud NATted behind their firewall. The applications knows their respective private IPs and exchange that (the 10.x.xxx.xxx range), when they try to connect back to each other (using the private IPs with range 10.x.xxx.xxx) for transferring data they fail. The connection is TCP and the port range is pretty varied.
I am curious if there is anyway I can hard code (for this one time) a rule (at may be firewall level or some place outside my application) that says if there is a connection being initiated for IP address 10.x.xxx.xxx then redirect it to 205.x.xxx.xxx?
Private IP address ranges like 10.x.y.z are, by their very nature, private.
You can't do any meaningful resolution unless each node in between the endpoints has rules in place to translate these.
Translation is tricky, all the main tools you would use cater for static translation (port forwarding, e.g. where a particular port is forwarded to a particular IP). This is one avenue, but it is a hacky one (it requires you to open lots of ports, procedurally update your router and probably have some sort of broker server to maintain mappings).
Alternatively, you could run the isolated networks over a VPN, which would give your endpoints mutual private IPs which you can use to connect to eachother. It would simply be a case of binding to this new address and communicating across the VPN. This would also potentially encrypt your communication over the internet.
Other possibilities are to use NAT/TCP punchthrough techniques which can allow traversal, but these are really a patch to a broken network topology (Read up on IPv6 to see how this can be alleviated).
Alternatively, you could route all the connections over a proxy, but this will complicate matters compared to a VPN.
To answer the question about hardcoding a rule, port forwarding is the solution here. It will obviously depend on your router configuration for the peer accepting the connection, but this client should have the port target port forwarded to the machine. This will obviously not scale very well and is really shifting to a server/client architecture for one connection!
Depending on your hardware, you may be able to forward a range of ports (if a single port cannot be established) and limit the port forwarding to certain incoming connections (the external IPs).
Information on port forwarding can be found at http://portforward.com/
This sounds a lot like what you'd want out of a VPN. Is there anyway that you could set one up? Basically the Site-To-Site VPN between you and the cloud would say 'oh hey, here is an ip located on the remote network, go ahead and connect through the link'. Would this kind of solution work in your case?
Something along these lines: http://i.msdn.microsoft.com/dynimg/IC589512.jpg
I'm writing a P2P application. Peers regularly ping a main server to update their current IP/port, so when a peer wants to reach another one it can ask the server for that information. For now peers use UPnP to configure the NAT (for classic home setups) to be accessible from outside.
So everything works, except when a peer's client tries to reach another (or the same) peer's server and both are behind the same NAT. Since in that case the client is trying to reach its own "external" (public) IP address from behind the NAT, the NAT doesn't do the port forwarding and is unable to route the IP packet.
For now I'm thinking of two solutions:
query the NAT with UPnP to see to which local IP the port is forwarded
store on the main server the internal IPs of the peers
Can you think of other solutions? What strategies do mainstream P2P applications implement to solve this problem?
Since in that case the client is trying to reach its own "external"
(public) IP address from behind the NAT, the NAT doesn't do the port
forwarding and is unable to route the IP packet.
This is known as the hairpin condition. Not all router/NAT solve this properly. The solutions are:
a) Check whether your router/NAT can be configured to enable 'hairpining'. This solution works iff you control all router/NATs in your deployment.
b) Buy another router/node allowing this. Just like a), it works iff your control all router/NATs in your deployment.
c) If you can get obtain the port information for from UPnP, this is a solution too, but not all Router/NAT know or support UPnP. It does not cover for all cases in large deployment.
d) Using multicasting to 'discover' other nodes on the LAN and even communicate with them is a common solution to this problem. You need to agree on an IP address and have peers listen to it.
e) Storing the private IP address on the server is a solution too, but it requires more storage capacity on the server than solution d. There is a timeout (i.e., expiration of data validity) to handle too.
f) Use a TURN like communication between peers (i.e., communication between nodes pass through central server). This solution is rock solid, but not the most efficient in terms of bandwidth consumption.
Hope this helps.
Interactive Connectivity Establishment (ICE) was specifically developed for solving that type of NAT problems. It uses STUN and TURN to achieve the result and is used in modern p2p applications. (e.g. Voicechat)
The PJNATH library has a document explaining
unlike standalone STUN solution, it (ICE) solves the hairpinning issue, since it also offers host candidates.
Which of the following ports is the best one to use for a program. I'm working on using a custom protocol still under development. I'm looking for one that will be accessible to virtually every host that is connected to the public Internet (that is, every host that can view websites can use this port). The three main options are:
port 53 UDP (DNS)
port 80 TCP (HTTP)
port 443 TCP (HTTPS)
Which of these is most widely accessible over the Internet, including all ISPs, corporate firewalls, etc.
All of those ports are used by well-known services, and you should use none of them (if your product is not a webserver or a DNS server.) DCCP Well Known ports SHOULD NOT be used without IANA registration. If your service is commercially viable or has benefits for the network as a whole, consider registering it for a lower port number: The registration procedure is defined in RFC4340, Section 19.9.
For experimental use, use a port between 1024 and 49151. Remember that even those ports should be registered with the IANA as soon as your service goes "live".
Regarding firewalls: You cannot predict if your service will be available to any network at all. Even if you use port 80, you probably will run against firewalls that do content checking.
Not port 53. Toss-up between 80 and 443. If you make your protocol look sufficiently like HTTPS that a proxy will forward it the same way, then maybe 443 is your best choice.
As all the ports you've nominated are used for particular well-specified protocols, it's a very bad idea to use these for a different protocol. There's a convention that for a well-known port, there's a corresponding protocol, and if you break this convention, then at the least you're going to cause confusion, and at worst be suspected of nefarious intentions and be blocked. Martin's answer points you in the right direction.