code: func (ep *endpoint) Connect(addr tcpip.FullAddress) *tcpip.Error {
  	ep.mu.Lock()
  	defer ep.mu.Unlock()
  
  	if ep.closed {
  		return tcpip.ErrInvalidEndpointState
  	}
  
  	// We don't support IPv6 yet.
  	if len(addr.Addr) != header.IPv4AddressSize {
  		return tcpip.ErrInvalidEndpointState
  	}
  
  	nic := addr.NIC
  	if ep.bound {
  		if ep.boundNIC == 0 {
  			// If we're bound, but not to a specific NIC, the NIC
  			// in addr will be used. Nothing to do here.
  		} else if addr.NIC == 0 {
  			// If we're bound to a specific NIC, but addr doesn't
  			// specify a NIC, use the bound NIC.
  			nic = ep.boundNIC
  		} else if addr.NIC != ep.boundNIC {
  			// We're bound and addr specifies a NIC. They must be
  			// the same.
  			return tcpip.ErrInvalidEndpointState
  		}
  	}
  
  	// Find a route to the destination.
  	route, err := ep.stack.FindRoute(nic, tcpip.Address(""), addr.Addr, ep.netProto, false)
  	if err != nil {
  		return err
  	}
  	defer route.Release()
  
  	// Re-register the endpoint with the appropriate NIC.
  	if err := ep.stack.RegisterRawTransportEndpoint(addr.NIC, ep.netProto, ep.transProto, ep); err != nil {
  		return err
  	}
  	ep.stack.UnregisterRawTransportEndpoint(ep.registeredNIC, ep.netProto, ep.transProto, ep)
  
  	// Save the route and NIC we've connected via.
  	ep.route = route.Clone()
  	ep.registeredNIC = nic
  	ep.connected = true
  
  	return nil
  }
docs: // Connect implements tcpip.Endpoint.Connect.