1
0
mirror of https://github.com/simh/simh.git synced 2026-02-10 18:21:15 +00:00

ETHER: Made LAN connections more robust under failing network conditions.

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.
This commit is contained in:
Mark Pizzolato
2014-06-10 10:20:02 -07:00
parent e9b312f26a
commit c15c0058f4
4 changed files with 359 additions and 168 deletions

View File

@@ -237,12 +237,14 @@ struct eth_device {
char* name; /* name of ethernet device */
void* handle; /* handle of implementation-specific device */
SOCKET fd_handle; /* fd to kernel device (where needed) */
char* bpf_filter; /* bpf filter currently in effect */
int eth_api; /* Designator for which API is being used to move packets */
#define ETH_API_PCAP 0 /* Pcap API in use */
#define ETH_API_TAP 1 /* tun/tap API in use */
#define ETH_API_VDE 2 /* VDE API in use */
#define ETH_API_UDP 3 /* UDP API in use */
#define ETH_API_NAT 4 /* NAT (SLiRP) API in use */
#define ETH_API_NONE 0 /* No API in use yet */
#define ETH_API_PCAP 1 /* Pcap API in use */
#define ETH_API_TAP 2 /* tun/tap API in use */
#define ETH_API_VDE 3 /* VDE API in use */
#define ETH_API_UDP 4 /* UDP API in use */
#define ETH_API_NAT 5 /* NAT (SLiRP) API in use */
ETH_PCALLBACK read_callback; /* read callback function */
ETH_PCALLBACK write_callback; /* write callback function */
ETH_PACK* read_packet; /* read packet */
@@ -264,6 +266,13 @@ struct eth_device {
uint32 packets_sent; /* Total Packets Sent */
uint32 packets_received; /* Total Packets Received */
uint32 loopback_packets_processed; /* Total Loopback Packets Processed */
uint32 transmit_packet_errors; /* Total Send Packet Errors */
uint32 receive_packet_errors; /* Total Read Packet Errors */
int32 error_waiting_threads; /* Count of threads currently waiting after an error */
BOOL error_needs_reset; /* Flag indicating to force reset */
#define ETH_ERROR_REOPEN_THRESHOLD 10 /* Attempt ReOpen after 20 send/receive errors */
#define ETH_ERROR_REOPEN_PAUSE 4 /* Seconds to pause between closing and reopening LAN */
uint32 error_reopen_count; /* Count of ReOpen Attempts */
DEVICE* dptr; /* device ethernet is attached to */
uint32 dbit; /* debugging bit */
int reflections; /* packet reflections on interface */