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 }