code: func (e *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error {
  	e.mu.Lock()
  	defer e.mu.Unlock()
  
  	nicid := addr.NIC
  	localPort := uint16(0)
  	switch e.state {
  	case stateBound, stateConnected:
  		localPort = e.id.LocalPort
  		if e.bindNICID == 0 {
  			break
  		}
  
  		if nicid != 0 && nicid != e.bindNICID {
  			return tcpip.ErrInvalidEndpointState
  		}
  
  		nicid = e.bindNICID
  	default:
  		return tcpip.ErrInvalidEndpointState
  	}
  
  	netProto, err := e.checkV4Mapped(&addr, false)
  	if err != nil {
  		return err
  	}
  
  	// Find a route to the desired destination.
  	r, err := e.stack.FindRoute(nicid, e.bindAddr, addr.Addr, netProto, false /* multicastLoop */)
  	if err != nil {
  		return err
  	}
  	defer r.Release()
  
  	id := stack.TransportEndpointID{
  		LocalAddress:  r.LocalAddress,
  		LocalPort:     localPort,
  		RemoteAddress: r.RemoteAddress,
  	}
  
  	// Even if we're connected, this endpoint can still be used to send
  	// packets on a different network protocol, so we register both even if
  	// v6only is set to false and this is an ipv6 endpoint.
  	netProtos := []tcpip.NetworkProtocolNumber{netProto}
  
  	id, err = e.registerWithStack(nicid, netProtos, id)
  	if err != nil {
  		return err
  	}
  
  	e.id = id
  	e.route = r.Clone()
  	e.regNICID = nicid
  
  	e.state = stateConnected
  
  	e.rcvMu.Lock()
  	e.rcvReady = true
  	e.rcvMu.Unlock()
  
  	return nil
  }
docs: // Connect connects the endpoint to its peer. Specifying a NIC is optional.