dial.go
func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (c iconn.Conn, err error) {
	deadline := time.Now().Add(DialTimeout)
	ctx, cancel := context.WithDeadline(ctx, deadline)
	defer cancel()

	logdial := lgbl.Dial("conn", d.LocalPeer, remote, nil, raddr)
	logdial["encrypted"] = (d.PrivateKey != nil) // log wether this will be an encrypted dial or not.
	logdial["inPrivNet"] = (d.Protector != nil)

	defer log.EventBegin(ctx, "connDial", logdial).Done()

	if d.Protector == nil && ipnet.ForcePrivateNetwork {
		log.Error("tried to dial with no Private Network Protector but usage" +
			" of Private Networks is forced by the enviroment")
		return nil, ipnet.ErrNotInPrivateNetwork
	}

	defer func() {
		if err != nil {
			logdial["error"] = err.Error()
			logdial["dial"] = "failure"
		}
	}()

	maconn, err := d.rawConnDial(ctx, raddr, remote)
	if err != nil {
		return nil, err
	}

	defer func() {
		if err != nil {
			maconn.Close()
		}
	}()

	if d.Protector != nil {
		maconn, err = d.Protector.Protect(maconn)
		if err != nil {
			return nil, err
		}
	}

	if d.Wrapper != nil {
		maconn = d.Wrapper(maconn)
	}

	cryptoProtoChoice := SecioTag
	if !iconn.EncryptConnections || d.PrivateKey == nil {
		cryptoProtoChoice = NoEncryptionTag
	}

	selectResult := make(chan error, 1)
	go func() {
		selectResult <- msmux.SelectProtoOrFail(cryptoProtoChoice, maconn)
	}()
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case err = <-selectResult:
		if err != nil {
			return nil, err
		}
	}

	c = newSingleConn(ctx, d.LocalPeer, remote, maconn)
	if d.PrivateKey == nil || !iconn.EncryptConnections {
		log.Warning("dialer %s dialing INSECURELY %s at %s!", d, remote, raddr)
		return c, nil
	}

	c2, err := newSecureConn(ctx, d.PrivateKey, c)
	if err != nil {
		c.Close()
		return nil, err
	}

	// if the connection is not to whom we thought it would be...
	connRemote := c2.RemotePeer()
	if connRemote != remote {
		c2.Close()
		return nil, fmt.Errorf("misdial to %s through %s (got %s): %s", remote, raddr, connRemote, err)
	}

	logdial["dial"] = "success"
	return c2, nil
}
func (d *Dialer) Dial(ctx context.Context, raddr ma.Multiaddr, remote peer.ID) (c iconn.Conn, err error) {
	deadline := time.Now().Add(DialTimeout)
	ctx, cancel := context.WithDeadline(ctx, deadline)
	defer cancel()

	logdial := lgbl.Dial("conn", d.LocalPeer, remote, nil, raddr)
	logdial["encrypted"] = (d.PrivateKey != nil) // log wether this will be an encrypted dial or not.
	logdial["inPrivNet"] = (d.Protector != nil)

	defer log.EventBegin(ctx, "connDial", logdial).Done()

	if d.Protector == nil && ipnet.ForcePrivateNetwork {
		log.Error("tried to dial with no Private Network Protector but usage" +
			" of Private Networks is forced by the enviroment")
		return nil, ipnet.ErrNotInPrivateNetwork
	}

	defer func() {
		if err != nil {
			logdial["error"] = err.Error()
			logdial["dial"] = "failure"
		}
	}()

	maconn, err := d.rawConnDial(ctx, raddr, remote)
	if err != nil {
		return nil, err
	}

	defer func() {
		if err != nil {
			maconn.Close()
		}
	}()

	if d.Protector != nil {
		maconn, err = d.Protector.Protect(maconn)
		if err != nil {
			return nil, err
		}
	}

	if d.Wrapper != nil {
		maconn = d.Wrapper(maconn)
	}

	cryptoProtoChoice := SecioTag
	if !iconn.EncryptConnections || d.PrivateKey == nil {
		cryptoProtoChoice = NoEncryptionTag
	}

	selectResult := make(chan error, 1)
	go func() {
		selectResult <- msmux.SelectProtoOrFail(cryptoProtoChoice, maconn)
	}()
	select {
	case <-ctx.Done():
		return nil, ctx.Err()
	case err = <-selectResult:
		if err != nil {
			return nil, err
		}
	}

	c = newSingleConn(ctx, d.LocalPeer, remote, maconn)
	if d.PrivateKey == nil || !iconn.EncryptConnections {
		log.Warning("dialer %s dialing INSECURELY %s at %s!", d, remote, raddr)
		return c, nil
	}

	c2, err := newSecureConn(ctx, d.PrivateKey, c)
	if err != nil {
		c.Close()
		return nil, err
	}

	// if the connection is not to whom we thought it would be...
	connRemote := c2.RemotePeer()
	if connRemote != remote {
		c2.Close()
		return nil, fmt.Errorf("misdial to %s through %s (got %s): %s", remote, raddr, connRemote, err)
	}

	logdial["dial"] = "success"
	return c2, nil
}
// Dial connects to a peer over a particular address.
// The remote peer ID is only verified if secure connections are in use.
// It returns once the connection is established, the protocol negotiated,
// and the handshake complete (if applicable).