Using TURN server for peer-2-peer communication - c#

I’m very new to TURN and I want to create an experimental application which requires a TURN server for its udp communication.
I have used UDP hole punching already and I’m familiar with the subject.Also I know about NAT types and UPnP for port mapping.
To solve port mapping in Symmetric and Port restricted NATs with routers without UPnP capability I must communicate with a TURN server and send UDP packets through it.But I don’t have any idea how to communicate with TURN server and how to work with it in C# programming.
I’d appreciate it if you could point me to the right direction and give me some pointers.
Thanks.

I can answer about how to use TURN for completing a relay call. But to know how to form messages for TURN you need to read the RFC.
How TURN Works
TURN is needed because its impossible to bypass some NATs filtering and establish direct connection with a host. As TURN sits on a public IP, anyone can connect with it.
So hosts under symmetric NAT can send allocation request to TURN server and TURN server will allocate a port for the host. Now the host will have IP information of the other side. And it will send another request to TURN specifying the IP info of other host and packets from that other host in the allocated port will be forwarded to the host behind the symmetric NAT. And packet from the host behind the symmetric NAT will be forwarded to the other host. This way they create a relay connection.
You really need to read the RFC for TURN to know this in more details. Everything you need is there.

#tahili I see this is an old post but I want ask you a question.
If Turn server can reach the peer's server-reflexive address why can't the client just send packages directly to peer's reflexive address. If client can't send data to peer directly because of mapping problems how does the turn server can send a udp to peers server reflexive address.
Mind you peer has not contacted the turn server yet "relay address of the client", so there is no mapping between the turn server(client's relay address) and the peer.
Knowing peers reflexive address alone is nor enough. After all we can just send data directly to the peer.
Assuming is peer is behind NAT as well.

Related

Testing UDP on localhost

I'm currently trying to make an online video game, which currently uses TCP to send packets. I want to use UDP, but I'm extremely new to UDP and I'm having some issues.
When I test my server/client(s) on the same computer (localhost), the packets seem to be interfering with each other.
For example, if the client sends a packet to the server (UDP, 127.0.0.1:1338), the client ends up receiving the packet, since the client is also listening for packets from 127.0.0.1 on port 1338. Similarly, when I try to test 2 clients and 1 server, the clients may send out packets which are meant for the server, but are picked up by the other client.
How can I test UDP on localhost since all packets are being received from/sent to 127.0.0.1:1338? Do I need to implement some sort of layer in my packets that distinguishes if the packet is meant for the server, or a specific client?
Only your Server should listen on the defined port number (1338). Each client should select a free port number and send the server this port number. The server has to store the client information and send then the packets to the clients in this client list.
The clients should also send a goodby packet when the client is closing to know on the server side which clients are still available and which aren't participating anymore.
You should also implement some kind of housekeeping in this client list. For example store the timestamp of the last received packet from the client and remove clients that haven't sent data for some time (crashed client, lost connection ...) from the list.
An additional layer will not help - because the server may never actually get the packet.
Make the ports on the server and client configurable. That way you could have different ports on the same machine for testing and change it when going to production. Just remember you need to configure both ports in both the client and server. This is a good practice anyway.
You still have another problem - of several clients residing on the same machine and listening to the same port. You can have a random port for each client (the client selects one in random and then notifies the server). Or you can try binding to different IP addresses (one will use 127.0.0.1 an another will use the real IP of the PC), but it's not extensible.
If you are going to use this in a LAN setup, then you can always filter the received packet based on the sender's address -- recvmsg() of UDP allows you to retrieve sender's address and port number. If you are going to use this in a WAN setup, then this likely would not be an issue unless you are trying to do multicast. And, even with multicast, duplciate packets are not send back to the receiver. You can use IP_MULTICAST_LOOP to disable this option.

UDP P2P connection behind NAT

I want to make P2P connection between 2 clients behind NAT. I studied methods to make it work and I want to try "UDP hole punching method".
So...
I made a server in PHP, which can send connection details to clients on demand (Like remote IP, remote port).
Source code as example is here: http://pastebin.com/FdiKMSFq
Next, I made an Client in C# which permanently connects to server and ask him about another client info. Client recieves remote IP and remote port (used for connection with server) of another client and tries to connect.
Full source code here: http://pastebin.com/VUJyZivW
First step (connecting, and asking for details) are OK, but when client (A) connects to another client (B) and send some data (A->B), client B do not recieve any data.
I set both IPEndPoints working with port 2000. But it didn't work anyway.
Example:
A: 192.168.1.11:2000, server gets 32.14.15.16:56666
B: 192.168.1.5:2000, server gets 32.99.15.16:56699
A tries to connect on 32.99.15.16:56699 and send some data
Looking over your example, B's NAT is going to drop the packet destined for its public endpoint (pair of address and port). This is because B's NAT sees this as an unsolicited request.
In order for B's NAT to let the packet from A through, it has to think that B had communicated with A prior, thus considering the request solicited. The NAT keeps an internal table to track this.
The way you can establish the connection is by having B send a packet to A's public endpoint (32.14.15.16:56666) as well. Doing this will "punch" a hole in B's NAT. In your example A is already "punching" a hole by sending traffic to B.
Keep in mind that this will only work if at least one of the NATs consistently translates private source endpoints to public source endpoints (regardless of destination address). This is because otherwise the public endpoint seen by your server may be different than the one seen by the P2P peers' NAT even when the peers are using the same private endpoint.

C# Changing incoming and outgoing TCP Communication

What is the best way of reading, changing, and resending tcp communications?
For instance i have a server application that tells a master server it's alive sending a packet over TCP on port 3209. It sends out "I'm alive, my ip is xxx.xxx.xxx.xxx and I have currently 3 clients connected to me." the master server then responds, "Hello xxx.xxx.xxx.xxx i see you there."
Whats the best way of MITM of the server sending its packet to the master server? I would like to be able to change "i'm alive," to something like, "I'm changed," or even "currently 3 clients connected" to "currently 0 clients connected"
Any ideas appreciated, thank you.
There's no need to send out that kind of message.
First of all, TCP is connection oriented, so as long as you have a connection you'll be alive.
You can check if you're still connected by using the TCPClient.Connected property.
Secondly, TCP runs over IP so in the IP header you can find the sender IP (is in the socket properties) so no need to send the IP neither.
You can check the remote IP address by using TCPClient.Socket.RemoteEndPoint property.
Finally, the only thing you might be interested in telling is the "3 clients connected part" wich can be coded as a simple integer transmision. That is, a 4 bytes hearbeat.
Getting in the middle of the connection IS tricky and has nothing to do with communication protocols. And honestly it's a hell of a job, if there's a connection already present you'll have to find a way to make the client or the server drop it and then have the server reestablish it to your MIDM. More though, if the connection is made directly to an IP address you'll have to mess with the router tables somehow for the attact to be succesful, if it's not maybe DNS poisoning will work for you... anyway not an easy task.
Those are only ideas... it depends on the class of network, if you have physical access or not, if the client and the server trust each other (as in if they are your applications) and so on... I assume all this is ethical or educational at least... :)
Have a look at SharpPcap or any other packet capturing/injecting library.
In order to MITM, you'll have to force the client to think you're the server and the server to think you're the client. For that, you'll have to send ICMP packet to both machines as described here. Then, you will capture the packets, modify them and inject them to the network (with the correct MAC address).
Pick a different tool - this is too low level a kind of thing to attempt in C#. This kind of thing is achieved (on Vista and later) using the Windows Filtering Platform

Can lidgren-network library connect directly peer to peer given both IP addresses

I am using lidgen-network library 3 to try and create a peer to peer connection. I am new to network programming which is why i'm using this library.
Using the DiscoverKnownPeer() function i have been able to connect within my network. What i have read online is that i need to do a NAT punchthrough which requires a running server that is outside the router. I am hoping for a solution that doesnt require this extra server.
If i can store both ip addesses on a web server, and get create a web service to send the ip's to each respective client through XML, would I be able to create a peer to peer connection?
Thank you in advance.
No, you won't be able to establish a connection through NAT without a rendezvous server
NAT stands in your way because even if you know the IP address, that only gets you as far as the router. The router receives a request coming from the internet, and doesn't know which internal IP to send it to, so it throws it away.
NAT punchthrough works by making both peers send outgoing request to each other, the router then "knows" that packets directed at its public IP on the given port should go to the given computer.
So, you need to connect both computers to an external server not behind NAT, and then use that external server to coordinate connecting the two NAT obscured peers together (this is the peer introduction thing that Lidgren has built in).
I know this is old but...
You didn't specify that using the DiscoverKnownPeer() was necessary in your setup. If it isn't then you can setup peer to peer by appplying port forwarding rules in your router.

Sending a message through a particular client port in remoting

I am doing applications in .net remoting.actually we register a channel in the server side and connect the client using the iP and port of the server,but i want to send my messages from client through a specific port for ex: 8085 or 8086.how to achieve this?
Why? There are numerous disadvantages to specifying the client port:
the client must effectively be single-threaded
TCP will impose a two-minute TIME_WAIT before you can reuse the port.
Firewall administrators sometimes like to create these rules not realizing that they cripple the client. Such rules don't actually server any useful purpose that I'm aware of.

Categories

Resources