Computer Networking — Part Three

Sanket Saxena
11 min readJul 2, 2023

--

In this comprehensive exploration, we delve into the intricate world of internet protocols (UDP, TCP, HTTP 1–3, and TLS), and secure connections, specifically focusing on the workings of SSL, its process of encryption, public key exchange, and the concept of SSL termination. This knowledge is essential to understand the underpinnings of secure, reliable data transmission over the internet.

User Datagram Protocol (UDP)

UDP, or User Datagram Protocol, is a transport layer protocol primarily used for establishing low-latency and loss-tolerating connections between applications on the internet. It speeds up transmissions by enabling the transfer of data before an agreement is provided by the receiving party.

The data in UDP is sent in units called datagrams. Each datagram contains five parts:

  1. Source Port Number (16 bits)
  2. Destination Port Number (16 bits)
  3. Length (16 bits)
  4. Checksum (16 bits)
  5. Data

There is no ordering of messages in UDP. They might arrive out of order, get duplicated, or disappear without any notice. This is due to UDP’s connectionless nature.

UDP is mainly used in real-time scenarios where loss of packets is acceptable and latency needs to be minimized. This includes services like video streaming, online gaming, and voice over IP (VoIP) where a few lost packets do not significantly impact the overall quality but delay would.

Transmission Control Protocol (TCP)

Unlike UDP, TCP (Transmission Control Protocol) is a connection-oriented protocol and provides numerous features that ensure the reliable delivery of a stream of bytes from one program on one computer to another program on another computer.

TCP organizes data into a stream of packets, which are then sent to the receiver. To maintain data reliability, each packet sent has a sequence number, which is used to put the data back into the correct order. If a packet goes missing, the receiver requests the missing packet again, thereby ensuring that no data is lost during transmission.

TCP data is arranged into a three-part structure: a header, the payload (data), and the end. The header contains all the necessary information like source and destination ports, sequence number, acknowledgment number, data offset, flags, window size, checksum, and urgent pointer.

Due to its connection setup and tear-down procedures, error detection and correction, and information about the order and integrity of packets, TCP is slower than UDP. However, it is widely used in scenarios where data completeness and order are critical. Examples include web pages, emails, file transfers, and database operations.

HTTP/1.x: The Original Web Protocol

HTTP/1.0, released in 1996, laid the foundation for the World Wide Web. It allowed for the communication of hypertext documents over a TCP/IP connection, introducing key concepts such as HTTP methods (GET, POST, etc.) and status codes (200, 404, etc.). However, HTTP/1.0 had a major flaw: it could only handle one request per TCP connection, which proved to be very inefficient.

HTTP/1.1, introduced in 1997 and updated in 1999, introduced a few improvements like persistent connections, pipelining, and chunked responses. Persistent connections allowed for multiple requests and responses to be sent over the same TCP connection, thereby reducing latency. Pipelining meant that multiple requests could be sent without waiting for each response, but in practice, it was hardly used due to several implementation issues in clients and servers.

Despite these improvements, HTTP/1.1 still had limitations. It didn’t fully support parallel requests due to the “head-of-line blocking” problem, where a slow or large request/response pair could block subsequent pairs on the same connection.

HTTP/2: Multiplexing and Server Push

HTTP/2, standardized in 2015, was a response to the increasing demand for faster load times and increased security. It introduced a number of significant improvements over HTTP/1.x:

Multiplexing: Unlike HTTP/1.1, HTTP/2 could handle multiple requests and responses concurrently over the same TCP connection. This eliminated the head-of-line blocking issue and made the transmission process more efficient.

HTTP/2 introduces the concept of “streams”, “frames” and multiplexing to solve this issue. In HTTP/2, each request-response pair (an exchange of data between client and server) is treated as a “stream”. Each stream has a unique identifier and priority. The data in the stream is broken down into smaller pieces known as “frames”. Frames from multiple streams are then mixed (or multiplexed) together into one connection.

So, when a slow request (a slow stream) occurs, it doesn’t hold up the entire connection. Frames from other streams can still be sent and received. As a result, other requests can still complete even if one is slow or blocking.

HTTP/2 also introduces flow control and prioritization mechanisms, which give the client and server granular control over how data is transmitted. The client can alter the priority of streams, or stop temporarily the data flow of individual streams, further minimizing the impact of slow requests.

Therefore, even though all data is ultimately transmitted over a single TCP connection, HTTP/2’s multiplexing effectively reduces the impact of slow or large responses on the performance of other requests and responses.

Server Push: This allowed servers to send resources proactively to the client before they were explicitly requested, potentially saving round-trip time.

Under the traditional HTTP/1.x model, a client makes a request for a webpage, and the server sends the HTML in the response. The client then parses the HTML and issues additional requests for embedded resources such as CSS, JavaScript, or images. These additional round trips between the client and server can significantly impact page load times.

Server Push seeks to optimize this process. When a client requests a webpage, the server can anticipate the resources that the client will need to render that page properly. The server can then “push” these resources into the client’s cache before the client even knows it needs them. When the client eventually requests these resources, it retrieves them from the cache instantly instead of making additional requests to the server.

Header Compression: HTTP/2 introduced HPACK, a new compression format to reduce overhead. This was particularly effective with repetitive header fields, which are common in HTTP traffic.

Binary Protocol: HTTP/2 changed the format from textual to binary, which computers can more efficiently process, parse, and transmit.

While HTTP/2 made significant improvements, it was still built upon TCP, which had its own issues like packet loss and retransmission, impacting all streams in a multiplexed connection.

HTTP/3: Introduction of QUIC

The newest version of HTTP, HTTP/3, was designed to overcome TCP’s limitations by replacing it with the QUIC (Quick UDP Internet Connections) protocol.

QUIC over UDP: Instead of TCP, HTTP/3 uses QUIC, a transport layer protocol over UDP. It maintains TCP’s reliable delivery but allows for separate streams of data to be delivered independently, so packet loss in one stream doesn’t affect others.

Packet loss in a TCP connection can significantly affect the performance of all streams in an HTTP/2 connection due to TCP’s inherent flow control mechanisms. This issue is known as head-of-line blocking at the TCP level.

When a TCP packet is lost during transmission, it’s detected either by a timeout or by receiving three duplicate acknowledgements for the packet sent after the lost one. Once a lost packet is detected, TCP’s congestion control mechanisms kick in. TCP reduces the sender’s congestion window size, which effectively reduces the rate at which the sender can transmit data.

Furthermore, TCP guarantees in-order delivery of packets. This means that if a packet is lost, all packets sent after the lost packet, even if they reach their destination, must wait for the lost packet to be retransmitted and acknowledged before they can be processed. This is the essence of TCP-level head-of-line blocking.

In the context of HTTP/2, since all streams share the same underlying TCP connection, a packet loss in one stream impacts all other streams. Even if the packets of other streams have been successfully received, they are blocked until the lost packet is retransmitted and acknowledged, and the sender’s congestion window size adjusts. This significantly degrades the performance of the entire HTTP/2 connection, even though HTTP/2 was designed to allow streams to operate independently.

HTTP/3 attempts to solve this issue by replacing TCP with QUIC, a transport protocol that operates over UDP. QUIC provides reliable, in-order delivery of streams (like TCP), but it handles packet loss on a per-stream basis. Thus, a packet loss in one stream does not affect other streams, avoiding head-of-line blocking and leading to better performance in the presence of packet loss.

Inbuilt TLS: Unlike HTTP/2, where TLS was an add-on, HTTP/3 has TLS (version 1.3) built into it, enforcing encrypted connections by default.

Reduced Latency: QUIC includes features to reduce connection establishment and congestion control latency, providing an overall smoother and faster browsing experience, particularly for real-time streaming of media and gaming applications.

Connection Migration: QUIC is designed to maintain a connection even if a client changes its IP address, which is beneficial for mobile devices switching between Wi-Fi and cellular networks.

QUIC accomplishes this via its unique Connection ID feature. The Connection ID is an identifier that each endpoint provides to the other during the initial connection setup. This Connection ID is carried in every subsequent QUIC packet header by the QUIC client, rather than relying on the IP and port information to maintain the continuity of the session, as in TCP.

While HTTP/3 and QUIC promise significant improvements adoption has been slow due to the substantial changes required in internet infrastructure to support the new protocols.

Transport Layer Security (TLS)

Transport Layer Security (TLS), the successor to SSL, is a cryptographic protocol designed to secure communication over a computer network. TLS involves a series of steps:

Here’s the sequence of events in an SSL/TLS handshake:

  1. The client starts the handshake process by sending a ClientHello message to the server, which includes a list of cryptographic algorithms it supports (like RSA or ECC for key exchange, AES or ChaCha20 for symmetric encryption, etc.).
  2. The server responds with a ServerHello message, which includes the server’s choice of cryptographic algorithms from the client’s list. The server also sends its certificate, which includes its public key.
  3. The client verifies the server’s certificate (to confirm that it’s communicating with the correct server), then generates a random pre-master secret. It encrypts this pre-master secret with the server’s public key (from the server’s certificate) and sends it to the server in a ClientKeyExchange message.
  4. The server, using its private key, decrypts the pre-master secret. At this point, both the client and the server have the same pre-master secret, but they didn’t have to send it directly over the network in the clear.
  5. Both the client and the server then use this pre-master secret, along with other publicly exchanged information, to generate the same symmetric encryption keys. This process is deterministic, meaning that if you have the same inputs (which they do), you get the same outputs.
  6. From this point forward, both the client and the server use these symmetric keys to encrypt and decrypt data. Because they’re using symmetric encryption, they both use the same key to encrypt and decrypt.

The ability to decrypt something encrypted with the public key using the corresponding private key (and vice versa) comes from the mathematical properties of the algorithms used to generate these key pairs. The details vary based on the exact algorithm (like RSA, DSA, ECC), but the general principle is that these algorithms use mathematical functions that are easy to compute in one direction but hard to reverse without some additional piece of information — the private key.

In the case of RSA, for example, the keys are generated using two large prime numbers. The public key consists of a large composite number (the product of the two primes) and a smaller number. The private key is a different number, derived from the two prime numbers and the smaller number in the public key. Because factoring a large composite number into its prime components is computationally hard (the “hard to reverse” part), it’s nearly impossible to derive the private key from the public key.

So when a client in an SSL/TLS handshake generates a pre-master secret and encrypts it with the server’s public key, only the server, with its private key, can decrypt it. This is due to the properties of the encryption algorithm: data encrypted with a public key can only be decrypted with the corresponding private key.

After the server decrypts the pre-master secret, both client and server use this shared secret along with other publicly exchanged information to generate the symmetric encryption keys used for the rest of the session. This allows them to securely exchange information over an insecure network, knowing that only they can decrypt and understand the transmitted data.

This process ensures that even if someone intercepts the communication, they can’t decipher the data without the shared session key. This is why TLS is slower than non-secure transmission, but this slight delay is a worthy trade-off for the significantly increased data security.

TLS is employed in numerous applications such as web browsing, email, instant messaging, and voice over IP (VoIP), providing privacy and data integrity between two or more communicating computer applications.

Secure Sockets Layer (SSL)

Secure Sockets Layer (SSL) is a cryptographic protocol developed by Netscape in the 1990s to ensure secure data transmission over the internet. It uses both asymmetric and symmetric encryption to secure a connection between two parties.

Asymmetric encryption involves a pair of keys — a public key and a private key. The public key is used to encrypt the data, and the corresponding private key is used to decrypt it. This key pair is used during the SSL handshake to exchange a symmetric key.

Symmetric encryption uses the same key to both encrypt and decrypt data. This symmetric key is what’s used to encrypt the actual transmitted data during an SSL session for performance reasons, as symmetric encryption is less resource-intensive than asymmetric encryption.

The process of establishing an SSL connection involves what’s known as an “SSL handshake,” which occurs immediately after a client and server establish a connection:

  1. The client sends a “ClientHello” message with its SSL version, cipher settings, and a random string of bytes known as the “client random.”
  2. The server responds with a “ServerHello” message, which also includes a random string of bytes — the “server random” — and decides on the highest SSL version and strongest cipher that both the client and server support.
  3. The server sends its SSL certificate (including its public key) and may request the client’s certificate.
  4. The client verifies the server’s SSL certificate with the certificate authority to confirm that it’s valid and trustworthy.
  5. The client creates a “pre-master secret,” encrypts it with the server’s public key (from the SSL certificate), and sends the encrypted pre-master secret to the server.
  6. The server decrypts the pre-master secret with its private key. Both the server and client then perform complex calculations to independently generate the same symmetric session key.
  7. Both the client and server exchange messages indicating that all future messages will be encrypted with the session key.

This process ensures that even if an attacker intercepts the encrypted pre-master secret, they won’t be able to decrypt it without the server’s private key. This whole process is completed in a matter of milliseconds and results in a secure, encrypted connection between the client and server.

SSL Termination

SSL Termination refers to the process of decrypting SSL-encrypted traffic at the load balancer level rather than at the web server. The primary advantage of SSL termination is that it offloads the resource-heavy process of encrypting and decrypting SSL traffic from the web server to the load balancer, allowing the web server to operate more efficiently.

However, SSL termination can introduce a security risk as the traffic sent from the load balancer to the web server is unencrypted, which could be an issue if that internal network is not secure. Some systems mitigate this risk by re-encrypting the traffic after SSL termination, but this introduces additional overhead.

Moreover, SSL termination can be costly in terms of the hardware or software required to handle SSL decryption at the load balancer level. It can be slower than end-to-end SSL because the SSL handshake is handled at the load balancer level rather than the origin server.

To improve performance, some systems employ SSL offloading, where the load balancer handles the computationally heavy parts of the SSL handshake and then re-encrypts the traffic to send to the backend servers. This allows for the benefits of SSL termination while still keeping the traffic secure.

--

--

Sanket Saxena
Sanket Saxena

Written by Sanket Saxena

I love writing about software engineering and all the cool things I learn along the way.

No responses yet