Skip to content

Commit 4bc9d83

Browse files
jondkinneyclaude
andcommitted
fix(version-exchange): also store peer commit on the listen side
Previously the Hello handler in `ListenTask` echoed our local commit back but deliberately threw away the peer's, on the assumption that the outgoing connect-side path (`connect.rs:278-279` → `set_peer_commit`) would always populate the visible state for any bidirectionally-configured peer. That assumption breaks any time the *outgoing* TCP/DTLS direction is broken even though the inbound direction is fine — happened just now when the peer Mac's daemon stopped listening on 4242 (DHCP-renewed IP, daemon crashed, asymmetric NAT, …). Mac was still happily connecting in the other direction and sending events, including the initial Hello, but Linux silently displayed "peer version unknown" because the listen side dropped Mac's commit on the floor. Add a `PeerHello { addr, commit }` EmulationEvent variant fired from the listen-side Hello handler. The service maps `addr → ClientHandle` via `client_manager.get_client(addr)` and calls `set_peer_commit` + `broadcast_client` exactly like the connect path does. The connect path remains the primary source for symmetric setups; this is the defensive fallback so version visibility doesn't depend on outbound reachability. Skips silently when no outgoing client is configured for the peer's addr (incoming-only setup) — there's no UI row to update in that case anyway. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 6de1c50 commit 4bc9d83

2 files changed

Lines changed: 37 additions & 10 deletions

File tree

src/emulation.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ pub(crate) enum EmulationEvent {
5353
EmulationEnabled,
5454
/// capture should be released
5555
ReleaseNotify,
56+
/// peer sent us a Hello with its build commit hash. Used to
57+
/// populate `client_manager.peer_commit` from the listen side
58+
/// too — without this, peer-version visibility silently fails
59+
/// whenever the outgoing connection in the *other* direction is
60+
/// broken (one-way setups, asymmetric NAT, peer's TCP listener
61+
/// down). The connect-side path stays as the primary source;
62+
/// this is the defensive fallback.
63+
PeerHello {
64+
addr: SocketAddr,
65+
commit: [u8; 8],
66+
},
5667
}
5768

5869
enum EmulationRequest {
@@ -180,16 +191,21 @@ impl ListenTask {
180191
}
181192
ProtoEvent::Input(event) => self.emulation_proxy.consume(event, addr),
182193
ProtoEvent::Ping => self.listener.reply(addr, ProtoEvent::Pong(self.emulation_proxy.emulation_active.get())).await,
183-
// Mirror the peer's version handshake. The
184-
// outgoing connect side initiated this with
185-
// its own Hello; we echo ours back so the
186-
// peer's connect-side receive_loop can
187-
// populate `peer_commit`. We don't store
188-
// the peer's commit on the listen side —
189-
// the user-visible state lives on outgoing
190-
// connections, where the same peer is also
191-
// configured as a `[[clients]]` entry.
192-
ProtoEvent::Hello { .. } => self.listener.reply(addr, ProtoEvent::Hello { commit: local_commit() }).await,
194+
// Peer's version handshake. Echo our own
195+
// commit back so the peer's connect-side
196+
// receive_loop populates its `peer_commit`,
197+
// AND publish a PeerHello upward so our
198+
// service can populate ours from the listen
199+
// side too — the connect side is the primary
200+
// path, but if the outbound direction is
201+
// broken (one-way setup, NAT, peer's TCP
202+
// listener down) the version display would
203+
// otherwise silently say "unknown" while
204+
// the peer is in fact happily talking to us.
205+
ProtoEvent::Hello { commit } => {
206+
self.listener.reply(addr, ProtoEvent::Hello { commit: local_commit() }).await;
207+
self.event_tx.send(EmulationEvent::PeerHello { addr, commit }).expect("channel closed");
208+
}
193209
// Capturing peer told us where on its own
194210
// screen the user's cursor was, as a
195211
// normalized fraction (nx, ny) ∈ [0, 1]

src/service.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,17 @@ impl Service {
333333
EmulationEvent::Connected { addr, fingerprint } => {
334334
self.notify_frontend(FrontendEvent::DeviceConnected { addr, fingerprint });
335335
}
336+
EmulationEvent::PeerHello { addr, commit } => {
337+
// Map the peer's source addr back to its client handle
338+
// and stamp the commit. Skip if we don't have an
339+
// outgoing client configured for this peer (incoming-
340+
// only setup) — there's nowhere to display the version
341+
// in that case anyway.
342+
if let Some(handle) = self.client_manager.get_client(addr) {
343+
self.client_manager.set_peer_commit(handle, Some(commit));
344+
self.broadcast_client(handle);
345+
}
346+
}
336347
}
337348
}
338349

0 commit comments

Comments
 (0)