fn postprocess_packet()

in neqo-transport/src/connection/mod.rs [1532:1593]


    fn postprocess_packet(
        &mut self,
        path: &PathRef,
        tos: IpTos,
        remote: SocketAddr,
        packet: &PublicPacket,
        packet_number: PacketNumber,
        migrate: bool,
        now: Instant,
    ) {
        let ecn_mark = IpTosEcn::from(tos);
        let mut stats = self.stats.borrow_mut();
        stats.ecn_rx[packet.packet_type()] += ecn_mark;
        if let Some(last_ecn_mark) = stats.ecn_last_mark.filter(|&last_ecn_mark| {
            last_ecn_mark != ecn_mark && stats.ecn_rx_transition[last_ecn_mark][ecn_mark].is_none()
        }) {
            stats.ecn_rx_transition[last_ecn_mark][ecn_mark] =
                Some((packet.packet_type(), packet_number));
        }

        stats.ecn_last_mark = Some(ecn_mark);
        drop(stats);
        let space = PacketNumberSpace::from(packet.packet_type());
        if let Some(space) = self.acks.get_mut(space) {
            *space.ecn_marks() += ecn_mark;
        } else {
            qtrace!("Not tracking ECN for dropped packet number space");
        }

        if self.state == State::WaitInitial {
            self.start_handshake(path, packet, now);
        }

        if matches!(self.state, State::WaitInitial | State::WaitVersion) {
            let new_state = if self.has_version() {
                State::Handshaking
            } else {
                State::WaitVersion
            };
            self.set_state(new_state, now);
            if self.role == Role::Server && self.state == State::Handshaking {
                self.zero_rtt_state =
                    if self.crypto.enable_0rtt(self.version, self.role) == Ok(true) {
                        qdebug!("[{self}] Accepted 0-RTT");
                        ZeroRttState::AcceptedServer
                    } else {
                        ZeroRttState::Rejected
                    };
            }
        }

        if self.state.connected() {
            self.handle_migration(path, remote, migrate, now);
        } else if self.role != Role::Client
            && (packet.packet_type() == PacketType::Handshake
                || (packet.dcid().len() >= 8 && packet.dcid() == self.local_initial_source_cid))
        {
            // We only allow one path during setup, so apply handshake
            // path validation to this path.
            path.borrow_mut().set_valid(now);
        }
    }