// This will spin up go routines to solicit the remote leaf node connections.
323722
func (s *Server) solicitLeafNodeRemotes(remotes []*RemoteLeafOpts) {
	for _, r := range remotes {
		remote := newLeafNodeCfg(r)
		s.startGoRoutine(func() { s.connectToRemoteLeafNode(remote) })
	}
}
1121314
func (c *NodeController) Run() {
	glog.Infof("starting node controller")

	stopCh := c.StopChannel()
	go c.runWatcher(stopCh)

	<-stopCh
	glog.Infof("shutting down node controller")
}
1353153
func (f *NodeClient) NodeGetCapabilities(ctx context.Context, in *csipb.NodeGetCapabilitiesRequest, opts ...grpc.CallOption) (*csipb.NodeGetCapabilitiesResponse, error) {
	resp := &csipb.NodeGetCapabilitiesResponse{
		Capabilities: []*csipb.NodeServiceCapability{},
	}
	if f.stageUnstageSet {
		resp.Capabilities = append(resp.Capabilities, &csipb.NodeServiceCapability{
			Type: &csipb.NodeServiceCapability_Rpc{
				Rpc: &csipb.NodeServiceCapability_RPC{
					Type: csipb.NodeServiceCapability_RPC_STAGE_UNSTAGE_VOLUME,
				},
			},
		})
	}
	if f.expansionSet {
		resp.Capabilities = append(resp.Capabilities, &csipb.NodeServiceCapability{
			Type: &csipb.NodeServiceCapability_Rpc{
				Rpc: &csipb.NodeServiceCapability_RPC{
					Type: csipb.NodeServiceCapability_RPC_EXPAND_VOLUME,
				},
			},
		})
	}
	return resp, nil
}
644688
func (rm RemoteNode) String() string {
	return fmt.Sprintf("ID: %d,\nEndpoint: %s,\nServerTLSCert:%s, ClientTLSCert:%s",
		rm.ID, rm.Endpoint, DERtoPEM(rm.ServerTLSCert), DERtoPEM(rm.ClientTLSCert))
}
283031
func (h *Handler) handleGetNodes(w http.ResponseWriter, r *http.Request) {
	if !validHeaderAcceptJSON(r.Header) {
		http.Error(w, "JSON only acceptable response", http.StatusNotAcceptable)
		return
	}

	// Retrieve all nodes.
	nodes := h.api.Hosts(r.Context())

	// Write to response.
	if err := json.NewEncoder(w).Encode(nodes); err != nil {
		h.logger.Printf("json write error: %s", err)
	}
}
201012
func (s *SimAdapter) Dial(dest *enode.Node) (conn net.Conn, err error) {
	node, ok := s.GetNode(dest.ID())
	if !ok {
		return nil, fmt.Errorf("unknown node: %s", dest.ID())
	}
	srv := node.Server()
	if srv == nil {
		return nil, fmt.Errorf("node not running: %s", dest.ID())
	}
	// SimAdapter.pipe is net.Pipe (NewSimAdapter)
	pipe1, pipe2, err := s.pipe()
	if err != nil {
		return nil, err
	}
	// this is simulated 'listening'
	// asynchronously call the dialed destination node's p2p server
	// to set up connection on the 'listening' side
	go srv.SetupConn(pipe1, 0, nil)
	return pipe2, nil
}
124487
func (c *Client) ConnectNode(nodeID, peerID string) error {
	return c.Post(fmt.Sprintf("/nodes/%s/conn/%s", nodeID, peerID), nil, nil)
}
299401
func go_on_connect_callback(privateCtx unsafe.Pointer) C.int {
	log.Debug("go_on_connect_callback BEGIN")
	defer log.Debug("go_on_connect_callback END")
	context.lock.RLock()
	defer context.lock.RUnlock()

	// Get memif reference.
	ifIndex := int(uintptr(privateCtx))
	memif, exists := context.memifs[ifIndex]
	if !exists {
		return C.int(ErrNoConn.Code())
	}

	// Initialize Rx/Tx queues.
	err := memif.initQueues()
	if err != nil {
		if memifErr, ok := err.(*MemifError); ok {
			return C.int(memifErr.Code())
		}
		return C.int(ErrUnknown.Code())
	}

	// Call the user callback.
	if memif.callbacks.OnConnect != nil {
		memif.callbacks.OnConnect(memif)
	}

	// Start polling the RX queues for interrupts.
	for i := 0; i < len(memif.queueIntCh); i++ {
		memif.wg.Add(1)
		go pollRxQueue(memif, uint8(i))
	}

	return C.int(0)
}
1034982
func newLeafNodeCfg(remote *RemoteLeafOpts) *leafNodeCfg {
	cfg := &leafNodeCfg{
		RemoteLeafOpts: remote,
		urls:           make([]*url.URL, 0, 4),
	}
	// Start with the one that is configured. We will add to this
	// array when receiving async leafnode INFOs.
	cfg.urls = append(cfg.urls, cfg.URL)
	return cfg
}
684212
func (net *Network) ConnectToLastNode(id enode.ID) (err error) {
	net.lock.Lock()
	defer net.lock.Unlock()

	ids := net.getUpNodeIDs()
	l := len(ids)
	if l < 2 {
		return nil
	}
	last := ids[l-1]
	if last == id {
		last = ids[l-2]
	}
	return net.connectNotConnected(last, id)
}
1155107
func (r *Router) findNode(pathSegments []string, fuzzy bool) (*routingTreeNode, []string) {
	node := r.root
	for i, p := range pathSegments {
		if c, found := node.children[p]; found {
			node = c
		} else {
			if fuzzy { // try fuzzy search
				candidates := []string{}
				for key, _ := range node.children {
					if strings.HasPrefix(key, p) {
						candidates = append(candidates, key)
					}
				}
				if len(candidates) == 1 {
					node = node.children[candidates[0]]
					continue
				}
			}
			return node, pathSegments[i:]
		}
	}
	return node, nil
}
289852
func (net *Network) GetNodes() (nodes []*Node) {
	net.lock.RLock()
	defer net.lock.RUnlock()

	return net.getNodes()
}
1118839
func (s *Server) sendAsyncLeafNodeInfo() {
	for _, c := range s.leafs {
		c.mu.Lock()
		c.sendInfo(s.leafNodeInfoJSON)
		c.mu.Unlock()
	}
}
324842
func (s *Server) solicitGateway(cfg *gatewayCfg) {
	var (
		opts       = s.getOpts()
		isImplicit = cfg.isImplicit()
		urls       = cfg.getURLs()
		attempts   int
		typeStr    string
	)
	if isImplicit {
		typeStr = "implicit"
	} else {
		typeStr = "explicit"
	}
	for s.isRunning() && len(urls) > 0 {
		// Iteration is random
		for _, u := range urls {
			address, err := s.getRandomIP(s.gateway.resolver, u.Host)
			if err != nil {
				s.Errorf("Error getting IP for %s gateway %q (%s): %v", typeStr, cfg.Name, u.Host, err)
				continue
			}
			s.Noticef("Connecting to %s gateway %q (%s) at %s", typeStr, cfg.Name, u.Host, address)
			conn, err := net.DialTimeout("tcp", address, DEFAULT_ROUTE_DIAL)
			if err == nil {
				// We could connect, create the gateway connection and return.
				s.createGateway(cfg, u, conn)
				return
			}
			s.Errorf("Error connecting to %s gateway %q (%s) at %s: %v", typeStr, cfg.Name, u.Host, address, err)
			// Break this loop if server is being shutdown...
			if !s.isRunning() {
				break
			}
		}
		if isImplicit {
			attempts++
			if opts.Gateway.ConnectRetries == 0 || attempts > opts.Gateway.ConnectRetries {
				s.gateway.Lock()
				delete(s.gateway.remotes, cfg.Name)
				s.gateway.Unlock()
				return
			}
		}
		select {
		case <-s.quitCh:
			return
		case <-time.After(gatewayConnectDelay):
			continue
		}
	}
}
371105
func (g *gregorHandler) connectTLS() error {
	ctx := context.Background()
	if g.conn != nil {
		g.chatLog.Debug(ctx, "skipping connect, conn is not nil")
		return nil
	}

	uri := g.uri
	g.chatLog.Debug(ctx, "connecting to gregord via TLS at %s", uri)
	rawCA := g.G().Env.GetBundledCA(uri.Host)
	if len(rawCA) == 0 {
		return fmt.Errorf("No bundled CA for %s", uri.Host)
	}
	g.chatLog.Debug(ctx, "Using CA for gregor: %s", libkb.ShortCA(rawCA))
	// Let people know we are trying to sync
	g.G().NotifyRouter.HandleChatInboxSyncStarted(ctx, g.G().Env.GetUID())

	opts := rpc.ConnectionOpts{
		TagsFunc:                      logger.LogTagsFromContextRPC,
		WrapErrorFunc:                 libkb.MakeWrapError(g.G().ExternalG()),
		InitialReconnectBackoffWindow: func() time.Duration { return g.chatAwareInitialReconnectBackoffWindow(ctx) },
		ReconnectBackoff:              func() backoff.BackOff { return g.chatAwareReconnectBackoff(ctx) },
		DialerTimeout:                 10 * time.Second,
		// We deliberately avoid ForceInitialBackoff here, becuase we don't
		// want to penalize mobile, which tears down its connection frequently.
	}
	g.conn = rpc.NewTLSConnection(rpc.NewFixedRemote(uri.HostPort),
		[]byte(rawCA), libkb.NewContextifiedErrorUnwrapper(g.G().ExternalG()),
		g, libkb.NewRPCLogFactory(g.G().ExternalG()),
		logger.LogOutputWithDepthAdder{Logger: g.G().Log},
		rpc.DefaultMaxFrameLength, opts)

	// The client we get here will reconnect to gregord on disconnect if necessary.
	// We should grab it here instead of in OnConnect, since the connection is not
	// fully established in OnConnect. Anything that wants to make calls outside
	// of OnConnect should use g.cli, everything else should the client that is
	// a parameter to OnConnect
	g.cli = WrapGenericClientWithTimeout(g.conn.GetClient(), GregorRequestTimeout,
		chat.ErrChatServerTimeout)
	g.pingCli = g.conn.GetClient() // Don't want this to have a timeout from here

	// Start up ping loop to keep the connection to gregord alive, and to kick
	// off the reconnect logic in the RPC library
	go g.pingLoop()

	return nil
}
570724
func (s *ChainService) ConnectNode(addr string, permanent bool) error {
	replyChan := make(chan error)

	select {
	case s.query <- connectNodeMsg{
		addr:      addr,
		permanent: permanent,
		reply:     replyChan,
	}:
		return <-replyChan
	case <-s.quit:
		return nil
	}
}
836801
func (r *Router) dispatch(node *Trie, key, path, method, version string, leaf bool, params Params) (http.Handler, Params) {
	catchall := false
	if node.name != "" {
		if params == nil {
			params = Params{}
		}
		params.Add("rname", node.name)
	}
	if len(node.Handler) > 0 && leaf {
		return r.checkMethod(node, method), params
	} else if node.HasRegex {
		for _, n := range node.Node {
			if strings.HasPrefix(n.path, ":") {
				rx := r.dynamicRoutes[n.path]
				if rx.MatchString(key) {
					// add param to context
					if params == nil {
						params = Params{}
					}
					params.Add(n.path, key)
					node, key, path, leaf := node.Get(n.path+path, version)
					return r.dispatch(node, key, path, method, version, leaf, params)
				}
			}
		}
		if node.HasCatchall {
			catchall = true
		}
	} else if node.HasCatchall {
		catchall = true
	}
	if catchall {
		for _, n := range node.Node {
			if n.path == "*" {
				// add "*" to context
				if params == nil {
					params = Params{}
				}
				params.Add("*", key)
				if n.name != "" {
					params.Add("rname", n.name)
				}
				return r.checkMethod(n, method), params
			}
		}
	}
	// NotFound
	if r.NotFoundHandler != nil {
		return r.NotFoundHandler, params
	}
	return http.NotFoundHandler(), params
}