pub fn decrypt_client_payload_aead_2022(
    context: &Context,
    method: CipherKind,
    key: &[u8],
    payload: &mut [u8],
    user_manager: Option<&ServerUserManager>,
) -> ProtocolResult<(usize, Address, UdpSocketControlData)> {
    let nonce_len = get_nonce_len(method);
    let tag_len = method.tag_len();
    let require_eih = method_support_eih(method) && user_manager.is_some();
    let eih_len = if require_eih { 16 } else { 0 };

    let header_len = nonce_len + tag_len + 8 + 8 + eih_len + 1 + 8 + 2;
    if payload.len() < header_len {
        return Err(ProtocolError::PacketTooShort(header_len, payload.len()));
    }

    let user = decrypt_message(context, method, key, payload, user_manager)?;

    let data = &payload[nonce_len..payload.len() - tag_len];
    let mut cursor = Cursor::new(data);

    let client_session_id = cursor.get_u64();
    let packet_id = cursor.get_u64();

    if require_eih {
        cursor.advance(16);
    }

    let socket_type = cursor.get_u8();
    if socket_type != CLIENT_SOCKET_TYPE {
        return Err(ProtocolError::InvalidSocketType(CLIENT_SOCKET_TYPE, socket_type));
    }
    let timestamp = cursor.get_u64();

    let now = get_now_timestamp();
    if now.abs_diff(timestamp) > SERVER_PACKET_TIMESTAMP_MAX_DIFF {
        return Err(ProtocolError::InvalidTimestamp(timestamp, now));
    }

    let padding_size = cursor.get_u16() as usize;
    if padding_size > 0 {
        cursor.seek(SeekFrom::Current(padding_size as i64))?;
    }

    let control = UdpSocketControlData {
        client_session_id,
        server_session_id: 0,
        packet_id,
        user,
    };

    let addr = match Address::read_cursor(&mut cursor) {
        Ok(a) => a,
        Err(err) => return Err(ProtocolError::InvalidAddress(err)),
    };

    let payload_start = cursor.position() as usize;
    let payload_len = data.len() - payload_start;

    payload.copy_within(nonce_len + payload_start..nonce_len + payload_start + payload_len, 0);

    Ok((payload_len, addr, control))
}
Decrypt `Client -> Server` UDP AEAD protocol packet
crates/shadowsocks/src/relay/udprelay/aead_2022.rs