|
31 | 31 |
|
32 | 32 | -module(rabbit_networking). |
33 | 33 |
|
34 | | --export([start/0, start_tcp_listener/2, stop_tcp_listener/2, |
35 | | - on_node_down/1, active_listeners/0, node_listeners/1, |
36 | | - connections/0, connection_info/1, connection_info/2, |
37 | | - connection_info_all/0, connection_info_all/1]). |
| 34 | +-export([start/0, start_tcp_listener/2, start_ssl_listener/3, |
| 35 | + stop_tcp_listener/2, on_node_down/1, active_listeners/0, |
| 36 | + node_listeners/1, connections/0, connection_info/1, |
| 37 | + connection_info/2, connection_info_all/0, |
| 38 | + connection_info_all/1]). |
38 | 39 | %%used by TCP-based transports, e.g. STOMP adapter |
39 | 40 | -export([check_tcp_listener_address/3]). |
40 | 41 |
|
41 | | --export([tcp_listener_started/2, tcp_listener_stopped/2, start_client/1]). |
| 42 | +-export([tcp_listener_started/2, ssl_connection_upgrade/2, |
| 43 | + tcp_listener_stopped/2, start_client/1]). |
42 | 44 |
|
43 | 45 | -include("rabbit.hrl"). |
44 | 46 | -include_lib("kernel/include/inet.hrl"). |
45 | 47 |
|
| 48 | +-define(RABBIT_TCP_OPTS, [ |
| 49 | + binary, |
| 50 | + {packet, raw}, % no packaging |
| 51 | + {reuseaddr, true}, % allow rebind without waiting |
| 52 | + %% {nodelay, true}, % TCP_NODELAY - disable Nagle's alg. |
| 53 | + %% {delay_send, true}, |
| 54 | + {exit_on_close, false} |
| 55 | + ]). |
46 | 56 | %%---------------------------------------------------------------------------- |
47 | 57 |
|
48 | 58 | -ifdef(use_specs). |
|
52 | 62 |
|
53 | 63 | -spec(start/0 :: () -> 'ok'). |
54 | 64 | -spec(start_tcp_listener/2 :: (host(), ip_port()) -> 'ok'). |
| 65 | +-spec(start_ssl_listener/3 :: (host(), ip_port(), [info()]) -> 'ok'). |
55 | 66 | -spec(stop_tcp_listener/2 :: (host(), ip_port()) -> 'ok'). |
56 | 67 | -spec(active_listeners/0 :: () -> [listener()]). |
57 | 68 | -spec(node_listeners/1 :: (erlang_node()) -> [listener()]). |
@@ -96,21 +107,24 @@ check_tcp_listener_address(NamePrefix, Host, Port) -> |
96 | 107 | {IPAddress, Name}. |
97 | 108 |
|
98 | 109 | start_tcp_listener(Host, Port) -> |
99 | | - {IPAddress, Name} = check_tcp_listener_address(rabbit_tcp_listener_sup, Host, Port), |
| 110 | + start_listener(Host, Port, "TCP Listener", |
| 111 | + {?MODULE, start_client, []}). |
| 112 | + |
| 113 | +start_ssl_listener(Host, Port, SslOpts) -> |
| 114 | + start_listener(Host, Port, "SSL Listener", |
| 115 | + {?MODULE, ssl_connection_upgrade, [SslOpts]}). |
| 116 | + |
| 117 | +start_listener(Host, Port, Label, OnConnect) -> |
| 118 | + {IPAddress, Name} = |
| 119 | + check_tcp_listener_address(rabbit_tcp_listener_sup, Host, Port), |
100 | 120 | {ok,_} = supervisor:start_child( |
101 | 121 | rabbit_sup, |
102 | 122 | {Name, |
103 | 123 | {tcp_listener_sup, start_link, |
104 | | - [IPAddress, Port, |
105 | | - [binary, |
106 | | - {packet, raw}, % no packaging |
107 | | - {reuseaddr, true}, % allow rebind without waiting |
108 | | - %% {nodelay, true}, % TCP_NODELAY - disable Nagle's alg. |
109 | | - %% {delay_send, true}, |
110 | | - {exit_on_close, false}], |
| 124 | + [IPAddress, Port, ?RABBIT_TCP_OPTS , |
111 | 125 | {?MODULE, tcp_listener_started, []}, |
112 | 126 | {?MODULE, tcp_listener_stopped, []}, |
113 | | - {?MODULE, start_client, []}]}, |
| 127 | + OnConnect, Label]}, |
114 | 128 | transient, infinity, supervisor, [tcp_listener_sup]}), |
115 | 129 | ok. |
116 | 130 |
|
@@ -148,10 +162,27 @@ on_node_down(Node) -> |
148 | 162 |
|
149 | 163 | start_client(Sock) -> |
150 | 164 | {ok, Child} = supervisor:start_child(rabbit_tcp_client_sup, []), |
151 | | - ok = gen_tcp:controlling_process(Sock, Child), |
| 165 | + ok = rabbit_net:controlling_process(Sock, Child), |
152 | 166 | Child ! {go, Sock}, |
153 | 167 | Child. |
154 | 168 |
|
| 169 | +ssl_connection_upgrade(SslOpts, Sock) -> |
| 170 | + {ok, {PeerAddress, PeerPort}} = rabbit_net:peername(Sock), |
| 171 | + PeerIp = inet_parse:ntoa(PeerAddress), |
| 172 | + |
| 173 | + case ssl:ssl_accept(Sock, SslOpts) of |
| 174 | + {ok, SslSock} -> |
| 175 | + rabbit_log:info("upgraded TCP connection from ~s:~p to SSL~n", |
| 176 | + [PeerIp, PeerPort]), |
| 177 | + RabbitSslSock = #ssl_socket{tcp = Sock, ssl = SslSock}, |
| 178 | + start_client(RabbitSslSock); |
| 179 | + {error, Reason} -> |
| 180 | + gen_tcp:close(Sock), |
| 181 | + rabbit_log:error("failed to upgrade TCP connection from ~s:~p " |
| 182 | + "to SSL: ~n~p~n", [PeerIp, PeerPort, Reason]), |
| 183 | + {error, Reason} |
| 184 | + end. |
| 185 | + |
155 | 186 | connections() -> |
156 | 187 | [Pid || {_, Pid, _, _} <- supervisor:which_children( |
157 | 188 | rabbit_tcp_client_sup)]. |
|
0 commit comments