From 57abd27ee8e189791c4d97ef86de6136c4924b52 Mon Sep 17 00:00:00 2001
From: Micael Karlberg
Date: Thu, 31 Oct 2013 17:03:02 +0100
Subject: [snmp] Improving ATL handling of corrupt logs
When converting an Audit Trail Log to text a corrupt
log entry could cause the entire conversion to fail.
Also, for a log with sequence numbers, failing to
decode a log entry would cause the conversion to fail
(not because of the failed decode, but because of the
failure to write the error message).
OTP-11453
---
lib/snmp/doc/src/notes.xml | 62 ++++++++
lib/snmp/src/app/snmp.appup.src | 40 +++--
lib/snmp/src/misc/snmp_log.erl | 276 ++++++++++++++++++++++++++---------
lib/snmp/src/misc/snmp_verbosity.erl | 14 +-
lib/snmp/vsn.mk | 2 +-
5 files changed, 309 insertions(+), 85 deletions(-)
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 8d280fb3a1..8320b8762e 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,68 @@
+
+ SNMP Development Toolkit 4.22.3
+ Version 4.22.3 supports code replacement in runtime from/to
+ version 4.22.2, 4.22.1, 4.22,
+ 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21.
+
+
+ Improvements and new features
+ -
+
+
+
+
+
+
+ Fixed Bugs and Malfunctions
+
+
+
+ -
+
When converting an Audit Trail Log to text a corrupt
+ log entry could cause the entire conversion to fail.
+ Also, for a log with sequence numbers, failing to
+ decode a log entry would cause the conversion to fail
+ (not because of the failed decode, but because of the
+ failure to write the error message).
+ Own Id: OTP-111453
+ Aux Id: Seq 12459
+
+
+
+
+
+
+
+ Incompatibilities
+ -
+
+
+
+
+
SNMP Development Toolkit 4.22.2
Version 4.22.2 supports code replacement in runtime from/to
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 39e154d463..daf8496670 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,13 +22,24 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.22.2",
+ [
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
+ ]
+ },
{"4.22.1",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22",
[
{load_module, snmpm, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge,
+ [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}
@@ -51,7 +62,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -80,7 +91,7 @@
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
{load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_verbosity, soft_purge, soft_purge, []},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
{update, snmpa_local_db, soft, soft_purge, soft_purge, []},
@@ -105,7 +116,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -137,7 +148,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -173,7 +184,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -209,7 +220,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -247,7 +258,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -286,7 +297,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -316,13 +327,24 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.22.2",
+ [
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
+ ]
+ },
{"4.22.1",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22",
[
{load_module, snmpm, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge,
+ [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, []}
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index a8c5df0b64..a365e8c8ed 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -16,6 +16,7 @@
%%
%% %CopyrightEnd%
%%
+%%
-module(snmp_log).
@@ -397,6 +398,8 @@ log_to_txt(Log, FileName, Dir, Mibs, TextFile, Start, Stop)
[Log, FileName, Dir, Mibs, TextFile, Start, Stop]),
File = filename:join(Dir, FileName),
Converter = fun(L) ->
+ ?vtrace("log_to_txt:fun -> entry with"
+ "~n L: ~p", [L]),
do_log_to_file(L, TextFile, Mibs, Start, Stop)
end,
log_convert(Log, File, Converter).
@@ -422,6 +425,8 @@ log_to_io(Log, FileName, Dir, Mibs, Start, Stop)
[Log, FileName, Dir, Mibs, Start, Stop]),
File = filename:join(Dir, FileName),
Converter = fun(L) ->
+ ?vtrace("log_to_io:fun -> entry with"
+ "~n L: ~p", [L]),
do_log_to_io(L, Mibs, Start, Stop)
end,
log_convert(Log, File, Converter).
@@ -439,22 +444,25 @@ log_convert(Log, File, Converter) ->
do_log_convert(Log, File, Converter).
do_log_convert(Log, File, Converter) ->
- %% ?vtrace("do_log_converter -> entry with"
- %% "~n Log: ~p"
- %% "~n File: ~p"
- %% "~n disk_log:info(Log): ~p", [Log, File, disk_log:info(Log)]),
+ ?vtrace("do_log_converter -> entry with"
+ "~n Log: ~p"
+ "~n File: ~p", [Log, File]),
+ Verbosity = get(verbosity),
{Pid, Ref} =
erlang:spawn_monitor(
fun() ->
+ put(sname, "LOG-CONVERTER"),
+ put(verbosity, Verbosity),
+ erlang:process_flag(trap_exit, true),
+ ?vlog("begin converting", []),
Result = do_log_convert2(Log, File, Converter),
+ ?vlog("convert result: ~p", [Result]),
exit(Result)
end),
receive
{'DOWN', Ref, process, Pid, Result} ->
- %% ?vtrace("do_log_converter -> received result"
- %% "~n Result: ~p"
- %% "~n disk_log:info(Log): ~p",
- %% [Result, disk_log:info(Log)]),
+ ?vtrace("do_log_converter -> received result"
+ "~n Result: ~p", [Result]),
Result
end.
@@ -462,19 +470,31 @@ do_log_convert2(Log, File, Converter) ->
%% First check if the caller process has already opened the
%% log, because if we close an already open log we will cause
%% a runtime error.
+ ?vtrace("do_log_convert2 -> entry - check if owner", []),
case is_owner(Log) of
true ->
+ ?vtrace("do_log_convert2 -> owner - now convert", []),
Converter(Log);
false ->
%% Not yet member of the ruling party, apply for membership...
+ ?vtrace("do_log_convert2 -> not owner - open", []),
case log_open(Log, File) of
{ok, _} ->
+ ?vdebug("do_log_convert2 -> opened - now convert", []),
Res = Converter(Log),
+ ?vtrace("do_log_convert2 -> converted - now close", []),
disk_log:close(Log),
+ ?vtrace("do_log_convert2 -> closed - done", []),
Res;
{error, {name_already_open, _}} ->
- Converter(Log);
+ ?vdebug("do_log_convert2 -> "
+ "already opened - now convert", []),
+ Res = Converter(Log),
+ ?vtrace("do_log_convert2 -> converted - done", []),
+ Res;
{error, Reason} ->
+ ?vinfo("do_log_convert2 -> failed open: "
+ "~n Reason: ~p", [Reason]),
{error, {Log, Reason}}
end
end.
@@ -483,50 +503,93 @@ do_log_convert2(Log, File, Converter) ->
%% -- do_log_to_text ---
do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
+ ?vtrace("do_log_to_txt -> entry with"
+ "~n Log: ~p"
+ "~n TextFile: ~p"
+ "~n Start: ~p"
+ "~n Stop: ~p", [Log, TextFile, Start, Stop]),
case file:open(TextFile, [write]) of
{ok, Fd} ->
+ ?vtrace("do_log_to_txt -> outfile created - create mini MIB", []),
MiniMib = snmp_mini_mib:create(Mibs),
+ ?vtrace("do_log_to_txt -> mini-MIB created - begin conversion", []),
Write = fun(X) ->
+ ?vtrace("do_log_to_txt:fun -> "
+ "entry - try format", []),
case format_msg(X, MiniMib, Start, Stop) of
{ok, S} ->
+ ?vtrace("do_log_to_txt:fun -> "
+ "formated - now write", []),
io:format(Fd, "~s", [S]);
_ ->
+ ?vdebug("do_log_to_txt:fun -> "
+ "format failed", []),
ok
end
end,
Res = (catch loop(disk_log:chunk(Log, start), Log, Write)),
+ ?vtrace("do_log_to_txt -> converted - now delete mini-MIB", []),
snmp_mini_mib:delete(MiniMib),
+ ?vtrace("do_log_to_txt -> "
+ "mini-MIB closed - now close output file", []),
file:close(Fd),
+ ?vtrace("do_log_to_txt -> done", []),
Res;
{error, Reason} ->
+ ?vinfo("failed opening output file: "
+ "~n TestFile: ~p"
+ "~n Reason: ~p", [TextFile, Reason]),
{error, {TextFile, Reason}}
end.
do_log_to_io(Log, Mibs, Start, Stop) ->
+ ?vtrace("do_log_to_io -> entry with"
+ "~n Log: ~p"
+ "~n Mibs: ~p"
+ "~n Start: ~p"
+ "~n Stop: ~p", [Log, Mibs, Start, Stop]),
MiniMib = snmp_mini_mib:create(Mibs),
+ ?vtrace("do_log_to_io -> mini-MIB created - begin conversion", []),
Write = fun(X) ->
+ ?vtrace("do_log_to_io:fun -> entry", []),
case format_msg(X, MiniMib, Start, Stop) of
{ok, S} ->
+ ?vtrace("do_log_to_io:fun -> "
+ "formated - now write", []),
io:format("~s", [S]);
_ ->
+ ?vdebug("do_log_to_io:fun -> "
+ "format failed", []),
ok
end
end,
(catch loop(disk_log:chunk(Log, start), Log, Write)),
+ ?vtrace("do_log_to_io -> converted - now delete mini-MIB", []),
snmp_mini_mib:delete(MiniMib),
+ ?vtrace("do_log_to_io -> done", []),
ok.
loop(eof, _Log, _Write) ->
+ ?vtrace("loop -> entry when eof", []),
ok;
-loop({error, _} = Error, _Log, _Write) ->
+loop({error, _Reason} = Error, _Log, _Write) ->
+ ?vtrace("loop -> entry with error"
+ "~n Reason: ~p", [_Reason]),
Error;
loop({Cont, Terms}, Log, Write) ->
- case (catch lists:foreach(Write, Terms)) of
+ ?vtrace("loop -> entry with terms"
+ "~n Cont: ~p"
+ "~n length(Terms): ~p", [Cont, length(Terms)]),
+ case (catch lists:foreach(Write, Terms)) of
{'EXIT', Reason} ->
+ ?vtrace("loop -> failure while writing terms"
+ "~n Reason: ~p", [Reason]),
{error, Reason};
- _ ->
+ _X ->
+ ?vtrace("loop -> terms written"
+ "~n X: ~p", [_X]),
loop(disk_log:chunk(Log, Cont), Log, Write)
end;
loop({Cont, Terms, BadBytes}, Log, Write) ->
@@ -539,6 +602,8 @@ loop({Cont, Terms, BadBytes}, Log, Write) ->
loop(disk_log:chunk(Log, Cont), Log, Write)
end;
loop(Error, _Log, _Write) ->
+ ?vtrace("loop -> entry with unknown"
+ "~n Error: ~p", [Error]),
Error.
@@ -553,14 +618,17 @@ format_msg(Entry, Mib, Start, Stop) ->
%% This is an old-style entry, that never had the sequence-number
do_format_msg({Timestamp, Packet, {Addr, Port}}, Mib) ->
+ ?vdebug("do_format_msg -> old style log entry", []),
do_format_msg(Timestamp, Packet, Addr, Port, Mib);
%% This is the format without sequence-number
do_format_msg({Timestamp, Packet, Addr, Port}, Mib) ->
+ ?vdebug("do_format_msg -> log entry without seqno", []),
do_format_msg(Timestamp, Packet, Addr, Port, Mib);
%% This is the format with sequence-number
do_format_msg({Timestamp, SeqNo, Packet, Addr, Port}, Mib) ->
+ ?vdebug("do_format_msg -> log entry with seqno", []),
do_format_msg(Timestamp, SeqNo, Packet, Addr, Port, Mib);
%% This is crap...
@@ -568,103 +636,165 @@ do_format_msg(_, _) ->
format_tab("** unknown entry in log file\n\n", []).
do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode scoped pdu",
+ [TimeStamp, Addr, Port]),
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ ?vtrace("do_format_msg -> scoped pdu decoded"
+ "~n ScopedPDU: ~p", [ScopedPDU]),
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding scoped pdu: "
+ "~n V3Hdr: ~w"
+ "~n ScopedPdu: ~w"
+ "~n Reason: ~p", [V3Hdr, ScopedPdu, Reason]),
+ format_tab("** error in log file at ~s from ~s:~w ~p\n\n",
[ts2str(TimeStamp), ip(Addr), Port, Reason])
end;
+
do_format_msg(TimeStamp, Packet, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode packet",
+ [TimeStamp, Addr, Port]),
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
- Msg when is_record(Msg, message) ->
+ #message{data = Data} = Msg when (is_record(Data, scopedPdu) orelse
+ is_record(Data, pdu) orelse
+ is_record(Data, trappdu)) ->
+ ?vtrace("do_format_msg -> packet decoded"
+ "~n Msg: ~p", [Msg]),
f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib);
+
+ #message{version = Vsn,
+ vsn_hdr = VsnHdr} = Msg ->
+ ?vinfo("Message not fully decoded: "
+ "~n Msg: ~p", [Msg]),
+ Reason =
+ lists:flatten(
+ io_lib:format("Message not fully decoded: "
+ "Vsn = ~p, VsnHdr = ~w", [Vsn, VsnHdr])),
+ format_tab("** error in log file ~s from ~s:~w => "
+ "\n ~s\n\n",
+ [ts2str(TimeStamp), ip(Addr), Port, Reason]);
+
{'EXIT', Reason} ->
+ ?vinfo("Failed decoding packet: "
+ "~n Packet: ~w"
+ "~n Reason: ~p", [Packet, Reason]),
format_tab("** error in log file ~p\n\n", [Reason])
end.
do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode scoped pdu",
+ [TimeStamp, SeqNo, Addr, Port]),
case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
ScopedPDU when is_record(ScopedPDU, scopedPdu) ->
+ ?vtrace("do_format_msg -> scoped pdu decoded"
+ "~n ScopedPDU: ~p", [ScopedPDU]),
Msg = #message{version = 'version-3',
vsn_hdr = V3Hdr,
data = ScopedPDU},
f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+
{'EXIT', Reason} ->
- format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding scoped pdu: "
+ "~n V3Hdr: ~w"
+ "~n ScopedPdu: ~w"
+ "~n Reason: ~p", [V3Hdr, ScopedPdu, Reason]),
+ format_tab("** error in log file at ~s~s from ~s:~w ~p\n\n",
[ts2str(TimeStamp), sn2str(SeqNo),
ip(Addr), Port, Reason])
end;
do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) ->
+ ?vtrace("do_format_msg -> entry with"
+ "~n Timestamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n => Try decode message",
+ [TimeStamp, SeqNo, Addr, Port]),
case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
- Msg when is_record(Msg, message) ->
+ #message{data = Data} = Msg when (is_record(Data, scopedPdu) orelse
+ is_record(Data, pdu) orelse
+ is_record(Data, trappdu)) ->
+ ?vtrace("do_format_msg -> message decoded"
+ "~n Msg: ~p", [Msg]),
f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib);
+
+ #message{version = Vsn,
+ vsn_hdr = VsnHdr} = Msg ->
+ ?vinfo("Message not fully decoded: "
+ "~n Msg: ~p", [Msg]),
+ Reason =
+ lists:flatten(
+ io_lib:format("Message not fully decoded: "
+ "Vsn = ~p, VsnHdr = ~w", [Vsn, VsnHdr])),
+ format_tab("** error in log file ~s~s from ~s:~w => "
+ "\n ~s\n\n",
+ [ts2str(TimeStamp), sn2str(SeqNo),
+ ip(Addr), Port, Reason]);
+
{'EXIT', Reason} ->
- format_tab("** error in log file ~s from ~p:~w ~p\n\n",
+ ?vinfo("Failed decoding packet: "
+ "~n Packet: ~w"
+ "~n Reason: ~p", [Packet, Reason]),
+ format_tab("** error in log file ~s (~s) from ~s:~w ~p\n\n",
[ts2str(TimeStamp), sn2str(SeqNo),
ip(Addr), Port, Reason])
end.
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, {Addr, Port}},
-%% Mib, Start, Stop) ->
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
-%% Mib, Start, Stop);
-%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port},
-%% Mib, Start, Stop) ->
-%% case timestamp_filter(TimeStamp, Start, Stop) of
-%% true ->
-%% case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of
-%% ScopedPDU when record(ScopedPDU, scopedPdu) ->
-%% Msg = #message{version = 'version-3',
-%% vsn_hdr = V3Hdr,
-%% data = ScopedPDU},
-%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
-%% {'EXIT', Reason} ->
-%% format_tab("** error in log file at ~s from ~p:~w ~p\n\n",
-%% [ts2str(TimeStamp), ip(Addr), Port, Reason])
-%% end;
-%% false ->
-%% ignore
-%% end;
-%% format_msg({TimeStamp, Packet, {Addr, Port}}, Mib, Start, Stop) ->
-%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop);
-%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop) ->
-%% case timestamp_filter(TimeStamp, Start, Stop) of
-%% true ->
-%% case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of
-%% Msg when record(Msg, message) ->
-%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib);
-%% {'EXIT', Reason} ->
-%% format_tab("** error in log file ~p\n\n", [Reason])
-%% end;
-%% false ->
-%% ignore
-%% end;
-%% format_msg(_, _Mib, _Start, _Stop) ->
-%% format_tab("** unknown entry in log file\n\n", []).
-
f(TimeStamp, SeqNo,
#message{version = Vsn, vsn_hdr = VsnHdr, data = Data},
Addr, Port, Mib) ->
- Str = format_pdu(Data, Mib),
- HdrStr = format_header(Vsn, VsnHdr),
- case get_type(Data) of
- trappdu ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'snmpv2-trap' ->
- f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'inform-request' ->
- f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- 'get-response' ->
- f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- report ->
- f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
- _ ->
- f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
+ try
+ begin
+ Str = format_pdu(Data, Mib),
+ HdrStr = format_header(Vsn, VsnHdr),
+ case get_type(Data) of
+ trappdu ->
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'snmpv2-trap' ->
+ f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'inform-request' ->
+ f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ 'get-response' ->
+ f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ report ->
+ f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port);
+ _ ->
+ f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port)
+ end
+ end
+ catch
+ T:E ->
+ ?vinfo("Failed formating log entry"
+ "~n TimeStamp: ~p"
+ "~n SeqNo: ~p"
+ "~n Data: ~p"
+ "~n Vsn: ~p"
+ "~n VsnHdr: ~p"
+ "~n Addr: ~p"
+ "~n Port: ~p"
+ "~n Error Type: ~w"
+ "~n Error: ~p",
+ [TimeStamp, SeqNo, Data, Vsn, VsnHdr, Addr, Port, T, E]),
+ format_tab("** error while formating log entry ~p\n\n", [{T, E}])
end.
f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
@@ -691,7 +821,7 @@ f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) ->
%% Convert a timestamp 2-tupple to a printable string
%%
ts2str({Local,Universal}) ->
- dat2str(Local) ++ " , " ++ dat2str(Universal);
+ lists:flatten(dat2str(Local) ++ " , " ++ dat2str(Universal));
ts2str(_) ->
"".
@@ -788,7 +918,7 @@ get_type(#pdu{type = Type}) ->
ip({A,B,C,D}) ->
- io_lib:format("~w.~w.~w.~w", [A,B,C,D]).
+ lists:flatten(io_lib:format("~w.~w.~w.~w", [A,B,C,D])).
diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl
index df5986b7bc..8c4fe3fcb0 100644
--- a/lib/snmp/src/misc/snmp_verbosity.erl
+++ b/lib/snmp/src/misc/snmp_verbosity.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -152,7 +152,17 @@ image_of_sname(mgr) -> "MGR";
image_of_sname(mgr_misc) -> "MGR_MISC";
image_of_sname(undefined) -> "";
-image_of_sname(V) -> lists:flatten(io_lib:format("~p",[V])).
+image_of_sname(S) when is_list(S) ->
+ %% The assumption is that its a printable string,
+ %% but just in case it is some other list...
+ try lists:flatten(io_lib:format("~s", [S])) of
+ L ->
+ L
+ catch
+ _:_ ->
+ lists:flatten(io_lib:format("~p", [S]))
+ end;
+image_of_sname(V) -> lists:flatten(io_lib:format("~p", [V])).
validate(info) -> info;
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 5d3c393bcc..8a4d9c14c0 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 4.22.2
+SNMP_VSN = 4.22.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
--
cgit v1.2.3
From bb52546e9a671ed0fd55d2e5274f299a853bed51 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Tue, 5 Nov 2013 15:52:56 +0100
Subject: Implement prim_inet:socknames/1,2 and prim_inet:peernames/1,2
---
erts/configure.in | 2 +-
erts/emulator/beam/io.c | 2 +-
erts/emulator/drivers/common/inet_drv.c | 225 ++++++++++++++++++++++++++++++--
erts/preloaded/ebin/prim_inet.beam | Bin 70856 -> 72632 bytes
erts/preloaded/src/prim_inet.erl | 70 +++++++++-
lib/kernel/src/inet_int.hrl | 2 +
6 files changed, 289 insertions(+), 12 deletions(-)
diff --git a/erts/configure.in b/erts/configure.in
index f17f4cb5c8..4f94f0d156 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1647,7 +1647,7 @@ if test "x$enable_sctp" != "xno" ; then
fi
if test x"$ac_cv_header_netinet_sctp_h" = x"yes"; then
- AC_CHECK_FUNCS([sctp_bindx sctp_peeloff])
+ AC_CHECK_FUNCS([sctp_bindx sctp_peeloff sctp_getladdrs sctp_freeladdrs sctp_getpaddrs sctp_freepaddrs])
AC_CHECK_DECLS([SCTP_UNORDERED, SCTP_ADDR_OVER, SCTP_ABORT,
SCTP_EOF, SCTP_SENDALL, SCTP_ADDR_CONFIRMED,
SCTP_DELAYED_ACK_TIME,
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index c1e66b59af..aeecea1ff5 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -4078,7 +4078,7 @@ erts_port_control(Process* c_p,
copy = 1;
else {
binp = ((ProcBin *) ebinp)->val;
- ASSERT(bufp < bufp + size);
+ ASSERT(bufp <= bufp + size);
ASSERT(binp->orig_bytes <= bufp
&& bufp + size <= binp->orig_bytes + binp->orig_size);
erts_refc_inc(&binp->refc, 1);
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 60db50e80a..8d26adfa63 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -417,13 +417,44 @@ static unsigned long one_value = 1;
# define sctp_adaptation_layer_event sctp_adaption_layer_event
#endif
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(HAVE_SCTP_BINDX)
static typeof(sctp_bindx) *p_sctp_bindx = NULL;
+#else
+static int (*p_sctp_bindx)
+ (int sd, struct sockaddr *addrs, int addrcnt, int flags) = NULL;
+#endif
+
+#if defined(__GNUC__) && defined(HAVE_SCTP_PEELOFF)
static typeof(sctp_peeloff) *p_sctp_peeloff = NULL;
#else
-static int (*p_sctp_bindx)(int sd, struct sockaddr *addrs,
- int addrcnt, int flags) = NULL;
-static int (*p_sctp_peeloff)(int sd, sctp_assoc_t assoc_id) = NULL;
+static int (*p_sctp_peeloff)
+ (int sd, sctp_assoc_t assoc_id) = NULL;
+#endif
+
+#if defined(__GNUC__) && defined(HAVE_SCTP_GETLADDRS)
+static typeof(sctp_getladdrs) *p_sctp_getladdrs = NULL;
+#else
+static int (*p_sctp_getladdrs)
+ (int sd, sctp_assoc_t assoc_id, struct sockaddr **ss) = NULL;
+#endif
+
+#if defined(__GNUC__) && defined(HAVE_SCTP_FREELADDRS)
+static typeof(sctp_freeladdrs) *p_sctp_freeladdrs = NULL;
+#else
+static void (*p_sctp_freeladdrs)(struct sockaddr *addrs) = NULL;
+#endif
+
+#if defined(__GNUC__) && defined(HAVE_SCTP_GETPADDRS)
+static typeof(sctp_getpaddrs) *p_sctp_getpaddrs = NULL;
+#else
+static int (*p_sctp_getpaddrs)
+ (int sd, sctp_assoc_t assoc_id, struct sockaddr **ss) = NULL;
+#endif
+
+#if defined(__GNUC__) && defined(HAVE_SCTP_FREEPADDRS)
+static typeof(sctp_freepaddrs) *p_sctp_freepaddrs = NULL;
+#else
+static void (*p_sctp_freepaddrs)(struct sockaddr *addrs) = NULL;
#endif
#endif /* #if defined(HAVE_SCTP_H) */
@@ -593,7 +624,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INET_F_BUSY 0x0080
#define INET_F_MULTI_CLIENT 0x0100 /* Multiple clients for one descriptor, i.e. multi-accept */
-/* One numberspace for *_REC_* so if an e.g UDP request is issued
+/* One numberspace for *_REQ_* so if an e.g UDP request is issued
** for a TCP socket, the driver can protest.
*/
#define INET_REQ_OPEN 1
@@ -624,6 +655,8 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INET_REQ_ACCEPT 26
#define INET_REQ_LISTEN 27
#define INET_REQ_IGNOREFD 28
+#define INET_REQ_GETLADDRS 29
+#define INET_REQ_GETPADDRS 30
/* TCP requests */
/* #define TCP_REQ_ACCEPT 40 MOVED */
@@ -3658,9 +3691,27 @@ static int inet_init()
/* Check the size of SCTP AssocID -- currently both this driver and the
Erlang part require 32 bit: */
ASSERT(sizeof(sctp_assoc_t)==ASSOC_ID_LEN);
-# if defined(HAVE_SCTP_BINDX) && defined (HAVE_SCTP_PEELOFF)
+# if defined(HAVE_SCTP_BINDX)
p_sctp_bindx = sctp_bindx;
+# if defined(HAVE_SCTP_PEELOFF)
p_sctp_peeloff = sctp_peeloff;
+# else
+ p_sctp_peeloff = NULL;
+# endif
+# if defined(HAVE_SCTP_GETLADDRS) && defined(HAVE_SCTP_FREELADDRS)
+ p_sctp_getladdrs = sctp_getladdrs;
+ p_sctp_freeladdrs = sctp_freeladdrs;
+# else
+ p_sctp_getladdrs = NULL;
+ p_sctp_freeladdrs = NULL;
+# endif
+# if defined(HAVE_SCTP_GETPADDRS) && defined(HAVE_SCTP_FREEPADDRS)
+ p_sctp_getpaddrs = sctp_getpaddrs;
+ p_sctp_freepaddrs = sctp_freepaddrs;
+# else
+ p_sctp_getpaddrs = NULL;
+ p_sctp_freepaddrs = NULL;
+# endif
inet_init_sctp();
add_driver_entry(&sctp_inet_driver_entry);
# else
@@ -3675,12 +3726,36 @@ static int inet_init()
void *ptr;
if (erts_sys_ddll_sym(h_libsctp, "sctp_bindx", &ptr) == 0) {
p_sctp_bindx = ptr;
- inet_init_sctp();
- add_driver_entry(&sctp_inet_driver_entry);
if (erts_sys_ddll_sym(h_libsctp, "sctp_peeloff", &ptr) == 0) {
p_sctp_peeloff = ptr;
}
+ else p_sctp_peeloff = NULL;
+ if (erts_sys_ddll_sym(h_libsctp, "sctp_getladdrs", &ptr) == 0) {
+ p_sctp_getladdrs = ptr;
+ }
+ else p_sctp_getladdrs = NULL;
+ if (erts_sys_ddll_sym(h_libsctp, "sctp_freeladdrs", &ptr) == 0) {
+ p_sctp_freeladdrs = ptr;
+ }
+ else {
+ p_sctp_freeladdrs = NULL;
+ p_sctp_getladdrs = NULL;
+ }
+ if (erts_sys_ddll_sym(h_libsctp, "sctp_getpaddrs", &ptr) == 0) {
+ p_sctp_getpaddrs = ptr;
+ }
+ else p_sctp_getpaddrs = NULL;
+ if (erts_sys_ddll_sym(h_libsctp, "sctp_freepaddrs", &ptr) == 0) {
+ p_sctp_freepaddrs = ptr;
+ }
+ else {
+ p_sctp_freepaddrs = NULL;
+ p_sctp_getpaddrs = NULL;
+ }
+ inet_init_sctp();
+ add_driver_entry(&sctp_inet_driver_entry);
}
+ else p_sctp_bindx = NULL;
}
}
# endif
@@ -3860,6 +3935,74 @@ static int inet_get_address(int family, char* dst, inet_address* src, unsigned i
return -1;
}
+/* Same as the above, but take family from the address structure,
+** and advance the address pointer to the next address
+** according to the size of the current,
+** and return the resulting encoded size
+*/
+static int inet_address_to_erlang(char *dst, inet_address **src) {
+ short port;
+
+ switch ((*src)->sa.sa_family) {
+ case AF_INET:
+ if (dst) {
+ dst[0] = INET_AF_INET;
+ port = sock_ntohs((*src)->sai.sin_port);
+ put_int16(port, dst+1);
+ sys_memcpy(dst+1+2, (char *) &(*src)->sai.sin_addr, 4);
+ }
+ (*src) = (inet_address *) (&(*src)->sai + 1);
+ return 1 + 2 + 4;
+#if defined(HAVE_IN6) && defined(AF_INET6)
+ case AF_INET6:
+ if (dst) {
+ dst[0] = INET_AF_INET6;
+ port = sock_ntohs((*src)->sai6.sin6_port);
+ put_int16(port, dst+1);
+ sys_memcpy(dst+1+2, (char *) &(*src)->sai6.sin6_addr, 16);
+ }
+ (*src) = (inet_address *) (&(*src)->sai6 + 1);
+ return 1 + 2 + 16;
+#endif
+ default:
+ return -1;
+ }
+}
+
+/* Encode n encoded addresses from addrs in the result buffer
+*/
+static ErlDrvSizeT reply_inet_addrs
+(int n, inet_address *addrs, char **rbuf, ErlDrvSizeT rsize) {
+ inet_address *ia;
+ int i, s;
+ ErlDrvSizeT rlen;
+
+ if (IS_SOCKET_ERROR(n)) return ctl_error(sock_errno(), rbuf, rsize);
+ if (n == 0) return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
+
+ /* Calculate result length */
+ rlen = 1;
+ ia = addrs;
+ for (i = 0; i < n; i++) {
+ s = inet_address_to_erlang(NULL, &ia);
+ if (s < 0) break;
+ rlen += s;
+ }
+
+ if (rlen > rsize) (*rbuf) = ALLOC(rlen);
+
+ (*rbuf)[0] = INET_REP_OK;
+ rlen = 1;
+ ia = addrs;
+ for (i = 0; i < n; i++) {
+ s = inet_address_to_erlang((*rbuf)+rlen, &ia);
+ if (s < 0) break;
+ rlen += s;
+ }
+
+ return rlen;
+}
+
static void desc_close(inet_descriptor* desc)
{
if (desc->s != INVALID_SOCKET) {
@@ -7879,6 +8022,39 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
return ctl_reply(INET_REP_OK, tbuf, strlen(tbuf), rbuf, rsize);
}
+ case INET_REQ_GETPADDRS: {
+ DEBUGF(("inet_ctl(%ld): INET_GETPADDRS\r\n", (long)desc->port));
+
+ if (len != 4) return ctl_error(EINVAL, rbuf, rsize);
+
+ if (! IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize);
+ if (! IS_BOUND(desc)) return ctl_xerror(EXBADSEQ, rbuf, rsize);
+
+#ifdef HAVE_SCTP
+ if (IS_SCTP(desc) && p_sctp_getpaddrs) {
+ struct sockaddr *sa;
+ Uint32 assoc_id;
+ int n;
+ ErlDrvSizeT rlen;
+
+ assoc_id = get_int32(buf);
+ n = p_sctp_getpaddrs(desc->s, assoc_id, &sa);
+ rlen = reply_inet_addrs(n, (inet_address *) sa, rbuf, rsize);
+ if (n > 0) p_sctp_freepaddrs(sa);
+ return rlen;
+ }
+#endif
+ { /* Fallback to sock_peer */
+ inet_address addr;
+ unsigned int sz;
+ int i;
+
+ sz = sizeof(addr);
+ i = sock_peer(desc->s, (struct sockaddr *) &addr, &sz);
+ return reply_inet_addrs(i >= 0 ? 1 : i, &addr, rbuf, rsize);
+ }
+ }
+
case INET_REQ_PEER: { /* get peername */
char tbuf[sizeof(inet_address)];
inet_address peer;
@@ -7915,6 +8091,39 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
}
}
+ case INET_REQ_GETLADDRS: {
+ DEBUGF(("inet_ctl(%ld): INET_GETLADDRS\r\n", (long)desc->port));
+
+ if (len != 4) return ctl_error(EINVAL, rbuf, rsize);
+
+ if (! IS_OPEN(desc)) return ctl_xerror(EXBADPORT, rbuf, rsize);
+ if (! IS_BOUND(desc)) return ctl_xerror(EXBADSEQ, rbuf, rsize);
+
+#ifdef HAVE_SCTP
+ if (IS_SCTP(desc) && p_sctp_getladdrs) {
+ struct sockaddr *sa;
+ Uint32 assoc_id;
+ int n;
+ ErlDrvSizeT rlen;
+
+ assoc_id = get_int32(buf);
+ n = p_sctp_getladdrs(desc->s, assoc_id, &sa);
+ rlen = reply_inet_addrs(n, (inet_address *) sa, rbuf, rsize);
+ if (n > 0) p_sctp_freeladdrs(sa);
+ return rlen;
+ }
+#endif
+ { /* Fallback to sock_name */
+ inet_address addr;
+ unsigned int sz;
+ int i;
+
+ sz = sizeof(addr);
+ i = sock_name(desc->s, (struct sockaddr *) &addr, &sz);
+ return reply_inet_addrs(i >= 0 ? 1 : i, &addr, rbuf, rsize);
+ }
+ }
+
case INET_REQ_NAME: { /* get sockname */
char tbuf[sizeof(inet_address)];
inet_address name;
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index b0bef84e68..5d4be0b684 100644
Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ
diff --git a/erts/preloaded/src/prim_inet.erl b/erts/preloaded/src/prim_inet.erl
index fa621681f3..aa700c5194 100644
--- a/erts/preloaded/src/prim_inet.erl
+++ b/erts/preloaded/src/prim_inet.erl
@@ -41,8 +41,8 @@
getifaddrs/1, getiflist/1, ifget/3, ifset/3,
gethostname/1]).
-export([getservbyname/3, getservbyport/3]).
--export([peername/1, setpeername/2]).
--export([sockname/1, setsockname/2]).
+-export([peername/1, setpeername/2, peernames/1, peernames/2]).
+-export([sockname/1, setsockname/2, socknames/1, socknames/2]).
-export([attach/1, detach/1]).
-include("inet_sctp.hrl").
@@ -574,6 +574,36 @@ setpeername(S, undefined) when is_port(S) ->
{error,_}=Error -> Error
end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% PEERNAMES(insock()) -> {ok, [{IP, Port}, ...]} | {error, Reason}
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+peernames(S) when is_port(S) ->
+ peernames(S, undefined).
+
+peernames(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
+ peernames(S, AssocId);
+peernames(S, AssocId)
+ when is_port(S), is_integer(AssocId);
+ is_port(S), AssocId =:= undefined ->
+ Q = get,
+ Type = [[sctp_assoc_id,0]],
+ case type_value(Q, Type, AssocId) of
+ true ->
+ case ctl_cmd
+ (S, ?INET_REQ_GETPADDRS,
+ enc_value(Q, Type, AssocId)) of
+ {ok,Addrs} ->
+ {ok,get_addrs(Addrs)};
+ Error ->
+ Error
+ end;
+ false ->
+ {error,einval}
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% SOCKNAME(insock()) -> {ok, {IP, Port}} | {error, Reason}
@@ -599,6 +629,36 @@ setsockname(S, undefined) when is_port(S) ->
{error,_}=Error -> Error
end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%
+%% SOCKNAMES(insock()) -> {ok, [{IP, Port}, ...]} | {error, Reason}
+%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+socknames(S) when is_port(S) ->
+ socknames(S, undefined).
+
+socknames(S, #sctp_assoc_change{assoc_id=AssocId}) when is_port(S) ->
+ socknames(S, AssocId);
+socknames(S, AssocId)
+ when is_port(S), is_integer(AssocId);
+ is_port(S), AssocId =:= undefined ->
+ Q = get,
+ Type = [[sctp_assoc_id,0]],
+ case type_value(Q, Type, AssocId) of
+ true ->
+ case ctl_cmd
+ (S, ?INET_REQ_GETLADDRS,
+ enc_value(Q, Type, AssocId)) of
+ {ok,Addrs} ->
+ {ok,get_addrs(Addrs)};
+ Error ->
+ Error
+ end;
+ false ->
+ {error,einval}
+ end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% SETOPT(insock(), Opt, Value) -> ok | {error, Reason}
@@ -2213,6 +2273,12 @@ ip6_to_bytes({A,B,C,D,E,F,G,H}) ->
[?int16(A), ?int16(B), ?int16(C), ?int16(D),
?int16(E), ?int16(F), ?int16(G), ?int16(H)].
+get_addrs([]) ->
+ [];
+get_addrs([F,P1,P0|Addr]) ->
+ {IP,Addrs} = get_ip(F, Addr),
+ [{IP,?u16(P1, P0)}|get_addrs(Addrs)].
+
get_ip(?INET_AF_INET, Addr) -> get_ip4(Addr);
get_ip(?INET_AF_INET6, Addr) -> get_ip6(Addr).
diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl
index 18a4a61b2f..641a8dc0ca 100644
--- a/lib/kernel/src/inet_int.hrl
+++ b/lib/kernel/src/inet_int.hrl
@@ -86,6 +86,8 @@
-define(INET_REQ_ACCEPT, 26).
-define(INET_REQ_LISTEN, 27).
-define(INET_REQ_IGNOREFD, 28).
+-define(INET_REQ_GETLADDRS, 29).
+-define(INET_REQ_GETPADDRS, 30).
%% TCP requests
%%-define(TCP_REQ_ACCEPT, 40). MOVED
--
cgit v1.2.3
From 018e60a9131ecc7462b70ce31672e65b3093ed5c Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Wed, 6 Nov 2013 16:24:19 +0100
Subject: Implement inet:socknames/1,2 and inet:peernames/1,2
---
lib/kernel/src/inet.erl | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index 27f085c3aa..99373f3d9d 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -24,6 +24,7 @@
%% socket
-export([peername/1, sockname/1, port/1, send/2,
+ peernames/1, peernames/2, socknames/1, socknames/2,
setopts/2, getopts/2,
getifaddrs/0, getifaddrs/1,
getif/1, getif/0, getiflist/0, getiflist/1,
@@ -146,6 +147,7 @@ close(Socket) ->
ok
end.
+
-spec peername(Socket) -> {ok, {Address, Port}} | {error, posix()} when
Socket :: socket(),
Address :: ip_address(),
@@ -162,6 +164,24 @@ setpeername(Socket, {IP,Port}) ->
setpeername(Socket, undefined) ->
prim_inet:setpeername(Socket, undefined).
+-spec peernames(Socket) -> {ok, [{Address, Port}]} | {error, posix()} when
+ Socket :: socket(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
+
+peernames(Socket) ->
+ prim_inet:peernames(Socket).
+
+-spec peernames(Socket, Assoc) ->
+ {ok, [{Address, Port}]} | {error, posix()} when
+ Socket :: socket(),
+ Assoc :: #sctp_assoc_change{} | gen_sctp:assoc_id(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
+
+peernames(Socket, Assoc) ->
+ prim_inet:peernames(Socket, Assoc).
+
-spec sockname(Socket) -> {ok, {Address, Port}} | {error, posix()} when
Socket :: socket(),
@@ -179,6 +199,25 @@ setsockname(Socket, {IP,Port}) ->
setsockname(Socket, undefined) ->
prim_inet:setsockname(Socket, undefined).
+-spec socknames(Socket) -> {ok, [{Address, Port}]} | {error, posix()} when
+ Socket :: socket(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
+
+socknames(Socket) ->
+ prim_inet:socknames(Socket).
+
+-spec socknames(Socket, Assoc) ->
+ {ok, [{Address, Port}]} | {error, posix()} when
+ Socket :: socket(),
+ Assoc :: #sctp_assoc_change{} | gen_sctp:assoc_id(),
+ Address :: ip_address(),
+ Port :: non_neg_integer().
+
+socknames(Socket, Assoc) ->
+ prim_inet:socknames(Socket, Assoc).
+
+
-spec port(Socket) -> {'ok', Port} | {'error', any()} when
Socket :: socket(),
Port :: port_number().
--
cgit v1.2.3
From 0b6da5e217eca0280a19ce398dcf24cfd7ead53b Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Thu, 7 Nov 2013 14:05:47 +0100
Subject: Write testcases for inet:socknames and inet:peernames
---
lib/kernel/test/gen_sctp_SUITE.erl | 100 ++++++++++++++++++++++++++++++++++---
1 file changed, 93 insertions(+), 7 deletions(-)
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index e89cb44797..f6ce14c7fc 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -36,7 +36,9 @@
open_multihoming_ipv6_socket/1,
open_multihoming_ipv4_and_ipv6_socket/1,
basic_stream/1, xfer_stream_min/1, peeloff_active_once/1,
- peeloff_active_true/1, buffers/1]).
+ peeloff_active_true/1, buffers/1,
+ names_unihoming_ipv4/1, names_unihoming_ipv6/1,
+ names_multihoming_ipv4/1, names_multihoming_ipv6/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -48,7 +50,9 @@ all() ->
open_multihoming_ipv6_socket,
open_multihoming_ipv4_and_ipv6_socket,
basic_stream, xfer_stream_min, peeloff_active_once,
- peeloff_active_true, buffers].
+ peeloff_active_true, buffers,
+ names_unihoming_ipv4, names_unihoming_ipv6,
+ names_multihoming_ipv4, names_multihoming_ipv6].
groups() ->
[].
@@ -1190,6 +1194,81 @@ open_multihoming_ipv4_and_ipv6_socket(Config) when is_list(Config) ->
{skip, Reason}
end.
+names_unihoming_ipv4(doc) ->
+ "Test inet:socknames/peernames on unihoming IPv4 sockets";
+names_unihoming_ipv4(suite) ->
+ [];
+names_unihoming_ipv4(Config) when is_list(Config) ->
+ ?line do_names(Config, inet, 1).
+
+names_unihoming_ipv6(doc) ->
+ "Test inet:socknames/peernames on unihoming IPv6 sockets";
+names_unihoming_ipv6(suite) ->
+ [];
+names_unihoming_ipv6(Config) when is_list(Config) ->
+ ?line do_names(Config, inet6, 1).
+
+names_multihoming_ipv4(doc) ->
+ "Test inet:socknames/peernames on multihoming IPv4 sockets";
+names_multihoming_ipv4(suite) ->
+ [];
+names_multihoming_ipv4(Config) when is_list(Config) ->
+ ?line do_names(Config, inet, 2).
+
+names_multihoming_ipv6(doc) ->
+ "Test inet:socknames/peernames on multihoming IPv6 sockets";
+names_multihoming_ipv6(suite) ->
+ [];
+names_multihoming_ipv6(Config) when is_list(Config) ->
+ ?line do_names(Config, inet6, 2).
+
+
+
+do_names(_, FamilySpec, AddressCount) ->
+ Fun =
+ fun (ServerSocket, _, ServerAssoc, ClientSocket, _, ClientAssoc) ->
+ ?line ServerSocknames =
+ lists:sort(ok(inet:socknames(ServerSocket))),
+ ?line ServerSocknames =
+ lists:sort(ok(inet:socknames(ServerSocket, ServerAssoc))),
+ ?line ?LOGVAR(ServerSocknames),
+ ?line ClientSocknames =
+ lists:sort(ok(inet:socknames(ClientSocket))),
+ ?line ClientSocknames =
+ lists:sort(ok(inet:socknames(ClientSocket, ClientAssoc))),
+ ?line ?LOGVAR(ClientSocknames),
+ ?line {error,einval} = inet:peernames(ServerSocket),
+ ?line ServerPeernames =
+ lists:sort(ok(inet:peernames(ServerSocket, ServerAssoc))),
+ ?line ?LOGVAR(ServerPeernames),
+ ?line {error,einval} = inet:peernames(ClientSocket),
+ ?line ClientPeernames =
+ lists:sort(ok(inet:peernames(ClientSocket, ClientAssoc))),
+ ?line ?LOGVAR(ClientPeernames),
+ ?line ServerSocknames = ClientPeernames,
+ ?line ClientSocknames = ServerPeernames,
+ ?line {ok,Socket} = gen_sctp:peeloff(ServerSocket, ServerAssoc),
+ ?line Socknames =
+ lists:sort(ok(inet:socknames(Socket))),
+ ?line Socknames =
+ lists:sort(ok(inet:socknames(Socket, ServerAssoc))),
+ ?line ?LOGVAR(Socknames),
+ ?line Peernames =
+ lists:sort(ok(inet:peernames(Socket, ServerAssoc))),
+ ?line ?LOGVAR(Peernames),
+ ?line ok = gen_sctp:close(Socket),
+ ?line Socknames = ClientPeernames,
+ ?line ClientSocknames = Peernames,
+ ok
+ end,
+ ?line case get_addrs_by_family(FamilySpec, AddressCount) of
+ {ok, Addresses} when length(Addresses) =:= AddressCount ->
+ ?line do_open_and_connect(Addresses, hd(Addresses), Fun);
+ {error, Reason} ->
+ {skip, Reason}
+ end.
+
+
get_addrs_by_family(Family, NumAddrs) ->
case os:type() of
@@ -1274,6 +1353,10 @@ f(F, A) ->
lists:flatten(io_lib:format(F, A)).
do_open_and_connect(ServerAddresses, AddressToConnectTo) ->
+ ?line Fun = fun (_, _, _, _, _, _) -> ok end,
+ ?line do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun).
+%%
+do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
?line ServerFamily = get_family_by_addrs(ServerAddresses),
?line io:format("Serving ~p addresses: ~p~n",
[ServerFamily, ServerAddresses]),
@@ -1286,12 +1369,14 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo) ->
[ClientFamily, AddressToConnectTo]),
?line S2 = ok(gen_sctp:open(0, [ClientFamily])),
%% Verify client can connect
- ?line #sctp_assoc_change{state=comm_up} =
+ ?line #sctp_assoc_change{state=comm_up} = S2Assoc =
ok(gen_sctp:connect(S2, AddressToConnectTo, P1, [])),
%% verify server side also receives comm_up from client
- ?line recv_comm_up_eventually(S1),
+ ?line S1Assoc = recv_comm_up_eventually(S1),
+ ?line Result = Fun(S1, ServerFamily, S1Assoc, S2, ClientFamily, S2Assoc),
?line ok = gen_sctp:close(S2),
- ?line ok = gen_sctp:close(S1).
+ ?line ok = gen_sctp:close(S1),
+ Result.
%% If at least one of the addresses is an ipv6 address, return inet6, else inet.
get_family_by_addrs(Addresses) ->
@@ -1306,8 +1391,9 @@ get_family_by_addr(Addr) when tuple_size(Addr) =:= 8 -> inet6.
recv_comm_up_eventually(S) ->
?line case ok(gen_sctp:recv(S)) of
- {_Addr, _Port, _Info, #sctp_assoc_change{state=comm_up}} ->
- ok;
+ {_Addr, _Port, _Info,
+ #sctp_assoc_change{state=comm_up} = Assoc} ->
+ Assoc;
{_Addr, _Port, _Info, _OtherSctpMsg} ->
?line recv_comm_up_eventually(S)
end.
--
cgit v1.2.3
From 9177d60b79cc6ec58025de70cef628822da5d178 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Mon, 11 Nov 2013 09:47:58 +0100
Subject: Fix testcases for FreeBSD 9.1
---
lib/kernel/test/gen_sctp_SUITE.erl | 142 +++++++++++++++++++++++++------------
1 file changed, 95 insertions(+), 47 deletions(-)
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index f6ce14c7fc..243abcdff9 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1,4 +1,4 @@
-%%
+%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2007-2013. All Rights Reserved.
@@ -152,17 +152,20 @@ xfer_min(Config) when is_list(Config) ->
assoc_id=SbAssocId}],
Data} -> ok;
Event1 ->
- {Loopback,Pa,
- #sctp_paddr_change{addr = {Loopback,_},
- state = addr_available,
- error = 0,
- assoc_id = SbAssocId}} =
- recv_event(Event1),
- {ok,{Loopback,
- Pa,
- [#sctp_sndrcvinfo{stream=Stream,
- assoc_id=SbAssocId}],
- Data}} = gen_sctp:recv(Sb, infinity)
+ case recv_event(Event1) of
+ {Loopback,Pa,
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = State,
+ error = 0,
+ assoc_id = SbAssocId}}
+ when State =:= addr_available;
+ State =:= addr_confirmed ->
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} = log_ok(gen_sctp:recv(Sb, infinity))
+ end
end,
?line ok = gen_sctp:send(Sb, SbAssocId, 0, Data),
?line case log_ok(gen_sctp:recv(Sa, infinity)) of
@@ -459,18 +462,22 @@ def_sndrcvinfo(Config) when is_list(Config) ->
stream=1, ppid=0, context=0, assoc_id=S1AssocId}],
<<"3: ",Data/binary>>} -> ok;
Event2 ->
- {Loopback,P2,
- #sctp_paddr_change{
- addr={Loopback,_}, state=addr_available,
- error=0, assoc_id=S1AssocId}} =
- recv_event(Event2),
- ?line case log_ok(gen_sctp:recv(S1)) of
- {Loopback,P2,
- [#sctp_sndrcvinfo{
- stream=1, ppid=0, context=0,
- assoc_id=S1AssocId}],
- <<"3: ",Data/binary>>} -> ok
- end
+ case recv_event(Event2) of
+ {Loopback,P2,
+ #sctp_paddr_change{
+ addr={Loopback,_},
+ state=State,
+ error=0, assoc_id=S1AssocId}}
+ when State =:= addr_available;
+ State =:= addr_confirmed ->
+ ?line case log_ok(gen_sctp:recv(S1)) of
+ {Loopback,P2,
+ [#sctp_sndrcvinfo{
+ stream=1, ppid=0, context=0,
+ assoc_id=S1AssocId}],
+ <<"3: ",Data/binary>>} -> ok
+ end
+ end
end,
?line ok =
do_from_other_process(
@@ -513,6 +520,13 @@ log_ok(X) -> log(ok(X)).
ok({ok,X}) -> X.
+err([], Result) ->
+ erlang:error(Result);
+err([Reason|_], {error,Reason}) ->
+ ok;
+err([_|Reasons], Result) ->
+ err(Reasons, Result).
+
log(X) ->
io:format("LOG[~w]: ~p~n", [self(),X]),
X.
@@ -844,23 +858,36 @@ xfer_stream_min(Config) when is_list(Config) ->
?line SbOutboundStreams = SaInboundStreams,
?line ?LOGVAR(SbOutboundStreams),
?line ok = gen_sctp:send(Sa, SaAssocId, 0, Data),
- ?line case gen_sctp:recv(Sb, infinity) of
- {ok,{Loopback,
+ ?line case log_ok(gen_sctp:recv(Sb, infinity)) of
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} -> ok;
+ {Loopback,
+ Pa,[],
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = addr_available,
+ error = 0,
+ assoc_id = SbAssocId}} ->
+ {Loopback,
Pa,
[#sctp_sndrcvinfo{stream=Stream,
assoc_id=SbAssocId}],
- Data}} -> ok;
- {ok,{Loopback,
- Pa,[],
- #sctp_paddr_change{addr = {Loopback,_},
- state = addr_available,
- error = 0,
- assoc_id = SbAssocId}}} ->
- {ok,{Loopback,
- Pa,
- [#sctp_sndrcvinfo{stream=Stream,
- assoc_id=SbAssocId}],
- Data}} = gen_sctp:recv(Sb, infinity)
+ Data} = log_ok(gen_sctp:recv(Sb, infinity));
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ #sctp_paddr_change{addr = {Loopback,_},
+ state = addr_confirmed,
+ error = 0,
+ assoc_id = SbAssocId}} ->
+ {Loopback,
+ Pa,
+ [#sctp_sndrcvinfo{stream=Stream,
+ assoc_id=SbAssocId}],
+ Data} = log_ok(gen_sctp:recv(Sb, infinity))
end,
?line ok =
do_from_other_process(
@@ -1227,27 +1254,36 @@ names_multihoming_ipv6(Config) when is_list(Config) ->
do_names(_, FamilySpec, AddressCount) ->
Fun =
fun (ServerSocket, _, ServerAssoc, ClientSocket, _, ClientAssoc) ->
- ?line ServerSocknames =
+ ?line ServerSocknamesNoassoc =
lists:sort(ok(inet:socknames(ServerSocket))),
+ ?line ?LOGVAR(ServerSocknamesNoassoc),
?line ServerSocknames =
lists:sort(ok(inet:socknames(ServerSocket, ServerAssoc))),
?line ?LOGVAR(ServerSocknames),
- ?line ClientSocknames =
+ ?line [_|_] =
+ ordsets:intersection
+ (ServerSocknamesNoassoc, ServerSocknames),
+ ?line ClientSocknamesNoassoc =
lists:sort(ok(inet:socknames(ClientSocket))),
+ ?line ?LOGVAR(ClientSocknamesNoassoc),
?line ClientSocknames =
lists:sort(ok(inet:socknames(ClientSocket, ClientAssoc))),
?line ?LOGVAR(ClientSocknames),
- ?line {error,einval} = inet:peernames(ServerSocket),
+ ?line [_|_] =
+ ordsets:intersection
+ (ClientSocknamesNoassoc, ClientSocknames),
+ ?line err([einval,enotconn], inet:peernames(ServerSocket)),
?line ServerPeernames =
lists:sort(ok(inet:peernames(ServerSocket, ServerAssoc))),
?line ?LOGVAR(ServerPeernames),
- ?line {error,einval} = inet:peernames(ClientSocket),
+ ?line err([einval,enotconn], inet:peernames(ClientSocket)),
?line ClientPeernames =
lists:sort(ok(inet:peernames(ClientSocket, ClientAssoc))),
?line ?LOGVAR(ClientPeernames),
?line ServerSocknames = ClientPeernames,
?line ClientSocknames = ServerPeernames,
- ?line {ok,Socket} = gen_sctp:peeloff(ServerSocket, ServerAssoc),
+ ?line {ok,Socket} =
+ gen_sctp:peeloff(ServerSocket, ServerAssoc),
?line Socknames =
lists:sort(ok(inet:socknames(Socket))),
?line Socknames =
@@ -1367,10 +1403,20 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
?line ClientFamily = get_family_by_addr(AddressToConnectTo),
?line io:format("Connecting to ~p ~p~n",
[ClientFamily, AddressToConnectTo]),
- ?line S2 = ok(gen_sctp:open(0, [ClientFamily])),
+ ?line ClientOpts =
+ [ClientFamily |
+ case ClientFamily of
+ inet6 ->
+ [{ipv6_v6only,true}];
+ _ ->
+ []
+ end],
+ ?line S2 = ok(gen_sctp:open(0, ClientOpts)),
+ log(open),
%% Verify client can connect
?line #sctp_assoc_change{state=comm_up} = S2Assoc =
ok(gen_sctp:connect(S2, AddressToConnectTo, P1, [])),
+ log(comm_up),
%% verify server side also receives comm_up from client
?line S1Assoc = recv_comm_up_eventually(S1),
?line Result = Fun(S1, ServerFamily, S1Assoc, S2, ClientFamily, S2Assoc),
@@ -1394,7 +1440,8 @@ recv_comm_up_eventually(S) ->
{_Addr, _Port, _Info,
#sctp_assoc_change{state=comm_up} = Assoc} ->
Assoc;
- {_Addr, _Port, _Info, _OtherSctpMsg} ->
+ {_Addr, _Port, _Info, _OtherSctpMsg} = Msg ->
+ ?line log({unexpected,Msg}),
?line recv_comm_up_eventually(S)
end.
@@ -1575,8 +1622,9 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
[] -> ok
end,
case {gb_get({assoc_change,AssocId}, State),St} of
- {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],
- addr_available} -> ok;
+ {[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
+ when St =:= addr_available;
+ St =:= addr_confirmed -> ok;
{[],addr_confirmed} -> ok
end,
Key = {paddr_change,AssocId},
--
cgit v1.2.3
From fed6d0eb871f9f9a103ddb0d87ebf23f824f5301 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Mon, 11 Nov 2013 11:16:48 +0100
Subject: Fix testcase indentation
---
lib/kernel/test/gen_sctp_SUITE.erl | 110 ++++++++++++++++++-------------------
1 file changed, 55 insertions(+), 55 deletions(-)
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index 243abcdff9..8bd1633ef1 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -111,7 +111,7 @@ xfer_min(Config) when is_list(Config) ->
?line {ok,Sb} = gen_sctp:open([{type,seqpacket}]),
?line {ok,Pb} = inet:port(Sb),
?line ok = gen_sctp:listen(Sb, true),
-
+
?line {ok,Sa} = gen_sctp:open(),
?line {ok,Pa} = inet:port(Sa),
?line {ok,#sctp_assoc_change{state=comm_up,
@@ -122,18 +122,18 @@ xfer_min(Config) when is_list(Config) ->
gen_sctp:connect(Sa, Loopback, Pb, []),
?line {SbAssocId,SaOutboundStreams,SaInboundStreams} =
case recv_event(log_ok(gen_sctp:recv(Sb, infinity))) of
- {Loopback,Pa,
- #sctp_assoc_change{state=comm_up,
- error=0,
- outbound_streams=SbOutboundStreams,
- inbound_streams=SbInboundStreams,
- assoc_id=AssocId}} ->
- {AssocId,SbInboundStreams,SbOutboundStreams};
- {Loopback,Pa,
- #sctp_paddr_change{state=addr_confirmed,
- addr={Loopback,Pa},
- error=0,
- assoc_id=AssocId}} ->
+ {Loopback,Pa,
+ #sctp_assoc_change{state=comm_up,
+ error=0,
+ outbound_streams=SbOutboundStreams,
+ inbound_streams=SbInboundStreams,
+ assoc_id=AssocId}} ->
+ {AssocId,SbInboundStreams,SbOutboundStreams};
+ {Loopback,Pa,
+ #sctp_paddr_change{state=addr_confirmed,
+ addr={Loopback,Pa},
+ error=0,
+ assoc_id=AssocId}} ->
{Loopback,Pa,
#sctp_assoc_change{state=comm_up,
error=0,
@@ -204,7 +204,7 @@ xfer_min(Config) when is_list(Config) ->
recv_event(log_ok(gen_sctp:recv(Sb, infinity))),
?line ok = gen_sctp:close(Sa),
?line ok = gen_sctp:close(Sb),
-
+
?line receive
Msg -> test_server:fail({received,Msg})
after 17 -> ok
@@ -223,7 +223,7 @@ xfer_active(Config) when is_list(Config) ->
?line {ok,Sb} = gen_sctp:open([{active,true}]),
?line {ok,Pb} = inet:port(Sb),
?line ok = gen_sctp:listen(Sb, true),
-
+
?line {ok,Sa} = gen_sctp:open([{active,true}]),
?line {ok,Pa} = inet:port(Sa),
?line ok = gen_sctp:connect_init(Sa, Loopback, Pb, []),
@@ -355,7 +355,7 @@ def_sndrcvinfo(Config) when is_list(Config) ->
%%
?line S1 =
log_ok(gen_sctp:open(
- 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])),
+ 0, [{sctp_default_send_param,#sctp_sndrcvinfo{ppid=17}}])),
?LOGVAR(S1),
?line P1 =
log_ok(inet:port(S1)),
@@ -547,57 +547,57 @@ api_open_close(Config) when is_list(Config) ->
?line {ok,S1} = gen_sctp:open(0),
?line {ok,P} = inet:port(S1),
?line ok = gen_sctp:close(S1),
-
+
?line {ok,S2} = gen_sctp:open(P),
?line {ok,P} = inet:port(S2),
?line ok = gen_sctp:close(S2),
-
+
?line {ok,S3} = gen_sctp:open([{port,P}]),
?line {ok,P} = inet:port(S3),
?line ok = gen_sctp:close(S3),
-
+
?line {ok,S4} = gen_sctp:open(P, []),
?line {ok,P} = inet:port(S4),
?line ok = gen_sctp:close(S4),
-
+
?line {ok,S5} = gen_sctp:open(P, [{ifaddr,any}]),
?line {ok,P} = inet:port(S5),
?line ok = gen_sctp:close(S5),
?line ok = gen_sctp:close(S5),
-
+
?line try gen_sctp:close(0)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open({})
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(-1)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(65536)
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(make_ref(), [])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, {})
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, [make_ref()])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open([{invalid_option,0}])
catch error:badarg -> ok
end,
-
+
?line try gen_sctp:open(0, [{mode,invalid_mode}])
catch error:badarg -> ok
end,
@@ -609,11 +609,11 @@ api_listen(suite) ->
[];
api_listen(Config) when is_list(Config) ->
?line Localhost = {127,0,0,1},
-
+
?line try gen_sctp:listen(0, true)
catch error:badarg -> ok
end,
-
+
?line {ok,S} = gen_sctp:open(),
?line {ok,Pb} = inet:port(S),
?line try gen_sctp:listen(S, not_allowed_for_listen)
@@ -621,7 +621,7 @@ api_listen(Config) when is_list(Config) ->
end,
?line ok = gen_sctp:close(S),
?line {error,closed} = gen_sctp:listen(S, true),
-
+
?line {ok,Sb} = gen_sctp:open(Pb),
?line {ok,Sa} = gen_sctp:open(),
?line case gen_sctp:connect(Sa, localhost, Pb, []) of
@@ -633,8 +633,8 @@ api_listen(Config) when is_list(Config) ->
gen_sctp:recv(Sa, infinity);
{error,#sctp_assoc_change{state=cant_assoc}} ->
ok%;
- %% {error,{Localhost,Pb,_,#sctp_assoc_change{state=cant_assoc}}} ->
- %% ok
+ %% {error,{Localhost,Pb,_,#sctp_assoc_change{state=cant_assoc}}} ->
+ %% ok
end,
?line ok = gen_sctp:listen(Sb, true),
?line {ok,#sctp_assoc_change{state=comm_up,
@@ -1003,10 +1003,10 @@ peeloff(Config, SockOpts) when is_list(Config) ->
?line ?LOGVAR(S2Ai),
?line S1Ai =
receive
- {S1,{Addr,P2,
- #sctp_assoc_change{
- state=comm_up,
- assoc_id=AssocId1}}} -> AssocId1
+ {S1,{Addr,P2,
+ #sctp_assoc_change{
+ state=comm_up,
+ assoc_id=AssocId1}}} -> AssocId1
after Timeout ->
socket_bailout([S1,S2])
end,
@@ -1034,8 +1034,8 @@ peeloff(Config, SockOpts) when is_list(Config) ->
?line P3 = case P3_X of 0 -> P1; _ -> P3_X end,
?line [{_,#sctp_paddrinfo{assoc_id=S3Ai,state=active}}] =
socket_call(S3,
- {getopts,[{sctp_get_peer_addr_info,
- #sctp_paddrinfo{address={Addr,P2}}}]}),
+ {getopts,[{sctp_get_peer_addr_info,
+ #sctp_paddrinfo{address={Addr,P2}}}]}),
%%?line S3Ai = S1Ai,
?line ?LOGVAR(S3Ai),
%%
@@ -1118,9 +1118,9 @@ buffers(Config) when is_list(Config) ->
%%
?line socket_call(S1, {setopts,[{recbuf,Limit}]}),
?line Recbuf =
- case socket_call(S1, {getopts,[recbuf]}) of
- [{recbuf,RB1}] when RB1 >= Limit -> RB1
- end,
+ case socket_call(S1, {getopts,[recbuf]}) of
+ [{recbuf,RB1}] when RB1 >= Limit -> RB1
+ end,
?line Data = mk_data(Recbuf+Limit),
?line socket_call(S2, {setopts,[{sndbuf,Recbuf+Limit}]}),
?line socket_call(S2, {send,S2Ai,Stream,Data}),
@@ -1406,10 +1406,10 @@ do_open_and_connect(ServerAddresses, AddressToConnectTo, Fun) ->
?line ClientOpts =
[ClientFamily |
case ClientFamily of
- inet6 ->
- [{ipv6_v6only,true}];
- _ ->
- []
+ inet6 ->
+ [{ipv6_v6only,true}];
+ _ ->
+ []
end],
?line S2 = ok(gen_sctp:open(0, ClientOpts)),
log(open),
@@ -1500,10 +1500,10 @@ socket_bailout([]) ->
socket_history({State,Flush}) ->
{lists:keysort(
- 2,
- lists:flatten(
- [[{Key,Val} || Val <- Vals]
- || {Key,Vals} <- gb_trees:to_list(State)])),
+ 2,
+ lists:flatten(
+ [[{Key,Val} || Val <- Vals]
+ || {Key,Vals} <- gb_trees:to_list(State)])),
Flush}.
s_handler(Socket) ->
@@ -1586,7 +1586,7 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
#sctp_assoc_change{
state=comm_up,
inbound_streams=Is}}}|_]
- when 0 =< Stream, Stream < Is-> ok;
+ when 0 =< Stream, Stream < Is-> ok;
[] -> ok
end,
Key = {msg,AssocId,Stream},
@@ -1606,7 +1606,7 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
case {gb_get(Key, State),St} of
{[],_} -> ok;
{[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
- when St =:= comm_lost; St =:= shutdown_comp -> ok
+ when St =:= comm_lost; St =:= shutdown_comp -> ok
end,
NewState = gb_push(Key, Val, State),
Parent ! {self(),{Addr,Port,SAC}},
@@ -1623,8 +1623,8 @@ s_loop(Socket, Timeout, Parent, Handler, State) ->
end,
case {gb_get({assoc_change,AssocId}, State),St} of
{[{_,{Addr,Port,#sctp_assoc_change{state=comm_up}}}|_],_}
- when St =:= addr_available;
- St =:= addr_confirmed -> ok;
+ when St =:= addr_available;
+ St =:= addr_confirmed -> ok;
{[],addr_confirmed} -> ok
end,
Key = {paddr_change,AssocId},
--
cgit v1.2.3
From 2e96b554bd0374224aed1c28e48d139fad42c38e Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Mon, 11 Nov 2013 15:07:14 +0100
Subject: Clean up address family handling towards Erlang
---
erts/emulator/drivers/common/inet_drv.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 8d26adfa63..de18656273 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1450,8 +1450,7 @@ static int load_ip_address(ErlDrvTermData* spec, int i, int family, char* buf)
#ifdef HAVE_SCTP
/* For SCTP, we often need to return {IP, Port} tuples: */
-static int inet_get_address
- (int family, char* dst, inet_address* src, unsigned int* len);
+static int inet_get_address(char* dst, inet_address* src, unsigned int* len);
#define LOAD_IP_AND_PORT_CNT \
(8*LOAD_INT_CNT + LOAD_TUPLE_CNT + LOAD_INT_CNT + LOAD_TUPLE_CNT)
@@ -1466,8 +1465,7 @@ static int load_ip_and_port
unsigned int len = sizeof(struct sockaddr_storage);
unsigned int alen = len;
char abuf [len];
- int res =
- inet_get_address(desc->sfamily, abuf, (inet_address*) addr, &alen);
+ int res = inet_get_address(abuf, (inet_address*) addr, &alen);
ASSERT(res==0);
res = 0;
/* Now "abuf" contains: Family(1b), Port(2b), IP(4|16b) */
@@ -3910,10 +3908,12 @@ static char *inet_set_faddress(int family, inet_address* dst,
** and *len is the length of dst on return
** (suitable to deliver to erlang)
*/
-static int inet_get_address(int family, char* dst, inet_address* src, unsigned int* len)
+static int inet_get_address(char* dst, inet_address* src, unsigned int* len)
{
+ int family;
short port;
+ family = src->sa.sa_family;
if ((family == AF_INET) && (*len >= sizeof(struct sockaddr_in))) {
dst[0] = INET_AF_INET;
port = sock_ntohs(src->sai.sin_port);
@@ -8070,7 +8070,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
if (IS_SOCKET_ERROR(sock_peer(desc->s, (struct sockaddr*)ptr,&sz)))
return ctl_error(sock_errno(), rbuf, rsize);
}
- if (inet_get_address(desc->sfamily, tbuf, ptr, &sz) < 0)
+ if (inet_get_address(tbuf, ptr, &sz) < 0)
return ctl_error(EINVAL, rbuf, rsize);
return ctl_reply(INET_REP_OK, tbuf, sz, rbuf, rsize);
}
@@ -8140,7 +8140,7 @@ static ErlDrvSSizeT inet_ctl(inet_descriptor* desc, int cmd, char* buf,
if (IS_SOCKET_ERROR(sock_name(desc->s, (struct sockaddr*)ptr, &sz)))
return ctl_error(sock_errno(), rbuf, rsize);
}
- if (inet_get_address(desc->sfamily, tbuf, ptr, &sz) < 0)
+ if (inet_get_address(tbuf, ptr, &sz) < 0)
return ctl_error(EINVAL, rbuf, rsize);
return ctl_reply(INET_REP_OK, tbuf, sz, rbuf, rsize);
}
@@ -10979,7 +10979,7 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event)
inet_input_count(desc, n);
udesc->i_ptr += n;
- inet_get_address(desc->sfamily, abuf, &other, &len);
+ inet_get_address(abuf, &other, &len);
/* Copy formatted address to the buffer allocated; "len" is the
actual length which must be <= than the original reserved.
This means that the addr + data in the buffer are contiguous,
--
cgit v1.2.3
From 4b89567941ac6c00a994bde917e2d0d450dce91f Mon Sep 17 00:00:00 2001
From: Micael Karlberg
Date: Thu, 14 Nov 2013 17:53:11 +0100
Subject: [snmp] Loosing log entries when converting a large Audit Trail Log
When converting an entire Audit Trail Log in a running
system its possble to have log wraps and thereby loosing
log entries.
In order to prevent this the log is now blocked during
conversion (log_to_txt or log_to_io).
---
lib/snmp/doc/src/notes.xml | 61 ++++++++++++++++++++++++++++++++++++
lib/snmp/src/app/snmp.appup.src | 54 +++++++++++++++++++++----------
lib/snmp/src/misc/snmp_log.erl | 32 +++++++++++++++++--
lib/snmp/src/misc/snmp_verbosity.erl | 4 ++-
lib/snmp/vsn.mk | 2 +-
5 files changed, 131 insertions(+), 22 deletions(-)
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 8d280fb3a1..668e986486 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,67 @@
+
+ SNMP Development Toolkit 4.22.3
+ Version 4.22.3 supports code replacement in runtime from/to
+ version 4.22.2, 4.22.1, 4.22,
+ 4.21.7 4.21.6 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1 and 4.21.
+
+
+ Improvements and new features
+ -
+
+
+
+
+
+
+ Fixed Bugs and Malfunctions
+
+
+
+ -
+
Loosing log entries when converting a large Audit Trail Log.
+ When converting an entire Audit Trail Log in a running
+ system its possble to have log wraps and thereby loosing log
+ entries.
+ In order to prevent this the log is now blocked
+ during conversion (log_to_txt or log_to_io).
+ Own Id: OTP-11396
+ Own Id: seq12433
+
+
+
+
+
+
+ Incompatibilities
+ -
+
+
+
+
+
SNMP Development Toolkit 4.22.2
Version 4.22.2 supports code replacement in runtime from/to
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 39e154d463..69237838ab 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -22,12 +22,22 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.22.2",
+ [
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
+ ]
+ },
{"4.22.1",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
@@ -51,7 +61,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -79,7 +89,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -105,7 +115,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -137,7 +147,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -173,7 +183,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -209,7 +219,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -247,7 +257,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -286,7 +296,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -316,12 +326,22 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.22.2",
+ [
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
+ ]
+ },
{"4.22.1",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []}
]
},
{"4.22",
[
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
+ {load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
@@ -346,7 +366,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -374,7 +394,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpa, soft_purge, soft_purge, [snmp]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -400,7 +420,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -432,7 +452,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -468,7 +488,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -504,7 +524,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -542,7 +562,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
@@ -581,7 +601,7 @@
{load_module, snmp, soft_purge, soft_purge, [snmp_log]},
{load_module, snmpm, soft_purge, soft_purge, [snmp]},
- {load_module, snmp_log, soft_purge, soft_purge, []},
+ {load_module, snmp_log, soft_purge, soft_purge, [snmp_verbosity]},
{load_module, snmp_verbosity, soft_purge, soft_purge, []},
{load_module, snmpm_mpd, soft_purge, soft_purge, []},
diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl
index a8c5df0b64..9c6cb1e077 100644
--- a/lib/snmp/src/misc/snmp_log.erl
+++ b/lib/snmp/src/misc/snmp_log.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -443,9 +443,12 @@ do_log_convert(Log, File, Converter) ->
%% "~n Log: ~p"
%% "~n File: ~p"
%% "~n disk_log:info(Log): ~p", [Log, File, disk_log:info(Log)]),
+ Verbosity = get(verbosity),
{Pid, Ref} =
erlang:spawn_monitor(
fun() ->
+ put(sname, lc),
+ put(verbosity, Verbosity),
Result = do_log_convert2(Log, File, Converter),
exit(Result)
end),
@@ -462,19 +465,35 @@ do_log_convert2(Log, File, Converter) ->
%% First check if the caller process has already opened the
%% log, because if we close an already open log we will cause
%% a runtime error.
+ ?vtrace("do_log_convert2 -> entry - check if owner", []),
case is_owner(Log) of
true ->
- Converter(Log);
+ ?vdebug("do_log_converter2 -> owner - now convert log", []),
+ disk_log:block(Log, true),
+ Res = Converter(Log),
+ disk_log:unblock(Log),
+ Res;
false ->
%% Not yet member of the ruling party, apply for membership...
+ ?vtrace("do_log_converter2 -> not owner - open log", []),
case log_open(Log, File) of
{ok, _} ->
+ ?vdebug("do_log_convert2 -> opened - now convert log", []),
+ disk_log:block(Log, true),
Res = Converter(Log),
+ disk_log:unblock(Log),
disk_log:close(Log),
Res;
{error, {name_already_open, _}} ->
- Converter(Log);
+ ?vdebug("do_log_convert2 -> "
+ "already opened - now convert log", []),
+ disk_log:block(Log, true),
+ Res = Converter(Log),
+ disk_log:unblock(Log),
+ Res;
{error, Reason} ->
+ ?vinfo("Failed converting log - open failed: "
+ "~n Reason: ~p", [Reason]),
{error, {Log, Reason}}
end
end.
@@ -491,6 +510,8 @@ do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
{ok, S} ->
io:format(Fd, "~s", [S]);
_ ->
+ ?vdebug("do_log_to_txt:fun -> "
+ "format failed", []),
ok
end
end,
@@ -499,6 +520,9 @@ do_log_to_file(Log, TextFile, Mibs, Start, Stop) ->
file:close(Fd),
Res;
{error, Reason} ->
+ ?vinfo("Failed opening output file: "
+ "~n TestFile: ~p"
+ "~n Reason: ~p", [TextFile, Reason]),
{error, {TextFile, Reason}}
end.
@@ -510,6 +534,8 @@ do_log_to_io(Log, Mibs, Start, Stop) ->
{ok, S} ->
io:format("~s", [S]);
_ ->
+ ?vdebug("do_log_to_io:fun -> "
+ "format failed", []),
ok
end
end,
diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl
index df5986b7bc..e5ff3daf91 100644
--- a/lib/snmp/src/misc/snmp_verbosity.erl
+++ b/lib/snmp/src/misc/snmp_verbosity.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2000-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2000-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -148,6 +148,8 @@ image_of_sname(mnifl) -> "M-NET-IF-LOGGER";
image_of_sname(mnifw) -> io_lib:format("M-NET-IF-worker(~p)", [self()]);
image_of_sname(mconf) -> "M-CONF";
+image_of_sname(lc) -> io_lib:format("LOG-CONVERTER(~p)", [self()]);
+
image_of_sname(mgr) -> "MGR";
image_of_sname(mgr_misc) -> "MGR_MISC";
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 5d3c393bcc..8a4d9c14c0 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 4.22.2
+SNMP_VSN = 4.22.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"
--
cgit v1.2.3
From 0a41cdc148fd30e67a9a9a34e5e9c2a2a523f80c Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Thu, 14 Nov 2013 18:45:41 +0100
Subject: Adjust test cases for SLES 10 SP 1
---
lib/kernel/test/gen_sctp_SUITE.erl | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/kernel/test/gen_sctp_SUITE.erl b/lib/kernel/test/gen_sctp_SUITE.erl
index 8bd1633ef1..d2de96b269 100644
--- a/lib/kernel/test/gen_sctp_SUITE.erl
+++ b/lib/kernel/test/gen_sctp_SUITE.erl
@@ -1284,11 +1284,14 @@ do_names(_, FamilySpec, AddressCount) ->
?line ClientSocknames = ServerPeernames,
?line {ok,Socket} =
gen_sctp:peeloff(ServerSocket, ServerAssoc),
- ?line Socknames =
+ ?line SocknamesNoassoc =
lists:sort(ok(inet:socknames(Socket))),
+ ?line ?LOGVAR(SocknamesNoassoc),
?line Socknames =
lists:sort(ok(inet:socknames(Socket, ServerAssoc))),
?line ?LOGVAR(Socknames),
+ ?line true =
+ ordsets:is_subset(SocknamesNoassoc, Socknames),
?line Peernames =
lists:sort(ok(inet:peernames(Socket, ServerAssoc))),
?line ?LOGVAR(Peernames),
--
cgit v1.2.3
From b4d7911ac364eb913d89ff459a8354a1b3983416 Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Mon, 18 Nov 2013 15:55:32 +0100
Subject: Document
---
lib/kernel/doc/src/inet.xml | 76 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index fd62f778a2..c09cb6a1ef 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -434,6 +434,46 @@ fe80::204:acff:fe17:bf38
connection.
+
+
+
+ Return all address/port numbers for the other end of a connection
+
+
+
+ The same as
+
+ peernames(Socket, 0)
+ .
+ Note that this function's behaviour for an SCTP
+ one-to-many style socket is not defined by the SCTP Socket API.
+
+
+
+
+
+
+ Return all address/port numbers for the other end of a connection
+
+
+
+ Returns a list of all address/port number pairs for the other end
+ of a socket's association Assoc.
+
+
+ This function can return multiple addresses for multihomed
+ sockets such as SCTP sockets. For other sockets it does the
+ same as peername/1.
+
+
+ Note that the Assoc parameter
+ is by the SCTP Socket API defined to be ignored for
+ one-to-one style sockets. What the special value 0
+ means hence its behaviour for one-to-many style sockets
+ is unfortunately not defined.
+
+
+
Return the local port number for a socket
@@ -448,6 +488,42 @@ fe80::204:acff:fe17:bf38
Returns the local address and port number for a socket.
+
+
+ Return all local address/port numbers for a socket
+
+
+ The same as
+
+ socknames(Socket, 0)
+ .
+
+
+
+
+
+ Return all local address/port numbers for a socket
+
+
+ Returns a list of all local address/port number pairs for a socket
+ for the given association Assoc.
+
+
+ This function can return multiple addresses for multihomed
+ sockets such as SCTP sockets. For other sockets it does the
+ same as sockname/1.
+
+
+ Note that the Assoc parameter
+ is by the SCTP Socket API defined to be ignored for
+ one-to-one style sockets. For one-to-many style sockets
+ the special value 0 is defined to mean that
+ the returned addresses shall be without regard to any
+ particular association. How different SCTP implementations
+ interprets this varies somewhat.
+
+
+
Set one or more options for a socket
--
cgit v1.2.3
From cd5f69d2148b77c2700d216939938e250477b5f7 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 19 Nov 2013 19:19:06 +0100
Subject: Suppress false valgrind warnings caused by sctp_getpaddrs
---
erts/emulator/drivers/common/inet_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index de18656273..f55e6efacc 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -3959,6 +3959,7 @@ static int inet_address_to_erlang(char *dst, inet_address **src) {
dst[0] = INET_AF_INET6;
port = sock_ntohs((*src)->sai6.sin6_port);
put_int16(port, dst+1);
+ VALGRIND_MAKE_MEM_DEFINED(&(*src)->sai6.sin6_addr,16); /* false undefs from syscall sctp_get[lp]addrs */
sys_memcpy(dst+1+2, (char *) &(*src)->sai6.sin6_addr, 16);
}
(*src) = (inet_address *) (&(*src)->sai6 + 1);
--
cgit v1.2.3
From f032cab84cfa89e986b080fb9ded8651ced655dd Mon Sep 17 00:00:00 2001
From: Micael Karlberg
Date: Wed, 20 Nov 2013 14:10:33 +0100
Subject: [snmp] Adjust verbosity for some of the log test cases
Also fixed release notes. Used wrong (invalid) ticket number
on release notes (111453 instead if 11453).
---
lib/snmp/doc/src/notes.xml | 2 +-
lib/snmp/test/snmp_log_test.erl | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 2350c0947e..9d9aa02d72 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -90,7 +90,7 @@
decode a log entry would cause the conversion to fail
(not because of the failed decode, but because of the
failure to write the error message).
- Own Id: OTP-111453
+ Own Id: OTP-11453
Aux Id: Seq 12459
diff --git a/lib/snmp/test/snmp_log_test.erl b/lib/snmp/test/snmp_log_test.erl
index aeac4d1f71..3b810493cb 100644
--- a/lib/snmp/test/snmp_log_test.erl
+++ b/lib/snmp/test/snmp_log_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2013. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -331,7 +331,7 @@ log_to_io1(doc) -> "Log to io from the same process that opened "
log_to_io1(Config) when is_list(Config) ->
p(log_to_io1),
put(sname,l2i1),
- put(verbosity,trace),
+ put(verbosity, debug),
?DBG("log_to_io1 -> start", []),
Dir = ?config(log_dir, Config),
Name = "snmp_test_l2i1",
@@ -386,7 +386,7 @@ log_to_io2(Config) when is_list(Config) ->
process_flag(trap_exit, true),
p(log_to_io2),
put(sname, l2i2),
- put(verbosity,trace),
+ put(verbosity, debug),
?DBG("log_to_io2 -> start", []),
Dir = ?config(log_dir, Config),
Name = "snmp_test_l2i2",
@@ -445,7 +445,7 @@ log_to_txt1(suite) -> [];
log_to_txt1(Config) when is_list(Config) ->
p(log_to_txt1),
put(sname,l2t1),
- put(verbosity,trace),
+ put(verbosity, debug),
?DBG("log_to_txt1 -> start", []),
Name = "snmp_test_l2t1",
@@ -463,7 +463,7 @@ log_to_txt2(suite) -> [];
log_to_txt2(Config) when is_list(Config) ->
p(log_to_txt2),
put(sname,l2t2),
- put(verbosity,trace),
+ put(verbosity, debug),
?DBG("log_to_txt2 -> start", []),
Name = "snmp_test_l2t2",
@@ -593,7 +593,7 @@ log_to_txt3(Config) when is_list(Config) ->
process_flag(trap_exit, true),
p(log_to_txt3),
put(sname,l2t3),
- put(verbosity,trace),
+ put(verbosity, debug),
?DBG("log_to_txt3 -> start", []),
Dir = ?config(log_dir, Config),
Name = "snmp_test_l2t3",
--
cgit v1.2.3
From b9278a19e1abdb80d93833773f4b9c431958bdcb Mon Sep 17 00:00:00 2001
From: Raimo Niskanen
Date: Mon, 25 Nov 2013 10:13:29 +0100
Subject: Improve documentation
---
lib/kernel/doc/src/inet.xml | 60 +++++++++++++++++++++++++++------------------
1 file changed, 36 insertions(+), 24 deletions(-)
diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml
index c09cb6a1ef..bc4c68230e 100644
--- a/lib/kernel/doc/src/inet.xml
+++ b/lib/kernel/doc/src/inet.xml
@@ -430,8 +430,16 @@ fe80::204:acff:fe17:bf38
Return the address and port for the other end of a connection
- Returns the address and port for the other end of a
- connection.
+
+ Returns the address and port for the other end of a
+ connection.
+
+
+ Note that for SCTP sockets this function only returns
+ one of the socket's peer addresses. The function
+ peernames/1,2
+ returns all.
+
@@ -441,12 +449,11 @@ fe80::204:acff:fe17:bf38
- The same as
-
- peernames(Socket, 0)
- .
+ Equivalent to
+ peernames(Socket, 0).
Note that this function's behaviour for an SCTP
- one-to-many style socket is not defined by the SCTP Socket API.
+ one-to-many style socket is not defined by the
+ SCTP Sockets API Extensions.
@@ -462,12 +469,13 @@ fe80::204:acff:fe17:bf38
This function can return multiple addresses for multihomed
- sockets such as SCTP sockets. For other sockets it does the
- same as peername/1.
+ sockets such as SCTP sockets. For other sockets it
+ returns a one element list.
- Note that the Assoc parameter
- is by the SCTP Socket API defined to be ignored for
+ Note that the Assoc parameter is by the
+ SCTP Sockets API Extensions
+ defined to be ignored for
one-to-one style sockets. What the special value 0
means hence its behaviour for one-to-many style sockets
is unfortunately not defined.
@@ -486,6 +494,12 @@ fe80::204:acff:fe17:bf38
Return the local address and port number for a socket
Returns the local address and port number for a socket.
+
+ Note that for SCTP sockets this function only returns
+ one of the socket addresses. The function
+ socknames/1,2
+ returns all.
+
@@ -493,10 +507,8 @@ fe80::204:acff:fe17:bf38
Return all local address/port numbers for a socket
- The same as
-
- socknames(Socket, 0)
- .
+ Equivalent to
+ socknames(Socket, 0).
@@ -510,17 +522,17 @@ fe80::204:acff:fe17:bf38
This function can return multiple addresses for multihomed
- sockets such as SCTP sockets. For other sockets it does the
- same as sockname/1.
+ sockets such as SCTP sockets. For other sockets it
+ returns a one element list.
- Note that the Assoc parameter
- is by the SCTP Socket API defined to be ignored for
- one-to-one style sockets. For one-to-many style sockets
- the special value 0 is defined to mean that
- the returned addresses shall be without regard to any
- particular association. How different SCTP implementations
- interprets this varies somewhat.
+ Note that the Assoc parameter is by the
+ SCTP Sockets API Extensions
+ defined to be ignored for one-to-one style sockets.
+ For one-to-many style sockets the special value 0
+ is defined to mean that the returned addresses shall be
+ without regard to any particular association.
+ How different SCTP implementations interprets this varies somewhat.
--
cgit v1.2.3