summaryrefslogtreecommitdiff
path: root/pkg/snowflake/lib/turbotunnel.go
blob: aad2e6a231e267d2e54707d73f4f3e5d4625d61a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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 }