aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/erl_interface/include/ei.h2
-rw-r--r--lib/erl_interface/src/decode/decode_fun.c12
-rw-r--r--lib/erl_interface/src/encode/encode_fun.c2
-rw-r--r--lib/kernel/doc/src/gen_tcp.xml6
-rw-r--r--lib/public_key/doc/src/public_key.xml4
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl8
-rw-r--r--lib/ssh/src/ssh_dbg.erl73
7 files changed, 94 insertions, 13 deletions
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 591367dc95..a860df3f77 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -287,7 +287,7 @@ typedef struct {
struct {
char* func;
int func_allocated;
- } export;
+ } exprt;
} u;
} erlang_fun;
diff --git a/lib/erl_interface/src/decode/decode_fun.c b/lib/erl_interface/src/decode/decode_fun.c
index 32a950433e..3a7a2b01c1 100644
--- a/lib/erl_interface/src/decode/decode_fun.c
+++ b/lib/erl_interface/src/decode/decode_fun.c
@@ -153,8 +153,8 @@ int ei_decode_fun(const char *buf, int *index, erlang_fun *p)
/* try use module buffer for function name */
used = strlen(p->module) + 1;
p_func = p->module + used;
- p->u.export.func = p_func;
- p->u.export.func_allocated = 0;
+ p->u.exprt.func = p_func;
+ p->u.exprt.func_allocated = 0;
}
else {
used = 0;
@@ -165,8 +165,8 @@ int ei_decode_fun(const char *buf, int *index, erlang_fun *p)
if (!used)
return -1;
p_func = malloc(MAXATOMLEN_UTF8);
- p->u.export.func = p_func;
- p->u.export.func_allocated = 1;
+ p->u.exprt.func = p_func;
+ p->u.exprt.func_allocated = 1;
used = 0;
}
if (ei_decode_long(s, &ix, p_arity) < 0)
@@ -186,8 +186,8 @@ void free_fun(erlang_fun* f)
ei_free(f->u.closure.free_vars);
break;
case EI_FUN_EXPORT:
- if (f->u.export.func_allocated)
- ei_free(f->u.export.func);
+ if (f->u.exprt.func_allocated)
+ ei_free(f->u.exprt.func);
break;
}
}
diff --git a/lib/erl_interface/src/encode/encode_fun.c b/lib/erl_interface/src/encode/encode_fun.c
index 38ba7c5b30..e29424f9f4 100644
--- a/lib/erl_interface/src/encode/encode_fun.c
+++ b/lib/erl_interface/src/encode/encode_fun.c
@@ -87,7 +87,7 @@ int ei_encode_fun(char *buf, int *index, const erlang_fun *p)
ix++;
if (ei_encode_atom_as(buf, &ix, p->module, ERLANG_UTF8, ERLANG_UTF8) < 0)
return -1;
- if (ei_encode_atom_as(buf, &ix, p->u.export.func, ERLANG_UTF8, ERLANG_UTF8) < 0)
+ if (ei_encode_atom_as(buf, &ix, p->u.exprt.func, ERLANG_UTF8, ERLANG_UTF8) < 0)
return -1;
if (ei_encode_long(buf, &ix, p->arity) < 0)
return -1;
diff --git a/lib/kernel/doc/src/gen_tcp.xml b/lib/kernel/doc/src/gen_tcp.xml
index fc16473393..f8b41d24e2 100644
--- a/lib/kernel/doc/src/gen_tcp.xml
+++ b/lib/kernel/doc/src/gen_tcp.xml
@@ -259,6 +259,12 @@ do_recv(Sock, Bs) ->
<p>The optional <c><anno>Timeout</anno></c> parameter specifies a
time-out in milliseconds. Defaults to <c>infinity</c>.</p>
<note>
+ <p>Keep in mind that if the underlying OS <c>connect()</c> call returns
+ a timeout, <c>gen_tcp:connect</c> will also return a timeout
+ (i.e. <c>{error, etimedout}</c>), even if a larger <c>Timeout</c> was
+ specified.</p>
+ </note>
+ <note>
<p>The default values for options specified to <c>connect</c> can
be affected by the Kernel configuration parameter
<c>inet_default_connect_options</c>. For details, see
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 8db5620686..12bb0b21b0 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -286,7 +286,9 @@
entries as ASN.1 DER encoded entities.</fsummary>
<desc>
<p>Decodes PEM binary data and returns entries as ASN.1 DER encoded entities.</p>
- <p>Example <c>{ok, PemBin} = file:read_file("cert.pem").</c></p>
+ <p>Example <c>{ok, PemBin} = file:read_file("cert.pem").
+ PemEntries = public_key:pem_decode(PemBin).
+ </c></p>
</desc>
</func>
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 7c87591cf2..8f32966a12 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -594,7 +594,7 @@ handle_event(_, socket_control, {hello,_}=StateName, D) ->
{stop, {shutdown,{unexpected_getopts_return, Other}}}
end;
-handle_event(_, {info_line,_Line}, {hello,Role}=StateName, D) ->
+handle_event(_, {info_line,Line}, {hello,Role}=StateName, D) ->
case Role of
client ->
%% The server may send info lines to the client before the version_exchange
@@ -605,9 +605,9 @@ handle_event(_, {info_line,_Line}, {hello,Role}=StateName, D) ->
%% But the client may NOT send them to the server. Openssh answers with cleartext,
%% and so do we
send_bytes("Protocol mismatch.", D),
- ?call_disconnectfun_and_log_cond("Protocol mismatch.",
- "Protocol mismatch in version exchange. Client sent info lines.",
- StateName, D),
+ Msg = io_lib:format("Protocol mismatch in version exchange. Client sent info lines.~n~s",
+ [ssh_dbg:hex_dump(Line, 64)]),
+ ?call_disconnectfun_and_log_cond("Protocol mismatch.", Msg, StateName, D),
{stop, {shutdown,"Protocol mismatch in version exchange. Client sent info lines."}}
end;
diff --git a/lib/ssh/src/ssh_dbg.erl b/lib/ssh/src/ssh_dbg.erl
index 4fe15b24d3..43ac4c0ccf 100644
--- a/lib/ssh/src/ssh_dbg.erl
+++ b/lib/ssh/src/ssh_dbg.erl
@@ -60,6 +60,7 @@
cbuf_stop_clear/0,
cbuf_in/1,
cbuf_list/0,
+ hex_dump/1, hex_dump/2,
fmt_cbuf_items/0, fmt_cbuf_item/1
]).
@@ -439,3 +440,75 @@ fmt_value(#circ_buf_entry{module = M,
io_lib:format("~p:~p ~p/~p ~p~n~s",[M,L,F,A,Pid,fmt_value(V)]);
fmt_value(Value) ->
io_lib:format("~p",[Value]).
+
+%%%================================================================
+
+-record(h, {max_bytes = 65536,
+ bytes_per_line = 16,
+ address_len = 4
+ }).
+
+
+hex_dump(Data) -> hex_dump1(Data, hd_opts([])).
+
+hex_dump(X, Max) when is_integer(Max) ->
+ hex_dump(X, [{max_bytes,Max}]);
+hex_dump(X, OptList) when is_list(OptList) ->
+ hex_dump1(X, hd_opts(OptList)).
+
+hex_dump1(B, Opts) when is_binary(B) -> hex_dump1(binary_to_list(B), Opts);
+hex_dump1(L, Opts) when is_list(L), length(L) > Opts#h.max_bytes ->
+ io_lib:format("~s---- skip ~w bytes----~n", [hex_dump1(lists:sublist(L,Opts#h.max_bytes), Opts),
+ length(L) - Opts#h.max_bytes
+ ]);
+hex_dump1(L, Opts0) when is_list(L) ->
+ Opts = Opts0#h{address_len = num_hex_digits(Opts0#h.max_bytes)},
+ Result = hex_dump(L, [{0,[],[]}], Opts),
+ [io_lib:format("~*.s | ~*s | ~s~n"
+ "~*.c-+-~*c-+-~*c~n",
+ [Opts#h.address_len, lists:sublist("Address",Opts#h.address_len),
+ -3*Opts#h.bytes_per_line, lists:sublist("Hexdump",3*Opts#h.bytes_per_line),
+ "ASCII",
+ Opts#h.address_len, $-,
+ 3*Opts#h.bytes_per_line, $-,
+ Opts#h.bytes_per_line, $-
+ ]) |
+ [io_lib:format("~*.16.0b | ~s~*c | ~s~n",[Opts#h.address_len, N*Opts#h.bytes_per_line,
+ lists:reverse(Hexs),
+ 3*(Opts#h.bytes_per_line-length(Hexs)), $ ,
+ lists:reverse(Chars)])
+ || {N,Hexs,Chars} <- lists:reverse(Result)
+ ]
+ ].
+
+
+hd_opts(L) -> lists:foldl(fun hd_opt/2, #h{}, L).
+
+hd_opt({max_bytes,M}, O) -> O#h{max_bytes=M};
+hd_opt({bytes_per_line,M}, O) -> O#h{bytes_per_line=M}.
+
+
+num_hex_digits(N) when N<16 -> 1;
+num_hex_digits(N) -> trunc(math:ceil(math:log2(N)/4)).
+
+
+hex_dump([L|Cs], Result0, Opts) when is_list(L) ->
+ Result = hex_dump(L,Result0, Opts),
+ hex_dump(Cs, Result, Opts);
+
+hex_dump(Cs, [{N0,_,Chars}|_]=Lines, Opts) when length(Chars) == Opts#h.bytes_per_line ->
+ hex_dump(Cs, [{N0+1,[],[]}|Lines], Opts);
+
+hex_dump([C|Cs], [{N,Hexs,Chars}|Lines], Opts) ->
+ Asc = if
+ 16#20 =< C,C =< 16#7E -> C;
+ true -> $.
+ end,
+ Hex = io_lib:format("~2.16.0b ", [C]),
+ hex_dump(Cs, [{N, [Hex|Hexs], [Asc|Chars]} | Lines], Opts);
+
+hex_dump([], Result, _) ->
+ Result.
+
+
+