Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mtproto_proxy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
mtproto_proxy
Commits
c711054b
Unverified
Commit
c711054b
authored
Aug 08, 2019
by
Sergey Prokhorov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for IPv6 clients. gh-11
parent
42eb63f2
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
92 additions
and
15 deletions
+92
-15
.travis.yml
.travis.yml
+3
-0
README.md
README.md
+32
-0
mtp_config.erl
src/mtp_config.erl
+2
-0
mtp_down_conn.erl
src/mtp_down_conn.erl
+1
-1
mtp_handler.erl
src/mtp_handler.erl
+1
-1
mtproto_proxy_app.erl
src/mtproto_proxy_app.erl
+18
-8
single_dc_SUITE.erl
test/single_dc_SUITE.erl
+35
-5
No files found.
.travis.yml
View file @
c711054b
sudo
:
required
language
:
erlang
language
:
erlang
otp_release
:
otp_release
:
-
22.0
-
22.0
...
@@ -6,6 +7,8 @@ otp_release:
...
@@ -6,6 +7,8 @@ otp_release:
-
20.3
-
20.3
#- 19.3 not supported (string:lexemes/2)
#- 19.3 not supported (string:lexemes/2)
#- 18.3 not supported (string:lexemes/2, tricky binary comprehension, map typespec with `:=`, ?assertEqual/3)
#- 18.3 not supported (string:lexemes/2, tricky binary comprehension, map typespec with `:=`, ?assertEqual/3)
install
:
-
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
script
:
script
:
-
./rebar3 compile
-
./rebar3 compile
-
./rebar3 xref
-
./rebar3 xref
...
...
README.md
View file @
c711054b
...
@@ -246,6 +246,38 @@ You should disable all protocols other than `mtp_secure` by providing `allowed_p
...
@@ -246,6 +246,38 @@ You should disable all protocols other than `mtp_secure` by providing `allowed_p
<
..
>
<
..
>
```
```
### IPv6
Currently proxy only supports client connections via IPv6, but can only connect to Telegram servers
using IPv4.
To enable IPv6, you should put IPv6 address in
`listen_ip`
config key.
If you want proxy to accept clients on the same port with both IPv4 and IPv6, you should
have 2
`ports`
sections with the same
`port`
,
`secret`
and
`tag`
, but with different names and
different
`listen_ip`
(one v4 and one v6):
```
erlang
{
mtproto_proxy
,
%% see src/mtproto_proxy.app.src for examples.
[
{
ports
,
[
#
{
name
=>
mtp_handler_all_ipv4
,
listen_ip
=>
"0.0.0.0"
,
% IPv4 address, eg 203.0.113.1
port
=>
1443
,
secret
=>
<<
"d0d6e111bada5511fcce9584deadbeef"
>>
,
tag
=>
<<
"dcbe8f1493fa4cd9ab300891c0b5b326"
>>
},
#
{
name
=>
mtp_handler_all_ipv6
,
listen_ip
=>
"::"
,
% IPv6 address, eg "2001:db8:85a3::8a2e:370:7334"
port
=>
1443
,
secret
=>
<<
"d0d6e111bada5511fcce9584deadbeef"
>>
,
tag
=>
<<
"dcbe8f1493fa4cd9ab300891c0b5b326"
>>
}
]}
]},
{
lager
,
<
...
>
```
### Tune resource consumption
### Tune resource consumption
If your server have low amount of RAM, try to set
If your server have low amount of RAM, try to set
...
...
src/mtp_config.erl
View file @
c711054b
...
@@ -26,9 +26,11 @@
...
@@ -26,9 +26,11 @@
%% gen_server callbacks
%% gen_server callbacks
-
export
([
init
/
1
,
handle_call
/
3
,
handle_cast
/
2
,
handle_info
/
2
,
-
export
([
init
/
1
,
handle_call
/
3
,
handle_cast
/
2
,
handle_info
/
2
,
terminate
/
2
,
code_change
/
3
]).
terminate
/
2
,
code_change
/
3
]).
-
export_type
([
netloc_v4v6
/
0
]).
-
type
dc_id
()
::
integer
().
-
type
dc_id
()
::
integer
().
-
type
netloc
()
::
{
inet
:
ip4_address
(),
inet
:
port_number
()}.
-
type
netloc
()
::
{
inet
:
ip4_address
(),
inet
:
port_number
()}.
-
type
netloc_v4v6
()
::
{
inet
:
ip_address
(),
inet
:
port_number
()}.
-
include_lib
(
"hut/include/hut.hrl"
).
-
include_lib
(
"hut/include/hut.hrl"
).
...
...
src/mtp_down_conn.erl
View file @
c711054b
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
-
endif
.
-
endif
.
-
type
handle
()
::
pid
().
-
type
handle
()
::
pid
().
-
type
upstream_opts
()
::
#
{
addr
:
=
mtp_config
:
netloc
(),
% IP/Port of TG client
-
type
upstream_opts
()
::
#
{
addr
:
=
mtp_config
:
netloc
_v4v6
(),
% IP/Port of TG client
ad_tag
=>
binary
()}.
ad_tag
=>
binary
()}.
-
type
upstream
()
::
{
-
type
upstream
()
::
{
_
UpsStatic
::{_
ConnId
::
mtp_rpc
:
conn_id
(),
_
UpsStatic
::{_
ConnId
::
mtp_rpc
:
conn_id
(),
...
...
src/mtp_handler.erl
View file @
c711054b
...
@@ -49,7 +49,7 @@
...
@@ -49,7 +49,7 @@
dc_id
::
{
DcId
::
integer
(),
Pool
::
pid
()}
|
undefined
,
dc_id
::
{
DcId
::
integer
(),
Pool
::
pid
()}
|
undefined
,
ad_tag
::
binary
(),
ad_tag
::
binary
(),
addr
::
mtp_config
:
netloc
(),
% IP/Port of remote side
addr
::
mtp_config
:
netloc
_v4v6
(),
% IP/Port of remote side
started_at
::
pos_integer
(),
started_at
::
pos_integer
(),
timer_state
=
init
::
init
|
hibernate
|
stop
,
timer_state
=
init
::
init
|
hibernate
|
stop
,
timer
::
gen_timeout
:
tout
(),
timer
::
gen_timeout
:
tout
(),
...
...
src/mtproto_proxy_app.erl
View file @
c711054b
...
@@ -19,7 +19,7 @@
...
@@ -19,7 +19,7 @@
port
:
=
inet
:
port_number
(),
port
:
=
inet
:
port_number
(),
secret
:
=
binary
(),
secret
:
=
binary
(),
tag
:
=
binary
(),
tag
:
=
binary
(),
listen_ip
=>
inet
:
ip4_addr
()}.
listen_ip
=>
string
()}.
%%====================================================================
%%====================================================================
%% API
%% API
...
@@ -69,11 +69,16 @@ running_ports() ->
...
@@ -69,11 +69,16 @@ running_ports() ->
ip
:
=
Ip
,
ip
:
=
Ip
,
port
:
=
Port
}
=
maps
:
from_list
(
Opts
),
port
:
=
Port
}
=
maps
:
from_list
(
Opts
),
[
Name
,
Secret
,
AdTag
]
=
ProtoOpts
,
[
Name
,
Secret
,
AdTag
]
=
ProtoOpts
,
#
{
name
=>
Name
,
case
inet
:
ntoa
(
Ip
)
of
listen_ip
=>
inet
:
ntoa
(
Ip
),
{
error
,
einval
}
->
port
=>
Port
,
error
({
invalid_ip
,
Ip
});
secret
=>
Secret
,
IpAddr
->
tag
=>
AdTag
}
#
{
name
=>
Name
,
listen_ip
=>
IpAddr
,
port
=>
Port
,
secret
=>
Secret
,
tag
=>
AdTag
}
end
end
,
mtp_listeners
()).
end
,
mtp_listeners
()).
%%====================================================================
%%====================================================================
...
@@ -84,14 +89,19 @@ start_proxy(#{name := Name, port := Port, secret := Secret, tag := Tag} = P) ->
...
@@ -84,14 +89,19 @@ start_proxy(#{name := Name, port := Port, secret := Secret, tag := Tag} = P) ->
ListenIpStr
=
maps
:
get
(
ListenIpStr
=
maps
:
get
(
listen_ip
,
P
,
listen_ip
,
P
,
application
:
get_env
(
?
APP
,
listen_ip
,
"0.0.0.0"
)),
application
:
get_env
(
?
APP
,
listen_ip
,
"0.0.0.0"
)),
{
ok
,
ListenIp
}
=
inet
:
parse_ipv4_address
(
ListenIpStr
),
{
ok
,
ListenIp
}
=
inet
:
parse_address
(
ListenIpStr
),
Family
=
case
tuple_size
(
ListenIp
)
of
4
->
inet
;
8
->
inet6
end
,
NumAcceptors
=
application
:
get_env
(
?
APP
,
num_acceptors
,
60
),
NumAcceptors
=
application
:
get_env
(
?
APP
,
num_acceptors
,
60
),
MaxConnections
=
application
:
get_env
(
?
APP
,
max_connections
,
10240
),
MaxConnections
=
application
:
get_env
(
?
APP
,
max_connections
,
10240
),
Res
=
Res
=
ranch
:
start_listener
(
ranch
:
start_listener
(
Name
,
ranch_tcp
,
Name
,
ranch_tcp
,
#
{
socket_opts
=>
[{
ip
,
ListenIp
},
#
{
socket_opts
=>
[{
ip
,
ListenIp
},
{
port
,
Port
}],
{
port
,
Port
},
Family
],
num_acceptors
=>
NumAcceptors
,
num_acceptors
=>
NumAcceptors
,
max_connections
=>
MaxConnections
},
max_connections
=>
MaxConnections
},
mtp_handler
,
[
Name
,
Secret
,
Tag
]),
mtp_handler
,
[
Name
,
Secret
,
Tag
]),
...
...
test/single_dc_SUITE.erl
View file @
c711054b
...
@@ -14,7 +14,8 @@
...
@@ -14,7 +14,8 @@
downstream_qlen_backpressure_case
/
1
,
downstream_qlen_backpressure_case
/
1
,
config_change_case
/
1
,
config_change_case
/
1
,
replay_attack_case
/
1
,
replay_attack_case
/
1
,
replay_attack_server_error_case
/
1
replay_attack_server_error_case
/
1
,
ipv6_connect_case
/
1
]).
]).
-
export
([
set_env
/
2
,
-
export
([
set_env
/
2
,
...
@@ -375,26 +376,55 @@ replay_attack_server_error_case(Cfg) when is_list(Cfg) ->
...
@@ -375,26 +376,55 @@ replay_attack_server_error_case(Cfg) when is_list(Cfg) ->
%% TODO: send a lot, not read, and then close - assert connection IDs are cleaned up
%% TODO: send a lot, not read, and then close - assert connection IDs are cleaned up
%% @doc Test that it's possible to connect and communicate via IPv6
ipv6_connect_case
({
pre
,
Cfg
})
->
setup_single
(
?
FUNCTION_NAME
,
"::1"
,
10000
+
?
LINE
,
#
{},
Cfg
);
ipv6_connect_case
({
post
,
Cfg
})
->
stop_single
(
Cfg
);
ipv6_connect_case
(
Cfg
)
when
is_list
(
Cfg
)
->
DcId
=
?
config
(
dc_id
,
Cfg
),
Host
=
?
config
(
mtp_host
,
Cfg
),
Port
=
?
config
(
mtp_port
,
Cfg
),
Secret
=
?
config
(
mtp_secret
,
Cfg
),
ConnCount
=
fun
()
->
mtp_test_metric
:
get_tags
(
count
,
[
?
APP
,
in_connection
,
total
],
[
?
FUNCTION_NAME
])
end
,
?
assertEqual
(
not_found
,
ConnCount
()),
?
assertEqual
(
8
,
tuple_size
(
Host
)),
Cli0
=
mtp_test_client
:
connect
(
Host
,
Port
,
Secret
,
DcId
,
mtp_secure
),
Data
=
crypto
:
strong_rand_bytes
(
64
),
Cli1
=
mtp_test_client
:
send
(
Data
,
Cli0
),
{
ok
,
Packet
,
Cli2
}
=
mtp_test_client
:
recv_packet
(
Cli1
,
1000
),
ok
=
mtp_test_client
:
close
(
Cli2
),
?
assertEqual
(
Data
,
Packet
),
?
assertEqual
(
1
,
ConnCount
()),
ok
=
mtp_test_metric
:
wait_for_value
(
count
,
[
?
APP
,
in_connection_closed
,
total
],
[
?
FUNCTION_NAME
],
1
,
5000
).
%% Helpers
%% Helpers
setup_single
(
Name
,
MtpPort
,
DcCfg0
,
Cfg
)
->
setup_single
(
Name
,
MtpPort
,
DcCfg0
,
Cfg
)
->
setup_single
(
Name
,
"127.0.0.1"
,
MtpPort
,
DcCfg0
,
Cfg
).
setup_single
(
Name
,
MtpIpStr
,
MtpPort
,
DcCfg0
,
Cfg
)
->
{
ok
,
Pid
}
=
mtp_test_metric
:
start_link
(),
{
ok
,
Pid
}
=
mtp_test_metric
:
start_link
(),
PubKey
=
crypto
:
strong_rand_bytes
(
128
),
PubKey
=
crypto
:
strong_rand_bytes
(
128
),
DcId
=
1
,
DcId
=
1
,
Ip
=
{
127
,
0
,
0
,
1
},
DcConf
=
[{
DcId
,
{
127
,
0
,
0
,
1
},
MtpPort
+
10
}],
DcConf
=
[{
DcId
,
Ip
,
MtpPort
+
10
}],
Secret
=
mtp_handler
:
hex
(
crypto
:
strong_rand_bytes
(
16
)),
Secret
=
mtp_handler
:
hex
(
crypto
:
strong_rand_bytes
(
16
)),
Listeners
=
[
#
{
name
=>
Name
,
Listeners
=
[
#
{
name
=>
Name
,
port
=>
MtpPort
,
port
=>
MtpPort
,
listen_ip
=>
"127.0.0.1"
,
listen_ip
=>
MtpIpStr
,
secret
=>
Secret
,
secret
=>
Secret
,
tag
=>
<<
"dcbe8f1493fa4cd9ab300891c0b5b326"
>>
}],
tag
=>
<<
"dcbe8f1493fa4cd9ab300891c0b5b326"
>>
}],
application
:
load
(
mtproto_proxy
),
application
:
load
(
mtproto_proxy
),
Cfg1
=
set_env
([{
ports
,
Listeners
}],
Cfg
),
Cfg1
=
set_env
([{
ports
,
Listeners
}],
Cfg
),
{
ok
,
DcCfg
}
=
mtp_test_datacenter
:
start_dc
(
PubKey
,
DcConf
,
DcCfg0
),
{
ok
,
DcCfg
}
=
mtp_test_datacenter
:
start_dc
(
PubKey
,
DcConf
,
DcCfg0
),
{
ok
,
_}
=
application
:
ensure_all_started
(
mtproto_proxy
),
{
ok
,
_}
=
application
:
ensure_all_started
(
mtproto_proxy
),
{
ok
,
MtpIp
}
=
inet
:
parse_address
(
MtpIpStr
),
[{
dc_id
,
DcId
},
[{
dc_id
,
DcId
},
{
mtp_host
,
Ip
},
{
mtp_host
,
Mtp
Ip
},
{
mtp_port
,
MtpPort
},
{
mtp_port
,
MtpPort
},
{
mtp_secret
,
Secret
},
{
mtp_secret
,
Secret
},
{
dc_conf
,
DcCfg
},
{
dc_conf
,
DcCfg
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment