// handleMessages takes all messages from the Send channel // and actually sends them over the network. It then waits // for the response and puts it in the Recv channel. func (c *Client) handleMessages(tnl io.ReadWriter) { // We don't need compression for a local socket: protocol := protocol.NewProtocol(tnl, false) for { select { case <-c.quit: return case msg := <-c.Send: if err := protocol.Send(msg); err != nil { log.Warning("client-send: ", err) c.Recv <- nil continue } resp := &wire.Response{} if err := protocol.Recv(resp); err != nil { log.Warning("client-recv: ", err) c.Recv <- nil continue } c.Recv <- resp } } }
// Handles incoming requests: func (d *Server) handleConnection(ctx context.Context, conn net.Conn) { // Make sure this connection count gets released: defer func() { if err := conn.Close(); err != nil { log.Debugf("daemon-loop: connection drop failed: %v", err) } d.maxConnections <- allowOneConn{} }() tnl, err := security.NewEllipticTunnel(conn) if err != nil { log.Error("Tunnel failed", err) return } p := protocol.NewProtocol(tnl, false) // Loop until client disconnect or dies otherwise: for { msg := &wire.Command{} if err := p.Recv(msg); err != nil { if err != io.EOF { log.Warning("daemon-recv: ", err) } return } log.Infof("recv: %s: %v", conn.RemoteAddr().String(), msg) d.handleCommand(ctx, msg, p) } }
// wrapConnAsProto establishes the moose protocol on the raw ipfs connection func wrapConnAsProto(conn net.Conn, node *ipfsutil.Node, peerHash string) (*protocol.Protocol, error) { pub, err := node.PublicKeyFor(peerHash) if err != nil { return nil, err } priv, err := node.PrivateKey() if err != nil { return nil, err } authrw := security.NewAuthReadWriter(conn, priv, pub) if err := authrw.Trigger(); err != nil { return nil, err } return protocol.NewProtocol(authrw, true), nil }