mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
`coder vpn-daemon run` will instantiate a RPC connection with the specified pipe handles and communicate with the (yet to be implemented) parent process. The tests don't ensure that the tunnel is actually usable yet as the tunnel functionality isn't implemented, but it does make sure that the tunnel tries to read from the RPC pipe. Closes #14735
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package vpn
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
|
|
"github.com/hashicorp/go-multierror"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
// BidirectionalPipe combines a pair of files that can be used for bidirectional
|
|
// communication.
|
|
type BidirectionalPipe struct {
|
|
read *os.File
|
|
write *os.File
|
|
}
|
|
|
|
var _ io.ReadWriteCloser = BidirectionalPipe{}
|
|
|
|
// NewBidirectionalPipe creates a new BidirectionalPipe from the given file
|
|
// descriptors.
|
|
func NewBidirectionalPipe(readFd, writeFd uintptr) (BidirectionalPipe, error) {
|
|
read := os.NewFile(readFd, "pipe_read")
|
|
_, err := read.Stat()
|
|
if err != nil {
|
|
return BidirectionalPipe{}, xerrors.Errorf("stat pipe_read (fd=%v): %w", readFd, err)
|
|
}
|
|
write := os.NewFile(writeFd, "pipe_write")
|
|
_, err = write.Stat()
|
|
if err != nil {
|
|
return BidirectionalPipe{}, xerrors.Errorf("stat pipe_write (fd=%v): %w", writeFd, err)
|
|
}
|
|
return BidirectionalPipe{
|
|
read: read,
|
|
write: write,
|
|
}, nil
|
|
}
|
|
|
|
// Read implements io.Reader. Data is read from the read pipe.
|
|
func (b BidirectionalPipe) Read(p []byte) (int, error) {
|
|
n, err := b.read.Read(p)
|
|
if err != nil {
|
|
return n, xerrors.Errorf("read from pipe_read (fd=%v): %w", b.read.Fd(), err)
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// Write implements io.Writer. Data is written to the write pipe.
|
|
func (b BidirectionalPipe) Write(p []byte) (n int, err error) {
|
|
n, err = b.write.Write(p)
|
|
if err != nil {
|
|
return n, xerrors.Errorf("write to pipe_write (fd=%v): %w", b.write.Fd(), err)
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// Close implements io.Closer. Both the read and write pipes are closed.
|
|
func (b BidirectionalPipe) Close() error {
|
|
var err error
|
|
rErr := b.read.Close()
|
|
if rErr != nil {
|
|
err = multierror.Append(err, xerrors.Errorf("close pipe_read (fd=%v): %w", b.read.Fd(), rErr))
|
|
}
|
|
wErr := b.write.Close()
|
|
if err != nil {
|
|
err = multierror.Append(err, xerrors.Errorf("close pipe_write (fd=%v): %w", b.write.Fd(), wErr))
|
|
}
|
|
return err
|
|
}
|