1 |
|
%%============================================================================== |
2 |
|
%% Copyright 2017 Erlang Solutions Ltd. |
3 |
|
%% |
4 |
|
%% Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
|
%% you may not use this file except in compliance with the License. |
6 |
|
%% You may obtain a copy of the License at |
7 |
|
%% |
8 |
|
%% http://www.apache.org/licenses/LICENSE-2.0 |
9 |
|
%% |
10 |
|
%% Unless required by applicable law or agreed to in writing, software |
11 |
|
%% distributed under the License is distributed on an "AS IS" BASIS, |
12 |
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
|
%% See the License for the specific language governing permissions and |
14 |
|
%% limitations under the License. |
15 |
|
%%============================================================================== |
16 |
|
|
17 |
|
-module(mod_global_distrib_transport). |
18 |
|
-author('konrad.zemek@erlang-solutions.com'). |
19 |
|
|
20 |
|
-record(?MODULE, { |
21 |
|
transport :: fast_tls | gen_tcp, |
22 |
|
socket :: fast_tls:tls_socket() | gen_tcp:socket() |
23 |
|
}). |
24 |
|
|
25 |
|
-type t() :: #?MODULE{}. |
26 |
|
|
27 |
|
-export([wrap/2, setopts/2, recv_data/2, close/1, send/2, peername/1]). |
28 |
|
-export_types([t/0]). |
29 |
|
|
30 |
|
%%-------------------------------------------------------------------- |
31 |
|
%% API |
32 |
|
%%-------------------------------------------------------------------- |
33 |
|
|
34 |
|
-spec wrap(Socket :: gen_tcp:socket(), false | [connect | false] | proplists:proplist()) -> |
35 |
|
{ok, t()} | {error, any()}. |
36 |
|
wrap(Socket, [connect | false]) -> |
37 |
:-( |
wrap(Socket, false); |
38 |
|
wrap(Socket, false) -> |
39 |
:-( |
{ok, #?MODULE{transport = gen_tcp, socket = Socket}}; |
40 |
|
wrap(Socket, Opts0) -> |
41 |
3101 |
Opts1 = case proplists:get_value(ciphers, Opts0) of |
42 |
3101 |
undefined -> [{ciphers, "TLSv1.2:TLSv1.3"} | Opts0]; |
43 |
:-( |
_ -> Opts0 |
44 |
|
end, |
45 |
3101 |
case fast_tls:tcp_to_tls(Socket, Opts1) of |
46 |
3101 |
{ok, TLSSocket} -> {ok, #?MODULE{transport = fast_tls, socket = TLSSocket}}; |
47 |
:-( |
Error -> Error |
48 |
|
end. |
49 |
|
|
50 |
|
-spec setopts(t(), Opts :: proplists:proplist()) -> ok | {error, term()}. |
51 |
|
setopts(#?MODULE{transport = gen_tcp, socket = Socket}, Opts) -> |
52 |
:-( |
inet:setopts(Socket, Opts); |
53 |
|
setopts(#?MODULE{transport = fast_tls, socket = Socket}, Opts) -> |
54 |
13036 |
fast_tls:setopts(Socket, Opts). |
55 |
|
|
56 |
|
-spec recv_data(t(), Data :: binary()) -> {ok, binary()} | {error, any()}. |
57 |
|
recv_data(#?MODULE{transport = gen_tcp}, Data) -> |
58 |
:-( |
{ok, Data}; |
59 |
|
recv_data(#?MODULE{transport = fast_tls, socket = Socket}, Data) -> |
60 |
9935 |
fast_tls:recv_data(Socket, Data). |
61 |
|
|
62 |
|
-spec close(t()) -> ok | {error, any()}. |
63 |
|
close(#?MODULE{transport = gen_tcp, socket = Socket}) -> |
64 |
:-( |
gen_tcp:close(Socket); |
65 |
|
close(#?MODULE{transport = fast_tls, socket = Socket}) -> |
66 |
3101 |
fast_tls:close(Socket). |
67 |
|
|
68 |
|
-spec send(t(), Data :: binary()) -> ok | {error, any()}. |
69 |
|
send(#?MODULE{transport = gen_tcp, socket = Socket}, Data) -> |
70 |
:-( |
gen_tcp:send(Socket, Data); |
71 |
|
send(#?MODULE{transport = fast_tls, socket = Socket}, Data) -> |
72 |
1876 |
fast_tls:send(Socket, Data). |
73 |
|
|
74 |
|
-spec peername(t()) -> {inet:ip_address(), inet:port_number()} | unknown. |
75 |
|
peername(#?MODULE{transport = gen_tcp, socket = Socket}) -> |
76 |
:-( |
normalize_peername(inet:peername(Socket)); |
77 |
|
peername(#?MODULE{transport = fast_tls, socket = Socket}) -> |
78 |
3101 |
normalize_peername(fast_tls:peername(Socket)). |
79 |
|
|
80 |
|
-spec normalize_peername({ok, {inet:ip_address(), inet:port_number()}} | any()) -> |
81 |
|
{inet:ip_address(), inet:port_number()} | unknown. |
82 |
3081 |
normalize_peername({ok, {IP, Port}}) when is_tuple(IP), is_integer(Port) -> {IP, Port}; |
83 |
20 |
normalize_peername(_Other) -> unknown. |
84 |
|
|