Build a Service Mesh (Envoy / Istio style) (13 scenes)
Scene 04 · Listener and route — bind and match
A listener accepts on a port; an ordered route table picks a destination on the first match. Reorder the rules and the same request lands somewhere else.
Previously
Reading method and path is only useful if the proxy has a structured table that says 'this kind of request goes there' — and that table is two named pieces: a listener and a route.
Scene 04
Listener and route — bind and match
Diagram
The tab on the left edge of the sidecar is the **listener**: a socket the proxy binds — an `(address, port)` like 0.0.0.0:8080 where requests arrive. Inside the proxy is an ordered list of rows, each one a **route**: a match rule (path prefix, method, or header) and a destination name. The proxy evaluates the rows top-to-bottom and the first one that matches wins — every row below it is unreachable for that request.
↑ listener — socket bound to (0.0.0.0, 8080) where requests arrive
↓ ordered routes — first match wins, every row below is unreachable
← this route matched first → exit toward its destination
A test request `GET /checkout/cart` (with header `x-canary: true`) hits the listener on port 8080. The proxy walks the route table top-to-bottom. The first matching row glows green and the request exits toward its named destination.
Implementation
Listener.bind(address, port)
the socket the proxy listens on — LDS pushes this
1def bind_listener(cfg):2 sock = listen(addr=cfg.address, port=cfg.port)3 # filter chain: TLS? HTTP? raw TCP? — picks HCM here.4 chain = [http_connection_manager(routes=cfg.routes)]5 while conn := sock.accept():6 chain.handle(conn) # parse req, then route_match
RouteTable.match(req) # first-match-wins
walk the rows top-to-bottom; return on the first hit
1def match(req, routes):2 for route in routes: # ORDERED — RDS order is policy3 if matches(req, route.match):4 return route.destination5 return DEFAULT_REJECT # 404 / direct_response67def matches(req, m):8 if m.kind == 'wildcard': return True9 if m.kind == 'prefix': return req.path.startswith(m.value)10 if m.kind == 'header':11 name, want = m.value.split(':', 1)12 return req.headers.get(name.strip()) == want.strip()
match(GET /checkout/cart, x-canary: true)
same request, three orderings, three destinations
1# ordering 0: wildcard on top2[wildcard '/*', prefix '/checkout', header 'x-canary'] -> default-svc34# ordering 1: prefix on top (canary unreachable below)5[prefix '/checkout', header 'x-canary', wildcard '/*'] -> checkout-v167# ordering 2: header on top (canary works)8[header 'x-canary', prefix '/checkout', wildcard '/*'] -> checkout-v2