Esempio n. 1
0
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *      
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messges for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;
    fd_set          readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    struct timeval  sched, *svp = &sched, now, *nvp = &now;
    int             count, block, i;
#ifdef	USING_SMUX_MODULE
    int             sd;
#endif                          /* USING_SMUX_MODULE */


    /*
     * Set the 'sched'uled timeout to the current time + one TIMETICK.
     */
    gettimeofday(nvp, (struct timezone *) NULL);
    svp->tv_usec = nvp->tv_usec + TIMETICK;
    svp->tv_sec = nvp->tv_sec;

    while (svp->tv_usec >= ONE_SEC) {
        svp->tv_usec -= ONE_SEC;
        svp->tv_sec++;
    }

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

    /*
     * Loop-forever: execute message handlers for sockets with data,
     * reset the 'sched'uler.
     */
    while (netsnmp_running) {
        if (reconfig) {
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
	    /*  Stop and restart logging.  This allows logfiles to be
		rotated etc.  */
	    snmp_disable_log();
	    setup_log(1, 0, 0, 0, NULL);
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
		     netsnmp_get_version());
            update_config();
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
        }

        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        tvp = &timeout;
        tvp->tv_sec = 0;
        tvp->tv_usec = TIMETICK;

        numfds = 0;
        FD_ZERO(&readfds);
        FD_ZERO(&writefds);
        FD_ZERO(&exceptfds);
        block = 0;
        snmp_select_info(&numfds, &readfds, tvp, &block);
        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            FD_SET(smux_listen_sd, &readfds);
            numfds =
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
            for (i = 0; i < sdlen; i++) {
                FD_SET(sdlist[i], &readfds);
                numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
            }
        }
#endif                          /* USING_SMUX_MODULE */

        for (i = 0; i < external_readfdlen; i++) {
            FD_SET(external_readfd[i], &readfds);
            if (external_readfd[i] >= numfds)
                numfds = external_readfd[i] + 1;
        }
        for (i = 0; i < external_writefdlen; i++) {
            FD_SET(external_writefd[i], &writefds);
            if (external_writefd[i] >= numfds)
                numfds = external_writefd[i] + 1;
        }
        for (i = 0; i < external_exceptfdlen; i++) {
            FD_SET(external_exceptfd[i], &exceptfds);
            if (external_exceptfd[i] >= numfds)
                numfds = external_exceptfd[i] + 1;
        }

    reselect:
        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {

#ifdef USING_SMUX_MODULE
            /*
             * handle the SMUX sd's 
             */
            if (smux_listen_sd >= 0) {
                for (i = 0; i < sdlen; i++) {
                    if (FD_ISSET(sdlist[i], &readfds)) {
                        if (smux_process(sdlist[i]) < 0) {
                            for (; i < (sdlen - 1); i++) {
                                sdlist[i] = sdlist[i + 1];
                            }
                            sdlen--;
                        }
                    }
                }
                /*
                 * new connection 
                 */
                if (FD_ISSET(smux_listen_sd, &readfds)) {
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                        sdlist[sdlen++] = sd;
                    }
                }
            }
#endif                          /* USING_SMUX_MODULE */

            snmp_read(&readfds);

            for (i = 0; count && (i < external_readfdlen); i++) {
                if (FD_ISSET(external_readfd[i], &readfds)) {
                    DEBUGMSGTL(("snmpd/select", "readfd[%d] = %d\n",
                                i, external_readfd[i]));
                    external_readfdfunc[i] (external_readfd[i],
                                            external_readfd_data[i]);
                    FD_CLR(external_readfd[i], &readfds);
                    count--;
                }
            }
            for (i = 0; count && (i < external_writefdlen); i++) {
                if (FD_ISSET(external_writefd[i], &writefds)) {
                    DEBUGMSGTL(("snmpd/select", "writefd[%d] = %d\n",
                                i, external_writefd[i]));
                    external_writefdfunc[i] (external_writefd[i],
                                             external_writefd_data[i]);
                    FD_CLR(external_writefd[i], &writefds);
                    count--;
                }
            }
            for (i = 0; count && (i < external_exceptfdlen); i++) {
                if (FD_ISSET(external_exceptfd[i], &exceptfds)) {
                    DEBUGMSGTL(("snmpd/select", "exceptfd[%d] = %d\n",
                                i, external_exceptfd[i]));
                    external_exceptfdfunc[i] (external_exceptfd[i],
                                              external_exceptfd_data[i]);
                    FD_CLR(external_exceptfd[i], &exceptfds);
                    count--;
                }
            }

        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (netsnmp_running && !reconfig) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */




        /*
         * If the time 'now' is greater than the 'sched'uled time, then:
         *
         *    Check alarm and event timers.
         *    Reset the 'sched'uled time to current time + one TIMETICK.
         *    Age the cache network addresses (from whom messges have
         *        been received).
         */
        gettimeofday(nvp, (struct timezone *)NULL);

        if (nvp->tv_sec > svp->tv_sec || (nvp->tv_sec == svp->tv_sec &&
					  nvp->tv_usec > svp->tv_usec)) {
            svp->tv_usec = nvp->tv_usec + TIMETICK;
            svp->tv_sec = nvp->tv_sec;

            while (svp->tv_usec >= ONE_SEC) {
                svp->tv_usec -= ONE_SEC;
                svp->tv_sec++;
            }
        }

        /*
         * endif -- now>sched 
         */
        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();

    }                           /* endwhile */

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}                               /* end receive() */
Esempio n. 2
0
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *      
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messages for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;
    netsnmp_large_fd_set readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    int             count, block, i;
#ifdef	USING_SMUX_MODULE
    int             sd;
#endif                          /* USING_SMUX_MODULE */

    netsnmp_large_fd_set_init(&readfds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&writefds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE);

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

#if defined(WIN32)
    create_stdin_waiter_thread();
#endif

    /*
     * Loop-forever: execute message handlers for sockets with data
     */
    while (netsnmp_running) {
        if (reconfig) {
#if HAVE_SIGHOLD
            sighold(SIGHUP);
#endif
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
	    /*  Stop and restart logging.  This allows logfiles to be
		rotated etc.  */
	    netsnmp_logging_restart();
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
		     netsnmp_get_version());
            update_config();
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
#if HAVE_SIGHOLD
            sigrelse(SIGHUP);
#endif
        }

        /*
         * default to sleeping for a really long time. INT_MAX
         * should be sufficient (eg we don't care if time_t is
         * a long that's bigger than an int).
         */
        tvp = &timeout;
        tvp->tv_sec = INT_MAX;
        tvp->tv_usec = 0;

        numfds = 0;
        NETSNMP_LARGE_FD_ZERO(&readfds);
        NETSNMP_LARGE_FD_ZERO(&writefds);
        NETSNMP_LARGE_FD_ZERO(&exceptfds);
        block = 0;
        snmp_select_info2(&numfds, &readfds, tvp, &block);
        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            NETSNMP_LARGE_FD_SET(smux_listen_sd, &readfds);
            numfds =
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;

            for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                sd = smux_snmp_select_list_get_SD_from_List(i);
                if (sd != 0)
                {
                   NETSNMP_LARGE_FD_SET(sd, &readfds);
                   numfds = sd >= numfds ? sd + 1 : numfds;
                }
            }
        }
#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
        netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

    reselect:
        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        if (tvp)
            DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec,
                        (long) tvp->tv_usec));
        count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
				     tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {

#ifdef USING_SMUX_MODULE
            /*
             * handle the SMUX sd's 
             */
            if (smux_listen_sd >= 0) {
                for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                    sd = smux_snmp_select_list_get_SD_from_List(i);
                    if (NETSNMP_LARGE_FD_ISSET(sd, &readfds)) {
                        if (smux_process(sd) < 0) {
                            smux_snmp_select_list_del(sd);
                        }
                    }
                }
                /*
                 * new connection 
                 */
                if (NETSNMP_LARGE_FD_ISSET(smux_listen_sd, &readfds)) {
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                        smux_snmp_select_list_add(sd);
                    }
                }
            }

#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
            netsnmp_dispatch_external_events2(&count, &readfds,
                                              &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

            /* If there are still events leftover, process them */
            if (count > 0) {
              snmp_read2(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                DEBUGMSGTL(("snmpd/select", "  errno = %d\n", errno));
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (netsnmp_running && !reconfig) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */

        /*
         * see if persistent store needs to be saved
         */
        snmp_store_if_needed();

        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();

    }                           /* endwhile */

    netsnmp_large_fd_set_cleanup(&readfds);
    netsnmp_large_fd_set_cleanup(&writefds);
    netsnmp_large_fd_set_cleanup(&exceptfds);

#if defined(WIN32)
    join_stdin_waiter_thread();
#endif

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}                               /* end receive() */
Esempio n. 3
0
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messges for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int numfds;
    fd_set fdset;
    struct timeval	timeout, *tvp = &timeout;
    struct timeval	sched,   *svp = &sched,
                                  now,     *nvp = &now;
    int count, block;
#ifdef	USING_SMUX_MODULE
    int i, sd;
#endif	/* USING_SMUX_MODULE */


    /*
     * Set the 'sched'uled timeout to the current time + one TIMETICK.
     */
    gettimeofday(nvp, (struct timezone *) NULL);
    svp->tv_usec = nvp->tv_usec + TIMETICK;
    svp->tv_sec = nvp->tv_sec;

    while (svp->tv_usec >= ONE_SEC) {
        svp->tv_usec -= ONE_SEC;
        svp->tv_sec++;
    }

    /*
     * Loop-forever: execute message handlers for sockets with data,
     * reset the 'sched'uler.
     */
    while (running) {
        if (reconfig) {
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
            update_config();
        }
        tvp =  &timeout;
        tvp->tv_sec = 0;
        tvp->tv_usec = TIMETICK;

        numfds = 0;
        FD_ZERO(&fdset);
        block = 0;
        snmp_select_info(&numfds, &fdset, tvp, &block);
        if (block == 1)
            tvp = NULL; /* block without timeout */

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            FD_SET(smux_listen_sd, &fdset);
            numfds = smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;
            for (i = 0; i < sdlen; i++) {
                FD_SET(sdlist[i], &fdset);
                numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
            }
        }
#endif	/* USING_SMUX_MODULE */

        count = select(numfds, &fdset, 0, 0, tvp);

        if (count > 0) {
            snmp_read(&fdset);
        } else switch(count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                if (errno == EINTR) {
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }  /* endif -- count>0 */

#ifdef	USING_SMUX_MODULE
        /* handle the SMUX sd's */
        if (smux_listen_sd >= 0) {
            for (i = 0; i < sdlen; i++) {
                if (FD_ISSET(sdlist[i], &fdset)) {
                    if (smux_process(sdlist[i]) < 0) {
                        for (; i < (sdlen - 1); i++) {
                            sdlist[i] = sdlist[i+1];
                        }
                        sdlen--;
                    }
                }
            }
            /* new connection */
            if (FD_ISSET(smux_listen_sd, &fdset)) {
                if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                    sdlist[sdlen++] = sd;
                }
            }
        }
#endif	/* USING_SMUX_MODULE */



        /*
         * If the time 'now' is greater than the 'sched'uled time, then:
         *
         *    Check alarm and event timers.
         *    Reset the 'sched'uled time to current time + one TIMETICK.
         *    Age the cache network addresses (from whom messges have
         *        been received).
         */
        gettimeofday(nvp, (struct timezone *) NULL);

        if (nvp->tv_sec > svp->tv_sec
                || (nvp->tv_sec == svp->tv_sec && nvp->tv_usec > svp->tv_usec)) {
            svp->tv_usec = nvp->tv_usec + TIMETICK;
            svp->tv_sec = nvp->tv_sec;

            while (svp->tv_usec >= ONE_SEC) {
                svp->tv_usec -= ONE_SEC;
                svp->tv_sec++;
            }
            if (log_addresses && lastAddrAge++ > 600) {

                lastAddrAge = 0;
                for(count = 0; count < ADDRCACHE; count++) {
                    if (addrCache[count].status == OLD)
                        addrCache[count].status = UNUSED;
                    if (addrCache[count].status == USED)
                        addrCache[count].status = OLD;
                }
            }
        }  /* endif -- now>sched */

        /* run requested alarms */
        run_alarms();

    }  /* endwhile */

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}  /* end receive() */