예제 #1
0
파일: link.go 프로젝트: simia-tech/iris
// The actual message receiving logic. Reads a message from the stream, verifies
// its mac, decodes the headers and send it upwards. Direct receive is public for
// handshake simplifications, after which the link should switch to channel mode.
func (l *Link) RecvDirect() (*proto.Message, error) {
	var msg proto.Message
	var err error

	// Retrieve a new package
	if err = l.socket.Recv(&l.inHeadBuf); err != nil {
		return nil, err
	}
	if err = l.socket.Recv(&msg.Data); err != nil {
		return nil, err
	}
	if err = l.socket.Recv(&l.inMacBuf); err != nil {
		return nil, err
	}
	// Verify the message contents (payload + header)
	l.inMacer.Write(l.inHeadBuf)
	l.inMacer.Write(msg.Data)
	if !bytes.Equal(l.inMacBuf, l.inMacer.Sum(nil)) {
		err = errors.New(fmt.Sprintf("mac mismatch: have %v, want %v.", l.inMacer.Sum(nil), l.inMacBuf))
		return nil, err
	}
	// Extract the package contents
	l.inCipher.XORKeyStream(l.inHeadBuf, l.inHeadBuf)
	l.inBuffer.Write(l.inHeadBuf)
	if err = l.inCoder.Decode(&msg.Head); err != nil {
		return nil, err
	}
	// Set the message security knowingly to true
	msg.KnownSecure()
	return &msg, nil
}