// Note: Protocol v0 is symmetric until negotiation handshake completes
Protocol v0 is symmetric until negotiation handshake completes
Protocol v0 is symmetric until negotiation handshake completes
fn protocol_magic<'a, S: TunnelStream + Send + 'a>(
  stream: &'a mut S,
  protocol_version: u8,
) -> BoxFuture<'a, Result<u8, NegotiationError>> {
  let (mut read, write) = tokio::io::split(stream);
  // Write future to send our magic and version to the remote,
  // returning an error if writes are refused by the stream.
  let send_magic = write_magic_and_version(write, protocol_version);
  // Read future to get the magic from the remote, returning an error on magic mismatch
  let read_magic = async {
    let mut remote_magic = [0u8; 4];
    let remote_magic_len = read
      .read_exact(&mut remote_magic)
      .await
      .map_err(|_| NegotiationError::ProtocolViolation)?;
    if remote_magic_len < remote_magic.len() || &remote_magic != SNOCAT_NEGOTIATION_MAGIC {
      tracing::trace!("magic mismatch");
      return Err(NegotiationError::ProtocolViolation);
    }
    tracing::trace!("magic matched expectation");
    Result::<_, NegotiationError>::Ok(read)
  };
  async move {
    let (read, write) = futures::future::try_join(read_magic, send_magic).await?;
    let stream = read.unsplit(write);
    let remote_version = stream
      .read_u8()
      .await
      .map_err(|_| NegotiationError::ReadError)?;
    Ok(remote_version)
  }
  .instrument(tracing::trace_span!(stringify!(protocol_magic)))
  .boxed()
}
fn protocol_magic < ' a , S : TunnelStream + Send + ' a > ( stream : & ' a mut S , protocol_version : u8 , ) -> BoxFuture < ' a , Result < u8 , NegotiationError > > { let ( mut read , write ) = tokio :: io :: split ( stream ) ; // Write future to send our magic and version to the remote, // returning an error if writes are refused by the stream. let send_magic = write_magic_and_version ( write , protocol_version ) ; // Read future to get the magic from the remote, returning an error on magic mismatch let read_magic = async { let mut remote_magic = [ 0u8 ; 4 ] ; let remote_magic_len = read . read_exact ( & mut remote_magic ) . await . map_err ( | _ | NegotiationError :: ProtocolViolation ) ? ; if remote_magic_len < remote_magic . len ( ) || & remote_magic != SNOCAT_NEGOTIATION_MAGIC { tracing :: trace ! ( " " ) ; return Err ( NegotiationError :: ProtocolViolation ) ; } tracing :: trace ! ( " " ) ; Result :: < _ , NegotiationError > :: Ok ( read ) } ; async move { let ( read , write ) = futures :: future :: try_join ( read_magic , send_magic ) . await ? ; let stream = read . unsplit ( write ) ; let remote_version = stream . read_u8 ( ) . await . map_err ( | _ | NegotiationError :: ReadError ) ? ; Ok ( remote_version ) } . instrument ( tracing :: trace_span ! ( stringify ( protocol_magic ) ) ) . boxed ( ) }
Note: Protocol v0 is symmetric until negotiation handshake completes
Note : Protocol v0 is symmetric until negotiation handshake completes
stream
&'a mut S
protocol_version
u8