Skip to content
Dridi Boukelmoune edited this page Sep 28, 2023 · 1 revision

VDD 2023Q3 Sep 26/27 Oslo

Dridi Daniel Walid phk Martin Niklas (Got tired and got here punctually) Dag Asad Simon Alve slink

AGENDA

When/If we get bored: Safe binary strings in variables

WEBSOCKET

ideas:

  • return(websocket)? vcl_websocket_response?
  • return(tunnel)? inspect tunnel response?
  • return(pipe) from vcl_backend_response? <- minimum first step?
    • beresp.upgrade flag raised by status 101? (forcing pipe transition, or failing?)
  • vcl hook at the end of the connection?
    • or rely on filters? how to propagate timeouts to filters?
  • send Close frame both ways when timeout triggers

WS for H1 does not define Connection: close, only upgrade Need to look at H2

Unclear if vcl_websocket_response is sufficient or if we need more

CLI PARALLELISM

real world problems:

  • ban while vcl.load

  • multi-tenant hosting reduce vcl.load total latency

  • long running commands

    • push stdout/stderr while command is running
  • multiple mgt threads? concurrent commands? "task spooler"?

  • only make specific commands (vcl.load) async?

    async vcl.load ... < async status async wait

  • OR: multiple connections?

  • vcl.prepare: vcl.load except init - does not solve long vcl_init time

  • problem: vcl label dependencies

    • just accept return(vcl()) to fail if vcl not loaded?
  • separate ban service listen port?

phk summary on this and the next topic:

MGT=>worker CLI connection becomes socketpair Tagged "protocol" on socket pair, tagging different CLI commands running in parallel and "named packages" (holding fd's) for use by subsequent CLI commands. Drop VCL-dependency tracking. vcl.use fails if vcl return(vcl) to nonexistent vcl. Mutex per vcl-name, serializes CLI operations on that vcl. vcl_init stage of vcl.load still serialized. keymaster/agent process as dependent, (info package (-n etc.) as JSON on stdin ?) cross-dependent connections ? (ie: worker-keymaster) ? has name, vmod/vext can search by name. restarting dependent creates new socketpair, mgt sends to worker/dependent dependents report cli commands they handle to mgt vjail considerations for dependents: gid,uid from argv, default "same as master"

idea:

  • mgt sends help -j to process, registers commands
    • when to refresh?
  • specific commands with an"async" flag, like vcl.load
    • async
    • async.list, async.await, async.clear commands?
    • example: async vcl.load name /path/to/name.vcl
  • non-blocking by default
    • serialize on vcl name (eg. vcl.load and vcl.use on the same vcl name)
  • remove VCL labels and rely on the host name to route to a specific VCL
    • bind VCL to domain names (could be restricted to SNI, as early as TLS handshake)

WORKER PROCESSES / CLI / ACCEPT SOCKET FD PASSING (SMUGGLER)

  • generalize child handling
  • define cli command passing (which process does it go to)
    • scope: mgt, worker, "internal"? vcl?

misc

  • creating stats should work

fd passing

ACCEPTOR RESTRUCTURE / HTTP/3

Will the existing structure work? Roaming?

(detailed discussion for which I (Nils) did not take notes because of the general nature)

Random notes

SES_Close() in cache_req_fsm.c should be below XPORT level {client|server|local|remote}.ip should be XPORT service

LTS RELEASES

  • no plans for new LTS "nothing major enough"
  • TLS==LTS?
  • would march release be a good new LTS base?
    • some extension in tree (deprecated_persistent storage)
    • wait a couple months after march before deciding

TIMEOUTS

After a 47 slides presentation on the current state of timeouts and the proposal for a new nomenclature, a list of candidates was established to be voted on the second day.

Existing timeout candidates:

  • backend_idle_timeout renamed to backend_pool_timeout?
  • between_bytes_timeout renamed to beresp_{idle,read}_timeout
  • cli_timeout renamed to cli_resp_timeout
  • connect_timeout renamed to {bereq,backend}_connect_timeout
  • first_byte_timeout renamed to beresp_start_timeout
  • idle_send_timeout renamed to resp_{idle,write}_timeout
  • pipe_timeout renamed to pipe_idle_timeout
  • send_timeout renamed to resp_{send,deliver,complete,finish}_timeout
  • startup_timeout renamed to cli_startup_timeout
  • timeout_idle renamed to sess_idle_timeout
  • timeout_linger renamed to sess_linger_timeout

Retired timeout candidates:

  • timeout_req brought back as sess_req_timeout

New timeout candidates:

  • bereq_{send,deliver,complete,finish}_timeout
  • req_{fetch,complete,finish}_timeout

Deadline candidates:

  • client_task_deadline
  • backend_task_deadline
  • pipe_task_deadline

No soft consensus reached.

TLS

Mockup from Simon:

vcl 4.1;

backend be none;
import std;
import tls;

sub vcl_init {
        tls.load_certificate("${topsrc}/etc/ca/bundle/example.com.pem",
                labels="default");

        tls.load_certificate("${topsrc}/etc/ca/bundle/wildcard.example.com.pem");
}

sub vcl_tls_handshake {
        if (!tls.set_certificate(tls.get_server_name())) {

                # Failed to find server name,
                # Use the default label
                if (! tls.set_certificate("default")) {
                        # Give up, failed to load cert
                        return(fail);
                }
        }

        tls.set_alpn("h3");

        # change alpn for specific url
        if(tls.get_server_name() == "h2_example.com"){
                tls.set_alpn("h2");
        }

        return(recv);
}

Binding connections to domains from TLS certificates?

Add to built-in vcl_recv?

if (req.http.host !~ sess.authority) {
          return (synth(404));
}

Where sess.authority has a dedicated VCL type for matching domain names (including wildcards).

We have req.proto, we probably need sess.proto (tcp, unix, quic).

  • Implement as Extensions with vmod interface
  • Add vcl "session" method to be called from transports
import tls from "/var/lib/varnish/vmods/libvmod_dridi_bikeshed.so";


sub vcl_init {
    tls.register_handshake_callback(tls_handshake);
    tls.register_shutdown_callback(tls_shutdown);
}

sub tls_handshake {
    // see simon's example above
}

sub tls_shutdown {
    mystats.add(tls.authority());
}

sub vcl_recv {
    // Dridi's example
    if (req.http.host !~ tls.authorities()) {
        return (synth(404));
    }
}

from SOCKET MGMT https://github.com/varnishcache/varnish-cache/pull/3959

-E FOOTLS.so => calls MAC_Register("FOOTLS", ...)

varnishd -a "public_https=:443,UDP FOOTLS options..."

socket.add  -p FOOTLS public_https :443 UDP options...

From the pull request discussion:

socket.open [name]
socket.close [-g grace] [name]
socket.list
socket.add [-c] [-p proto [-o proto_option ...]] [-a FOOTLS [-o acceptor_option ...]] name endpoint [endpoint_options...]
socket.mod [-p proto [-o proto_option ...]] [-a acceptor [-o acceptor_option ...]] name endpoint [endpoint_options...]
socket.discard name

VTEST/TLS

VS has vtest tls

https://github.com/varnishcache/varnish-cache/issues/3983

concensus: JUST DO IT

SESSION STATE MACHINE

  • see above: (re-)implemented transports can offer vcl hooks
  • would be unclear how a good state machine looked like
  • using the hooks we will understand how a potential generic state machine or hooks would look like
  • would at least need some mock up

BUGWASH

Syntax?

set beresp.http = obj_stale.http; # replace
set beresp.http |= obj_stale.http; # merge

Usage?

sub vcl_backend_refresh {
    if (special) {
        set beresp.http |= obj_stale.http;
        set beresp.status = 200;
        unset beresp.http.do-not-carry-over;
        return (beresp);
    }
}

# built-in
sub vcl_backend_refresh {
    set beresp.http |= obj_stale.http;
    set beresp.status = 200;
    return (beresp);
}

Transitions?

return (merge, stale, beresp|done, fail, abandon, error, retry);
# or
return (merge, obj, beresp, done);

CONSENSUS:

1.Do not add new functionality unless an implementor cannot complete a real application without it.

  • vcl_backend_refresh
  • beresp r/w access
  • obj_stale r/o access
  • return (merge, obj_stale, beresp, fail, abandon, error, retry);

merge: existing logic

  • change status to 200 if beresp.status == 304
  • header merge logic as is obj_stale: undo the result of the sub, just copy everything from obj_stale beresp: use beresp as it is (including status) beresp.was_304 is going to stay true

CLI IMPROVEMENTS

Nothing controversial. Left comments in PR (nils, minor) Suggestions: - Reverse the AUTH flag logic: make an UNAUTH flag instead, and make all commands require AUTH by default - SENSITIVE_COMMANDS: We want to log the command and only hide the sensitive part. Let the command decide what to log.

JSON CLI

simon to write up something

STRING TO BLOB CAST

yes

(should work similar to TOSTRAND(), simon will write something)

EOF

Clone this wiki locally