fn decode_preferred_address()

in neqo-transport/src/tparams.rs [212:255]


    fn decode_preferred_address(d: &mut Decoder) -> Res<Self> {
        // IPv4 address (maybe)
        let v4ip = Ipv4Addr::from(<[u8; 4]>::try_from(d.decode(4).ok_or(Error::NoMoreData)?)?);
        let v4port = d.decode_uint::<u16>().ok_or(Error::NoMoreData)?;
        // Can't have non-zero IP and zero port, or vice versa.
        if v4ip.is_unspecified() ^ (v4port == 0) {
            return Err(Error::TransportParameterError);
        }
        let v4 = if v4port == 0 {
            None
        } else {
            Some(SocketAddrV4::new(v4ip, v4port))
        };

        // IPv6 address (mostly the same as v4)
        let v6ip = Ipv6Addr::from(<[u8; 16]>::try_from(
            d.decode(16).ok_or(Error::NoMoreData)?,
        )?);
        let v6port = d.decode_uint().ok_or(Error::NoMoreData)?;
        if v6ip.is_unspecified() ^ (v6port == 0) {
            return Err(Error::TransportParameterError);
        }
        let v6 = if v6port == 0 {
            None
        } else {
            Some(SocketAddrV6::new(v6ip, v6port, 0, 0))
        };
        // Need either v4 or v6 to be present.
        if v4.is_none() && v6.is_none() {
            return Err(Error::TransportParameterError);
        }

        // Connection ID (non-zero length)
        let cid = ConnectionId::from(d.decode_vec(1).ok_or(Error::NoMoreData)?);
        if cid.is_empty() || cid.len() > MAX_CONNECTION_ID_LEN {
            return Err(Error::TransportParameterError);
        }

        // Stateless reset token
        let srtbuf = d.decode(16).ok_or(Error::NoMoreData)?;
        let srt = <[u8; 16]>::try_from(srtbuf)?;

        Ok(Self::PreferredAddress { v4, v6, cid, srt })
    }