code: func (m *Memberlist) sendAndReceiveState(addr string, join bool) ([]pushNodeState, []byte, error) {
  	// Attempt to connect
  	conn, err := m.transport.DialTimeout(addr, m.config.TCPTimeout)
  	if err != nil {
  		return nil, nil, err
  	}
  	defer conn.Close()
  	m.logger.Printf("[DEBUG] memberlist: Initiating push/pull sync with: %s", conn.RemoteAddr())
  	metrics.IncrCounter([]string{"memberlist", "tcp", "connect"}, 1)
  
  	// Send our state
  	if err := m.sendLocalState(conn, join); err != nil {
  		return nil, nil, err
  	}
  
  	conn.SetDeadline(time.Now().Add(m.config.TCPTimeout))
  	msgType, bufConn, dec, err := m.readStream(conn)
  	if err != nil {
  		return nil, nil, err
  	}
  
  	if msgType == errMsg {
  		var resp errResp
  		if err := dec.Decode(&resp); err != nil {
  			return nil, nil, err
  		}
  		return nil, nil, fmt.Errorf("remote error: %v", resp.Error)
  	}
  
  	// Quit if not push/pull
  	if msgType != pushPullMsg {
  		err := fmt.Errorf("received invalid msgType (%d), expected pushPullMsg (%d) %s", msgType, pushPullMsg, LogConn(conn))
  		return nil, nil, err
  	}
  
  	// Read remote state
  	_, remoteNodes, userState, err := m.readRemoteState(bufConn, dec)
  	return remoteNodes, userState, err
  }
docs: // sendAndReceiveState is used to initiate a push/pull over a stream with a
  // remote host.