diff options
Diffstat (limited to 'pkg/snowflake/lib/turbotunnel.go')
-rw-r--r-- | pkg/snowflake/lib/turbotunnel.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/pkg/snowflake/lib/turbotunnel.go b/pkg/snowflake/lib/turbotunnel.go new file mode 100644 index 0000000..aad2e6a --- /dev/null +++ b/pkg/snowflake/lib/turbotunnel.go @@ -0,0 +1,68 @@ +package lib + +import ( + "bufio" + "errors" + "io" + "net" + "time" + + "git.torproject.org/pluggable-transports/snowflake.git/common/encapsulation" +) + +var errNotImplemented = errors.New("not implemented") + +// EncapsulationPacketConn implements the net.PacketConn interface over an +// io.ReadWriteCloser stream, using the encapsulation package to represent +// packets in a stream. +type EncapsulationPacketConn struct { + io.ReadWriteCloser + localAddr net.Addr + remoteAddr net.Addr + bw *bufio.Writer +} + +// NewEncapsulationPacketConn makes +func NewEncapsulationPacketConn( + localAddr, remoteAddr net.Addr, + conn io.ReadWriteCloser, +) *EncapsulationPacketConn { + return &EncapsulationPacketConn{ + ReadWriteCloser: conn, + localAddr: localAddr, + remoteAddr: remoteAddr, + bw: bufio.NewWriter(conn), + } +} + +// ReadFrom reads an encapsulated packet from the stream. +func (c *EncapsulationPacketConn) ReadFrom(p []byte) (int, net.Addr, error) { + data, err := encapsulation.ReadData(c.ReadWriteCloser) + if err != nil { + return 0, c.remoteAddr, err + } + return copy(p, data), c.remoteAddr, nil +} + +// WriteTo writes an encapsulated packet to the stream. +func (c *EncapsulationPacketConn) WriteTo(p []byte, addr net.Addr) (int, error) { + // addr is ignored. + _, err := encapsulation.WriteData(c.bw, p) + if err == nil { + err = c.bw.Flush() + } + if err != nil { + return 0, err + } + return len(p), nil +} + +// LocalAddr returns the localAddr value that was passed to +// NewEncapsulationPacketConn. +func (c *EncapsulationPacketConn) LocalAddr() net.Addr { + return c.localAddr +} + +func (c *EncapsulationPacketConn) SetDeadline(t time.Time) error { return errNotImplemented } +func (c *EncapsulationPacketConn) SetReadDeadline(t time.Time) error { return errNotImplemented } +func (c *EncapsulationPacketConn) SetWriteDeadline(t time.Time) error { return errNotImplemented } |