public virtual async ValueTask <(int auxHandle, string ipAddress, int portNumber, int timeout)> ConnectionRequestAsync(CancellationToken cancellationToken = default) { try { await Xdr.WriteAsync(IscCodes.op_connect_request, cancellationToken).ConfigureAwait(false); await Xdr.WriteAsync(IscCodes.P_REQ_async, cancellationToken).ConfigureAwait(false); await Xdr.WriteAsync(_handle, cancellationToken).ConfigureAwait(false); await Xdr.WriteAsync(PartnerIdentification, cancellationToken).ConfigureAwait(false); await Xdr.FlushAsync(cancellationToken).ConfigureAwait(false); await ReadOperationAsync(cancellationToken).ConfigureAwait(false); var auxHandle = await Xdr.ReadInt32Async(cancellationToken).ConfigureAwait(false); var garbage1 = new byte[8]; await Xdr.ReadBytesAsync(garbage1, 8, cancellationToken).ConfigureAwait(false); var respLen = await Xdr.ReadInt32Async(cancellationToken).ConfigureAwait(false); respLen += respLen % 4; var sin_family = new byte[2]; await Xdr.ReadBytesAsync(sin_family, 2, cancellationToken).ConfigureAwait(false); respLen -= 2; var sin_port = new byte[2]; await Xdr.ReadBytesAsync(sin_port, 2, cancellationToken).ConfigureAwait(false); var portNumber = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(sin_port, 0)); respLen -= 2; // * The address returned by the server may be incorrect if it is behind a NAT box // * so we must use the address that was used to connect the main socket, not the // * address reported by the server. var sin_addr = new byte[4]; await Xdr.ReadBytesAsync(sin_addr, 4, cancellationToken).ConfigureAwait(false); var ipAddress = _connection.IPAddress.ToString(); respLen -= 4; var garbage2 = new byte[respLen]; await Xdr.ReadBytesAsync(garbage2, respLen, cancellationToken).ConfigureAwait(false); await Xdr.ReadStatusVectorAsync(cancellationToken).ConfigureAwait(false); return(auxHandle, ipAddress, portNumber, _connection.Timeout); } catch (IOException ex) { throw IscException.ForIOException(ex); } }