Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
er
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
er
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
otp_release
:
-
22.0
...
...
@@ -6,6 +7,8 @@ otp_release:
-
20.3
#- 19.3 not supported (string:lexemes/2)
#- 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
:
-
./rebar3 compile
-
./rebar3 xref
...
...
README.md
View file @
c711054b
...
...
@@ -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
If your server have low amount of RAM, try to set
...
...
src/mtp_config.erl
View file @
c711054b
...
...
@@ -26,9 +26,11 @@
%% gen_server callbacks
-
export
([
init
/
1
,
handle_call
/
3
,
handle_cast
/
2
,
handle_info
/
2
,
terminate
/
2
,
code_change
/
3
]).
-
export_type
([
netloc_v4v6
/
0
]).
-
type
dc_id
()
::
integer
().
-
type
netloc
()
::
{
inet
:
ip4_address
(),
inet
:
port_number
()}.
-
type
netloc_v4v6
()
::
{
inet
:
ip_address
(),
inet
:
port_number
()}.
-
include_lib
(
"hut/include/hut.hrl"
).
...
...
src/mtp_down_conn.erl
View file @
c711054b
...
...
@@ -42,7 +42,7 @@
-
endif
.
-
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
()}.
-
type
upstream
()
::
{
_
UpsStatic
::{_
ConnId
::
mtp_rpc
:
conn_id
(),
...
...
src/mtp_handler.erl
View file @
c711054b
...
...
@@ -49,7 +49,7 @@
dc_id
::
{
DcId
::
integer
(),
Pool
::
pid
()}
|
undefined
,
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
(),
timer_state
=
init
::
init
|
hibernate
|
stop
,
timer
::
gen_timeout
:
tout
(),
...
...
src/mtproto_proxy_app.erl
View file @
c711054b
...
...
@@ -19,7 +19,7 @@
port
:
=
inet
:
port_number
(),
secret
:
=
binary
(),
tag
:
=
binary
(),
listen_ip
=>
inet
:
ip4_addr
()}.
listen_ip
=>
string
()}.
%%====================================================================
%% API
...
...
@@ -69,11 +69,16 @@ running_ports() ->
ip
:
=
Ip
,
port
:
=
Port
}
=
maps
:
from_list
(
Opts
),
[
Name
,
Secret
,
AdTag
]
=
ProtoOpts
,
#
{
name
=>
Name
,
listen_ip
=>
inet
:
ntoa
(
Ip
),
port
=>
Port
,
secret
=>
Secret
,
tag
=>
AdTag
}
case
inet
:
ntoa
(
Ip
)
of
{
error
,
einval
}
->
error
({
invalid_ip
,
Ip
});
IpAddr
->
#
{
name
=>
Name
,
listen_ip
=>
IpAddr
,
port
=>
Port
,
secret
=>
Secret
,
tag
=>
AdTag
}
end
end
,
mtp_listeners
()).
%%====================================================================
...
...
@@ -84,14 +89,19 @@ start_proxy(#{name := Name, port := Port, secret := Secret, tag := Tag} = P) ->
ListenIpStr
=
maps
:
get
(
listen_ip
,
P
,
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
),
MaxConnections
=
application
:
get_env
(
?
APP
,
max_connections
,
10240
),
Res
=
ranch
:
start_listener
(
Name
,
ranch_tcp
,
#
{
socket_opts
=>
[{
ip
,
ListenIp
},
{
port
,
Port
}],
{
port
,
Port
},
Family
],
num_acceptors
=>
NumAcceptors
,
max_connections
=>
MaxConnections
},
mtp_handler
,
[
Name
,
Secret
,
Tag
]),
...
...
test/single_dc_SUITE.erl
View file @
c711054b
...
...
@@ -14,7 +14,8 @@
downstream_qlen_backpressure_case
/
1
,
config_change_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
,
...
...
@@ -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
%% @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
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
(),
PubKey
=
crypto
:
strong_rand_bytes
(
128
),
DcId
=
1
,
Ip
=
{
127
,
0
,
0
,
1
},
DcConf
=
[{
DcId
,
Ip
,
MtpPort
+
10
}],
DcConf
=
[{
DcId
,
{
127
,
0
,
0
,
1
},
MtpPort
+
10
}],
Secret
=
mtp_handler
:
hex
(
crypto
:
strong_rand_bytes
(
16
)),
Listeners
=
[
#
{
name
=>
Name
,
port
=>
MtpPort
,
listen_ip
=>
"127.0.0.1"
,
listen_ip
=>
MtpIpStr
,
secret
=>
Secret
,
tag
=>
<<
"dcbe8f1493fa4cd9ab300891c0b5b326"
>>
}],
application
:
load
(
mtproto_proxy
),
Cfg1
=
set_env
([{
ports
,
Listeners
}],
Cfg
),
{
ok
,
DcCfg
}
=
mtp_test_datacenter
:
start_dc
(
PubKey
,
DcConf
,
DcCfg0
),
{
ok
,
_}
=
application
:
ensure_all_started
(
mtproto_proxy
),
{
ok
,
MtpIp
}
=
inet
:
parse_address
(
MtpIpStr
),
[{
dc_id
,
DcId
},
{
mtp_host
,
Ip
},
{
mtp_host
,
Mtp
Ip
},
{
mtp_port
,
MtpPort
},
{
mtp_secret
,
Secret
},
{
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