summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Klishin <michael@novemberain.com>2015-07-31 18:45:40 +0300
committerMichael Klishin <michael@novemberain.com>2015-07-31 18:45:40 +0300
commitb5d2e0090717a5f4559fb9a68dcffa2266347004 (patch)
treef4996b9f773d0bf4989f3d273174c19983b024d6
parent7fa5f4eb28a9d9d4c9b5e166213b2e5d9666c2ec (diff)
parente5b4276660e660899549b8f184b2810a7b031ad8 (diff)
downloadrabbitmq-server-git-b5d2e0090717a5f4559fb9a68dcffa2266347004.tar.gz
Merge pull request #247 from rabbitmq/rabbitmq-server-246
Support the new `ssl:connection_information/{1,2}` API
-rw-r--r--src/rabbit_net.erl4
-rw-r--r--src/rabbit_reader.erl19
-rw-r--r--src/ssl_compat.erl75
3 files changed, 89 insertions, 9 deletions
diff --git a/src/rabbit_net.erl b/src/rabbit_net.erl
index 1731d489fa..b6cf9842ff 100644
--- a/src/rabbit_net.erl
+++ b/src/rabbit_net.erl
@@ -40,7 +40,7 @@
-spec(is_ssl/1 :: (socket()) -> boolean()).
-spec(ssl_info/1 :: (socket())
-> 'nossl' | ok_val_or_error(
- {atom(), {atom(), atom(), atom()}})).
+ [{atom(), any()}])).
-spec(controlling_process/2 :: (socket(), pid()) -> ok_or_any_error()).
-spec(getstat/2 ::
(socket(), [stat_option()])
@@ -90,7 +90,7 @@
is_ssl(Sock) -> ?IS_SSL(Sock).
ssl_info(Sock) when ?IS_SSL(Sock) ->
- ssl:connection_info(Sock#ssl_socket.ssl);
+ ssl_compat:connection_information(Sock#ssl_socket.ssl);
ssl_info(_Sock) ->
nossl.
diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl
index 5781e9f0d4..eaa2c0d3bb 100644
--- a/src/rabbit_reader.erl
+++ b/src/rabbit_reader.erl
@@ -1339,14 +1339,19 @@ socket_info(Get, Select, #v1{sock = Sock}) ->
end.
ssl_info(F, #v1{sock = Sock}) ->
- %% The first ok form is R14
- %% The second is R13 - the extra term is exportability (by inspection,
- %% the docs are wrong)
case rabbit_net:ssl_info(Sock) of
- nossl -> '';
- {error, _} -> '';
- {ok, {P, {K, C, H}}} -> F({P, {K, C, H}});
- {ok, {P, {K, C, H, _}}} -> F({P, {K, C, H}})
+ nossl -> '';
+ {error, _} -> '';
+ {ok, Items} ->
+ P = proplists:get_value(protocol, Items),
+ CS = proplists:get_value(cipher_suite, Items),
+ %% The first form is R14.
+ %% The second is R13 - the extra term is exportability (by
+ %% inspection, the docs are wrong).
+ case CS of
+ {K, C, H} -> F({P, {K, C, H}});
+ {K, C, H, _} -> F({P, {K, C, H}})
+ end
end.
cert_info(F, #v1{sock = Sock}) ->
diff --git a/src/ssl_compat.erl b/src/ssl_compat.erl
new file mode 100644
index 0000000000..fc83fbcfa6
--- /dev/null
+++ b/src/ssl_compat.erl
@@ -0,0 +1,75 @@
+%% The contents of this file are subject to the Mozilla Public License
+%% Version 1.1 (the "License"); you may not use this file except in
+%% compliance with the License. You may obtain a copy of the License
+%% at http://www.mozilla.org/MPL/
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and
+%% limitations under the License.
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developer of the Original Code is GoPivotal, Inc.
+%% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved.
+%%
+
+-module(ssl_compat).
+
+%% We don't want warnings about the use of erlang:now/0 in
+%% this module.
+-compile(nowarn_deprecated_function).
+
+-export([connection_information/1,
+ connection_information/2]).
+
+connection_information(SslSocket) ->
+ try
+ ssl:connection_information(SslSocket)
+ catch
+ error:undef ->
+ case ssl:connection_info(SslSocket) of
+ {ok, {ProtocolVersion, CipherSuite}} ->
+ {ok, [{protocol, ProtocolVersion},
+ {cipher_suite, CipherSuite}]};
+ {error, Reason} ->
+ {error, Reason}
+ end
+ end.
+
+connection_information(SslSocket, Items) ->
+ try
+ ssl:connection_information(SslSocket, Items)
+ catch
+ error:undef ->
+ WantProtocolVersion = lists:member(protocol, Items),
+ WantCipherSuite = lists:member(cipher_suite, Items),
+ if
+ WantProtocolVersion orelse WantCipherSuite ->
+ case ssl:connection_info(SslSocket) of
+ {ok, {ProtocolVersion, CipherSuite}} ->
+ filter_information_items(ProtocolVersion,
+ CipherSuite,
+ Items,
+ []);
+ {error, Reason} ->
+ {error, Reason}
+ end;
+ true ->
+ {ok, []}
+ end
+ end.
+
+filter_information_items(ProtocolVersion, CipherSuite, [protocol | Rest],
+ Result) ->
+ filter_information_items(ProtocolVersion, CipherSuite, Rest,
+ [{protocol, ProtocolVersion} | Result]);
+filter_information_items(ProtocolVersion, CipherSuite, [cipher_suite | Rest],
+ Result) ->
+ filter_information_items(ProtocolVersion, CipherSuite, Rest,
+ [{cipher_suite, CipherSuite} | Result]);
+filter_information_items(ProtocolVersion, CipherSuite, [_ | Rest],
+ Result) ->
+ filter_information_items(ProtocolVersion, CipherSuite, Rest, Result);
+filter_information_items(_ProtocolVersion, _CipherSuite, [], Result) ->
+ {ok, lists:reverse(Result)}.