I am writing a peer-to-peer binary socket program. There are only two endpoints. One socket is listening on my laptop system. The other socket is broadcasting from my desktop system. I have a third program running on a hosted server, that is available to broker the connection between the two. My problem is that when the laptop and desktop are on the same network, they both have the same internet IP address but different intranet IPs, but when the laptop is on the road, then the IP addresses are different. In order to be truly peer-to-peer, I have to write it so that after the connection is established, that the two computers communicate directly between one another. How is this generally accomplished, when the two computers could potentially share the same IP address, if they are running on the same network?
Your question is really: how do I deal with network address translation in a P2P system?
One possibility is to require holes poked in the NAT/firewall systems--that will ensure that requests to a given port are sent to a given computer. Allowing multiple clients inside the network would require poking multiple holes and configuring each client with the corresponding port.
Another possibility involving UDP is here--I haven't reviewed it enough to know if it really removes the broker from the equation after a handshake.
As always, Google can be your friend.
Related
I am sorry, I dont know if this question is already asked (afaik this wasnt asked based on my search results). I have a computer running a software that needs license from a server in my company's domain. For pulling the license, I need to connect to the company network. Also there is a hardware setup in our company which is not integrated to the network. And I need to process some data from the hardware, and the data has to be shared with the software. So, I make two connections, one ethernet connection to the hardware and other wireless for using the software's license. I tried accessing the data from the hardware in the software through hardware's IP address. The problem is, there is another computer in our company from another location sharing the same IP as the Hardware, and the software tries retrieving the data from that computer and fails. I am sorry, if this is priliminary and I am not a networking person.
Simply put, one of the two systems need to change its IP address.
The alternatives are usually too complex and error prone, and their viability depends on the particularity of your environment:
Use arp command to force your PC IP-Mac mapping
Put a router in front of your hardware that does port forwarding
Use VLANs
Is there a mechanism or protocol for a TCP connection, or more fundamentally a UDP or IP communication session, between nodes behind the NAT of the same public IP, to discover the fact that the are in the same LAN and then switch to a shorter and faster local connection? If so, what is it?
I have tested several video/voice chatting apps and remote desktop apps. For some of them, if you cut the Internet connection, the chatting or RD session continues to work, while for some others it just stops working. The lag is very little and it doesn't feel like there is a relay server, so I assume for all of them they use a direct connection between the 2 nodes and the difference is that some of them use local connections and some others use public connections. However my assumption might be wrong. So I am wondering how this works and if I want to create an app to support this (automatically detect if 2 nodes are in the same LAN and switch to a local connection if possible) how I am going to do this.
I am a rookie in computer networks, so excuse me if there are any amateur expressions.
The protocol LSD (Local Service Discovery) will meet your demand. You can first use this protocol to find neighbor peers in LAN, and then use some other protocols like DHT to find peers which are not in the LAN.
I'm trying to develop an applicaton for p2p communication between two android devices. In order to punch a hole through my NAT(s), I'd need to know my external ip address and port.
To that end, I've developed a java server on GAE to report my "remote" ip address and port. The problem is that on GAE I can get my ip address, but not my port. Without it, I'm unable to successfully punch the hole.
So, my question is what's the best, free method to find out my external IP address and port?
That's a question that has no answer with TCP.
Here's the problem: your "port" is not a fixed value. You don't have "an" external port. You typically get one dynamically assigned for each outbound connection.
As answers you should see from the test sites posted in another answer clearly indicate, it's a moving target (though it may stay stationary for a short time due to the browser using HTTP/1.1 keepalives and actually reusing the same connection, not just the same port)... but if you hit the site repeatedly, you'll see it either drift around randomly, or increment. Trying it from two different web browsers on the same machine, you'd never see the same port number -- the port corresponds to the specific source connection, not the machine sourcing the connection.
Sometimes, you may find that it's the same port number as the port your machine's stack opened for the outbound connection, but even when it is, it doesn't matter, because no traffic should be able to return to your machine on that port unless it is from the IP address and port of the machine to which you made the outbound connection. Any decent network address translating device would never accept traffic from another source IP address and/or port, other than the one you addressed in the outbound connection.
There is no standard, simple, predictable, reliable, or consistent way to punch a hole in TCP NAT and then exploit that hole for a peer-to-per connection. To the extent that such things are possible in a given NAT implementation, that is an implementation that is shoddy, broken, defective, and insecure.
See also: https://www.rfc-editor.org/rfc/rfc5128
Sounds like your app could use a STUN server to get its external address.
I'm currently working on the UDP networking of a game.
Let's say there are two players on the same NAT/LAN. They consequently share the same external IP. They both join the same game server which is at another location and has a different external IP.
How can the game server send UDP packets to a specific player over the LAN?
Everything is fine when every player is on a different LAN, but when two or more are on the same LAN I know don't how to reach them.
BTW I'm using C# but I guess it doesn't really matters here.
By your description I assume their access to the server is through a NATting device. In this case you don't have anything to do, the two clients will be seen coming from the same IP address but different source port, hence easily distinguishable.
Some background first. I have a .net client agent installed on each of the machines in the lan. They are interacting with my central server [website] also on the same lan.
It is important for my website to figure out which of the machines can talk to each other. For example, machines of one subnet cannot directly talk to machines of another subnet without configuring the routers and such. But machines in the same subnet should be able to talk to each other directly.
The problem I am facing is when the lan setup is like in Figure 1.
Because Comp1, Comp2 and Comp3 are behind a router, they have got the ipaddress 192.168.1.2 till 192.168.1.4. My client agent on these machines report the same ipaddress back to the server. However, machines Comp4, Comp5 also have the same ipaddresses.
Thus, as far as my server is concerned, there are 2 machines with the same ipaddress. Not just that, because the subnet mask is 255.255.255.0 for all machines, my server is fooled into thinking that Comp1 can directly talk to Comp5, which is not possible.
So, how do I solve this? What do I need to change in my client or in my server, so that I can support this scenario. These two are the only things in my control.
EDIT: Seems that the network diagram
is over simplified and there could be
multiple router/subnet levels. My
original answer will not handle this
scenario. Also, with the restriction
of modifying only the client app or server
app and not tampering with the
routers and firewalls makes
it more difficult.
EDIT2: Using 'arp -a' you can extract
the MAC address of the router. If the
client apps can manage to do this then
the puzzle is solved!
The client app knows the local machine address and passes it to the server app.
The server app knows the remote address when a connection comes in. This would be machine address or a router address.
From these two values you can work out what you ask.
For example:
Server app receives connection from 10.10.10.2 with client supplying 192.168.1.2
Server app receives connection from 10.10.10.3 with client supplying 192.168.1.3
The 'remote address' distinguishes the subnets.
So, all you need to figure out is how to extract the remote address of a client connection. If you are using any of the popular web technologies for your server app then this is very easy.
One approach is for the individual client machines to determine who they can see using a broadcast message. Have each client listen on some particular UDP port, and each client broadcast its presence to whatever the local broadcast domain is. When clients can see each other in this way, they can probably also make TCP connections to each other.
If the server needs to know which clients can talk to each other, just have the clients tell the server.
If the network diagram is complicated enough I think if would be very difficuilt to find what you need.
You should also take into account that Comp1 can establish direct connection to Comp6.
The solution I can suggest is probing. Client receives list of all other clients from server and tries to establish connection to each of them. I think that would be the only way to know which clients are REALLY accessible assuming any number of routers/firewalls/NATs in the network. Doesn'r scale much for a big number of computers of course.