Initialize de-dup'ed debug line buffer:
realloc(NULL, size) == malloc(size), which is uninitialized space.
This causes the Clang memory sanitizer to detect an attempt to read
uninitialized memory when debug_line_buf and debug_line_buf_last are
different lengths. While the uninitialized space may never actually be
compared, the memory sanitizer emits a strong hint to not do stupid.
The sanitizer trips in the i650 simulator on the first memcmp(),
debug_line_buf has 108 characters, debug_line_buf_last has 56
characters (uninitialized space follows the 56 characters, tripping
the sanitizer.)
- memset() debug_line_buf and debug_line_buf_last to zero so that
memcmp() will always gracefully return non-zero if somehow memcmp()
ends up going past the end of either buffer. Should never happen in
practice, but theory always gets mugged by reality.
- Keep track of debug_line_buf_last's comparison length (i.e., up to
the '\r') and only execute memcmp() when this length equals the
current debug_line_buf comparison length (end - endprefix + 1).
- Added a log deduplication test to "testlib" command to ensure that
nothing broke as a result of this fix.
Network ACL check in sim_addr_acl_check:
The memory sanitizer found an off-by-one bug in sim_addr_acl_check
while executing "testlib". This makes CIDR network ACLs functional,
e.g., "127.0.0.1/32" is interpreted properly and the associated
"testlib" test passes.
The currently used backlog of (1) effectively disables any two or more
simultanueously incoming connections at the kernel level, because the
backlog parameter only allows 1 such connection. Yet since terminal
multiplexers can handle tens of clients, it's not technically impossible to
have more than one incoming request to be received at any particular moment
(for two different "lines"). A reasonable backlog of more than 1 safeguards
that the "extra" connections won't be refused outright, and postpones that
decision to be made by simh (not the kernel) -- for example, when, say, all
multiplexer lines are busy, with an explanation (which states so) rather than
just the infamous "Connection reset by peer" (effected by the kernel reset).
This patch increases the backlog to 64.
Some dependent packages on some platforms may also define HAVE_DLOPEN
and that definition may have different syntax or semantics. This change
avoids the potential symbol conflict.
As reported in #1098
Also provide a way to build so that the IPv6 fallback stubs can be tested on
systems with native IPv6 support when compiled with TEST_INFO_STUBS
defined.
Outbound connections are rare and most may have wanted explicit blocking
behavior, so no one noticed the missing non-blocking case.
Any place which did do outbound connects have explicitly added
SIM_SOCK_OPT_BLOCKING so that the prior behavior is preserved.
The SIM_SOCK_OPT_BLOCKING flag is no honored as it was originally
intended to be.
These changes facilitate more robust parameter type checking and helps
to identify unexpected coding errors.
Most simulators can now also be compiled with a C++ compiler without
warnings.
Additionally, these changes have also been configured to facilitate easier
backporting of simulator and device simulation modules to run under the
simh v3.9+ SCP framework.
Cleanup/Simplification by:
1) removing irrelevant master flag variable from sim_close_sock and thus sim_err_sock
2) change previous boolean feature arguments (datagram, nodelay, reuseaddr) to flag bits in a single option argument. This allows for features to be added by new flag bits which don't change the calling signatures.
3) changed all status returns to be int (vs t_stat) with success being 0 and error being -1
4) removed unneeded simh specific type references to allow sim_sock to be used by n
Extended API by providing flags to influence socket setup/behavior:
SIM_SOCK_OPT_REUSEADDR Retains prior behavior when sim_switches had -U set
SIM_SOCK_OPT_DATAGRAM UDP socket setup provided for when prior datagram argument was specified
SIM_SOCK_OPT_NODELAY TCP Nagle disable provided for when prior nodelay argument was specified
SIM_SOCK_OPT_BLOCKING Blocking socket mode (detault is non blocking)
Avoid permanent network network hangs when a network transport starts to return errors for various reasons.
These hangs also result in at least one thread in a CPU bound loop attempting to read on a pcap connection which will never be useful again.
When transmit or receive errors occur, the invoking thread sleeps for 1 second and subsequent operations proceed. When the total of read + write errors reaches a multiple of ETH_ERROR_REOPEN_THRESHOLD the current transport connection (usually pcap) is closed and re-opened after a ETH_ERROR_REOPEN_PAUSE second delay. If the open succeeds, we're happy. If it fails, then the link behaves as if it were never attached until some subsequent operator intervention is performed.
Activities which are known to induce this problems include (but are not limited to) when a simulator is running in a Windows Virtual Machine on a Hyper-V host system and the Hyper-V host system performs a SAVE and a subsequent Restart of the Guest Windows Virtual Machine. This operation can occur due to specific operator requests or merely when the Hyper-V host system reboots.
The goals here being to simplify calling code while getting consistent output delivered everywhere it may be useful.
Modified most places which explicitly used sim_log or merely called printf to now avoid doing that and merely call sim_printf().
- Avoid assignments of void * values. Cast all memory allocation return values to appropriate types.
- Add output to sim_log where missing in various places.
- Fixed issue with lost file positions after a restore for devices which leverage the UNIT_SEQ flag.
1. getaddrinfo returns IPv6 address even if IPv6 is not configured.
The socket syscalls fails to create IPv6 socket. This is fixed by retrying for all possible addresses returned by getaddrinfo.
2. On HP-UX EAGAIN is used, not EWOULDBLOCK.