STUN server for TCP flow - c#

I am looking for a reliable STUN solution for the TCP flow. I have tried STUNT (by cornell University in the US) and XSTUNT (by a University in Taiwan). But they both seem old and useless.
What I want to do is to transfer files between two clients in two different networks via C#. Please let me know if you have any solution for either of the following:
And UDP-based Client/Server solutions for C#
Any TCP-based STUN server

Stuntman is a STUN server that supports TCP STUN.
www.stunprotocol.org
On that site, there's some links to some sample code, including C# implementations for client libraries. Most all are for UDP, but with a little work you can role your own C# code for TCP STUN by modifying one of the existing UDP code bases.
Afterwards, you will still need to implement a signaling service for exchanging address candidates (obtained directly or via STUN) and doing your own ICE-like connectivity checks.
For TCP, the easy solutions is to have both endpoints using two sockets. One socket or listening and another for connecting - but both share the same local port (ala SO_REUSEADDR socket option).
Another solution is to have each endpoint use just one socket. Both endpoints try repeatedly to do a TCP simultaneous connect. If the NAT's behave nicely, a connection can be made.
NAT traversal, especially TCP NAT Traversal, is not an exact science. There will always be cases where two endpoints can't get connected directly and will either have to fall back to UDP and/or go through a relay solution such as TURN.
Merge all the information above with the answer I wrote up last year on basic P2P/NAT traversal here.

Related

P2P hand-shaking without a central server

I wrote a client-server application designed to exchange files (among other things) over the local area network. In server mode, the application listens for TCP connections with a specific identification header. In client mode, it tries to establish TCP connections to IP Addresses that are provided by the user.
I now need to adapt this application to work over the internet. Without much exposure to network programming, I am not sure how to achieve this without some kind of a central server (for announcing presence, etc.). This is not an option.
Suppose I have the app running in server mode on my machine which is behind a home network. You (the reader) have the app in client mode and we need to connect. Neither of us have static IP addresses. Is there a way for the client to reach the server? Both the server and client could figure out their public IP addresses but beyond that, I'm not sure what to do.
Any guidance would be appreciated.
EDIT: Based on the answers, some clarification is in order. My question is not about discovery. Both client and server can query their public addresses and users can exchange these IPs over some other medium. The question is, how to establish a connection once each other's IPs are known but both parties are behind networks which do not have the appropriate port forwardings. My app uses port 51200 as a default over TCP for example.
I've learned that the techniques of UDP hole punching to obtain a true direct connection between 2 peers, is imperfect due to some possible combinations of NAT types involved. What this means is that UDP hole punching alone is not always going to work.
The way to claim 100% operability is to, in the cases where a p2p connection is impossible, use a relay server. The process of discovering whether a true p2p connection is possible has been standardized by ICE,TURN,and STUN. All I know is that using ICE/TURN/STUN seems to be the standardized strategy in subverting the NAT problem. It can facilitate a true p2p connection when available and offer relaying services when necessary.
Note: I use the term p2p in this answer to distinguish a truly direct connection between 2 endpoints, not to be confused with overlay networks and the like.
Advanced Users: It is possible to gain more direct p2p connections by introducing more complicated strategies to cooperate with symmetric NAT behaviour, such as port prediction, etc. But the libraries that implement these methods are costly, and seems too difficult for a DIY job.
I have not explained in detail the different types of NAT connection possibilities. You will want to research on NAT types and how they relate to UDP hole punching. There are RFCs out there and I will try to update my answer with links. But the point is that you can avert a lot of this learning by refocusing on implementing TURN/STUN/ICE, learn how they are implemented and how you can use their standardized behavior.
Potential Solutions
PJSIP - contains a stand-alone high level NAT traversal library for C/C++, also has bindings for other langauges. If you just want the NAT Traversal library sub-component, see PJNATH
LibJingle - a P2P (peer-to-peer) and RTC (real-time communication) stack that builds on XMPP. Note that many of LibJingle implementation is not interoperable with actual XMPP Jingle specification and subsidiary specifications.
These may add considerable complexity to the program, which is why it can be compelling to implement some of the mechanisms myself.
Documents
NAT on Wikipedia
NAT Traversal Fundamentals
How NAT Compatible are VoIP Applications
STUN server list
Teredo/Shipworm Doc
Symmetric NAT and UDP Hole Punching
STUN/TURN/ICE Summary
IETF
RFCs
RFC 5245 – ICE
RFC 5389 – STUN
RFC 5766 – TURN (iirc, TURN uses a STUN server.)
RFC 5768 – ICE – SIP
RFC 6336 – ICE – IANA Registry
RFC 6544 – ICE – TCP
RFC 5928 – TURN Resolution Mechanism
RFC 6062 – TURN Extensions for TCP Allocations
RFC 6156 – TURN Extension for IPv6
[Draft] Symmetric NAT Traversal using STUN
[Draft] Network Address Translation and Peer-to-Peer Applications (NATP2P)
Microsoft
MS-STUN – Microsoft STUN extensions
MS-TURN – Microsoft TURN extensions
MS-ICE – Microsoft ICE extensions
MS-ICE2 – Microsoft ICE2 extensions
Notes
I have heard that the eventual migration to IPv6 may squash the NAT traversal problem, but [probably not]. Someone could enlighten this topic. Either way, the progression to IPv6 appears slow from my non-experienced viewpoint, and I wouldn't count on it as a solution.
Few months ago I was looking for a similar solution, but unfortunately I got stuck and henceforth I dropped it.
People say you could use UDP hole punching or TCP hole punching, but I was unable to do this (I'm not a specialist in computer networks though). Whether it will work or not depends on the network itself.
Here is the question I originally asked, maybe it will be helpful to you. Honestly, I don't want to kill your hopes, but I'm afraid it may be a dead end. :(
I don't believe this is possible without some sort of central place to "find" each other. You need some way for the client the find the servers ip address to connect to.
Also, udp or tcp hole punching is an entirely different thing and uses, guess what: a central server.
If you use IPv6 it is possible - but you still need to know the other parties address. It also is possible if you use a DynDns service - but that is already a kind of central infrastructure.

Initiating tcp connection from public IP to private machine on another network

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.

Does WCF offer options to avoid port forwarding?

So many programs in the past and even the present operate on a Server/Client basis. Examples include TeamSpeak, Ventrilo, Mumble, etc. These programs typically require going into the router and forwarding ports so that the computer running the server can get the messages from the clients which are sending connection requests to the server's router.
Is there anything in WCF these days that allow you to prevent that sort of thing? I have a chat/file transfer program and I would really prefer that users not have to know how to forward their ports.
What kind of options are there out there in the way of UPnP or Punchthrough? The notion of having to go through and forward all the specific ports that a program uses seems so outdated.
Have a look at WS-Discovery with WCF:
http://weblogs.asp.net/gsusx/archive/2009/02/13/using-ws-discovery-in-wcf-4-0.aspx
The discovery protocol negates a central, "server router" as you put it. It's uses UDP broadcast to notify clients of each other.
Note that the discovery protocol itself is just a stateless messaging protocol. It has no guarantees or state synchronization. If for example, Client A doesn't receive the broadcast message from Client B, then Client A wont know of Client B. The protocol overhead of maintaining this P2P states is complex and usually a single server to hold this state is the easiest approach.

Testing NAT Breakthrough Code

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.

TCP or UDP help with a server/client in c#?

Can anyone help, i trying to figure what i need to do, i have been given the tasks of writing a server and a client in TCP (UDP). basically multiple clients will connect to the server.. and the server sends MESSSAGES to the client.
I have no problem in creating the server and client but with tcp i am unsure whcih way to go. DOes the .net 3.5 support everything or do i need to go on the hunt for some component?
I am looking for soome good examples with c# for TCP or UDP. THis is where i am not 100% sure .. as far as i know there is UDP and TCP ... 1 is connected and 1 is not.. So which way do i go and can c# support both?? Advantages /Disadvantages?
Say if the server has to support multiple clients that i only need to open 1 port or do i need to open 2?
Also if a client crashes i need for it not to effect the SERVER hence the server can either ignore it and close connection if one is open or timeout a connection... If in fact a connection is needed again going back to tcp udp
Any ideas where i shoudl beging and choosing which protocol and amount of ports i am going to need to assign?
thanks
UDP cons:
packet size restriction means you can only send small messages (less than about 1.5k bytes).
Lack of stream makes it hard to secure UDP: hard to do an authentication scheme that works on lossy exchange, and just as hard to protect the integrity and confidentiality of individual messages (no key state to rely on).
No delivery guarantee means your target must be prepared to deal with message loss. Now is easy to argue that if the target can handle a total loss of messages (which is possible) then why bother to send them in the first place?
UDP Pros:
No need to store a system endpoint on the server for each client (ie. no socket). This is one major reason why MMO games connected to hundred of thousands of clients use UDP.
Speed: The fact that each message is routed individually means that you cannot hit a stream congestion like TCP can.
Broadcast: UDP can broadcast to all listeners on a network segment.
You shouldn't even consider UDP if you're considering TCP too. If you're considering TCP means you are thinking in terms of a stream (exactly once in order messages) and using UDP will put the burden of fragmentation, retry and acknowledgment, duplicate detection and ordering in your app. You'll be in no time reinventing TCP in your application and it took all engineers in the word 20 years to get that right (or at least as right as it is in IPv4).
If you're unfamiliar with these topics I recommend you go with the flow and use WCF, at least it gives you the advantage of switching in and out with relative ease various transports and protocols. Will be much harder to change your code base from TCP to UDP and vice versa if you made the wrong choice using raw .Net socket components.
It sounds to me like you're not clear on the distinction between TCP and UDP.
TCP is connection oriented. i.e. 2 peers will have a dedicated connection. Packet delivery and ordering is guaranteed. Typically a server will present a port, and multiple clients can connect to that port (think of a HTTP server and browsers).
UDP is connectionless. It doesn't guarantee packet delivery, nor ordering. You can implement broadcast and multicast mechanisms very easily. If you need some sort of reliability, you will have to implement this on top of UDP. Sometimes you may not care, and simply issue requests and retry on no response (SNMP does this). Because it's connectionless, you don't really worry about peers being up/down. You just have to retry if required.
So your choice of protocol is dictated by the above. e.g. does your client require a dedicated connection to the server ? Are you transmitting the same data to multiple clients ? Can you tolerate packet loss (e.g. real time price updates etc.). Perhaps it's feasible to use both TCP and UDP for different requirements within your app (e.g. TCP for registering orders, UDP for transmitting price updates/events?)
I'd consider your requirements, and familiarise yourself with the limitations and features of TCP and UDP. That should make things a little clearer.
Is there a requirement to do this at such a low level? Why not use WCF? It fully supports messaging over TCP/IP, using binary data transfer, but it's at a much higher level of abstraction than raw sockets.
Everything you need is in .Net 3.5 (and probably below). Check out the documentation and examples with the UdpClient class at MSDN for insight into how to write your client/server. A quick google found some sample code for a server and client at www.java2s.com among many other networking examples in C#. Don't be put off by the domain name.

Categories

Resources