ソースを参照

Change rwc to rwc with addresses

tags/0.9
9seconds 7年前
コミット
09476cc467

+ 2
- 2
client/client.go ファイルの表示

1
 package client
1
 package client
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"net"
4
 	"net"
6
 
5
 
7
 	"github.com/9seconds/mtg/config"
6
 	"github.com/9seconds/mtg/config"
8
 	"github.com/9seconds/mtg/mtproto"
7
 	"github.com/9seconds/mtg/mtproto"
8
+	"github.com/9seconds/mtg/wrappers"
9
 )
9
 )
10
 
10
 
11
 // Init has to initialize client connection based on given config.
11
 // Init has to initialize client connection based on given config.
12
-type Init func(net.Conn, *config.Config) (*mtproto.ConnectionOpts, io.ReadWriteCloser, error)
12
+type Init func(net.Conn, *config.Config) (*mtproto.ConnectionOpts, wrappers.ReadWriteCloserWithAddr, error)

+ 1
- 2
client/direct.go ファイルの表示

1
 package client
1
 package client
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"net"
4
 	"net"
6
 	"time"
5
 	"time"
7
 
6
 
16
 const handshakeTimeout = 10 * time.Second
15
 const handshakeTimeout = 10 * time.Second
17
 
16
 
18
 // DirectInit initializes client to access Telegram bypassing middleproxies.
17
 // DirectInit initializes client to access Telegram bypassing middleproxies.
19
-func DirectInit(conn net.Conn, conf *config.Config) (*mtproto.ConnectionOpts, io.ReadWriteCloser, error) {
18
+func DirectInit(conn net.Conn, conf *config.Config) (*mtproto.ConnectionOpts, wrappers.ReadWriteCloserWithAddr, error) {
20
 	if err := config.SetSocketOptions(conn); err != nil {
19
 	if err := config.SetSocketOptions(conn); err != nil {
21
 		return nil, nil, errors.Annotate(err, "Cannot set socket options")
20
 		return nil, nil, errors.Annotate(err, "Cannot set socket options")
22
 	}
21
 	}

+ 5
- 3
mtproto/wrappers/crypt.go ファイルの表示

7
 	"crypto/md5"
7
 	"crypto/md5"
8
 	"crypto/sha1"
8
 	"crypto/sha1"
9
 	"encoding/binary"
9
 	"encoding/binary"
10
-	"io"
11
 	"net"
10
 	"net"
12
 
11
 
13
 	"github.com/9seconds/mtg/mtproto/rpc"
12
 	"github.com/9seconds/mtg/mtproto/rpc"
23
 
22
 
24
 var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
23
 var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
25
 
24
 
26
-func NewMiddleProxyCipherRWC(conn io.ReadWriteCloser, req *rpc.RPCNonceRequest, resp *rpc.RPCNonceResponse, client *net.TCPAddr, remote *net.TCPAddr, secret []byte) io.ReadWriteCloser {
25
+func NewMiddleProxyCipherRWC(conn wrappers.ReadWriteCloserWithAddr, req *rpc.RPCNonceRequest,
26
+	resp *rpc.RPCNonceResponse, client *net.TCPAddr, remote *net.TCPAddr,
27
+	secret []byte) wrappers.ReadWriteCloserWithAddr {
27
 	encryptor := newCBCCipher(CipherPurposeClient, req, resp, client, remote, secret)
28
 	encryptor := newCBCCipher(CipherPurposeClient, req, resp, client, remote, secret)
28
 	decryptor := newCBCCipher(CipherPurposeServer, req, resp, client, remote, secret)
29
 	decryptor := newCBCCipher(CipherPurposeServer, req, resp, client, remote, secret)
29
 
30
 
30
 	return wrappers.NewBlockCipherRWC(conn, encryptor, decryptor)
31
 	return wrappers.NewBlockCipherRWC(conn, encryptor, decryptor)
31
 }
32
 }
32
 
33
 
33
-func newCBCCipher(purpose CipherPurpose, req *rpc.RPCNonceRequest, resp *rpc.RPCNonceResponse, client *net.TCPAddr, remote *net.TCPAddr, secret []byte) cipher.BlockMode {
34
+func newCBCCipher(purpose CipherPurpose, req *rpc.RPCNonceRequest, resp *rpc.RPCNonceResponse,
35
+	client *net.TCPAddr, remote *net.TCPAddr, secret []byte) cipher.BlockMode {
34
 	message := bytes.Buffer{}
36
 	message := bytes.Buffer{}
35
 	message.Write(resp.Nonce[:])
37
 	message.Write(resp.Nonce[:])
36
 	message.Write(req.Nonce[:])
38
 	message.Write(req.Nonce[:])

+ 9
- 2
mtproto/wrappers/frame.go ファイルの表示

6
 	"encoding/binary"
6
 	"encoding/binary"
7
 	"hash/crc32"
7
 	"hash/crc32"
8
 	"io"
8
 	"io"
9
+	"net"
9
 
10
 
10
 	"github.com/juju/errors"
11
 	"github.com/juju/errors"
12
+
13
+	"github.com/9seconds/mtg/wrappers"
11
 )
14
 )
12
 
15
 
13
 // Frame: { MessageLength(4) | SequenceNumber(4) | Message(???) | CRC32(4) [| padding(4), ...] }
16
 // Frame: { MessageLength(4) | SequenceNumber(4) | Message(???) | CRC32(4) [| padding(4), ...] }
19
 var frameRWCPadding = [4]byte{0x04, 0x00, 0x00, 0x00}
22
 var frameRWCPadding = [4]byte{0x04, 0x00, 0x00, 0x00}
20
 
23
 
21
 type FrameRWC struct {
24
 type FrameRWC struct {
22
-	conn io.ReadWriteCloser
25
+	conn wrappers.ReadWriteCloserWithAddr
23
 
26
 
24
 	readSeqNo  int32
27
 	readSeqNo  int32
25
 	writeSeqNo int32
28
 	writeSeqNo int32
102
 	return f.conn.Close()
105
 	return f.conn.Close()
103
 }
106
 }
104
 
107
 
108
+func (f *FrameRWC) Addr() *net.TCPAddr {
109
+	return f.conn.Addr()
110
+}
111
+
105
 func (f *FrameRWC) flush(p []byte) (int, error) {
112
 func (f *FrameRWC) flush(p []byte) (int, error) {
106
 	sizeToRead := len(p)
113
 	sizeToRead := len(p)
107
 	if f.readBuf.Len() < sizeToRead {
114
 	if f.readBuf.Len() < sizeToRead {
119
 	return sizeToRead, nil
126
 	return sizeToRead, nil
120
 }
127
 }
121
 
128
 
122
-func NewFrameRWC(conn io.ReadWriteCloser, seqNo int32) io.ReadWriteCloser {
129
+func NewFrameRWC(conn wrappers.ReadWriteCloserWithAddr, seqNo int32) wrappers.ReadWriteCloserWithAddr {
123
 	return &FrameRWC{
130
 	return &FrameRWC{
124
 		conn:       conn,
131
 		conn:       conn,
125
 		readSeqNo:  seqNo,
132
 		readSeqNo:  seqNo,

+ 1
- 2
telegram/dialer.go ファイルの表示

1
 package telegram
1
 package telegram
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"net"
4
 	"net"
6
 	"time"
5
 	"time"
7
 
6
 
29
 	return conn, nil
28
 	return conn, nil
30
 }
29
 }
31
 
30
 
32
-func (t *tgDialer) dialRWC(addr string) (io.ReadWriteCloser, error) {
31
+func (t *tgDialer) dialRWC(addr string) (wrappers.ReadWriteCloserWithAddr, error) {
33
 	conn, err := t.dial(addr)
32
 	conn, err := t.dial(addr)
34
 	if err != nil {
33
 	if err != nil {
35
 		return nil, err
34
 		return nil, err

+ 2
- 3
telegram/direct.go ファイルの表示

1
 package telegram
1
 package telegram
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"net"
4
 	"net"
6
 
5
 
7
 	"github.com/juju/errors"
6
 	"github.com/juju/errors"
33
 	baseTelegram
32
 	baseTelegram
34
 }
33
 }
35
 
34
 
36
-func (t *directTelegram) Dial(connOpts *mtproto.ConnectionOpts) (io.ReadWriteCloser, error) {
35
+func (t *directTelegram) Dial(connOpts *mtproto.ConnectionOpts) (wrappers.ReadWriteCloserWithAddr, error) {
37
 	dc := connOpts.DC
36
 	dc := connOpts.DC
38
 	if dc < 0 {
37
 	if dc < 0 {
39
 		dc = -dc
38
 		dc = -dc
44
 	return t.baseTelegram.dial(dc-1, connOpts.ConnectionProto)
43
 	return t.baseTelegram.dial(dc-1, connOpts.ConnectionProto)
45
 }
44
 }
46
 
45
 
47
-func (t *directTelegram) Init(connOpts *mtproto.ConnectionOpts, conn io.ReadWriteCloser) (io.ReadWriteCloser, error) {
46
+func (t *directTelegram) Init(connOpts *mtproto.ConnectionOpts, conn wrappers.ReadWriteCloserWithAddr) (wrappers.ReadWriteCloserWithAddr, error) {
48
 	obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame(connOpts)
47
 	obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame(connOpts)
49
 
48
 
50
 	if n, err := conn.Write(frame); err != nil || n != obfuscated2.FrameLen {
49
 	if n, err := conn.Write(frame); err != nil || n != obfuscated2.FrameLen {

+ 2
- 2
telegram/middle_caller.go ファイルの表示

2
 
2
 
3
 import (
3
 import (
4
 	"bufio"
4
 	"bufio"
5
-	"io"
6
 	"io/ioutil"
5
 	"io/ioutil"
7
 	"net"
6
 	"net"
8
 	"net/http"
7
 	"net/http"
16
 	"go.uber.org/zap"
15
 	"go.uber.org/zap"
17
 
16
 
18
 	"github.com/9seconds/mtg/mtproto"
17
 	"github.com/9seconds/mtg/mtproto"
18
+	"github.com/9seconds/mtg/wrappers"
19
 )
19
 )
20
 
20
 
21
 const (
21
 const (
39
 	httpClient  *http.Client
39
 	httpClient  *http.Client
40
 }
40
 }
41
 
41
 
42
-func (t *middleTelegramCaller) Dial(connOpts *mtproto.ConnectionOpts) (io.ReadWriteCloser, error) {
42
+func (t *middleTelegramCaller) Dial(connOpts *mtproto.ConnectionOpts) (wrappers.ReadWriteCloserWithAddr, error) {
43
 	dc := connOpts.DC
43
 	dc := connOpts.DC
44
 	if dc == 0 {
44
 	if dc == 0 {
45
 		dc = 1
45
 		dc = 1

+ 4
- 4
telegram/telegram.go ファイルの表示

1
 package telegram
1
 package telegram
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"math/rand"
4
 	"math/rand"
6
 
5
 
7
 	"github.com/juju/errors"
6
 	"github.com/juju/errors"
8
 
7
 
9
 	"github.com/9seconds/mtg/mtproto"
8
 	"github.com/9seconds/mtg/mtproto"
9
+	"github.com/9seconds/mtg/wrappers"
10
 )
10
 )
11
 
11
 
12
 // Telegram defines an interface to connect to Telegram. This
12
 // Telegram defines an interface to connect to Telegram. This
13
 // encapsulates logic of working with middleproxies or direct
13
 // encapsulates logic of working with middleproxies or direct
14
 // connections.
14
 // connections.
15
 type Telegram interface {
15
 type Telegram interface {
16
-	Dial(*mtproto.ConnectionOpts) (io.ReadWriteCloser, error)
17
-	Init(*mtproto.ConnectionOpts, io.ReadWriteCloser) (io.ReadWriteCloser, error)
16
+	Dial(*mtproto.ConnectionOpts) (wrappers.ReadWriteCloserWithAddr, error)
17
+	Init(*mtproto.ConnectionOpts, wrappers.ReadWriteCloserWithAddr) (wrappers.ReadWriteCloserWithAddr, error)
18
 }
18
 }
19
 
19
 
20
 type baseTelegram struct {
20
 type baseTelegram struct {
24
 	v6Addresses map[int16][]string
24
 	v6Addresses map[int16][]string
25
 }
25
 }
26
 
26
 
27
-func (b *baseTelegram) dial(dcIdx int16, proto mtproto.ConnectionProtocol) (io.ReadWriteCloser, error) {
27
+func (b *baseTelegram) dial(dcIdx int16, proto mtproto.ConnectionProtocol) (wrappers.ReadWriteCloserWithAddr, error) {
28
 	addrs := make([]string, 2)
28
 	addrs := make([]string, 2)
29
 
29
 
30
 	if proto&mtproto.ConnectionProtocolIPv6 != 0 {
30
 	if proto&mtproto.ConnectionProtocolIPv6 != 0 {

+ 13
- 9
wrappers/blockcipherrwc.go ファイルの表示

4
 	"bytes"
4
 	"bytes"
5
 	"crypto/aes"
5
 	"crypto/aes"
6
 	"crypto/cipher"
6
 	"crypto/cipher"
7
-	"io"
7
+	"net"
8
 
8
 
9
 	"github.com/juju/errors"
9
 	"github.com/juju/errors"
10
 )
10
 )
11
 
11
 
12
-type BlockCipherReadWriteCloser struct {
12
+type BlockCipherReadWriteCloserWithAddr struct {
13
 	buf *bytes.Buffer
13
 	buf *bytes.Buffer
14
 
14
 
15
-	conn      io.ReadWriteCloser
15
+	conn      ReadWriteCloserWithAddr
16
 	encryptor cipher.BlockMode
16
 	encryptor cipher.BlockMode
17
 	decryptor cipher.BlockMode
17
 	decryptor cipher.BlockMode
18
 }
18
 }
19
 
19
 
20
-func (c *BlockCipherReadWriteCloser) Read(p []byte) (int, error) {
20
+func (c *BlockCipherReadWriteCloserWithAddr) Read(p []byte) (int, error) {
21
 	if c.buf.Len() > 0 {
21
 	if c.buf.Len() > 0 {
22
 		return c.flush(p)
22
 		return c.flush(p)
23
 	}
23
 	}
34
 	return c.flush(p)
34
 	return c.flush(p)
35
 }
35
 }
36
 
36
 
37
-func (c *BlockCipherReadWriteCloser) Write(p []byte) (int, error) {
37
+func (c *BlockCipherReadWriteCloserWithAddr) Write(p []byte) (int, error) {
38
 	if len(p)%aes.BlockSize > 0 {
38
 	if len(p)%aes.BlockSize > 0 {
39
 		return 0, errors.Errorf("Incorrect block size %d", len(p))
39
 		return 0, errors.Errorf("Incorrect block size %d", len(p))
40
 	}
40
 	}
50
 	return c.conn.Write(encrypted)
50
 	return c.conn.Write(encrypted)
51
 }
51
 }
52
 
52
 
53
-func (c *BlockCipherReadWriteCloser) Close() error {
53
+func (c *BlockCipherReadWriteCloserWithAddr) Close() error {
54
 	defer putBuffer(c.buf)
54
 	defer putBuffer(c.buf)
55
 	return c.conn.Close()
55
 	return c.conn.Close()
56
 }
56
 }
57
 
57
 
58
-func (c *BlockCipherReadWriteCloser) flush(p []byte) (int, error) {
58
+func (c *BlockCipherReadWriteCloserWithAddr) Addr() *net.TCPAddr {
59
+	return c.conn.Addr()
60
+}
61
+
62
+func (c *BlockCipherReadWriteCloserWithAddr) flush(p []byte) (int, error) {
59
 	sizeToRead := len(p)
63
 	sizeToRead := len(p)
60
 	if c.buf.Len() < sizeToRead {
64
 	if c.buf.Len() < sizeToRead {
61
 		sizeToRead = c.buf.Len()
65
 		sizeToRead = c.buf.Len()
76
 	return sizeToRead, nil
80
 	return sizeToRead, nil
77
 }
81
 }
78
 
82
 
79
-func NewBlockCipherRWC(conn io.ReadWriteCloser, encryptor, decryptor cipher.BlockMode) io.ReadWriteCloser {
80
-	return &BlockCipherReadWriteCloser{
83
+func NewBlockCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.BlockMode) ReadWriteCloserWithAddr {
84
+	return &BlockCipherReadWriteCloserWithAddr{
81
 		buf:       getBuffer(),
85
 		buf:       getBuffer(),
82
 		conn:      conn,
86
 		conn:      conn,
83
 		encryptor: encryptor,
87
 		encryptor: encryptor,

+ 12
- 8
wrappers/ctxrwc.go ファイルの表示

2
 
2
 
3
 import (
3
 import (
4
 	"context"
4
 	"context"
5
-	"io"
5
+	"net"
6
 
6
 
7
 	"github.com/juju/errors"
7
 	"github.com/juju/errors"
8
 )
8
 )
9
 
9
 
10
 // CtxReadWriteCloser wraps underlying connection and does management of the
10
 // CtxReadWriteCloser wraps underlying connection and does management of the
11
 // context and its cancel function.
11
 // context and its cancel function.
12
-type CtxReadWriteCloser struct {
12
+type CtxReadWriteCloserWithAddr struct {
13
 	ctx    context.Context
13
 	ctx    context.Context
14
-	conn   io.ReadWriteCloser
14
+	conn   ReadWriteCloserWithAddr
15
 	cancel context.CancelFunc
15
 	cancel context.CancelFunc
16
 }
16
 }
17
 
17
 
18
 // Read reads from connection
18
 // Read reads from connection
19
-func (c *CtxReadWriteCloser) Read(p []byte) (int, error) {
19
+func (c *CtxReadWriteCloserWithAddr) Read(p []byte) (int, error) {
20
 	select {
20
 	select {
21
 	case <-c.ctx.Done():
21
 	case <-c.ctx.Done():
22
 		return 0, errors.Annotate(c.ctx.Err(), "Read is failed because of closed context")
22
 		return 0, errors.Annotate(c.ctx.Err(), "Read is failed because of closed context")
30
 }
30
 }
31
 
31
 
32
 // Write writes into connection.
32
 // Write writes into connection.
33
-func (c *CtxReadWriteCloser) Write(p []byte) (int, error) {
33
+func (c *CtxReadWriteCloserWithAddr) Write(p []byte) (int, error) {
34
 	select {
34
 	select {
35
 	case <-c.ctx.Done():
35
 	case <-c.ctx.Done():
36
 		return 0, errors.Annotate(c.ctx.Err(), "Write is failed because of closed context")
36
 		return 0, errors.Annotate(c.ctx.Err(), "Write is failed because of closed context")
44
 }
44
 }
45
 
45
 
46
 // Close closes underlying connection.
46
 // Close closes underlying connection.
47
-func (c *CtxReadWriteCloser) Close() error {
47
+func (c *CtxReadWriteCloserWithAddr) Close() error {
48
 	return c.conn.Close()
48
 	return c.conn.Close()
49
 }
49
 }
50
 
50
 
51
+func (c *CtxReadWriteCloserWithAddr) Addr() *net.TCPAddr {
52
+	return c.conn.Addr()
53
+}
54
+
51
 // NewCtxRWC returns ReadWriteCloser which respects given context,
55
 // NewCtxRWC returns ReadWriteCloser which respects given context,
52
 // cancellation etc.
56
 // cancellation etc.
53
-func NewCtxRWC(ctx context.Context, cancel context.CancelFunc, conn io.ReadWriteCloser) io.ReadWriteCloser {
54
-	return &CtxReadWriteCloser{
57
+func NewCtxRWC(ctx context.Context, cancel context.CancelFunc, conn ReadWriteCloserWithAddr) ReadWriteCloserWithAddr {
58
+	return &CtxReadWriteCloserWithAddr{
55
 		conn:   conn,
59
 		conn:   conn,
56
 		ctx:    ctx,
60
 		ctx:    ctx,
57
 		cancel: cancel,
61
 		cancel: cancel,

+ 12
- 8
wrappers/logrwc.go ファイルの表示

1
 package wrappers
1
 package wrappers
2
 
2
 
3
 import (
3
 import (
4
-	"io"
4
+	"net"
5
 
5
 
6
 	"go.uber.org/zap"
6
 	"go.uber.org/zap"
7
 )
7
 )
8
 
8
 
9
 // LogReadWriteCloser adds additional logging for reading/writing. All
9
 // LogReadWriteCloser adds additional logging for reading/writing. All
10
 // logging is performed for debug mode only.
10
 // logging is performed for debug mode only.
11
-type LogReadWriteCloser struct {
12
-	conn   io.ReadWriteCloser
11
+type LogReadWriteCloserWithAddr struct {
12
+	conn   ReadWriteCloserWithAddr
13
 	logger *zap.SugaredLogger
13
 	logger *zap.SugaredLogger
14
 	sockid string
14
 	sockid string
15
 	name   string
15
 	name   string
16
 }
16
 }
17
 
17
 
18
 // Read reads from connection
18
 // Read reads from connection
19
-func (l *LogReadWriteCloser) Read(p []byte) (n int, err error) {
19
+func (l *LogReadWriteCloserWithAddr) Read(p []byte) (n int, err error) {
20
 	n, err = l.conn.Read(p)
20
 	n, err = l.conn.Read(p)
21
 	l.logger.Debugw("Finish reading", "name", l.name, "socketid", l.sockid, "nbytes", n, "error", err)
21
 	l.logger.Debugw("Finish reading", "name", l.name, "socketid", l.sockid, "nbytes", n, "error", err)
22
 	return
22
 	return
23
 }
23
 }
24
 
24
 
25
 // Write writes into connection.
25
 // Write writes into connection.
26
-func (l *LogReadWriteCloser) Write(p []byte) (n int, err error) {
26
+func (l *LogReadWriteCloserWithAddr) Write(p []byte) (n int, err error) {
27
 	n, err = l.conn.Write(p)
27
 	n, err = l.conn.Write(p)
28
 	l.logger.Debugw("Finish writing", "name", l.name, "socketid", l.sockid, "nbytes", n, "error", err)
28
 	l.logger.Debugw("Finish writing", "name", l.name, "socketid", l.sockid, "nbytes", n, "error", err)
29
 	return
29
 	return
30
 }
30
 }
31
 
31
 
32
 // Close closes underlying connection.
32
 // Close closes underlying connection.
33
-func (l *LogReadWriteCloser) Close() error {
33
+func (l *LogReadWriteCloserWithAddr) Close() error {
34
 	err := l.conn.Close()
34
 	err := l.conn.Close()
35
 	l.logger.Debugw("Finish closing socket", "name", l.name, "socketid", l.sockid, "error", err)
35
 	l.logger.Debugw("Finish closing socket", "name", l.name, "socketid", l.sockid, "error", err)
36
 	return err
36
 	return err
37
 }
37
 }
38
 
38
 
39
+func (l *LogReadWriteCloserWithAddr) Addr() *net.TCPAddr {
40
+	return l.conn.Addr()
41
+}
42
+
39
 // NewLogRWC wraps ReadWriteCloser with logger calls.
43
 // NewLogRWC wraps ReadWriteCloser with logger calls.
40
-func NewLogRWC(conn io.ReadWriteCloser, logger *zap.SugaredLogger, sockid string, name string) io.ReadWriteCloser {
41
-	return &LogReadWriteCloser{
44
+func NewLogRWC(conn ReadWriteCloserWithAddr, logger *zap.SugaredLogger, sockid string, name string) ReadWriteCloserWithAddr {
45
+	return &LogReadWriteCloserWithAddr{
42
 		conn:   conn,
46
 		conn:   conn,
43
 		logger: logger,
47
 		logger: logger,
44
 		sockid: sockid,
48
 		sockid: sockid,

+ 12
- 0
wrappers/rwcaddr.go ファイルの表示

1
+package wrappers
2
+
3
+import (
4
+	"io"
5
+	"net"
6
+)
7
+
8
+type ReadWriteCloserWithAddr interface {
9
+	io.ReadWriteCloser
10
+
11
+	Addr() *net.TCPAddr
12
+}

+ 12
- 8
wrappers/streamcipherrwc.go ファイルの表示

2
 
2
 
3
 import (
3
 import (
4
 	"crypto/cipher"
4
 	"crypto/cipher"
5
-	"io"
5
+	"net"
6
 )
6
 )
7
 
7
 
8
 // StreamCipherReadWriteCloser is a ReadWriteCloser which ciphers
8
 // StreamCipherReadWriteCloser is a ReadWriteCloser which ciphers
9
 // incoming and outgoing data with givem cipher.Stream instances.
9
 // incoming and outgoing data with givem cipher.Stream instances.
10
-type StreamCipherReadWriteCloser struct {
10
+type StreamCipherReadWriteCloserWithAddr struct {
11
 	encryptor cipher.Stream
11
 	encryptor cipher.Stream
12
 	decryptor cipher.Stream
12
 	decryptor cipher.Stream
13
-	conn      io.ReadWriteCloser
13
+	conn      ReadWriteCloserWithAddr
14
 }
14
 }
15
 
15
 
16
 // Read reads from connection
16
 // Read reads from connection
17
-func (c *StreamCipherReadWriteCloser) Read(p []byte) (n int, err error) {
17
+func (c *StreamCipherReadWriteCloserWithAddr) Read(p []byte) (n int, err error) {
18
 	n, err = c.conn.Read(p)
18
 	n, err = c.conn.Read(p)
19
 	c.decryptor.XORKeyStream(p, p[:n])
19
 	c.decryptor.XORKeyStream(p, p[:n])
20
 	return
20
 	return
21
 }
21
 }
22
 
22
 
23
 // Write writes into connection.
23
 // Write writes into connection.
24
-func (c *StreamCipherReadWriteCloser) Write(p []byte) (int, error) {
24
+func (c *StreamCipherReadWriteCloserWithAddr) Write(p []byte) (int, error) {
25
 	// This is to decrease an amount of allocations. Unfortunately, escape
25
 	// This is to decrease an amount of allocations. Unfortunately, escape
26
 	// analysis in (at least Golang 1.10) is absolutely not perfect. For
26
 	// analysis in (at least Golang 1.10) is absolutely not perfect. For
27
 	// example, it understands that we want to have a slice locally, right?
27
 	// example, it understands that we want to have a slice locally, right?
39
 }
39
 }
40
 
40
 
41
 // Close closes underlying connection.
41
 // Close closes underlying connection.
42
-func (c *StreamCipherReadWriteCloser) Close() error {
42
+func (c *StreamCipherReadWriteCloserWithAddr) Close() error {
43
 	return c.conn.Close()
43
 	return c.conn.Close()
44
 }
44
 }
45
 
45
 
46
+func (c *StreamCipherReadWriteCloserWithAddr) Addr() *net.TCPAddr {
47
+	return c.conn.Addr()
48
+}
49
+
46
 // NewStreamCipherRWC returns wrapper which transparently
50
 // NewStreamCipherRWC returns wrapper which transparently
47
 // encrypts/decrypts traffic with obfuscated2 protocol.
51
 // encrypts/decrypts traffic with obfuscated2 protocol.
48
-func NewStreamCipherRWC(conn io.ReadWriteCloser, encryptor, decryptor cipher.Stream) io.ReadWriteCloser {
49
-	return &StreamCipherReadWriteCloser{
52
+func NewStreamCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.Stream) ReadWriteCloserWithAddr {
53
+	return &StreamCipherReadWriteCloserWithAddr{
50
 		conn:      conn,
54
 		conn:      conn,
51
 		encryptor: encryptor,
55
 		encryptor: encryptor,
52
 		decryptor: decryptor,
56
 		decryptor: decryptor,

+ 10
- 7
wrappers/timeoutrwc.go ファイルの表示

1
 package wrappers
1
 package wrappers
2
 
2
 
3
 import (
3
 import (
4
-	"io"
5
 	"net"
4
 	"net"
6
 	"time"
5
 	"time"
7
 
6
 
8
 	"github.com/9seconds/mtg/config"
7
 	"github.com/9seconds/mtg/config"
9
 )
8
 )
10
 
9
 
11
-type TimeoutReadWriteCloser struct {
10
+type TimeoutReadWriteCloserWithAddr struct {
12
 	conn net.Conn
11
 	conn net.Conn
13
 }
12
 }
14
 
13
 
15
-func (t *TimeoutReadWriteCloser) Read(p []byte) (int, error) {
14
+func (t *TimeoutReadWriteCloserWithAddr) Read(p []byte) (int, error) {
16
 	t.conn.SetReadDeadline(time.Now().Add(config.TimeoutRead))
15
 	t.conn.SetReadDeadline(time.Now().Add(config.TimeoutRead))
17
 	return t.conn.Read(p)
16
 	return t.conn.Read(p)
18
 }
17
 }
19
 
18
 
20
-func (t *TimeoutReadWriteCloser) Write(p []byte) (int, error) {
19
+func (t *TimeoutReadWriteCloserWithAddr) Write(p []byte) (int, error) {
21
 	t.conn.SetWriteDeadline(time.Now().Add(config.TimeoutWrite))
20
 	t.conn.SetWriteDeadline(time.Now().Add(config.TimeoutWrite))
22
 	return t.conn.Write(p)
21
 	return t.conn.Write(p)
23
 }
22
 }
24
 
23
 
25
-func (t *TimeoutReadWriteCloser) Close() error {
24
+func (t *TimeoutReadWriteCloserWithAddr) Close() error {
26
 	return t.conn.Close()
25
 	return t.conn.Close()
27
 }
26
 }
28
 
27
 
29
-func NewTimeoutRWC(conn net.Conn) io.ReadWriteCloser {
30
-	return &TimeoutReadWriteCloser{conn}
28
+func (t *TimeoutReadWriteCloserWithAddr) Addr() *net.TCPAddr {
29
+	return t.conn.RemoteAddr().(*net.TCPAddr)
30
+}
31
+
32
+func NewTimeoutRWC(conn net.Conn) ReadWriteCloserWithAddr {
33
+	return &TimeoutReadWriteCloserWithAddr{conn}
31
 }
34
 }

+ 12
- 8
wrappers/trafficrwc.go ファイルの表示

1
 package wrappers
1
 package wrappers
2
 
2
 
3
-import "io"
3
+import "net"
4
 
4
 
5
 // TrafficReadWriteCloser counts an amount of ingress/egress traffic by
5
 // TrafficReadWriteCloser counts an amount of ingress/egress traffic by
6
 // calling given callbacks.
6
 // calling given callbacks.
7
-type TrafficReadWriteCloser struct {
8
-	conn          io.ReadWriteCloser
7
+type TrafficReadWriteCloserWithAddr struct {
8
+	conn          ReadWriteCloserWithAddr
9
 	readCallback  func(int)
9
 	readCallback  func(int)
10
 	writeCallback func(int)
10
 	writeCallback func(int)
11
 }
11
 }
12
 
12
 
13
 // Read reads from connection
13
 // Read reads from connection
14
-func (t *TrafficReadWriteCloser) Read(p []byte) (n int, err error) {
14
+func (t *TrafficReadWriteCloserWithAddr) Read(p []byte) (n int, err error) {
15
 	n, err = t.conn.Read(p)
15
 	n, err = t.conn.Read(p)
16
 	t.readCallback(n)
16
 	t.readCallback(n)
17
 	return
17
 	return
18
 }
18
 }
19
 
19
 
20
 // Write writes into connection.
20
 // Write writes into connection.
21
-func (t *TrafficReadWriteCloser) Write(p []byte) (n int, err error) {
21
+func (t *TrafficReadWriteCloserWithAddr) Write(p []byte) (n int, err error) {
22
 	n, err = t.conn.Write(p)
22
 	n, err = t.conn.Write(p)
23
 	t.writeCallback(n)
23
 	t.writeCallback(n)
24
 	return
24
 	return
25
 }
25
 }
26
 
26
 
27
 // Close closes underlying connection.
27
 // Close closes underlying connection.
28
-func (t *TrafficReadWriteCloser) Close() error {
28
+func (t *TrafficReadWriteCloserWithAddr) Close() error {
29
 	return t.conn.Close()
29
 	return t.conn.Close()
30
 }
30
 }
31
 
31
 
32
+func (t *TrafficReadWriteCloserWithAddr) Addr() *net.TCPAddr {
33
+	return t.conn.Addr()
34
+}
35
+
32
 // NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.
36
 // NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.
33
-func NewTrafficRWC(conn io.ReadWriteCloser, readCallback, writeCallback func(int)) io.ReadWriteCloser {
34
-	return &TrafficReadWriteCloser{
37
+func NewTrafficRWC(conn ReadWriteCloserWithAddr, readCallback, writeCallback func(int)) ReadWriteCloserWithAddr {
38
+	return &TrafficReadWriteCloserWithAddr{
35
 		conn:          conn,
39
 		conn:          conn,
36
 		readCallback:  readCallback,
40
 		readCallback:  readCallback,
37
 		writeCallback: writeCallback,
41
 		writeCallback: writeCallback,

読み込み中…
キャンセル
保存