// ServeConn serves a single connection
963655
func (s *rpcServer) ServeConn(sock transport.Socket) {
	defer func() {
		// close socket
		sock.Close()

		if r := recover(); r != nil {
			log.Log("panic recovered: ", r)
			log.Log(string(debug.Stack()))
		}
	}()

	for {
		var msg transport.Message
		if err := sock.Recv(&msg); err != nil {
			return
		}

		// add to wait group
		s.wg.Add(1)

		// we use this Timeout header to set a server deadline
		to := msg.Header["Timeout"]
		// we use this Content-Type header to identify the codec needed
		ct := msg.Header["Content-Type"]

		// strip our headers
		hdr := make(map[string]string)
		for k, v := range msg.Header {
			hdr[k] = v
		}

		// set local/remote ips
		hdr["Local"] = sock.Local()
		hdr["Remote"] = sock.Remote()

		// create new context
		ctx := metadata.NewContext(context.Background(), hdr)

		// set the timeout if we have it
		if len(to) > 0 {
			if n, err := strconv.ParseUint(to, 10, 64); err == nil {
				ctx, _ = context.WithTimeout(ctx, time.Duration(n))
			}
		}

		// no content type
		if len(ct) == 0 {
			msg.Header["Content-Type"] = DefaultContentType
			ct = DefaultContentType
		}

		// setup old protocol
		cf := setupProtocol(&msg)

		// no old codec
		if cf == nil {
			// TODO: needs better error handling
			var err error
			if cf, err = s.newCodec(ct); err != nil {
				sock.Send(&transport.Message{
					Header: map[string]string{
						"Content-Type": "text/plain",
					},
					Body: []byte(err.Error()),
				})
				s.wg.Done()
				return
			}
		}

		rcodec := newRpcCodec(&msg, sock, cf)

		// internal request
		request := &rpcRequest{
			service:     getHeader("Micro-Service", msg.Header),
			method:      getHeader("Micro-Method", msg.Header),
			endpoint:    getHeader("Micro-Endpoint", msg.Header),
			contentType: ct,
			codec:       rcodec,
			header:      msg.Header,
			body:        msg.Body,
			socket:      sock,
			stream:      true,
		}

		// internal response
		response := &rpcResponse{
			header: make(map[string]string),
			socket: sock,
			codec:  rcodec,
		}

		// set router
		r := s.opts.Router

		// if nil use default router
		if s.opts.Router == nil {
			r = s.router
		}

		// create a wrapped function
		handler := func(ctx context.Context, req Request, rsp interface{}) error {
			return r.ServeRequest(ctx, req, rsp.(Response))
		}

		for i := len(s.opts.HdlrWrappers); i > 0; i-- {
			handler = s.opts.HdlrWrappers[i-1](handler)
		}

		// TODO: handle error better
		if err := handler(ctx, request, response); err != nil {
			if err != lastStreamResponseError {
				// write an error response
				err = rcodec.Write(&codec.Message{
					Header: msg.Header,
					Error:  err.Error(),
					Type:   codec.Error,
				}, nil)
				// could not write the error response
				if err != nil {
					log.Logf("rpc: unable to write error response: %v", err)
				}
			}
			s.wg.Done()
			return
		}

		// done
		s.wg.Done()
	}
}
460083
func (s *RPCServer) Serve(lis net.Listener) {
	for {
		conn, err := lis.Accept()
		if err != nil {
			log.Printf("[ERR] plugin: plugin server: %s", err)
			return
		}

		go s.ServeConn(conn)
	}
}
615947
func (db *DB) conn() (*driverConn, error) {
	db.mu.Lock()
	if db.closed {
		db.mu.Unlock()
		return nil, errDBClosed
	}

	// If db.maxOpen > 0 and the number of open connections is over the limit
	// and there are no free connection, make a request and wait.
	if db.maxOpen > 0 && db.numOpen >= db.maxOpen && len(db.freeConn) == 0 {
		// Make the connRequest channel. It's buffered so that the
		// connectionOpener doesn't block while waiting for the req to be read.
		req := make(chan connRequest, 1)
		db.connRequests = append(db.connRequests, req)
		db.maybeOpenNewConnections()
		db.mu.Unlock()
		ret := <-req
		return ret.conn, ret.err
	}

	if c := len(db.freeConn); c > 0 {
		conn := db.freeConn[0]
		copy(db.freeConn, db.freeConn[1:])
		db.freeConn = db.freeConn[:c-1]
		conn.inUse = true
		db.mu.Unlock()
		return conn, nil
	}

	dsn := db.dsn
	db.numOpen++ // optimistically
	db.mu.Unlock()
	ci, err := db.driver.Open(dsn)
	if err != nil {
		db.mu.Lock()
		db.numOpen-- // correct for earlier optimism
		db.mu.Unlock()
		return nil, err
	}
	db.mu.Lock()
	dc := &driverConn{
		db:  db,
		ci:  ci,
		dsn: dsn,
	}
	db.addDepLocked(dc, dc)
	dc.inUse = true
	db.mu.Unlock()
	return dc, nil
}
1171219
func ServeConnWithContext(conn io.ReadWriteCloser, context interface{}) {
	rpc.ServeCodecWithContext(NewServerCodec(conn), context)
}
1312205
func (c *Client) handleConn(conn net.Conn) {
	// Read a single byte
	buf := make([]byte, 1)
	if _, err := conn.Read(buf); err != nil {
		if err != io.EOF {
			c.rpcLogger.Error("error reading byte", "error", err)
		}
		conn.Close()
		return
	}

	// Switch on the byte
	switch pool.RPCType(buf[0]) {
	case pool.RpcNomad:
		c.handleNomadConn(conn)

	case pool.RpcStreaming:
		c.handleStreamingConn(conn)

	default:
		c.rpcLogger.Error("unrecognized RPC byte", "byte", buf[0])
		conn.Close()
		return
	}
}
463293
func WithConn(conn net.PacketConn) ClientOpt {
	return func(c *Client) error {
		c.conn = conn
		return nil
	}
}
315290
func (l *Listener) handleConn(src net.Conn) {
	defer src.Close()

	dst, err := l.dialFunc()
	if err != nil {
		l.logger.Printf("[ERR] failed to dial: %s", err)
		return
	}

	// Track active conn now (first function call) and defer un-counting it when
	// it closes.
	defer l.trackConn()()

	// Make sure Close() waits for this conn to be cleaned up. Note defer is
	// before conn.Close() so runs after defer conn.Close().
	l.connWG.Add(1)
	defer l.connWG.Done()

	// Note no need to defer dst.Close() since conn handles that for us.
	conn := NewConn(src, dst)
	defer conn.Close()

	connStop := make(chan struct{})

	// Run another goroutine to copy the bytes.
	go func() {
		err = conn.CopyBytes()
		if err != nil {
			l.logger.Printf("[ERR] connection failed: %s", err)
		}
		close(connStop)
	}()

	// Periodically copy stats from conn to metrics (to keep metrics calls out of
	// the path of every single packet copy). 5 seconds is probably good enough
	// resolution - statsd and most others tend to summarize with lower resolution
	// anyway and this amortizes the cost more.
	var tx, rx uint64
	statsT := time.NewTicker(5 * time.Second)
	defer statsT.Stop()

	reportStats := func() {
		newTx, newRx := conn.Stats()
		if delta := newTx - tx; delta > 0 {
			metrics.IncrCounterWithLabels([]string{l.metricPrefix, "tx_bytes"},
				float32(newTx-tx), l.metricLabels)
		}
		if delta := newRx - rx; delta > 0 {
			metrics.IncrCounterWithLabels([]string{l.metricPrefix, "rx_bytes"},
				float32(newRx-rx), l.metricLabels)
		}
		tx, rx = newTx, newRx
	}
	// Always report final stats for the conn.
	defer reportStats()

	// Wait for conn to close
	for {
		select {
		case <-connStop:
			return
		case <-l.stopChan:
			return
		case <-statsT.C:
			reportStats()
		}
	}
}
503951
func (r *RRLoadBalancer) ServeTCP(conn net.Conn) {
	r.next().ServeTCP(conn)
}
1085273
func (c *RedisCache) conn() (redis.Conn, error) {
	if c.pool == nil {
		return nil, errNilPool
	}

	conn := c.pool.Get()
	err := conn.Err()
	if err != nil {
		return nil, err
	}

	_, err = conn.Do("SELECT", c.dbno)
	if err != nil {
		return nil, err
	}

	return conn, nil
}
811029
func (server *Server) ServeConnWithContext(conn io.ReadWriteCloser, context interface{}) {
	buf := bufio.NewWriter(conn)
	srv := &gobServerCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(buf), buf}
	server.ServeCodecWithContext(srv, context)
}
1032172
func Conn() *MockConn {
	return &MockConn{
		first:    true,
		Written:  make([][]byte, 0, 4),
		readings: make([][]byte, 0, 4),
	}
}
294100
func (n *Network) Conn(c net.Conn) (net.Conn, error) {
	start := now()
	nc := &conn{Conn: c, network: n, readBuf: new(bytes.Buffer)}
	if err := nc.sync(); err != nil {
		return nil, err
	}
	sleep(start.Add(nc.delay).Sub(now()))
	return nc, nil
}
910104
func (s *RPCServer) ServeConn(conn io.ReadWriteCloser) {
	// First create the yamux server to wrap this connection
	mux, err := yamux.Server(conn, nil)
	if err != nil {
		conn.Close()
		log.Printf("[ERR] plugin: error creating yamux server: %s", err)
		return
	}

	// Accept the control connection
	control, err := mux.Accept()
	if err != nil {
		mux.Close()
		if err != io.EOF {
			log.Printf("[ERR] plugin: error accepting control connection: %s", err)
		}

		return
	}

	// Connect the stdstreams (in, out, err)
	stdstream := make([]net.Conn, 2)
	for i, _ := range stdstream {
		stdstream[i], err = mux.Accept()
		if err != nil {
			mux.Close()
			log.Printf("[ERR] plugin: accepting stream %d: %s", i, err)
			return
		}
	}

	// Copy std streams out to the proper place
	go copyStream("stdout", stdstream[0], s.Stdout)
	go copyStream("stderr", stdstream[1], s.Stderr)

	// Create the broker and start it up
	broker := newMuxBroker(mux)
	go broker.Run()

	// Use the control connection to build the dispenser and serve the
	// connection.
	server := rpc.NewServer()
	server.RegisterName("Control", &controlServer{
		server: s,
	})
	server.RegisterName("Dispenser", &dispenseServer{
		broker:  broker,
		plugins: s.Plugins,
	})
	server.ServeConn(control)
}
808934
func (h *ConnectionsStatsHandler) HandleConn(ctx context.Context, stat stats.ConnStats) {
	lab, _ := ctx.Value(tagConnKey).(prometheus.Labels)

	switch stat.(type) {
	case *stats.ConnBegin:
		switch {
		case stat.IsClient() && h.subsystem == Client:
			h.vec.With(lab).Inc()
		case !stat.IsClient() && h.subsystem == Server:
			h.vec.With(lab).Inc()
		}
	case *stats.ConnEnd:
		switch {
		case stat.IsClient() && h.subsystem == Client:
			h.vec.With(lab).Dec()
		case !stat.IsClient() && h.subsystem == Server:
			h.vec.With(lab).Dec()
		}
	}
}
1301704
func handleConnection(conn net.Conn, errChan chan<- error) {

	// close the connection when we're done here
	defer conn.Close()

	// create a new client for each connection
	proxy := mist.NewProxy()
	defer proxy.Close()

	// add basic TCP command handlers for this connection
	handlers := GenerateHandlers()

	encoder := json.NewEncoder(conn)
	decoder := json.NewDecoder(conn)

	// publish mist messages (pong, etc.. and messages if subscriber attatched)
	// to connected tcp client (non-blocking)
	go func() {
		for msg := range proxy.Pipe {
			lumber.Trace("Got message - %#v", msg)
			// if the message fails to encode its probably a syntax issue and needs to
			// break the loop here because it will never be able to encode it; this will
			// disconnect the client.
			if err := encoder.Encode(msg); err != nil {
				errChan <- fmt.Errorf("Failed to pubilsh proxy.Pipe contents to TCP clients - %s", err.Error())
				break
			}
		}
	}()

	// connection loop (blocking); continually read off the connection. Once something
	// is read, check to see if it's a message the client understands to be one of
	// its commands. If so attempt to execute the command.
	for {
		msg := mist.Message{}

		// if the message fails to decode its probably a syntax issue and needs to
		// break the loop here because it will never be able to decode it; this will
		// disconnect the client.
		if err := decoder.Decode(&msg); err != nil {
			switch err {
			case io.EOF:
				lumber.Debug("Client disconnected")
			case io.ErrUnexpectedEOF:
				lumber.Debug("Client disconnected unexpedtedly")
			default:
				errChan <- fmt.Errorf("Failed to decode message from TCP connection - %s", err.Error())
			}
			return
		}

		// if an authenticator was passed, check for a token on connect to see if
		// auth commands are allowed
		if auth.IsConfigured() && !proxy.Authenticated {

			// if the next input does not match the token then
			if msg.Data != authtoken {
				lumber.Debug("Client data doesn't match configured auth token")
				// break // allow connection w/o admin commands
				return // disconnect client
			}

			// todo: is this still used?
			// add auth commands ("admin" mode)
			for k, v := range auth.GenerateHandlers() {
				handlers[k] = v
			}

			// establish that the connection has already authenticated
			proxy.Authenticated = true
		}

		// look for the command
		handler, found := handlers[msg.Command]

		// if the command isn't found, return an error and wait for the next command
		if !found {
			lumber.Trace("Command '%s' not found", msg.Command)
			encoder.Encode(&mist.Message{Command: msg.Command, Tags: msg.Tags, Data: msg.Data, Error: "Unknown Command"})
			continue
		}

		// attempt to run the command; if the command fails return the error and wait
		// for the next command
		lumber.Trace("TCP Running '%s'...", msg.Command)
		if err := handler(proxy, msg); err != nil {
			lumber.Debug("TCP Failed to run '%s' - %s", msg.Command, err.Error())
			encoder.Encode(&mist.Message{Command: msg.Command, Error: err.Error()})
			continue
		}
	}
}
792295
func (s *Server) handleConsulConn(conn net.Conn) {
	defer conn.Close()
	rpcCodec := msgpackrpc.NewServerCodec(conn)
	for {
		select {
		case <-s.shutdownCh:
			return
		default:
		}

		if err := s.rpcServer.ServeRequest(rpcCodec); err != nil {
			if err != io.EOF && !strings.Contains(err.Error(), "closed") {
				s.logger.Printf("[ERR] consul.rpc: RPC error: %v %s", err, logConn(conn))
				metrics.IncrCounter([]string{"rpc", "request_error"}, 1)
			}
			return
		}
		metrics.IncrCounter([]string{"rpc", "request"}, 1)
	}
}
810756
func (s *Server) handleConn(conn net.Conn, isTLS bool) {
	// Read a single byte
	buf := make([]byte, 1)
	if _, err := conn.Read(buf); err != nil {
		if err != io.EOF {
			s.logger.Printf("[ERR] consul.rpc: failed to read byte: %v %s", err, logConn(conn))
		}
		conn.Close()
		return
	}
	typ := pool.RPCType(buf[0])

	// Enforce TLS if VerifyIncoming is set
	if s.config.VerifyIncoming && !isTLS && typ != pool.RPCTLS {
		s.logger.Printf("[WARN] consul.rpc: Non-TLS connection attempted with VerifyIncoming set %s", logConn(conn))
		conn.Close()
		return
	}

	// Switch on the byte
	switch typ {
	case pool.RPCConsul:
		s.handleConsulConn(conn)

	case pool.RPCRaft:
		metrics.IncrCounter([]string{"rpc", "raft_handoff"}, 1)
		s.raftLayer.Handoff(conn)

	case pool.RPCTLS:
		if s.rpcTLS == nil {
			s.logger.Printf("[WARN] consul.rpc: TLS connection attempted, server not configured for TLS %s", logConn(conn))
			conn.Close()
			return
		}
		conn = tls.Server(conn, s.rpcTLS)
		s.handleConn(conn, true)

	case pool.RPCMultiplexV2:
		s.handleMultiplexV2(conn)

	case pool.RPCSnapshot:
		s.handleSnapshotConn(conn)

	default:
		if !s.handleEnterpriseRPCConn(typ, conn, isTLS) {
			s.logger.Printf("[ERR] consul.rpc: unrecognized RPC byte: %v %s", typ, logConn(conn))
			conn.Close()
		}
	}
}