Varnish Cache Plus

TCP configuration (tcp)

Description

The TCP VMOD contains functions to control TCP congestion control algorithms, set pacing (rate limiting) and perform logging of protocol-related information.

VCL examples

TCP rate-limiting

import std;
import tcp;

sub vcl_recv
{
	# Limit all clients to 1000 KB/s.
	tcp.set_socket_pace(1000);
}

TCP congestion control algorithm

import std;
import tcp;

sub vcl_recv
{
	set req.http.X-Tcp = tcp.congestion_algorithm("bbr");
}

Here, the X-Tcp header field will be set to 0 when changing the congestion control algorithm succeeded. Otherwise, it will be -1, indicating an error.

See the tcp.congestion_algorithm() function for more information about congestion control algorithms.

API

tcp.congestion_algorithm()

INT congestion_algorithm(STRING algo)

Set the client socket congestion control algorithm to algo. Returns 0 on success, and -1 on error.

sub vcl_recv {
	set req.http.x-tcp = tcp.congestion_algorithm("cubic");
}

To see your available algorithms:

# sysctl net.ipv4.tcp_available_congestion_control 
net.ipv4.tcp_available_congestion_control = reno cubic bbr

The bbr congestion control algorithm is fairly new requires kernel version 4.9.0 or later. See: https://www.vultr.com/docs/how-to-deploy-google-bbr-on-centos-7

tcp.dump_info()

VOID dump_info()

Write the contents of the TCP_INFO data structure into varnishlog.

sub vcl_recv {
	tcp.dump_info();
}

The varnishlog output could look like this:

-   VCL_Log        tcpi: snd_mss=1448 rcv_mss=536 lost=0 retrans=0
-   VCL_Log        tcpi2: pmtu=1500 rtt=12042 rttvar=6021 snd_cwnd=10 advmss=1448 reordering=3
-   VCL_Log        getsockopt() returned: bbr

tcp.get_estimated_rtt()

REAL get_estimated_rtt()

Get the estimated round-trip-time for the client socket, measured in milliseconds.

sub vcl_recv
{
	if (tcp.get_estimated_rtt() > 300) {
		std.log("Client is far away!");
	}
}

tcp.set_socket_pace()

VOID set_socket_pace(INT pace)

Socket pacing is a Linux method for rate limiting TCP connections in a network friendly way.

Controls TCP rate limiting for the client connection, where pace is measured in KB/s. The outgoing network interface used must be configured with a supported scheduler, such as fq.

sub vcl_recv
{
	# Set client max bandwidth to 1000kb/s for this client,
	# as long as the current network scheduler supports it:
    if (tcp.set_socket_pace(1000) != 0) {
		std.log("Failed to set pacing for client socket!");
	}
}

Servers utilizing rate limiting must change their network scheduler. This can be changed with a sysctl setting:

net.core.default_qdisc=fq

See: https://wiki.mikejung.biz/Sysctl_tweaks