You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: handlers.go
    path of file: ./repos/sealer/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client
    
    the code of the file until where you have to start completion: package client

import (
	"time"

	pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb"
	pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb"
	"github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util"

	"github.com/libp2p/go-libp2p-core/network"
)

var (
	StreamTimeout = 1 * time.Minute
	AcceptTimeout = 10 * time.Second
)

func (c *Client) handleStreamV2(s network.Stream) {
	log.Debugf("new relay/v2 stream from: %s", s.Conn().RemotePeer())

	s.SetReadDeadline(time.Now().Add(StreamTimeout))

	rd := util.NewDelimitedReader(s, maxMessageSize)
	defer rd.Close()

	writeResponse := func(status pbv2.Status) error {
		wr := util.NewDelimitedWriter(s)

		var msg pbv2.StopMessage
		msg.Type = pbv2.StopMessage_STATUS.Enum()
		msg.Status = status.Enum()

		return wr.WriteMsg(&msg)
	}

	handleError := func(status pbv2.Status) {
		log.Debugf("protocol
    
func (c *Client) handleStreamV2(s network.Stream) {
	log.Debugf("new relay/v2 stream from: %s", s.Conn().RemotePeer())

	s.SetReadDeadline(time.Now().Add(StreamTimeout))

	rd := util.NewDelimitedReader(s, maxMessageSize)
	defer rd.Close()

	writeResponse := func(status pbv2.Status) error {
		wr := util.NewDelimitedWriter(s)

		var msg pbv2.StopMessage
		msg.Type = pbv2.StopMessage_STATUS.Enum()
		msg.Status = status.Enum()

		return wr.WriteMsg(&msg)
	}

	handleError := func(status pbv2.Status) {
		log.Debugf("protocol error: %s (%d)", pbv2.Status_name[int32(status)], status)
		err := writeResponse(status)
		if err != nil {
			s.Reset()
			log.Debugf("error writing circuit response: %s", err.Error())
		} else {
			s.Close()
		}
	}

	var msg pbv2.StopMessage

	err := rd.ReadMsg(&msg)
	if err != nil {
		handleError(pbv2.Status_MALFORMED_MESSAGE)
		return
	}
	// reset stream deadline as message has been read
	s.SetReadDeadline(time.Time{})

	if msg.GetType() != pbv2.StopMessage_CONNECT {
		handleError(pbv2.Status_UNEXPECTED_MESSAGE)
		return
	}

	src, err := util.PeerToPeerInfoV2(msg.GetPeer())
	if err != nil {
		handleError(pbv2.Status_MALFORMED_MESSAGE)
		return
	}

	// check for a limit provided by the relay; if the limit is not nil, then this is a limited
	// relay connection and we mark the connection as transient.
	var stat network.Stat
	if limit := msg.GetLimit(); limit != nil {
		stat.Transient = true
		stat.Extra = make(map[interface{}]interface{})
		stat.Extra[StatLimitDuration] = time.Duration(limit.GetDuration()) * time.Second
		stat.Extra[StatLimitData] = limit.GetData()
	}

	log.Debugf("incoming relay connection from: %s", src.ID)

	select {
	case c.incoming <- accept{
		conn: &Conn{stream: s, remote: src, stat: stat, client: c},
		writeResponse: func() error {
			return writeResponse(pbv2.Status_OK)
		},
	}:
	case <-time.After(AcceptTimeout):
		handleError(pbv2.Status_CONNECTION_FAILED)
	}
}