Переглянути джерело

Change rwc to rwc with addresses

tags/0.9
9seconds 7 роки тому
джерело
коміт
09476cc467

+ 2
- 2
client/client.go Переглянути файл

@@ -1,12 +1,12 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"net"
6 5
 
7 6
 	"github.com/9seconds/mtg/config"
8 7
 	"github.com/9seconds/mtg/mtproto"
8
+	"github.com/9seconds/mtg/wrappers"
9 9
 )
10 10
 
11 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,7 +1,6 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"net"
6 5
 	"time"
7 6
 
@@ -16,7 +15,7 @@ import (
16 15
 const handshakeTimeout = 10 * time.Second
17 16
 
18 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 19
 	if err := config.SetSocketOptions(conn); err != nil {
21 20
 		return nil, nil, errors.Annotate(err, "Cannot set socket options")
22 21
 	}

+ 5
- 3
mtproto/wrappers/crypt.go Переглянути файл

@@ -7,7 +7,6 @@ import (
7 7
 	"crypto/md5"
8 8
 	"crypto/sha1"
9 9
 	"encoding/binary"
10
-	"io"
11 10
 	"net"
12 11
 
13 12
 	"github.com/9seconds/mtg/mtproto/rpc"
@@ -23,14 +22,17 @@ const (
23 22
 
24 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 28
 	encryptor := newCBCCipher(CipherPurposeClient, req, resp, client, remote, secret)
28 29
 	decryptor := newCBCCipher(CipherPurposeServer, req, resp, client, remote, secret)
29 30
 
30 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 36
 	message := bytes.Buffer{}
35 37
 	message.Write(resp.Nonce[:])
36 38
 	message.Write(req.Nonce[:])

+ 9
- 2
mtproto/wrappers/frame.go Переглянути файл

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

+ 1
- 2
telegram/dialer.go Переглянути файл

@@ -1,7 +1,6 @@
1 1
 package telegram
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"net"
6 5
 	"time"
7 6
 
@@ -29,7 +28,7 @@ func (t *tgDialer) dial(addr string) (net.Conn, error) {
29 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 32
 	conn, err := t.dial(addr)
34 33
 	if err != nil {
35 34
 		return nil, err

+ 2
- 3
telegram/direct.go Переглянути файл

@@ -1,7 +1,6 @@
1 1
 package telegram
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"net"
6 5
 
7 6
 	"github.com/juju/errors"
@@ -33,7 +32,7 @@ type directTelegram struct {
33 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 36
 	dc := connOpts.DC
38 37
 	if dc < 0 {
39 38
 		dc = -dc
@@ -44,7 +43,7 @@ func (t *directTelegram) Dial(connOpts *mtproto.ConnectionOpts) (io.ReadWriteClo
44 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 47
 	obfs2, frame := obfuscated2.MakeTelegramObfuscated2Frame(connOpts)
49 48
 
50 49
 	if n, err := conn.Write(frame); err != nil || n != obfuscated2.FrameLen {

+ 2
- 2
telegram/middle_caller.go Переглянути файл

@@ -2,7 +2,6 @@ package telegram
2 2
 
3 3
 import (
4 4
 	"bufio"
5
-	"io"
6 5
 	"io/ioutil"
7 6
 	"net"
8 7
 	"net/http"
@@ -16,6 +15,7 @@ import (
16 15
 	"go.uber.org/zap"
17 16
 
18 17
 	"github.com/9seconds/mtg/mtproto"
18
+	"github.com/9seconds/mtg/wrappers"
19 19
 )
20 20
 
21 21
 const (
@@ -39,7 +39,7 @@ type middleTelegramCaller struct {
39 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 43
 	dc := connOpts.DC
44 44
 	if dc == 0 {
45 45
 		dc = 1

+ 4
- 4
telegram/telegram.go Переглянути файл

@@ -1,20 +1,20 @@
1 1
 package telegram
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"math/rand"
6 5
 
7 6
 	"github.com/juju/errors"
8 7
 
9 8
 	"github.com/9seconds/mtg/mtproto"
9
+	"github.com/9seconds/mtg/wrappers"
10 10
 )
11 11
 
12 12
 // Telegram defines an interface to connect to Telegram. This
13 13
 // encapsulates logic of working with middleproxies or direct
14 14
 // connections.
15 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 20
 type baseTelegram struct {
@@ -24,7 +24,7 @@ type baseTelegram struct {
24 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 28
 	addrs := make([]string, 2)
29 29
 
30 30
 	if proto&mtproto.ConnectionProtocolIPv6 != 0 {

+ 13
- 9
wrappers/blockcipherrwc.go Переглянути файл

@@ -4,20 +4,20 @@ import (
4 4
 	"bytes"
5 5
 	"crypto/aes"
6 6
 	"crypto/cipher"
7
-	"io"
7
+	"net"
8 8
 
9 9
 	"github.com/juju/errors"
10 10
 )
11 11
 
12
-type BlockCipherReadWriteCloser struct {
12
+type BlockCipherReadWriteCloserWithAddr struct {
13 13
 	buf *bytes.Buffer
14 14
 
15
-	conn      io.ReadWriteCloser
15
+	conn      ReadWriteCloserWithAddr
16 16
 	encryptor cipher.BlockMode
17 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 21
 	if c.buf.Len() > 0 {
22 22
 		return c.flush(p)
23 23
 	}
@@ -34,7 +34,7 @@ func (c *BlockCipherReadWriteCloser) Read(p []byte) (int, error) {
34 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 38
 	if len(p)%aes.BlockSize > 0 {
39 39
 		return 0, errors.Errorf("Incorrect block size %d", len(p))
40 40
 	}
@@ -50,12 +50,16 @@ func (c *BlockCipherReadWriteCloser) Write(p []byte) (int, error) {
50 50
 	return c.conn.Write(encrypted)
51 51
 }
52 52
 
53
-func (c *BlockCipherReadWriteCloser) Close() error {
53
+func (c *BlockCipherReadWriteCloserWithAddr) Close() error {
54 54
 	defer putBuffer(c.buf)
55 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 63
 	sizeToRead := len(p)
60 64
 	if c.buf.Len() < sizeToRead {
61 65
 		sizeToRead = c.buf.Len()
@@ -76,8 +80,8 @@ func (c *BlockCipherReadWriteCloser) flush(p []byte) (int, error) {
76 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 85
 		buf:       getBuffer(),
82 86
 		conn:      conn,
83 87
 		encryptor: encryptor,

+ 12
- 8
wrappers/ctxrwc.go Переглянути файл

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

+ 12
- 8
wrappers/logrwc.go Переглянути файл

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

+ 12
- 0
wrappers/rwcaddr.go Переглянути файл

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

+ 10
- 7
wrappers/timeoutrwc.go Переглянути файл

@@ -1,31 +1,34 @@
1 1
 package wrappers
2 2
 
3 3
 import (
4
-	"io"
5 4
 	"net"
6 5
 	"time"
7 6
 
8 7
 	"github.com/9seconds/mtg/config"
9 8
 )
10 9
 
11
-type TimeoutReadWriteCloser struct {
10
+type TimeoutReadWriteCloserWithAddr struct {
12 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 15
 	t.conn.SetReadDeadline(time.Now().Add(config.TimeoutRead))
17 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 20
 	t.conn.SetWriteDeadline(time.Now().Add(config.TimeoutWrite))
22 21
 	return t.conn.Write(p)
23 22
 }
24 23
 
25
-func (t *TimeoutReadWriteCloser) Close() error {
24
+func (t *TimeoutReadWriteCloserWithAddr) Close() error {
26 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,37 +1,41 @@
1 1
 package wrappers
2 2
 
3
-import "io"
3
+import "net"
4 4
 
5 5
 // TrafficReadWriteCloser counts an amount of ingress/egress traffic by
6 6
 // calling given callbacks.
7
-type TrafficReadWriteCloser struct {
8
-	conn          io.ReadWriteCloser
7
+type TrafficReadWriteCloserWithAddr struct {
8
+	conn          ReadWriteCloserWithAddr
9 9
 	readCallback  func(int)
10 10
 	writeCallback func(int)
11 11
 }
12 12
 
13 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 15
 	n, err = t.conn.Read(p)
16 16
 	t.readCallback(n)
17 17
 	return
18 18
 }
19 19
 
20 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 22
 	n, err = t.conn.Write(p)
23 23
 	t.writeCallback(n)
24 24
 	return
25 25
 }
26 26
 
27 27
 // Close closes underlying connection.
28
-func (t *TrafficReadWriteCloser) Close() error {
28
+func (t *TrafficReadWriteCloserWithAddr) Close() error {
29 29
 	return t.conn.Close()
30 30
 }
31 31
 
32
+func (t *TrafficReadWriteCloserWithAddr) Addr() *net.TCPAddr {
33
+	return t.conn.Addr()
34
+}
35
+
32 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 39
 		conn:          conn,
36 40
 		readCallback:  readCallback,
37 41
 		writeCallback: writeCallback,

Завантаження…
Відмінити
Зберегти