in nfm-common/src/sock_ops_handler.rs [172:221]
fn handle_state_change(&mut self) -> SockOpsResult {
self.counters.state_change_events += 1;
// This callback is called before the state is actually changed, so the arguments need to
// be used instead of the ctx.state.
let old_state = self.ctx.arg(0);
let new_state = self.ctx.arg(1);
let mut new_flags = SockStateFlags::empty();
match self.get_or_add_sock_stats() {
Ok(stats_raw) => unsafe {
let sock_stats = &mut *stats_raw;
if new_state == BPF_TCP_ESTABLISHED {
new_flags |= SockStateFlags::ENTERED_ESTABLISH;
sock_stats.connect_end_us = self.now_us;
if old_state == BPF_TCP_SYN_SENT {
self.counters.active_established_events += 1;
sock_stats.connect_successes += 1;
}
} else if !matches!(new_state, BPF_TCP_SYN_SENT | BPF_TCP_SYN_RECV) {
new_flags |= SockStateFlags::STARTED_CLOSURE;
if matches!(old_state, BPF_TCP_SYN_SENT | BPF_TCP_SYN_RECV) {
new_flags |= SockStateFlags::TERMINATED_FROM_SYN;
}
if new_state == BPF_TCP_CLOSE {
new_flags |= SockStateFlags::CLOSED;
// Store some final stats on connection close.
let event_stats = nfm_get_sock_ops_stats(self.ctx);
sock_stats.bytes_received = event_stats.bytes_received;
sock_stats.bytes_delivered = event_stats.bytes_acked;
sock_stats.segments_received = event_stats.segments_received;
sock_stats.segments_delivered = event_stats.segments_delivered;
if old_state == BPF_TCP_ESTABLISHED {
new_flags |= SockStateFlags::TERMINATED_FROM_EST;
}
}
}
sock_stats.state_flags.insert(new_flags);
Ok(())
},
Err(e) => Err(e),
}
}