9seconds 7 лет назад
Родитель
Сommit
90c10519ee

+ 1
- 2
client/direct.go Просмотреть файл

32
 		return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
32
 		return nil, nil, errors.Annotate(err, "Cannot parse obfuscated frame")
33
 	}
33
 	}
34
 	connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
34
 	connOpts.ConnectionProto = mtproto.ConnectionProtocolAny
35
-	connOpts.ClientAddr = conn.RemoteAddr().(*net.TCPAddr)
36
 
35
 
37
-	socket := wrappers.NewTimeoutRWC(conn)
36
+	socket := wrappers.NewTimeoutRWC(conn, conf.PublicIPv4, conf.PublicIPv6)
38
 	socket = wrappers.NewStreamCipherRWC(socket, obfs2.Encryptor, obfs2.Decryptor)
37
 	socket = wrappers.NewStreamCipherRWC(socket, obfs2.Encryptor, obfs2.Decryptor)
39
 
38
 
40
 	return connOpts, socket, nil
39
 	return connOpts, socket, nil

+ 14
- 21
config/config.go Просмотреть файл

59
 	return getAddr(c.BindIP, c.BindPort)
59
 	return getAddr(c.BindIP, c.BindPort)
60
 }
60
 }
61
 
61
 
62
-// IPv4Addr returns connection string to ipv6 for mtproto proxy.
63
-func (c *Config) IPv4Addr() string {
64
-	return getAddr(c.PublicIPv4, c.PublicIPv4Port)
65
-}
66
-
67
-// IPv6Addr returns connection string to ipv6 for mtproto proxy.
68
-func (c *Config) IPv6Addr() string {
69
-	return getAddr(c.PublicIPv6, c.PublicIPv6Port)
70
-}
71
-
72
 // StatAddr returns connection string to the stats API.
62
 // StatAddr returns connection string to the stats API.
73
 func (c *Config) StatAddr() string {
63
 func (c *Config) StatAddr() string {
74
 	return getAddr(c.StatsIP, c.StatsPort)
64
 	return getAddr(c.StatsIP, c.StatsPort)
76
 
66
 
77
 // GetURLs returns configured IPURLs instance with links to this server.
67
 // GetURLs returns configured IPURLs instance with links to this server.
78
 func (c *Config) GetURLs() IPURLs {
68
 func (c *Config) GetURLs() IPURLs {
79
-	return IPURLs{
80
-		IPv4: getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret),
81
-		IPv6: getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret),
69
+	urls := IPURLs{}
70
+	if c.PublicIPv4 != nil {
71
+		urls.IPv4 = getURLs(c.PublicIPv4, c.PublicIPv4Port, c.Secret)
82
 	}
72
 	}
73
+	if c.PublicIPv6 != nil {
74
+		urls.IPv6 = getURLs(c.PublicIPv6, c.PublicIPv6Port, c.Secret)
75
+	}
76
+
77
+	return urls
83
 }
78
 }
84
 
79
 
85
 func getAddr(host fmt.Stringer, port uint16) string {
80
 func getAddr(host fmt.Stringer, port uint16) string {
106
 	if publicIPv4 == nil {
101
 	if publicIPv4 == nil {
107
 		publicIPv4, err = getGlobalIPv4()
102
 		publicIPv4, err = getGlobalIPv4()
108
 		if err != nil {
103
 		if err != nil {
109
-			return nil, errors.Errorf("Cannot get public IP")
104
+			publicIPv4 = nil
105
+		} else if publicIPv4.To4() == nil {
106
+			return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
110
 		}
107
 		}
111
 	}
108
 	}
112
-	if publicIPv4.To4() == nil {
113
-		return nil, errors.Errorf("IP %s is not IPv4", publicIPv4.String())
114
-	}
115
 	if PublicIPv4Port == 0 {
109
 	if PublicIPv4Port == 0 {
116
 		PublicIPv4Port = bindPort
110
 		PublicIPv4Port = bindPort
117
 	}
111
 	}
119
 	if publicIPv6 == nil {
113
 	if publicIPv6 == nil {
120
 		publicIPv6, err = getGlobalIPv6()
114
 		publicIPv6, err = getGlobalIPv6()
121
 		if err != nil {
115
 		if err != nil {
122
-			publicIPv6 = publicIPv4
116
+			publicIPv6 = nil
117
+		} else if publicIPv6.To4() != nil {
118
+			return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
123
 		}
119
 		}
124
 	}
120
 	}
125
-	if publicIPv6.To16() == nil {
126
-		return nil, errors.Errorf("IP %s is not IPv6", publicIPv6.String())
127
-	}
128
 	if publicIPv6Port == 0 {
121
 	if publicIPv6Port == 0 {
129
 		publicIPv6Port = bindPort
122
 		publicIPv6Port = bindPort
130
 	}
123
 	}

+ 24
- 8
main.go Просмотреть файл

4
 
4
 
5
 import (
5
 import (
6
 	"encoding/json"
6
 	"encoding/json"
7
+	"fmt"
7
 	"io"
8
 	"io"
8
 	"math/rand"
9
 	"math/rand"
9
 	"os"
10
 	"os"
15
 	kingpin "gopkg.in/alecthomas/kingpin.v2"
16
 	kingpin "gopkg.in/alecthomas/kingpin.v2"
16
 
17
 
17
 	"github.com/9seconds/mtg/config"
18
 	"github.com/9seconds/mtg/config"
18
-	"github.com/9seconds/mtg/proxy"
19
+	"github.com/9seconds/mtg/mtproto"
20
+	"github.com/9seconds/mtg/telegram"
19
 	"github.com/juju/errors"
21
 	"github.com/juju/errors"
20
 )
22
 )
21
 
23
 
112
 		atom,
114
 		atom,
113
 	)).Sugar()
115
 	)).Sugar()
114
 
116
 
115
-	stat := proxy.NewStats(conf)
116
-	go stat.Serve()
117
-
118
-	srv := proxy.NewServer(conf, logger, stat)
119
-	printURLs(conf.GetURLs())
117
+	tg := telegram.NewMiddleTelegram(conf, logger)
118
+	connOpts := &mtproto.ConnectionOpts{
119
+		DC:              int16(1),
120
+		ConnectionType:  mtproto.ConnectionTypeAbridged,
121
+		ConnectionProto: mtproto.ConnectionProtocolIPv4,
122
+	}
120
 
123
 
121
-	if err := srv.Serve(); err != nil {
122
-		logger.Fatal(err.Error())
124
+	sock, err := tg.Dial(connOpts)
125
+	if err != nil {
126
+		panic(err)
123
 	}
127
 	}
128
+	_, err = tg.Init(connOpts, sock)
129
+	fmt.Println(err)
130
+
131
+	// stat := proxy.NewStats(conf)
132
+	// go stat.Serve()
133
+
134
+	// srv := proxy.NewServer(conf, logger, stat)
135
+	// printURLs(conf.GetURLs())
136
+
137
+	// if err := srv.Serve(); err != nil {
138
+	// 	logger.Fatal(err.Error())
139
+	// }
124
 }
140
 }
125
 
141
 
126
 func setRLimit() (err error) {
142
 func setRLimit() (err error) {

+ 2
- 2
mtproto/connection_options.go Просмотреть файл

2
 
2
 
3
 import (
3
 import (
4
 	"bytes"
4
 	"bytes"
5
-	"net"
6
 
5
 
7
 	"github.com/juju/errors"
6
 	"github.com/juju/errors"
8
 )
7
 )
19
 	DC              int16
18
 	DC              int16
20
 	ConnectionType  ConnectionType
19
 	ConnectionType  ConnectionType
21
 	ConnectionProto ConnectionProtocol
20
 	ConnectionProto ConnectionProtocol
22
-	ClientAddr      *net.TCPAddr
21
+	QuickAck        bool
22
+	SimpleAck       bool
23
 }
23
 }
24
 
24
 
25
 // Different connection types which user requests from Telegram.
25
 // Different connection types which user requests from Telegram.

+ 3
- 1
mtproto/rpc/rpc_handshake_request.go Просмотреть файл

1
 package rpc
1
 package rpc
2
 
2
 
3
-import "bytes"
3
+import (
4
+	"bytes"
5
+)
4
 
6
 
5
 const (
7
 const (
6
 	rpcHandshakeTagLength       = 4
8
 	rpcHandshakeTagLength       = 4

+ 6
- 5
mtproto/wrappers/crypt.go Просмотреть файл

22
 
22
 
23
 var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
23
 var emptyIP = [4]byte{0x00, 0x00, 0x00, 0x00}
24
 
24
 
25
-func NewMiddleProxyCipherRWC(conn wrappers.ReadWriteCloserWithAddr, req *rpc.RPCNonceRequest,
26
-	resp *rpc.RPCNonceResponse, client *net.TCPAddr, secret []byte) wrappers.ReadWriteCloserWithAddr {
27
-	remote := conn.Addr()
28
-	encKey, encIV := makeKeys(CipherPurposeClient, req, resp, client, remote, secret)
29
-	decKey, decIV := makeKeys(CipherPurposeServer, req, resp, client, remote, secret)
25
+func NewMiddleProxyCipherRWC(conn wrappers.ReadWriteCloserWithAddr, req *rpc.RPCNonceRequest, resp *rpc.RPCNonceResponse, secret []byte) wrappers.ReadWriteCloserWithAddr {
26
+	localAddr := conn.LocalAddr()
27
+	remoteAddr := conn.RemoteAddr()
28
+
29
+	encKey, encIV := makeKeys(CipherPurposeClient, req, resp, localAddr, remoteAddr, secret)
30
+	decKey, decIV := makeKeys(CipherPurposeServer, req, resp, localAddr, remoteAddr, secret)
30
 
31
 
31
 	enc, _ := makeEncrypterDecrypter(encKey, encIV)
32
 	enc, _ := makeEncrypterDecrypter(encKey, encIV)
32
 	_, dec := makeEncrypterDecrypter(decKey, decIV)
33
 	_, dec := makeEncrypterDecrypter(decKey, decIV)

+ 6
- 2
mtproto/wrappers/frame.go Просмотреть файл

112
 	return f.conn.Close()
112
 	return f.conn.Close()
113
 }
113
 }
114
 
114
 
115
-func (f *FrameRWC) Addr() *net.TCPAddr {
116
-	return f.conn.Addr()
115
+func (f *FrameRWC) LocalAddr() *net.TCPAddr {
116
+	return f.conn.LocalAddr()
117
+}
118
+
119
+func (f *FrameRWC) RemoteAddr() *net.TCPAddr {
120
+	return f.conn.RemoteAddr()
117
 }
121
 }
118
 
122
 
119
 func NewFrameRWC(conn wrappers.ReadWriteCloserWithAddr, seqNo int32) wrappers.ReadWriteCloserWithAddr {
123
 func NewFrameRWC(conn wrappers.ReadWriteCloserWithAddr, seqNo int32) wrappers.ReadWriteCloserWithAddr {

+ 3
- 1
telegram/dialer.go Просмотреть файл

14
 
14
 
15
 type tgDialer struct {
15
 type tgDialer struct {
16
 	net.Dialer
16
 	net.Dialer
17
+
18
+	conf *config.Config
17
 }
19
 }
18
 
20
 
19
 func (t *tgDialer) dial(addr string) (net.Conn, error) {
21
 func (t *tgDialer) dial(addr string) (net.Conn, error) {
34
 		return nil, err
36
 		return nil, err
35
 	}
37
 	}
36
 
38
 
37
-	return wrappers.NewTimeoutRWC(conn), nil
39
+	return wrappers.NewTimeoutRWC(conn, t.conf.PublicIPv4, t.conf.PublicIPv6), nil
38
 }
40
 }

+ 4
- 1
telegram/direct.go Просмотреть файл

57
 // to Telegram bypassing middleproxies.
57
 // to Telegram bypassing middleproxies.
58
 func NewDirectTelegram(conf *config.Config) Telegram {
58
 func NewDirectTelegram(conf *config.Config) Telegram {
59
 	return &directTelegram{baseTelegram{
59
 	return &directTelegram{baseTelegram{
60
-		dialer:      tgDialer{net.Dialer{Timeout: telegramDialTimeout}},
60
+		dialer: tgDialer{
61
+			Dialer: net.Dialer{Timeout: telegramDialTimeout},
62
+			conf:   conf,
63
+		},
61
 		v4Addresses: directV4Addresses,
64
 		v4Addresses: directV4Addresses,
62
 		v6Addresses: directV6Addresses,
65
 		v6Addresses: directV6Addresses,
63
 	}}
66
 	}}

+ 7
- 3
telegram/middle.go Просмотреть файл

1
 package telegram
1
 package telegram
2
 
2
 
3
 import (
3
 import (
4
+	"fmt"
4
 	"io"
5
 	"io"
5
 	"net"
6
 	"net"
6
 	"net/http"
7
 	"net/http"
24
 	tg := &middleTelegram{
25
 	tg := &middleTelegram{
25
 		middleTelegramCaller: middleTelegramCaller{
26
 		middleTelegramCaller: middleTelegramCaller{
26
 			baseTelegram: baseTelegram{
27
 			baseTelegram: baseTelegram{
27
-				dialer: tgDialer{net.Dialer{Timeout: telegramDialTimeout}},
28
+				dialer: tgDialer{
29
+					Dialer: net.Dialer{Timeout: telegramDialTimeout},
30
+					conf:   conf,
31
+				},
28
 			},
32
 			},
29
 			logger: logger,
33
 			logger: logger,
30
 			httpClient: &http.Client{
34
 			httpClient: &http.Client{
54
 		return nil, err
58
 		return nil, err
55
 	}
59
 	}
56
 
60
 
57
-	secureConn := mtwrappers.NewMiddleProxyCipherRWC(conn, rpcNonceReq,
58
-		rpcNonceResp, connOpts.ClientAddr, t.proxySecret)
61
+	secureConn := mtwrappers.NewMiddleProxyCipherRWC(conn, rpcNonceReq, rpcNonceResp, t.proxySecret)
59
 	secureConn = mtwrappers.NewFrameRWC(secureConn, rpc.RPCHandshakeSeqNo)
62
 	secureConn = mtwrappers.NewFrameRWC(secureConn, rpc.RPCHandshakeSeqNo)
60
 
63
 
61
 	rpcHandshakeReq, err := t.sendRPCHandshakeRequest(secureConn)
64
 	rpcHandshakeReq, err := t.sendRPCHandshakeRequest(secureConn)
123
 	if err = rpcHandshakeResp.Valid(req); err != nil {
126
 	if err = rpcHandshakeResp.Valid(req); err != nil {
124
 		return nil, errors.Annotate(err, "Invalid RPC handshake response")
127
 		return nil, errors.Annotate(err, "Invalid RPC handshake response")
125
 	}
128
 	}
129
+	fmt.Println("VICTORY")
126
 
130
 
127
 	return rpcHandshakeResp, nil
131
 	return rpcHandshakeResp, nil
128
 }
132
 }

+ 7
- 2
wrappers/blockcipherrwc.go Просмотреть файл

25
 				return errors.Annotate(err, "Cannot read from socket")
25
 				return errors.Annotate(err, "Cannot read from socket")
26
 			}
26
 			}
27
 			c.Buffer.Write(p[:n])
27
 			c.Buffer.Write(p[:n])
28
+			bufferLength = c.Buffer.Len()
28
 		}
29
 		}
29
 		c.decryptor.CryptBlocks(c.Buffer.Bytes(), c.Buffer.Bytes())
30
 		c.decryptor.CryptBlocks(c.Buffer.Bytes(), c.Buffer.Bytes())
30
 
31
 
47
 	return c.conn.Close()
48
 	return c.conn.Close()
48
 }
49
 }
49
 
50
 
50
-func (c *BlockCipherReadWriteCloserWithAddr) Addr() *net.TCPAddr {
51
-	return c.conn.Addr()
51
+func (c *BlockCipherReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
52
+	return c.conn.LocalAddr()
53
+}
54
+
55
+func (c *BlockCipherReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
56
+	return c.conn.RemoteAddr()
52
 }
57
 }
53
 
58
 
54
 func NewBlockCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.BlockMode) ReadWriteCloserWithAddr {
59
 func NewBlockCipherRWC(conn ReadWriteCloserWithAddr, encryptor, decryptor cipher.BlockMode) ReadWriteCloserWithAddr {

+ 6
- 2
wrappers/ctxrwc.go Просмотреть файл

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()
51
+func (c *CtxReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
52
+	return c.conn.LocalAddr()
53
+}
54
+
55
+func (c *CtxReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
56
+	return c.conn.RemoteAddr()
53
 }
57
 }
54
 
58
 
55
 // NewCtxRWC returns ReadWriteCloser which respects given context,
59
 // NewCtxRWC returns ReadWriteCloser which respects given context,

+ 6
- 2
wrappers/logrwc.go Просмотреть файл

36
 	return err
36
 	return err
37
 }
37
 }
38
 
38
 
39
-func (l *LogReadWriteCloserWithAddr) Addr() *net.TCPAddr {
40
-	return l.conn.Addr()
39
+func (l *LogReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
40
+	return l.conn.LocalAddr()
41
+}
42
+
43
+func (l *LogReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
44
+	return l.conn.RemoteAddr()
41
 }
45
 }
42
 
46
 
43
 // NewLogRWC wraps ReadWriteCloser with logger calls.
47
 // NewLogRWC wraps ReadWriteCloser with logger calls.

+ 2
- 1
wrappers/rwcaddr.go Просмотреть файл

8
 type ReadWriteCloserWithAddr interface {
8
 type ReadWriteCloserWithAddr interface {
9
 	io.ReadWriteCloser
9
 	io.ReadWriteCloser
10
 
10
 
11
-	Addr() *net.TCPAddr
11
+	LocalAddr() *net.TCPAddr
12
+	RemoteAddr() *net.TCPAddr
12
 }
13
 }

+ 6
- 2
wrappers/streamcipherrwc.go Просмотреть файл

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()
46
+func (c *StreamCipherReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
47
+	return c.conn.LocalAddr()
48
+}
49
+
50
+func (c *StreamCipherReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
51
+	return c.conn.RemoteAddr()
48
 }
52
 }
49
 
53
 
50
 // NewStreamCipherRWC returns wrapper which transparently
54
 // NewStreamCipherRWC returns wrapper which transparently

+ 25
- 4
wrappers/timeoutrwc.go Просмотреть файл

8
 )
8
 )
9
 
9
 
10
 type TimeoutReadWriteCloserWithAddr struct {
10
 type TimeoutReadWriteCloserWithAddr struct {
11
-	conn net.Conn
11
+	conn       net.Conn
12
+	publicIPv4 net.IP
13
+	publicIPv6 net.IP
12
 }
14
 }
13
 
15
 
14
 func (t *TimeoutReadWriteCloserWithAddr) Read(p []byte) (int, error) {
16
 func (t *TimeoutReadWriteCloserWithAddr) Read(p []byte) (int, error) {
25
 	return t.conn.Close()
27
 	return t.conn.Close()
26
 }
28
 }
27
 
29
 
28
-func (t *TimeoutReadWriteCloserWithAddr) Addr() *net.TCPAddr {
30
+func (t *TimeoutReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
29
 	return t.conn.RemoteAddr().(*net.TCPAddr)
31
 	return t.conn.RemoteAddr().(*net.TCPAddr)
30
 }
32
 }
31
 
33
 
32
-func NewTimeoutRWC(conn net.Conn) ReadWriteCloserWithAddr {
33
-	return &TimeoutReadWriteCloserWithAddr{conn}
34
+func (t *TimeoutReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
35
+	addr := t.conn.LocalAddr().(*net.TCPAddr)
36
+	newAddr := *addr
37
+
38
+	if t.RemoteAddr().IP.To4() != nil {
39
+		if t.publicIPv4 != nil {
40
+			newAddr.IP = t.publicIPv4
41
+		}
42
+	} else if t.publicIPv6 != nil {
43
+		newAddr.IP = t.publicIPv6
44
+	}
45
+
46
+	return &newAddr
47
+}
48
+
49
+func NewTimeoutRWC(conn net.Conn, ipv4, ipv6 net.IP) ReadWriteCloserWithAddr {
50
+	return &TimeoutReadWriteCloserWithAddr{
51
+		conn:       conn,
52
+		publicIPv4: ipv4,
53
+		publicIPv6: ipv6,
54
+	}
34
 }
55
 }

+ 6
- 2
wrappers/trafficrwc.go Просмотреть файл

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()
32
+func (t *TrafficReadWriteCloserWithAddr) LocalAddr() *net.TCPAddr {
33
+	return t.conn.LocalAddr()
34
+}
35
+
36
+func (t *TrafficReadWriteCloserWithAddr) RemoteAddr() *net.TCPAddr {
37
+	return t.conn.RemoteAddr()
34
 }
38
 }
35
 
39
 
36
 // NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.
40
 // NewTrafficRWC wraps ReadWriteCloser to have read/write callbacks.

Загрузка…
Отмена
Сохранить