示例#1
0
func exchangeHello(c net.Conn, h protocol.HelloMessage) (protocol.HelloMessage, error) {
	if err := c.SetDeadline(time.Now().Add(2 * time.Second)); err != nil {
		return protocol.HelloMessage{}, err
	}
	defer c.SetDeadline(time.Time{})

	header := make([]byte, 8)
	msg := h.MustMarshalXDR()

	binary.BigEndian.PutUint32(header[:4], protocol.HelloMessageMagic)
	binary.BigEndian.PutUint32(header[4:], uint32(len(msg)))

	if _, err := c.Write(header); err != nil {
		return protocol.HelloMessage{}, err
	}

	if _, err := c.Write(msg); err != nil {
		return protocol.HelloMessage{}, err
	}

	if _, err := io.ReadFull(c, header); err != nil {
		return protocol.HelloMessage{}, err
	}

	if binary.BigEndian.Uint32(header[:4]) != protocol.HelloMessageMagic {
		return protocol.HelloMessage{}, fmt.Errorf("incorrect magic")
	}

	msgSize := binary.BigEndian.Uint32(header[4:])
	if msgSize > 1024 {
		return protocol.HelloMessage{}, fmt.Errorf("hello message too big")
	}

	buf := make([]byte, msgSize)

	var hello protocol.HelloMessage

	if _, err := io.ReadFull(c, buf); err != nil {
		return protocol.HelloMessage{}, err
	}

	if err := hello.UnmarshalXDR(buf); err != nil {
		return protocol.HelloMessage{}, err
	}

	return hello, nil
}