예제 #1
0
파일: link.go 프로젝트: simia-tech/iris
// The actual message sending logic. Calculates the payload MAC, encrypts the
// headers and sends it down to the stream. Direct send is public for handshake
// simplifications. After that is done, the link should switch to channel mode.
func (l *Link) SendDirect(msg *proto.Message) error {
	var err error

	// Sanity check for message data security
	if !msg.Secure() && len(msg.Data) > 0 {
		log.Printf("link: unsecured data, send denied.")
		return errors.New("unsecured data, send denied")
	}
	// Flatten and encrypt the headers
	if err = l.outCoder.Encode(msg.Head); err != nil {
		return err
	}
	l.outCipher.XORKeyStream(l.outBuffer.Bytes(), l.outBuffer.Bytes())
	defer l.outBuffer.Reset()

	// Generate the MAC of the encrypted payload and headers
	l.outMacer.Write(l.outBuffer.Bytes())
	l.outMacer.Write(msg.Data)

	// Send the multi-part message (headers + payload + MAC)
	if err = l.socket.Send(l.outBuffer.Bytes()); err != nil {
		return err
	}
	if err = l.socket.Send(msg.Data); err != nil {
		return err
	}
	if err = l.socket.Send(l.outMacer.Sum(nil)); err != nil {
		return err
	}
	return l.socket.Flush()
}