fn handshake()

in neqo-transport/src/connection/mod.rs [2888:2935]


    fn handshake(
        &mut self,
        now: Instant,
        packet_version: Version,
        space: PacketNumberSpace,
        data: Option<&[u8]>,
    ) -> Res<()> {
        qtrace!("[{self}] Handshake space={space} data={data:0x?}");

        let was_authentication_pending =
            *self.crypto.tls.state() == HandshakeState::AuthenticationPending;
        let try_update = data.is_some();
        match self.crypto.handshake(now, space, data)? {
            HandshakeState::Authenticated(_) | HandshakeState::InProgress => (),
            HandshakeState::AuthenticationPending => {
                if !was_authentication_pending {
                    self.events.authentication_needed();
                }
            }
            HandshakeState::EchFallbackAuthenticationPending(public_name) => self
                .events
                .ech_fallback_authentication_needed(public_name.clone()),
            HandshakeState::Complete(_) => {
                if !self.state.connected() {
                    self.set_connected(now)?;
                }
            }
            _ => {
                qerror!("Crypto state should not be new or failed after successful handshake");
                return Err(Error::CryptoError(neqo_crypto::Error::InternalError));
            }
        }

        // There is a chance that this could be called less often, but getting the
        // conditions right is a little tricky, so call whenever CRYPTO data is used.
        if try_update {
            self.compatible_upgrade(packet_version)?;
            // We have transport parameters, it's go time.
            if self.tps.borrow().remote.is_some() {
                self.set_initial_limits();
            }
            if self.crypto.install_keys(self.role)? {
                self.saved_datagrams.make_available(Epoch::Handshake);
            }
        }

        Ok(())
    }