TCP, UDP, and SCTP

Now I know that if you’ve been on the internet long enough, you’ve at least heard the term TCP thrown around. Maybe UDP too, and to any networking people here, you should be very familiar with what they are and how they compare. Well today, I bring the unheard third layer 4 protocol into the spotlight: SCTP

Layer 4 Protocols

In the OSI model, layer 4, or the transport layer, is what provides host-to-host communication for applications. Layer 4 should provide services such as connection-oriented communication, reliability, flow control, and multiplexing.

Obviously the most well-known L4 protocol and the one that almost everything on the internet uses is TCP (Transmission Control Protocol), though a few do use the second-place winner, UDP (User Datagram Protocol). Now just because those are the two major ones does not mean that there aren’t more, DCCP (Datagram Congestion Control Protocol), and SCTP (Stream Control Transmission Protocol)

I’ll be covering all three, because why not.

Transmission Control Protocol (TCP)

TCP, which has been around since the invention of the Internet Protocol (IP), provides reliable, ordered, and error-checked delivery of a stream of bytes, between hosts. TCP is connection-oriented, meaning you have to deliberately decide to and agree to talk to another computer, and also provides for error correction, and retransmission of lost data.

TCP packets are given a number relative to each connection, called the sequence number. This allows both computers to know which ones have been received, and which ones failed somewhere and need to be sent again.

My favorite analogy for TCP is like two gentlemen starting a discussion:

Would you like to talk about <topic>?

I would indeed like to, if you are willing.

I am willing, let us talk.

[talk ensues]

That is all I have to say on the matter.

Very well, that's all I have to say too.

Good, then this discussion is finished.

Or in the case of a host rejecting a connection:

Would you like to talk about <topic>?

No sir, indeed I would not like to talk about <topic>.

TCP is meant to withstand the fundamental assumption of the internet: that network links are unstable, and can randomly fail or lose data at any time. It can be a little slow (relatively), but almost guarantees that if you send something, it will be received.

There is one big point to note: TCP works on a byte stream: there is no concept of the “beginning” or an “end” of a message. It’s just all bytes. This is why, for example, HTTP, specifies that a double CR LF pair is what signals the end of transmission, because TCP itself does not provide a method of saying “they’re finished, your turn.”

Ports

TCP, like all three protocols here, uses the concept of ports to demultiplex connections. A “port” is just a number, in all three cases, from 1 to 65535, inclusive. Ports do not signify anything, they are just a number that can be used by the host’s networking equipment to determine what application needs to be sent the incoming data. Some ports are commonly used for services, such as 80 for HTTP, 443 is HTTPS, 143 is IMAP, 22 is SSH, and so on. All you’re telling the receiving computer is “send this to port 80.” The receiving computer sees this, and the processing can be explained as “this is a packet for port 80, and httpd has requested to use port 80, therefore I’ll deliver it to httpd.”

Flags

All TCP packets have a set of “flags”: boolean yes-or-no options used to convey some data. These are used for connection set-up, tear-down, and various other state information that needs to be transmitted to provide reliable transport (oversimplified explanation).

User Datagram Protocol (UDP)

UDP, unlike TCP, is connectionless: there is no formal agreement on communicating, you just.. fire off some data. Depending on the program doing this, the appropriate analogy is anywhere from getting hit in the face with a letter folded into a paper airplane, to just turning a fire hose of data to someone, and blasting them with it.

UDP has very minimal overhead, and doesn’t really meddle too much with your data. You have the ports and a data checksum (that’s actually optional). The downside is that, in trading off the overhead, UDP is now considered “unreliable” in the sense that if something happens to the data, there is no mechanism in place by UDP itself to correct this. There’s an (optional) checksum but that has to be verified by the program receiving it, not the networking service as part of the OS, like on TCP, where it would be corrected before being given to the app.

There’s also a few other differences:

  • UDP is very simple, and can be handled by devices without a full network stack.
  • It’s stateless, there is no information carried over from one message to another.
  • UDP sends datagrams, or distinct groups of bytes. Unlike TCP where all messages are just concatenated together as one continuous stream of data, in UDP if they’re sent separately, they’re delivered separately, meaning that there is an actual definition for the start and end of messages.

UDP has a few uses: the Network File System protocol (NFS), as well as three core protocols of modern networks, Network Time Protocol (NTP), Dynamic Host Configuration Protocol (DHCP), and the Domain Name Service (DNS), all use UDP as their transport, not TCP.

Additionally, voice and video stream data, such as a livestream or VoIP session (Discord, anyone?), usually prefer UDP because the lack of latency, and for both those types, if one packet is not correct, it’s likely not going to be that big of a deal.

Stream Control Transmission Protocol (SCTP)

SCTP is.. well, kinda a mix of both TCP and UDP. Heck, the few libraries that I’ve seen that support it literally offer options to treat an SCTP connection like either one, with the standard calling conventions.

SCTP, like UDP, is a datagram transport, not a stream transport. Like TCP though, it provides reliable, ordered, congestion controlled transport.

SCTP does have a formal connection handshake, and is capable of breaking large messages into chunks, which can be transmitted separately and then re-assembled on the other end.

SCTP has a “stream identifier”, in each chunk, meaning that you can transmit several independent pieces of data at the same time over the same HTTP connection. This is very similar in implementation to ports, or to how HTTP/2 multiplexes data (also called streams there too).

SCTP also has a feature called “multi-homing”, where it will build multiple routes to the destination, such that if one fails, it can continue on another, thus improving reliability.

So, for all these features, what’s the downside?

Well, it does have some latency, like TCP. The main downside though, is just that very few things really support it, and almost no applications actually use it for any meaningful purpose, though some cheap “smart” devices use SCTP to force you to use their proprietary software to decode their “proprietary” protocol (no it’s not).

It’s really cool in theory, though likely not information you’re going to use in the wild. Good things to know, though, I guess?