I am very interested in at least trying to implement NAT break through for my senior project.
(I am doing a networking API).
It's not even a requirement of my project, just a interest of mine.
I know the basics of how it works, correct me if I'm wrong:
Two clients connect to a server that isn't behind a NAT and this server, knowing the IP of these two clients, tell the clients to connect to each other at the same time. Thus the "Breakthrough".
This seems not terribly easy or terribly hard to code.
However, the part I'm stuck at is the testing of this. Is there a reasonable setup I can do with just one router/one NAT and my three available computers?
Thanks for any advice!
In terms of code/theory on NAT breaking, I cannot offer advice, but I can make some suggestions on setting up a test environment.
You can download a copy of m0n0wall and run it inside of a Virtual PC image (both free). This will give you a second router w/out purchasing any additional hardware. With this extra router, you can create a seperate subnet for your two clients.
Another, easier to grasp option is simply to pickup a second router, you can get a good one pretty cheap.
Then setup your existing router and server as they are now, a 192.168.1.x /24 subnet; then setup your second router (m0n0wall/hardware router) as 192.168.2.x /24 subnet, and plug the second router's "internet" port into one of the "PC" ports on your first router. Then plug both clients into the second router.
(I realize thats a bit confusing, comment if you cannot follow what I mean)
Let me see if I have this straight. You have two clients that are both behind NAT and a server that is not. Both clients connect to the server and are informed of the public facing IP address of the other. Since each now has a destination, they disconnect from the server and connect directly through their respective NAT boxes to each other. Is that your thinking? If so, I may have some bad news for you.
In order for this to work at all, you will have to have dedicated ports set up in each NAT configuration to forward at least one external port to a predefined internal IP address/port number. In a generic NAT setup outgoing connection requests will be captured by the NAT which will open a temporary external port. That external port number is used only for communications to that one originating address and port. When the connection is closed, that external port goes away and will be reassigned for another connection later. So if both clients talk to the server and then disconnect, the information the server sent them is now invalid.
Assuming you've worked around this somehow, it should be fairly easy to just connect both clients to the "internal" side of the NAT and the server PC to the "external" side. Then you have to hope that your NAT box is smart enough to loop back packets from one local external port to another. I'm sure that netfiler could be configured this way but I doubt a home internet "router" (e.g., Linksys, NetGear, etc.) would do it of the shelf.
Related
I'm having difficulty finding help resources on this. I know how to use the TCPClient class to create a connection between one IP/Port/machine and another.
My doubt is how does that work when one machine wants to initiate a TCP connection to another machine where the destination machine is inside a different network. So the destination network may have hundreds of computers each with its own private ip and the network would have one public IP address. This would be using the TCPClient class or any other that is more appropriate.
I know we could use ports and then inside the network the port could be forwarded to the correct machine but I was looking for a solution like the one services like LogMeIn use. Basically I wanted to use port 80 always and then initiate the connection from the server to that particular machine or others on the same network when I needed.
I suppose, theoretically, I could create the connection first from inside that network, then on the server, save the details and close the connection and then in the near future, when I needed, I would re-open the connection.
So in my scenario, I would have many clients across multiple networks, each network might have multiple internal machines with a client installed. Then on the server I would initiate connection to these machines when needed. Within each network I would want to use port 80 for obvious reasons. The reason I want to initiate the connection from the server and not the client machines is simply to save resources, I couldn't cope with having opened connections until eventually I might need to communicate wit them.
Also, I have no control on the client networks besides them having my client installed.
Ideally, I wish to have c# info, possibly code and not network configuration.
I had this requirement at a previous company. We installed our client/server software (C# based) on numerous different networks with a mix of public/private IPs. I found two relatively simple ways to solve it. First, I want to say that without a public IP, its impossible to connect reliably (in my experience).
When I proposed the solution, I explained the problem to other developers/managers this way.
Your server, the machine with the public IP address [public to clients, but may still be an "internal address"], is like a house without any long distance calling. It can receive calls, but it can't make any calls. The clients are like houses with long distance service. Clients must call the server, because they have long distance. Once connected, any party can talk on the line.
From here you have two choices.
Client connects and never disconnects (this is what I implemented). On the server, I had an object that mapped the client object to the client connection so I could communicate any time with a client that was connected.
Server holds a queue of messages for the client. The client automatically connects on a fixed interval to see if there are any messages (maybe 5 minutes). There would be an option from the server to stay connected for a specific interval. Another vendor called this "fast talk".
There's a couple of approaches.
You could setup NAT - probably no good for your scenario.
You could make an outbound connection from your client.
You could "combine the above" by using STUN (see http://en.wikipedia.org/wiki/STUN) this is quite popular in VOIP for peer to peer scenarios.
The Windows Azure servicebus may have a solution for your problem; NetTcpRelayBinding in hybrid mode allows two comuters behind NAT to create a direct connection with each other. This might not solve your problem if you are money constrained as each connection has an associated cost.The simplest solution is probably to have the clients polling your server.
You may use SignalR, which has been developed for this kind of scenarios.
You must have a third party, though (a server which broadcasts messages from sender to other peers).
But the beauty of this technology is that it chooses the most appropriate way to push data to clients: Polling, long connections, sockets... etc.
This provides an abstraction layer which is quite comfortable.
It has been designed to interact with javascript clients, but may be used in full-C# clients as well.
You need a third server that acts as proxy between your machine and target machine that is behind a firewall.
That is how applications like LogMeIn work.
You can do this using SSH tunnels.
Please check https://serverfault.com/questions/285616/how-to-allow-remote-connections-from-non-localhost-clients-with-ssh-remote-port
The topic is about NAT traversal.
STUN is good choice to try to communicate with client behind NAT.
But if STUN don't work,you can use RELAY service to help to pass the message between your server and remote client.RELAY service is a public service that everyone can reach it.
That's it. It's a newbie question, probably. I'm almost giving up on TcpClient/Listener because of NAT and firewall issues. I wanted to know if theres an alternative. port 80 probably doesn't have to deal with any of these annoying things. I hope the answer is Yes.
What about the SignalR over WebScockets
Yes, you can implement WebSockets in a non-browser application, but it won't solve your problem.
When you try to open a server listening to websocket connections, you will run into the same problem you ran into when you created a normal socket connection: Personal firewall solutions will get in the way and not every router will forward the port you've chosen. Using the well-known port 80 won't help you here. It is quite uncommon for normal consumers to have a webserver running behind their NAT router, so by default no NAT router will forward the port unless specifically configured to do so.
A NAT router will generally prevent any hosts behind it to act as servers unless configured to allow it. When you want the users to not worry about their NAT configuration, both users must act as clients. The only way to do this is by having a central server all players connect to.
While hosting a server is still not free, it has become quite cheap due to cloud-based hosters who will rent you small, virtualized servers for very modest prices. The smallest instance from Amazon EC2 only costs you 2 cents per hour or $14.40 per month. Or you can build your own server from some spare-parts and host it on your own internet connection. When you don't have a static IP address you can use a dynamic nameserver service like no-ip or DynDNS.
Yes you can, but please don't.
I would suggest to change your architecture:
Use a server socket as a main point to handle clients. This server has to have a visible IP/port. In this case you may have clients behind nuts, and do not bother.
I've looked around at various C# Packet Sniffing tutorials and have built one that can parse packets sent to and from my computer. This is awesome, but I haven't found anything that relates to intercepting packets from another computer (obviously on the same network), e.g. from a different computer to a router.
Am I correct in thinking that any packets sent by a computer are visible to, not only the router, but any other computers on the same network? If this is the case, does that not mean that intercepting these packets is something we can do in C#?
To those who are desperately copying and pasting links to Wireshark etc. I appreciate your time but this is more of a learning experience for me, so I'd like answers relevant to C# if possible!
In summary, how can I intercept packets in C# that don't concern my computer? E.g. From my laptop to my router?
Assuming you're in an ethernet switched network rather than something funky like a token ring: Even the great Wireshark is limited in what it is able to see because it runs in the same confines as what you're trying to build - its host PC.
Unfortunately, your PC can only see the packets that hit its network interface. This means that in a layer 3 routed network you're unlikely to see any packets that aren't intended for you, unless of course your PC is the router.
You'll need to look into SOCKS5 proxies and the like to achieve the level of network transparency your question infers. While implying a small bit of network and configuration overhead, a proxy will provide you the most visibility into the traffic you're after.
M.Babcock already mentioned in his answer that your computer in a switched network won't see the traffic between two other computer.
Some (managed) switches and routers have the feature to send all traffic to a monitoring port. On this port you can connect your computer and use wireshark/pcap etc. to see the all the traffic that is passing through the switch/router.
Or, if you still have one reachable, put a Hub between Laptop and router and connect your pc to the hub. The Hub will forward all traffic to the other ports, as he doesn't care about the mac addresses.
So this is really not depending on any programming language but only on network management.
I'm working on a simple c# messenger and its works on the local network only. Does somebody know what should i do to make it works on the internet?
The solution contains the server project that listening on a certain port, and a client project connect to the server with that port.
Your clients need to be able to communicate with the server, which means that either:
You need to host the server application on a computer that is directly connected to the internet.
You need to setup port forwarding on the router that controls internet access for your network.
In either case the clients will need to know the IP address to connect to, and any firewall interactions need to be considered. This may also include ISP firewalls, as some ISPs limit inbound connections to subscriber connections.
I won't go into the specifics of setting up port forwarding on a router... there are plenty of examples, and every router is different. Google will help you with this if necessary.
Ideally you should have a static IP address for this, or some method for the clients to locate the IP address that your server is hosted on. If you must run from a dynamic IP address (such as some ISPs still use for subscribers) then one of the Dynamic DNS options might work for you.
In-order to make it work on Internet a simple answer is you need to enable ports which is used for communication.Generally the ports will be blocked by the Companies firewall for security reasons.So contact your IT dept to enable the port.
Or Use common port like 80.
I want to know how I can send or recieve data over internet to/from a computer in subnet
(this is specially in context to PPP users bcoz getting static IP is not so much in practice).
I actually want to create an application which can transfer file between 2 specific computer in WAN.
so what are things I need to know about to do the same..(ex. PRESENT IP or MAC ADDRESS etc..)
PROGRAMATICAL EXPLANATION ALTHOUGH PREFFERED,BUT IS NOT NECCESARY...
FTP?
There is a vast torrent of useful results in google, I seriously suggest to google before you ask here.
For instance, have a look at the top result: http://www.devarticles.com/c/a/C-Sharp/Network-Programming-in-C-sharp/
Apart from that, FTP, as suggested by Colin, may be what you're looking for. If you're new to using FTP in C# have a look at http://www.google.com/search?q=c%23+ftp
Put the information on a public IP server, so both computers keep polling if there is new data and send / download that data as needed. A single text file can hold necessary flags such as paths and other info you need.
server just need to be a web server, which means IIS or similar should be installed.
I'm thinking part of your question has to do with one of the computers not having a static IP address. If the two computers, A & B, don't know each others IP address, then an alternative is to use a server. Either A can store the information on the server to be picked up by B, or A can register his current IP address on the server for B to lookup and then connect to A, assuming firewalls don't interfere. Another scheme is that A and B can simultaneously connect to the server, and the server can relay data between the two.
Of course, all of this communication would be done using techniques such as those suggested by mafutrct and Colin.
This question sounds to me like the difficulties of NAT Traversal and trying to establish peer-to-peer connectivity over the Internet. I stumbled on this question researching the best way to set up Internet connectivity to a device that is sitting behind a firewall. I am assuming that the device behind the firewall has to initiate the connection, that a Internet server application (on a Public IP address) to at least manage the initiation of the connection is required, and the Internet server application may also have to act as a relay if the difficulties of NAT is not able to be traversed.
http://en.wikipedia.org/wiki/NAT_traversal
http://en.wikipedia.org/wiki/Peer-to-peer
A good example of this is LogMeIn. Where the application is installed on the computer that needs to be accessible over the Internet, that application communicates with the LogMeIn Internet servers, you can establish a connection to that computer either by initiating through the LogMeIn servers and connecting peer-to-peer over port 80/443 using NAT Traversal (this would be establishing a peer-to-peer connection) or by initiating through the LogMeIn server and the LogMeIn server acting as a relay if peer-to-peer is unable to be established.
Please note; you must have an application (something running) on both ends of the connection on the Internet, there is no other way. Just like FTP that was mentioned earlier (FTP Client, FTP Server)... but in this case it is peer-to-peer (basically you are writing your own Client and Server... or if you have to use a relay... Client--Relay--Server
http://en.wikipedia.org/wiki/LogMeIn
"The service connects the remote desktop and the local computer using SSL over TCP or UDP and utilizing NAT traversal techniques to achieve peer-to-peer connectivity when available."
The part I don't know is can the relay go in both directions; and I am figuring the device behind the firewall must have to constantly manage the open connection to the Internet Server that is the relay. Those are the questions I am wrestling with now.
Also, you may want to check out this post.
C# byte streams through TCP
From that time, till this date I have encounter so many problems with these four kinds of NAT that basically without an external server you cant do anything.
This is because, one computer can never find where the other one is located as suggested in the pic.
Here PC 'A' will never come to know about the port that corresponds to PC 'B' on R2B without an external server.Even more, if somehow u come to know about the ports you are still in a situation that the router wont allow you to access it if the request hasn't been made for your IP.