Chrome WebRTC DataChannels: ICE-TCP server reflexive candidates missing even with STUN - tcp

I'm building (yet another) manual signalling WebRTC chat via DataChannels (CoffeeScript, sorry JS guys). It works fine in local connections, but not over the internet behind a NAT (unfortunately I couldn't try NATless yet).
I don't want to maintain a TURN server, but I'm fine if only one peer must be publicly-reachable from the internet for the setup to work. Since I'm the only one with a reachable machine, we need me to host a TCP connection. In Firefox there are no TCP candidates reported so I guess ICE-TCP is not yet supported.
On Chrome, looking at the SDP offers/answers, the STUN servers correctly identified both peer's public IPs and added each server reflexive UDP candidate (see line 10 below) but there is no TCP server reflexive candidate, so the connection never succeeds. There is also a TCP candidate included (see line 9 below) but it's just a host candidate.
Here's a sample SDP offer (my public IP is 88.88.88.88):
01. v=0
02. o=- 7452583715680269460 2 IN IP4 127.0.0.1
03. s=-
04. t=0 0
05. a=msid-semantic: WMS
06. m=application 50816 DTLS/SCTP 5000
07. c=IN IP4 88.88.88.88
08. a=candidate:864190085 1 udp 2122194687 10.10.10.4 50816 typ host generation 0
09. a=candidate:2097250933 1 tcp 1518214911 10.10.10.4 0 typ host generation 0
10. a=candidate:3500406889 1 udp 1685987071 88.88.88.88 50816 typ srflx raddr 10.10.10.4 rport 50816 generation 0
11. a=ice-ufrag:2066nM5kqwFDQMBT
12. a=ice-pwd:thO7oP0H+H1VBHFNfT8SLFiI
13. a=ice-options:google-ice
14. a=fingerprint:sha-256 72:87:BF:AD:03:9C:09:A7:58:0C:3A:DF:.....:B7
15. a=setup:actpass
16. a=mid:data
17. a=sctpmap:5000 webrtc-datachannel 1024
I'm sure the internet can reach my machine via NAT and port forwarding is fine (my machine is the default host to NAT-forward to).
Why is there no TCP server-reflexive candidate reported in my offers/answers?
Does Chrome lack server-reflexive ICE-TCP candidate discovery?
Is it possible to manually add a server reflexive candidate given the public IP reported by the STUN server?

First, STUN can support TCP over a NAT in accordance with the new RFC and with the proposed updates for said RFC for DTLS. All this said, Chrome should still support SCTP over TCP and Firefox still does not according to bug 891551.
I also highly doubt that MEDIA will ever support a TCP connection and suspect that only SCTP will be supported for any TCP connection(relayed or not).
[Note: For history sake, I am keeping the rest of my answer intact but a good comment made by #adamfisk, showed me some errata.]
Original answer
STUN CANNOT work with TCP over a NAT.
Its RFC says as much in the application statement. Stun is only designed to work with UDP. This is why SCTP needs to be on built on UDP so that you can go around NATs. (Only Chrome gives the internal option of TCP).
You will have to set up port forwarding on one of the NATs if you want TCP traffic to go through it but STUN will not help you.
Sorry for the bad news :(
EDIT: This is simply a limitation of STUN, not of SCTP(so chrome could do nothing about it if they wanted to). FireFox does NOT support SCTP over TCP anyways. I am not 100% on TURN. The RFC seems to say that TCP is support only in the communication between the client and the server, not the actual relay. Check this out, Chrome may work with TCP through a TURN server from what T. R. Missner states at the bottom of the thread.
You MAY have to have port forwarding set up on both sides if you want to use TCP with an RTCDataConnection.

Related

why does TCP over VXLAN in mininet stop sending after switching tunnel?

topology
This is my experimental setup in Mininet. VM1 and VM2 are separate Virtualbox VM instances running on my computer connected by Bridged adapter, and S1 and S2 are connected with vxlan forwarding.
Then I used D-ITG on H1 and H2 to generate traffic. I send TCP traffic from H1 to H2 and use wireshark to capture. During a 10sec TCP flow, I used a python script that changes the tunnel id of the first rule on S1 from 100 to 200.
If the packet/sec rate and payload size is small enough, the TCP session does not seem to be affected, but when I start sending around 100 packet/sec each with payload of 64 bytes, TCP stop sending after receiving a dup ACK. Here is the wireshark capture:
wireshark1
wireshark2
On the link between H1 and S1 I received ICMP destination unreachable (fragmentation needed).
After the two errors, TCP stopped sending. I understand that the "previous segment not captured" is caused by the fact that when I alter the S1 routing table, there is some down time and packets are dropped by the switch. However, I don't understand why TCP does not initiate retransmission.
This does not happen if I reduce the packet rate or the payload to a smaller amount, or if I use UDP. Is this an issue with the TCP stack, or maybe D-ITG? Or maybe it is an issue with the sequence numbers? Is there a range where if very previous packets are not ACKed, they will not be retransmitted?
This problem has been bothering me for a while, so I hope someone here can maybe provide some clarification. Thanks a lot for reading XD.
I suspected it may be a problem with mininet NICs, so I tried to disable TCP fragmentation offload, and it worked much better. I suppose that the virtual NICs in mininet in a VM could not handle the large amount of traffic generated by D-ITG, so using TCP fragmentation offload can overload? the NIC and cause segmentation errors.
This is just my speculation, but disabling TSO did help my case. Additional input is welcomed!

Traceroute number of hops changes depending on the tcp port used

I use Nmap to traceroute some websites as follows
nmap -Pn --traceroute 108.177.127.103
I notice that the result varies depending on the used TCP port. So, when I use port 25 instead of port 80, it gives different results.
The weird thing is that the routing process should take place in the 3rd layer. The routing process should not depend on the TCP ports.
My first thought was that something is wrong with Nmap. But, when I used Wireshark to sniff the packets. I found the ICMP responses, they perfectly align with what Nmap is giving.
Then, I used windows command line as follows
tracert 108.177.127.103
I got a completely different result (it gave 24 hops, in nmap there were only 9 hops).
Again, I used Wireshark to see what was sent and received and they all perfectly fine. However, cmd tracert uses ping requests, it doesn't use TCP protocol.
What's worse is that in some cases, the traced routers IPs are all private. Even though, the target IP address is not even in my country!
This is one of the Nmap traceroutes on 162.121.211.20 port 25:
192.168.1.1 (192.168.1.1)
host-197.43.213.1.tedata.net (197.43.213.1)
10.45.3.49 (10.45.3.49)
10.38.6.30 (10.38.6.30)
10.38.7.81 (10.38.7.81)
10.37.87.141 (10.37.87.141)
10.37.22.190 (10.37.22.190)
10.37.242.170 (10.37.242.170)
162.121.211.20
Can anyone explain to me what's going on please ?!
In practice some routing decisions can depend on the upper layers.
For instance if an ISP provides anti-virus, content filtering, or proxying/content-distribution services, then it might send HTTP traffic to some special equipment to provide these services.
Port 25 (SMTP) traffic might be redirected to some anti-spam filters.
Various "low priority" traffic (the definition of which can vary) might be sent through other paths than "high priority" traffic. Classic examples are VoIP or gaming traffic being prioritized over BitTorrent.
This is part of what Net Neutrality is all about.

Does WebRTC use TCP or UDP?

I have some questions about WebRTC:
Does WebRTC use TCP or UDP as its peer-to-peer transport? How can I
know?
I read that there are reliability mode and DTLS agreement, how does
these affect?
Is this transport the same for both Media and DataChannel?
How do I switch between TCP and UDP?
I ask this because I know that browsers have a limit on the number of parallel connections (I think they talk over TCP), and maybe UDP connection is not limited.
It can use either. By default, preference is given to UDP, but depending on the firewall(s) in between the peers connecting it may only be able to connect with TCP. You can use Wireshark to capture packets and verify whether TCP or UDP is being used. In Chrome you can also see details on the selected candidate (googActiveConnection) by going to chrome://webrtc-internals.
"Reliability mode" probably refers to the reliability mode of the DataChannel, which can be configured to run in reliable or unreliable mode. DTLS refers to the currently optional, but soon to be default method of exchanging encryption keys (the other deprecated mode is SDES). Firefox only supports DTLS, so for browser interop, you'll currently need to enable it in Chrome.
The RTCPeerConnection (media) will use TCP or UDP, while the DataChannel uses SCTP. The SCTP implementation used by Firefox is implemented on top of UDP: https://code.google.com/p/sctp-refimpl/.
It's possible to filter out TCP or UDP ICE candidates before adding them with addIceCandidate. Generally, you should not try to force the transport used since WebRTC will just "do the right thing". The browser does not limit the number of TCP connections used by WebRTC beyond any limit on the RTCPeerConnection or DataChannel (i.e., if you can have 10 PeerConnections, they can each use TCP without any problem).

Can TCP be implemented via UDP?

I had a strange idea. I heard of software which from my understanding uses UDP to transfer files decreasing the overhead found in TCP packets.
If my app requires TCP and my LAN has software set up to communicate with another datacenter on the other side of the coast with software setup on their end. Would it be possible to send the actual data via UDP but than simulating TCP on both ends?
Does anyone have any ideas or information about such projects?
If you're asking if you can use UDP as a Layer 2, then the answer is yes, sort of. There are various protocols that allow you to create a tunnel to another network using a UDP transport, such as L2TP and even IPsec (with NAT traversal). You could also do it at the application layer.
If you're asking if TCP can be implemented in UDP, the answer is no. First, TCP packets and UDP packets have an incompatible format. Second, TCP and UDP have different protocol numbers (seen in the IP header) which means that TCP traffic destined for a UDP port would not be passed to the correct upper-layer protocol.
Both TCP and UDP are built on top of the IP, but the TCP uses different packet structure and at the layer-2 it is not possible to mimic the TCP using UDP packets.
Of course, if you have the control on both the source and destination, then it is possible to create a reliable UDP tunnel for the TCP packets. This would require some internal information (packet number, ack/nack flags) in the body of the UDP packet.
There is an interesting project http://udt.sourceforge.net/
It is a broadcast-capable reliable file transfer mechanism built on top the UDP.
PseudoTCP is a protocol which implements TCP algorithms on top of the UDP. It was introduced since the NAT traversal for TCP is much more complicated than UDP. But some P2P applications do need a reliable data transfer among nodes.
So far as I know, there are two PseudoTCP variations: Libjingle and Libnice.Libjingle is an open source library from google which was initially for gtalk. You could take a look at file sharing example from libjingle: https://developers.google.com/talk/libjingle/file_share. Recently, Chrome desktop also use PseudoTCP implementation from libjingle for reliable connections.
Yes, you can develop a protocol on UDP that simulates TCP. However, if you simulated TCP fully, it would technically have more overhead. Because TCP is implement as the packet and your simulated TCP is implemented in the body of the packet.
If you only need one or two features of TCP (such as basic ordering), then implementing it in UDP is useful.
Halo uses 2-3 (IIRC) UDP protocols that simulate different features of TCP, then full fledged TCP for initializing game-states. I Shot You First Networking, GDC publication
For example, in one case, they send 3 duplicate UDP packets to overcome packet loss.
If you control the software on both ends, and it is cost-effective to build your own protocol, then UDP can be versatile.
One way to do it now on Linux-3.18+ is to use Foo over UDP (FOU) which implements Generic UDP Encapsulation (GUE). Here's a good introduction to FOU, and the man page for ip-fou.
Or if you want an [open source] UDP based file transfer system there are things like UDT, UFTP, Tsunami-UDP, and even Google's QUIC (Now deprecated in favour of IETF QUIC).
Update: The QUIC protocol now has been standardised by the IETF which provides for secure reliable and unreliable transport over UDP as an alternative to TCP. There's a wide range of QUIC implementations available. There is also a growing set of protocol mappings on to QUIC such as HTTP/3, DNS over QUIC, etc
If my app requires TCP and my LAN has software setup to communicate
with another datacenter on the other side of the coast with software
setup on their end. Would it be possible to send the actual data via
UDP but than simulating TCP on both ends?
No. A UDP socket is in a different namespace from a TCP socket. You will be unable to write UDP at one end and send or receive TCP at the other end. TCP and UDP are peer protocols; both exist at the layer above IP. You can't use one to spoof the other.
Hmm, I believe so. You'd need to use a proxy at both ends, but it should be possible.
The biggest problem you are going to run into is that UDP is designed with the idea that you don't care if some of the packets don't ever make it to the other end.
Here's a link with some more info:
http://www.cyberciti.biz/faq/key-differences-between-tcp-and-udp-protocols/
IMHO, it's not a good idea to transmit files via UDP.
TCP's problems are in its algorithms, not its headers.
You certainly could implement the TCP algorithms on top of UDP. That would effectively be the same as tunneling TCP datagrams inside of UDP datagrams. But all this accomplishes is to add a few more bytes of overhead to each packet, and require another endpoint to unwrap the packets.
UDP itself is just thin shim on top of IP: its a convenient way to access IP packet switched networking without having to dive into kernels or receive special handling from routers. The main reason to implement reliable transport on top of UDP is to get away from TCP algorithms in favor of something more efficient. FileCatalyst was mentioned above as one company which does this, and my own company Data Expedition, Inc. does so as well.
So you could implement TCP algorithms on top of UDP, but you wouldn't want to.
You can simulate something like a connection over UDP, and you as well can add reliability checks and ordering and retransmission and so on. - but then, it still isn't TCP, it just acts the way.
Of course, one of the ends can be a kind of "hub" or "proxy" which does an adaption. Then you don't have a 2-end solution, but in fact a 4 end solution - one pair with "real" TCP and the other with the "self-knitted" "TCP" - which you put together with an appropriately crafted program.

Are there any protocol specifications that allow either TCP or UDP to be utilized?

Are there any networking protocols that are not strictly TCP or UDP but can be used with either one?
For example, HTTP, FTP, STMP, RTMP are always TCP.
DNS, SNMP, DHCP, RIP are always UDP.
Is there anything that can be either TCP or UDP? Or am I wrong in the above assertions?
RTSP is one weird one I know of that uses both, TCP for the control port but UDP for audio/video/quality, but it has strict requirements of what gets sent of each.
I'm asking about standard, published, or at least commonly used protocols, not custom ones.
DNS can use either UDP or TCP; TCP is required when the response data exceeds 512 bytes.
If you examine a Windows' services file you will see a number of protocols registered for both TCP and UDP. Path: C:\Windows\System32\drivers\etc In fact, most of the listings in the services file use both TCP and UDP protocols.
As far as well known apps that use both, I would think that most chat applications use both. sms-chat definitely does but probably most others.
Edit:
From that file, here's a few of the protocols that can be sent over either TCP or UDP (there are exactly 100 listed protocols that use both in the file, many internal MS protocols):
echo
discard
daytime
qotd (Quote of the day)
chargen (Character generator)
time
SIP can use UDP, TCP or SCTP. Using a reliable transport becomes important in SIP if your messages get to be at all large (i.e., significantly larger than the smallest MTU in between user agents). A good example is shared- or bridged-line appearances, which use a form of presence with XML bodies. The larger the number of SIP clients in the shared-line group, the larger the packets are likely to be, making fragmentation and retransmission an issue.
SIP can be either UDP or TCP. However, the reality is that UDP is mostly used for this protocol.
SNMP almost always runs over UDP, but it can and does run over TCP. Theory says that it's a bad idea to do SNMP over an error-correcting transport because because some of the very errors that SNMP intends to detect are masked.

Resources