Re: [tkined] scotty2.1.10 Trap Overload Problem

Erik Schoenfelder (schoenfr@gaertner.de)
Tue, 15 Dec 1998 12:43:53 +0100 (MET)

Hi,

Shahzad> It seem that when there are to many traps coming in,
Shahzad> scotty has a hard time binding to the trap socket. It
Shahzad> keeps giving the following message:

Shahzad> can not connect straps socket: no such file or directory

Erik> hmm, maybe you can clarify this a little bit: the ENOENT return code
Erik> indicates that scotty cannot `connect' to the straps daemon; IMHO this
Erik> indices that the socket-pseudo file is missing or it is stale and does
Erik> not belong to a running straps daemon.

there is indeed no straps daemon running at this moment, due to the
kind straps behaved: if there is no client connected straps exits.
this check is done too, if a trap packet comes in. so if scotty
launches straps and a trap was received by straps before scotty
connects to the daemon, it had no client and exits.

a patch to straps.c is appended, which waits some seconds before
exiting.

another patch is included, which works around the broken solaris
connect() call (a `broken pipe' error after a connection refused');
this should cause no harm to other platforms.

i hope this helps,
Erik

--
--- scotty-2.1.10/tnm/snmp/straps.c-merk	Tue Dec 15 11:24:48 1998
+++ scotty-2.1.10/tnm/snmp/straps.c	Tue Dec 15 12:24:57 1998
@@ -60,6 +60,9 @@
 #define SNMP_TRAP_PATH	"/tmp/.straps"
 #define SNMP_TRAP_MCIP	"234.0.0.1"
 
+/* path of the local unix-domain socket: */
+static char path[1024];
+
 /*
  * A signal handler which basically ignores all SIGPIPE signals.
  * It re-installs itself for all the bozo's outside.
@@ -75,6 +78,25 @@
 #endif
 
 
+/*
+ * A signal handler which exits; is setup to shutdown straps if idle:
+ */
+
+#ifdef SIGALRM
+static void
+sig_alarm(dummy)
+    int dummy;
+{
+  /* cleanup socket (closed by exiting): */
+  unlink(path);
+
+  /* exit: */
+  exit (0);
+}
+#endif
+
+
+
 int
 main(argc, argv)
     int argc;
@@ -86,12 +108,13 @@
     int trap_s, serv_s, slen, dlen, llen, rc, i;
     fd_set fds;
     static int cl_addr [FD_SETSIZE];
-    char buf[2048], path[1024];
+    char buf[2048];
     int go_on;
     int mcast_s = -1;
     char *name;
     int port;
-    
+    int alarm_set;
+
     /* 
      * Check the number of arguments. We accept an optional argument
      * which specifies the port number we are listening on.
@@ -228,19 +251,26 @@
     
     if (listen(serv_s, 5) < 0) {
 	perror("straps: unable to listen on server socket");
+	unlink(path);
 	exit(1);
     }
 
 #ifdef SIGPIPE
     signal(SIGPIPE, ign_pipe);
 #endif
+#ifdef SIGALRM
+    signal(SIGALRM, sig_alarm);
+    alarm_set = 1;
+    alarm (5);
+#endif
     
     /*
      * Fine everything is ready; lets listen for events: 
-     * the for(;;) loop aborts, if the last client went away.
+     * the for(;;) loop aborts, if the last client went away and 
+     * we are idle for some seconds.
      */
-
-    for (go_on = 1; go_on; ) {
+    
+    for ( ; go_on = 1; ) {
 
 	  FD_ZERO(&fds);
 	  FD_SET(trap_s, &fds);
@@ -330,6 +360,9 @@
 		  continue;
 	      }
 	      cl_addr [rc] = 1;
+	      /* clear alarm in case it is set: */
+	      alarm (0);
+	      alarm_set = 0;
 
 	  } else {
 	      /* fd's connected from clients. (XXX: should check for EOF): */
@@ -344,6 +377,12 @@
 	      for (go_on = 0, i = 0; i < FD_SETSIZE; i++) {
 		  go_on += cl_addr [i] > 0;
 	      }
+	  }
+
+	  if (! go_on && ! alarm_set) {
+	    /* no client listening; prepare for exit in some seconds: */
+	    alarm (5);
+	    alarm_set = 1;
 	  }
 	  
       } /* end for (;;) */
--- scotty-2.1.10/tnm/snmp/tnmSnmpNet.c-merk	Tue Dec 15 11:47:48 1998
+++ scotty-2.1.10/tnm/snmp/tnmSnmpNet.c	Tue Dec 15 11:44:03 1998
@@ -506,13 +506,27 @@
     slen = sizeof(saddr) - sizeof(saddr.sun_path) + strlen(saddr.sun_path);
     
     if (connect(trap_sock, (struct sockaddr *) &saddr, slen) < 0) {
-	
-	if (straps(interp) != TCL_OK) return TCL_ERROR;
+      
+        /* reopen socket to avoid erroneous behavior with Solaris;
+	 * (EPIPE after ECONNREFUSED) */
+        close (trap_sock);
+        trap_sock = TnmSocket(AF_UNIX, SOCK_STREAM, 0);
+        if (trap_sock == TNM_SOCKET_ERROR) {
+	    Tcl_AppendResult(interp, "can not create straps socket: ",
+			     Tcl_PosixError(interp), (char *) NULL);
+	    return TCL_ERROR;
+	}
+
+	if (straps(interp) != TCL_OK) {
+	  return TCL_ERROR;
+	}
 	
 	for (i = 0; i < 5; i++) {
 	    sleep(1);
 	    rc = connect(trap_sock, (struct sockaddr *) &saddr, slen);
-	    if (rc >= 0) break;
+	    if (rc >= 0) {
+	      break;
+	    }
 	}
 	
 	if (rc < 0) {
@@ -559,7 +573,8 @@
 	Tcl_FreeFile(trapSocket);
 	TnmSocketClose(trap_sock);
 	trap_sock = -1;
-	Tcl_ReapDetachedProcs();
+	/* useless without Tcl_DetachPids():
+	   Tcl_ReapDetachedProcs(); */
     }
 }
 
--
!! This message is brought to you via the `tkined & scotty' mailing list.
!! Please do not reply to this message to unsubscribe. To subscribe or
!! unsubscribe, send a mail message to <tkined-request@ibr.cs.tu-bs.de>.
!! See http://wwwsnmp.cs.utwente.nl/~schoenw/scotty/ for more information.