envoyproxy/envoy
Transport sockets
Transport sockets are the pluggable wire-framing layer that sits between Envoy's buffers and the kernel socket. Each connection (downstream or upstream) has exactly one transport socket. The interface is in envoy/network/transport_socket.h; implementations live under source/extensions/transport_sockets/.
What a transport socket does
- Reads from the kernel socket and produces decoded bytes for the filter manager and codec.
- Writes Envoy-produced bytes back to the kernel socket, possibly framing or encrypting.
- Negotiates during the connection setup (TLS handshake, ALTS handshake,
STARTTLSupgrade). - Reports SSL info, peer principal, transport-level errors.
- Supports drain / half-close semantics.
Shipped transport sockets
| Name | Path | Role |
|---|---|---|
raw_buffer |
raw_buffer/ |
Pass-through; the default. |
tls |
tls/ |
The BoringSSL-backed TLS socket — the headline implementation. |
quic |
source/common/quic/ |
TLS-equivalent for QUIC; integrates with the QUIC stack. |
alts |
alts/ |
Google ALTS, used for GCP service-to-service mTLS. |
proxy_protocol |
proxy_protocol/ |
Wraps another socket and prepends an outbound proxy-protocol header. Upstream side. |
http_11_proxy |
http_11_proxy/ |
Sends an HTTP/1.1 CONNECT to an HTTP proxy upstream, then negotiates the inner socket. |
starttls |
starttls/ |
Begins as plaintext, upgrades to TLS on a protocol-specific signal. Used for SMTP/IMAP/Postgres-style protocols. |
tap |
tap/ |
Wraps another socket and emits the wire bytes to the tap sink. |
tcp_stats |
tcp_stats/ |
Wraps another socket and emits TCP_INFO-derived stats (Linux-only). |
internal_upstream |
internal_upstream/ |
For "internal listeners": a virtual transport that connects to another listener in the same process. |
TLS transport socket
source/extensions/transport_sockets/tls/ is the largest single transport socket. It contains:
ssl_socket.{h,cc}— the actual transport socket implementation.context_impl.{h,cc}— the long-lived SSL context (cert chain, CA store, ALPN, etc.).context_manager_impl.{h,cc}— the per-server registry of contexts.cert_validator/— pluggable certificate validation (default, SPIFFE, allow-list).private_key/— plug-in support for hardware/HSM private keys.ocsp/— OCSP stapling.
Cert and key material come either inline in the bootstrap or, in production, via SDS. The TLS socket is wired with SDS-driven secret managers so cert rotation is hot.
Selection on the downstream side
Each FilterChain carries a transport_socket field. After listener-filter inspection (see listener filters) the matched chain's transport socket type is instantiated for the connection. SNI, source address, and ALPN can route different connections to different transport sockets.
Selection on the upstream side
Per-cluster transport_socket_matches (Cluster.transport_socket_matches) matches against host endpoint metadata. The cluster's TransportSocketMatcher (in source/extensions/transport_sockets/) chooses the right factory when a connection pool opens an upstream connection.
Transport socket interface
class TransportSocket {
void setTransportSocketCallbacks(TransportSocketCallbacks&);
std::string protocol() const;
absl::string_view failureReason() const;
bool canFlushClose();
Api::IoCallUint64Result doRead(Buffer::Instance&);
Api::IoCallUint64Result doWrite(Buffer::Instance&, bool end_stream);
void onConnected();
void closeSocket(Network::ConnectionEvent);
Ssl::ConnectionInfoConstSharedPtr ssl() const;
};doRead / doWrite are called by Network::ConnectionImpl (source/common/network/connection_impl.cc) on socket-readable / socket-writable events.
Common helpers
source/extensions/transport_sockets/common/ holds shared base classes for sockets that wrap an inner one (proxy_protocol, http_11_proxy, tap, tcp_stats). The pattern is identical:
class WrappingTransportSocket : public PassthroughSocket {
Api::IoCallUint64Result doWrite(Buffer::Instance& buffer, bool end_stream) override {
if (!header_sent_) {
writeHeader(...);
header_sent_ = true;
}
return PassthroughSocket::doWrite(buffer, end_stream);
}
};Adding a transport socket
- New directory under
source/extensions/transport_sockets/<name>/. - Implement
TransportSocketandTransportSocketFactory(downstream / upstream variants). - Register a
Network::DownstreamTransportSocketConfigFactoryand / orNetwork::UpstreamTransportSocketConfigFactory. - Add proto under
api/envoy/extensions/transport_sockets/<name>/v3/. - Register in
extensions_build_config.bzl.
See also
- Listener manager — picks the downstream transport socket.
- Cluster manager — picks the upstream transport socket.
- QUIC and HTTP/3 — the QUIC stack has its own transport-socket-equivalent.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.