The `Peer` message in `pong.proto` (field `sni = 6`) carries the TLS SNI the client must present when dialing that peer. The comment states the client must put this exact hostname in the ClientHello SNI and that the Hub assigns it when the Node is created. The field has no non-empty contract: proto3 serialises an absent or explicitly zero-value `sni` as the empty string, and a receiver cannot distinguish that from a validly set field.
A client that dials a `Peer` with `sni = ""` either sends an empty SNI extension or omits it entirely. The Node, configured to answer a specific domain, rejects or ignores that handshake. The resulting connection failure looks identical to the Node being unreachable, so the client may silently rotate away from a healthy Node or enter a retry loop against a peer that will always reject it.
The bug is latent whenever a truncated, partially-serialised, or default-initialised `Peer` message reaches the client — a case the protocol currently gives no way to detect before dialling.
Add a `[(buf.validate.field).string.min_len = 1]` annotation on the `sni` field in `pong.proto`, or document the zero-value behaviour explicitly and add a guard in the code that processes incoming `Peer` messages so that a `Peer` with an empty `sni` is discarded rather than dialled.
The `Peer` message in `pong.proto` (field `sni = 6`) carries the TLS SNI the client must present when dialing that peer. The comment states the client must put this exact hostname in the ClientHello SNI and that the Hub assigns it when the Node is created. The field has no non-empty contract: proto3 serialises an absent or explicitly zero-value `sni` as the empty string, and a receiver cannot distinguish that from a validly set field.
A client that dials a `Peer` with `sni = ""` either sends an empty SNI extension or omits it entirely. The Node, configured to answer a specific domain, rejects or ignores that handshake. The resulting connection failure looks identical to the Node being unreachable, so the client may silently rotate away from a healthy Node or enter a retry loop against a peer that will always reject it.
The bug is latent whenever a truncated, partially-serialised, or default-initialised `Peer` message reaches the client — a case the protocol currently gives no way to detect before dialling.
Add a `[(buf.validate.field).string.min_len = 1]` annotation on the `sni` field in `pong.proto`, or document the zero-value behaviour explicitly and add a guard in the code that processes incoming `Peer` messages so that a `Peer` with an empty `sni` is discarded rather than dialled.