blob: c038ef3feebebb20693cae575d40359283570d37 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vif
import (
"io"
"v.io/v23/verror"
"v.io/x/ref/runtime/internal/lib/iobuf"
"v.io/x/ref/runtime/internal/rpc/stream"
"v.io/x/ref/runtime/internal/rpc/stream/crypto"
"v.io/x/ref/runtime/internal/rpc/stream/message"
)
// setupConn writes the data to the net.Conn using SetupStream messages.
type setupConn struct {
writer io.Writer
reader *iobuf.Reader
cipher crypto.ControlCipher
rbuffer []byte // read buffer
}
var _ io.ReadWriteCloser = (*setupConn)(nil)
const maxFrameSize = 8192
func newSetupConn(writer io.Writer, reader *iobuf.Reader, c crypto.ControlCipher) *setupConn {
return &setupConn{writer: writer, reader: reader, cipher: c}
}
// Read implements the method from net.Conn.
func (s *setupConn) Read(buf []byte) (int, error) {
for len(s.rbuffer) == 0 {
msg, err := message.ReadFrom(s.reader, s.cipher)
if err != nil {
return 0, err
}
emsg, ok := msg.(*message.SetupStream)
if !ok {
return 0, verror.New(stream.ErrSecurity, nil, verror.New(errVersionNegotiationFailed, nil))
}
s.rbuffer = emsg.Data
}
n := copy(buf, s.rbuffer)
s.rbuffer = s.rbuffer[n:]
return n, nil
}
// Write implements the method from net.Conn.
func (s *setupConn) Write(buf []byte) (int, error) {
amount := 0
for len(buf) > 0 {
n := len(buf)
if n > maxFrameSize {
n = maxFrameSize
}
emsg := message.SetupStream{Data: buf[:n]}
if err := message.WriteTo(s.writer, &emsg, s.cipher); err != nil {
return 0, err
}
buf = buf[n:]
amount += n
}
return amount, nil
}
// Close does nothing.
func (s *setupConn) Close() error { return nil }