Skip to content
This repository was archived by the owner on Nov 17, 2020. It is now read-only.

Commit 5a6d690

Browse files
Merge branch 'stable'
Conflicts: src/rabbit_amqqueue.erl
2 parents 05ea2bc + 4d085df commit 5a6d690

File tree

4 files changed

+155
-102
lines changed

4 files changed

+155
-102
lines changed

src/rabbit_amqqueue.erl

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,6 @@
172172
(rabbit_types:amqqueue(), pid(), rabbit_types:ctag(), any(),
173173
rabbit_types:username()) -> 'ok'.
174174
-spec notify_decorators(rabbit_types:amqqueue()) -> 'ok'.
175-
-spec notify_sent(pid(), pid()) -> 'ok'.
176-
-spec notify_sent_queue_down(pid()) -> 'ok'.
177175
-spec resume(pid(), pid()) -> 'ok'.
178176
-spec internal_delete(name(), rabbit_types:username()) ->
179177
rabbit_types:ok_or_error('not_found') |
@@ -266,12 +264,12 @@ find_durable_queues() ->
266264
pid = Pid}
267265
<- mnesia:table(rabbit_durable_queue),
268266
node(Pid) == Node andalso
269-
%% Terminations on node down will not remove the rabbit_queue
270-
%% record if it is a mirrored queue (such info is now obtained from
271-
%% the policy). Thus, we must check if the local pid is alive
272-
%% - if the record is present - in order to restart.
273-
(mnesia:read(rabbit_queue, Name, read) =:= []
274-
orelse not erlang:is_process_alive(Pid))]))
267+
%% Terminations on node down will not remove the rabbit_queue
268+
%% record if it is a mirrored queue (such info is now obtained from
269+
%% the policy). Thus, we must check if the local pid is alive
270+
%% - if the record is present - in order to restart.
271+
(mnesia:read(rabbit_queue, Name, read) =:= []
272+
orelse not erlang:is_process_alive(Pid))]))
275273
end).
276274

277275
recover_durable_queues(QueuesAndRecoveryTerms) ->
@@ -795,21 +793,10 @@ notify_decorators(#amqqueue{pid = QPid}) ->
795793
delegate:cast(QPid, notify_decorators).
796794

797795
notify_sent(QPid, ChPid) ->
798-
Key = {consumer_credit_to, QPid},
799-
put(Key, case get(Key) of
800-
1 -> gen_server2:cast(
801-
QPid, {notify_sent, ChPid,
802-
?MORE_CONSUMER_CREDIT_AFTER}),
803-
?MORE_CONSUMER_CREDIT_AFTER;
804-
undefined -> erlang:monitor(process, QPid),
805-
?MORE_CONSUMER_CREDIT_AFTER - 1;
806-
C -> C - 1
807-
end),
808-
ok.
796+
rabbit_amqqueue_common:notify_sent(QPid, ChPid).
809797

810798
notify_sent_queue_down(QPid) ->
811-
erase({consumer_credit_to, QPid}),
812-
ok.
799+
rabbit_amqqueue_common:notify_sent_queue_down(QPid).
813800

814801
resume(QPid, ChPid) -> delegate:cast(QPid, {resume, ChPid}).
815802

@@ -839,10 +826,9 @@ internal_delete(QueueName, ActingUser) ->
839826
fun() ->
840827
ok = T(),
841828
rabbit_core_metrics:queue_deleted(QueueName),
842-
ok = rabbit_event:notify(
843-
queue_deleted,
844-
[{name, QueueName},
845-
{user_who_performed_action, ActingUser}])
829+
ok = rabbit_event:notify(queue_deleted,
830+
[{name, QueueName},
831+
{user_who_performed_action, ActingUser}])
846832
end
847833
end
848834
end).
@@ -888,8 +874,10 @@ forget_node_for_queue(DeadNode, [H|T], Q) ->
888874
node_permits_offline_promotion(Node) ->
889875
case node() of
890876
Node -> not rabbit:is_running(); %% [1]
891-
_ -> Running = rabbit_mnesia:cluster_nodes(running),
892-
not lists:member(Node, Running) %% [2]
877+
_ -> All = rabbit_mnesia:cluster_nodes(all),
878+
Running = rabbit_mnesia:cluster_nodes(running),
879+
lists:member(Node, All) andalso
880+
not lists:member(Node, Running) %% [2]
893881
end.
894882
%% [1] In this case if we are a real running node (i.e. rabbitmqctl
895883
%% has RPCed into us) then we cannot allow promotion. If on the other
@@ -963,9 +951,9 @@ on_node_down(Node) ->
963951
qlc:e(qlc:q([{QName, delete_queue(QName)} ||
964952
#amqqueue{name = QName, pid = Pid} = Q
965953
<- mnesia:table(rabbit_queue),
966-
not rabbit_amqqueue:is_mirrored(Q) andalso
967-
node(Pid) == Node andalso
968-
not rabbit_mnesia:is_process_alive(Pid)])),
954+
not rabbit_amqqueue:is_mirrored(Q) andalso
955+
node(Pid) == Node andalso
956+
not rabbit_mnesia:is_process_alive(Pid)])),
969957
{Qs, Dels} = lists:unzip(QsDels),
970958
T = rabbit_binding:process_deletions(
971959
lists:foldl(fun rabbit_binding:combine_deletions/2,
@@ -975,7 +963,7 @@ on_node_down(Node) ->
975963
T(),
976964
lists:foreach(
977965
fun(QName) ->
978-
rabbit_core_metrics:queue_deleted(QName),
966+
rabbit_core_metrics:queue_deleted(QName),
979967
ok = rabbit_event:notify(queue_deleted,
980968
[{name, QName},
981969
{user, ?INTERNAL_USER}])

src/rabbit_amqqueue_common.erl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
%% The contents of this file are subject to the Mozilla Public License
2+
%% Version 1.1 (the "License"); you may not use this file except in
3+
%% compliance with the License. You may obtain a copy of the License
4+
%% at http://www.mozilla.org/MPL/
5+
%%
6+
%% Software distributed under the License is distributed on an "AS IS"
7+
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
8+
%% the License for the specific language governing rights and
9+
%% limitations under the License.
10+
%%
11+
%% The Original Code is RabbitMQ.
12+
%%
13+
%% The Initial Developer of the Original Code is GoPivotal, Inc.
14+
%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
15+
%%
16+
17+
-module(rabbit_amqqueue_common).
18+
19+
-export([notify_sent/2, notify_sent_queue_down/1]).
20+
21+
-define(MORE_CONSUMER_CREDIT_AFTER, 50).
22+
23+
-spec notify_sent(pid(), pid()) -> 'ok'.
24+
25+
notify_sent(QPid, ChPid) ->
26+
Key = {consumer_credit_to, QPid},
27+
put(Key, case get(Key) of
28+
1 -> gen_server2:cast(
29+
QPid, {notify_sent, ChPid,
30+
?MORE_CONSUMER_CREDIT_AFTER}),
31+
?MORE_CONSUMER_CREDIT_AFTER;
32+
undefined -> erlang:monitor(process, QPid),
33+
?MORE_CONSUMER_CREDIT_AFTER - 1;
34+
C -> C - 1
35+
end),
36+
ok.
37+
38+
-spec notify_sent_queue_down(pid()) -> 'ok'.
39+
40+
notify_sent_queue_down(QPid) ->
41+
erase({consumer_credit_to, QPid}),
42+
ok.

src/rabbit_networking.erl

Lines changed: 2 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,12 @@
4646
%% Internal
4747
-export([connections_local/0]).
4848

49-
-import(rabbit_misc, [pget/2, pget/3, pset/3]).
50-
5149
-include("rabbit.hrl").
5250
-include_lib("kernel/include/inet.hrl").
5351

5452
%% IANA-suggested ephemeral port range is 49152 to 65535
5553
-define(FIRST_TEST_BIND_PORT, 49152).
5654

57-
%% POODLE
58-
-define(BAD_SSL_PROTOCOL_VERSIONS, [sslv3]).
59-
6055
%%----------------------------------------------------------------------------
6156

6257
-export_type([ip_port/0, hostname/0]).
@@ -100,7 +95,6 @@
10095
protocol(), any(), non_neg_integer(), label()) ->
10196
supervisor:child_spec().
10297
-spec ensure_ssl() -> rabbit_types:infos().
103-
-spec fix_ssl_options(rabbit_types:infos()) -> rabbit_types:infos().
10498
-spec poodle_check(atom()) -> 'ok' | 'danger'.
10599

106100
-spec boot() -> 'ok'.
@@ -150,7 +144,7 @@ ensure_ssl() ->
150144
{ok, SslAppsConfig} = application:get_env(rabbit, ssl_apps),
151145
ok = app_utils:start_applications(SslAppsConfig),
152146
{ok, SslOptsConfig} = application:get_env(rabbit, ssl_options),
153-
fix_ssl_options(SslOptsConfig).
147+
rabbit_ssl_options:fix(SslOptsConfig).
154148

155149
poodle_check(Context) ->
156150
{ok, Vsn} = application:get_key(ssl, vsn),
@@ -184,70 +178,7 @@ maybe_start_proxy_protocol() ->
184178
end.
185179

186180
fix_ssl_options(Config) ->
187-
fix_verify_fun(fix_ssl_protocol_versions(Config)).
188-
189-
fix_verify_fun(SslOptsConfig) ->
190-
%% Starting with ssl 4.0.1 in Erlang R14B, the verify_fun function
191-
%% takes 3 arguments and returns a tuple.
192-
case rabbit_misc:pget(verify_fun, SslOptsConfig) of
193-
{Module, Function, InitialUserState} ->
194-
Fun = make_verify_fun(Module, Function, InitialUserState),
195-
rabbit_misc:pset(verify_fun, Fun, SslOptsConfig);
196-
{Module, Function} when is_atom(Module) ->
197-
Fun = make_verify_fun(Module, Function, none),
198-
rabbit_misc:pset(verify_fun, Fun, SslOptsConfig);
199-
{Verifyfun, _InitialUserState} when is_function(Verifyfun, 3) ->
200-
SslOptsConfig;
201-
undefined ->
202-
SslOptsConfig
203-
end.
204-
205-
make_verify_fun(Module, Function, InitialUserState) ->
206-
try
207-
%% Preload the module: it is required to use
208-
%% erlang:function_exported/3.
209-
Module:module_info()
210-
catch
211-
_:Exception ->
212-
rabbit_log:error("SSL verify_fun: module ~s missing: ~p~n",
213-
[Module, Exception]),
214-
throw({error, {invalid_verify_fun, missing_module}})
215-
end,
216-
NewForm = erlang:function_exported(Module, Function, 3),
217-
OldForm = erlang:function_exported(Module, Function, 1),
218-
case {NewForm, OldForm} of
219-
{true, _} ->
220-
%% This verify_fun is supported by Erlang R14B+ (ssl
221-
%% 4.0.1 and later).
222-
Fun = fun(OtpCert, Event, UserState) ->
223-
Module:Function(OtpCert, Event, UserState)
224-
end,
225-
{Fun, InitialUserState};
226-
{_, true} ->
227-
%% This verify_fun is supported by Erlang R14B+ for
228-
%% undocumented backward compatibility.
229-
%%
230-
%% InitialUserState is ignored in this case.
231-
fun(Args) ->
232-
Module:Function(Args)
233-
end;
234-
_ ->
235-
rabbit_log:error("SSL verify_fun: no ~s:~s/3 exported~n",
236-
[Module, Function]),
237-
throw({error, {invalid_verify_fun, function_not_exported}})
238-
end.
239-
240-
fix_ssl_protocol_versions(Config) ->
241-
case application:get_env(rabbit, ssl_allow_poodle_attack) of
242-
{ok, true} ->
243-
Config;
244-
_ ->
245-
Configured = case pget(versions, Config) of
246-
undefined -> pget(available, ssl:versions(), []);
247-
Vs -> Vs
248-
end,
249-
pset(versions, Configured -- ?BAD_SSL_PROTOCOL_VERSIONS, Config)
250-
end.
181+
rabbit_ssl_options:fix(Config).
251182

252183
tcp_listener_addresses(Port) when is_integer(Port) ->
253184
tcp_listener_addresses_auto(Port);

src/rabbit_ssl_options.erl

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
%% The contents of this file are subject to the Mozilla Public License
2+
%% Version 1.1 (the "License"); you may not use this file except in
3+
%% compliance with the License. You may obtain a copy of the License
4+
%% at http://www.mozilla.org/MPL/
5+
%%
6+
%% Software distributed under the License is distributed on an "AS IS"
7+
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
8+
%% the License for the specific language governing rights and
9+
%% limitations under the License.
10+
%%
11+
%% The Original Code is RabbitMQ.
12+
%%
13+
%% The Initial Developer of the Original Code is GoPivotal, Inc.
14+
%% Copyright (c) 2007-2017 Pivotal Software, Inc. All rights reserved.
15+
%%
16+
17+
-module(rabbit_ssl_options).
18+
19+
-export([fix/1]).
20+
21+
%% POODLE
22+
-define(BAD_SSL_PROTOCOL_VERSIONS, [sslv3]).
23+
24+
-spec fix(rabbit_types:infos()) -> rabbit_types:infos().
25+
26+
fix(Config) ->
27+
fix_verify_fun(fix_ssl_protocol_versions(Config)).
28+
29+
fix_verify_fun(SslOptsConfig) ->
30+
%% Starting with ssl 4.0.1 in Erlang R14B, the verify_fun function
31+
%% takes 3 arguments and returns a tuple.
32+
case rabbit_misc:pget(verify_fun, SslOptsConfig) of
33+
{Module, Function, InitialUserState} ->
34+
Fun = make_verify_fun(Module, Function, InitialUserState),
35+
rabbit_misc:pset(verify_fun, Fun, SslOptsConfig);
36+
{Module, Function} when is_atom(Module) ->
37+
Fun = make_verify_fun(Module, Function, none),
38+
rabbit_misc:pset(verify_fun, Fun, SslOptsConfig);
39+
{Verifyfun, _InitialUserState} when is_function(Verifyfun, 3) ->
40+
SslOptsConfig;
41+
undefined ->
42+
SslOptsConfig
43+
end.
44+
45+
make_verify_fun(Module, Function, InitialUserState) ->
46+
try
47+
%% Preload the module: it is required to use
48+
%% erlang:function_exported/3.
49+
Module:module_info()
50+
catch
51+
_:Exception ->
52+
rabbit_log:error("SSL verify_fun: module ~s missing: ~p~n",
53+
[Module, Exception]),
54+
throw({error, {invalid_verify_fun, missing_module}})
55+
end,
56+
NewForm = erlang:function_exported(Module, Function, 3),
57+
OldForm = erlang:function_exported(Module, Function, 1),
58+
case {NewForm, OldForm} of
59+
{true, _} ->
60+
%% This verify_fun is supported by Erlang R14B+ (ssl
61+
%% 4.0.1 and later).
62+
Fun = fun(OtpCert, Event, UserState) ->
63+
Module:Function(OtpCert, Event, UserState)
64+
end,
65+
{Fun, InitialUserState};
66+
{_, true} ->
67+
%% This verify_fun is supported by Erlang R14B+ for
68+
%% undocumented backward compatibility.
69+
%%
70+
%% InitialUserState is ignored in this case.
71+
fun(Args) ->
72+
Module:Function(Args)
73+
end;
74+
_ ->
75+
rabbit_log:error("SSL verify_fun: no ~s:~s/3 exported~n",
76+
[Module, Function]),
77+
throw({error, {invalid_verify_fun, function_not_exported}})
78+
end.
79+
80+
fix_ssl_protocol_versions(Config) ->
81+
case application:get_env(rabbit, ssl_allow_poodle_attack) of
82+
{ok, true} ->
83+
Config;
84+
_ ->
85+
Configured = case rabbit_misc:pget(versions, Config) of
86+
undefined -> rabbit_misc:pget(available,
87+
ssl:versions(),
88+
[]);
89+
Vs -> Vs
90+
end,
91+
rabbit_misc:pset(versions, Configured -- ?BAD_SSL_PROTOCOL_VERSIONS, Config)
92+
end.

0 commit comments

Comments
 (0)