fix(gateway): prefer relay frames before LAN capture
The gateway bridge loop uses a biased select so shutdown and relay lifecycle control events win over frame work. After those control paths, the loop used to poll physical LAN capture before relay datagrams. On a busy LAN, a perpetually readable AF_PACKET socket can delay ready remote client frames waiting to be injected onto the LAN. Service relay datagrams before LAN capture so remote-to-LAN traffic can cross the gateway promptly, while still preserving lifecycle-before-frame ordering. Test Plan: - cargo fmt --check - cargo test -p lanparty-gateway - cargo test --workspace - cargo clippy --workspace --all-targets -- -D warnings - git diff --check - git diff --cached --check Refs: MVP gateway bridge scheduling
This commit is contained in:
@@ -353,6 +353,55 @@ impl GatewayConnection {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
relay_frame = recv_gateway_ethernet_outcome(&connection, &welcome, &stats) => {
|
||||||
|
match relay_frame? {
|
||||||
|
GatewayReceiveOutcome::Accepted(relay_frame) => {
|
||||||
|
if let Some(drop_reason) = remote_clients.relay_frame_drop_reason(
|
||||||
|
relay_frame.source_peer_id(),
|
||||||
|
relay_frame.payload(),
|
||||||
|
)? {
|
||||||
|
stats.record_dropped_frame();
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
gateway_frame_log_line(
|
||||||
|
packet_socket.get_ref().interface(),
|
||||||
|
FrameDirection::RemoteToLan,
|
||||||
|
Some(relay_frame.source_peer_id()),
|
||||||
|
relay_frame.payload(),
|
||||||
|
FrameAction::Filtered,
|
||||||
|
Some(drop_reason),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
write_lan_ethernet(&packet_socket, relay_frame.payload()).await?;
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
gateway_frame_log_line(
|
||||||
|
packet_socket.get_ref().interface(),
|
||||||
|
FrameDirection::RemoteToLan,
|
||||||
|
Some(relay_frame.source_peer_id()),
|
||||||
|
relay_frame.payload(),
|
||||||
|
FrameAction::Forwarded,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
GatewayReceiveOutcome::Filtered(relay_frame) => {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
gateway_frame_log_line(
|
||||||
|
packet_socket.get_ref().interface(),
|
||||||
|
FrameDirection::RemoteToLan,
|
||||||
|
Some(relay_frame.source_peer_id),
|
||||||
|
&relay_frame.payload,
|
||||||
|
FrameAction::Filtered,
|
||||||
|
Some(relay_frame.drop_reason),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lan_frame = read_lan_ethernet(&packet_socket) => {
|
lan_frame = read_lan_ethernet(&packet_socket) => {
|
||||||
let lan_frame = lan_frame?;
|
let lan_frame = lan_frame?;
|
||||||
if EthernetFrame::parse(&lan_frame).is_err() {
|
if EthernetFrame::parse(&lan_frame).is_err() {
|
||||||
@@ -409,55 +458,6 @@ impl GatewayConnection {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
relay_frame = recv_gateway_ethernet_outcome(&connection, &welcome, &stats) => {
|
|
||||||
match relay_frame? {
|
|
||||||
GatewayReceiveOutcome::Accepted(relay_frame) => {
|
|
||||||
if let Some(drop_reason) = remote_clients.relay_frame_drop_reason(
|
|
||||||
relay_frame.source_peer_id(),
|
|
||||||
relay_frame.payload(),
|
|
||||||
)? {
|
|
||||||
stats.record_dropped_frame();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
gateway_frame_log_line(
|
|
||||||
packet_socket.get_ref().interface(),
|
|
||||||
FrameDirection::RemoteToLan,
|
|
||||||
Some(relay_frame.source_peer_id()),
|
|
||||||
relay_frame.payload(),
|
|
||||||
FrameAction::Filtered,
|
|
||||||
Some(drop_reason),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
write_lan_ethernet(&packet_socket, relay_frame.payload()).await?;
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
gateway_frame_log_line(
|
|
||||||
packet_socket.get_ref().interface(),
|
|
||||||
FrameDirection::RemoteToLan,
|
|
||||||
Some(relay_frame.source_peer_id()),
|
|
||||||
relay_frame.payload(),
|
|
||||||
FrameAction::Forwarded,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
GatewayReceiveOutcome::Filtered(relay_frame) => {
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
gateway_frame_log_line(
|
|
||||||
packet_socket.get_ref().interface(),
|
|
||||||
FrameDirection::RemoteToLan,
|
|
||||||
Some(relay_frame.source_peer_id),
|
|
||||||
&relay_frame.payload,
|
|
||||||
FrameAction::Filtered,
|
|
||||||
Some(relay_frame.drop_reason),
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ = cam_refresh_tick.tick() => {
|
_ = cam_refresh_tick.tick() => {
|
||||||
for refresh in remote_clients.refreshes() {
|
for refresh in remote_clients.refreshes() {
|
||||||
write_lan_ethernet(&packet_socket, refresh.frame()).await?;
|
write_lan_ethernet(&packet_socket, refresh.frame()).await?;
|
||||||
|
|||||||
Reference in New Issue
Block a user