sub_agent.c

Go to the documentation of this file.
00001 /*
00002  * $Id: sub_agent.c 4764 2008-08-28 14:41:06Z henningw $
00003  *
00004  * SNMPStats Module 
00005  * Copyright (C) 2006 SOMA Networks, INC.
00006  * Written by: Jeffrey Magder (jmagder@somanetworks.com)
00007  *
00008  * This file is part of Kamailio, a free SIP server.
00009  *
00010  * Kamailio is free software; you can redistribute it and/or modify it
00011  * under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version
00014  *
00015  * Kamailio is distributed in the hope that it will be useful, but
00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023  * USA
00024  *
00025  * History:
00026  * --------
00027  * 2006-11-23 initial version (jmagder)
00028  */
00029 
00030 /*!
00031  * \file
00032  * \brief SNMP statistic module, master agent connection
00033  *
00034  * This file defines all functions required to establish a relationship with a
00035  * master agent.
00036  * \ingroup snmpstats
00037  * - Module: \ref snmpstats
00038  */
00039 
00040 
00041 #include <sys/types.h>
00042 #include <stdlib.h>
00043 #include <unistd.h>
00044 #include <signal.h>
00045 
00046 #include "sub_agent.h"
00047 
00048 /* Bring in the NetSNMP headers */
00049 #include <net-snmp/net-snmp-config.h>
00050 #include <net-snmp/net-snmp-includes.h>
00051 #include <net-snmp/agent/net-snmp-agent-includes.h>
00052 
00053 /* Bring in the initialization functions for all scalars */
00054 #include "openserSIPCommonObjects.h"
00055 #include "openserSIPServerObjects.h"
00056 #include "openserObjects.h"
00057 
00058 /* Bring in the initialization functions for all tables */
00059 #include "openserSIPPortTable.h"
00060 #include "openserSIPMethodSupportedTable.h"
00061 #include "openserSIPStatusCodesTable.h"
00062 #include "openserSIPRegUserTable.h"
00063 #include "openserSIPContactTable.h"
00064 #include "openserSIPRegUserLookupTable.h"
00065 #include "openserMIBNotifications.h"
00066 
00067 #include "../../dprint.h"
00068 
00069 static int keep_running;
00070 
00071 /*! The function handles Handles shutting down of the sub_agent process. */
00072 static void sigterm_handler(int signal) 
00073 {
00074    /* Just exit.  The master agent will clean everything up for us */
00075    exit(0);
00076 }
00077 
00078 /*! This function:
00079  *
00080  *   1) Registers itself with the Master Agent
00081  *   2) Initializes all of the SNMPStats modules scalars and tables, while
00082  *      simultaneously registering their respective SNMP OID's and handlers 
00083  *      with the master agent.
00084  *   3) Repeatedly checks for new SNMP messages to process
00085  *
00086  * \note This function never returns, so it should always be called from a 
00087  *       sub-process.
00088  */
00089 static int initialize_agentx(void) 
00090 {
00091    /* We register with a master agent */
00092    register_with_master_agent(AGENT_PROCESS_NAME);
00093    
00094    /* Initialize all scalars, and let the master agent know we want to
00095     * handle all OID's pertaining to these scalars. */
00096    init_openserSIPCommonObjects();
00097    init_openserSIPServerObjects();
00098    init_openserObjects();
00099 
00100    /* Initialiaze all the tables, and let the master agent know we want to
00101     * handle all the OID's pertaining to these tables */
00102    init_openserSIPPortTable();
00103    init_openserSIPMethodSupportedTable();
00104    init_openserSIPStatusCodesTable();
00105    init_openserSIPRegUserTable();
00106    init_openserSIPContactTable();
00107    init_openserSIPRegUserLookupTable();
00108 
00109    /* In case we recevie a request to stop (kill -TERM or kill -INT) */
00110    keep_running = 1;
00111 
00112    while(keep_running) {
00113       agent_check_and_process(1); /* 0 == don't block */
00114    }
00115 
00116    snmp_shutdown(AGENT_PROCESS_NAME);
00117    SOCK_CLEANUP;
00118    exit (0);
00119 
00120    return 0;
00121 }
00122 
00123 /*! Creates a child that will become the AgentX sub-agent.  The child will
00124  * insulate itself from the rest of OpenSER by overriding most of signal
00125  * handlers. */
00126 void agentx_child(int rank)
00127 {
00128    struct sigaction new_sigterm_handler;
00129    struct sigaction default_handlers;
00130    struct sigaction sigpipe_handler;
00131 
00132    /* Setup a SIGTERM handler */
00133    sigfillset(&new_sigterm_handler.sa_mask);
00134    new_sigterm_handler.sa_flags   = 0;
00135    new_sigterm_handler.sa_handler = sigterm_handler;
00136    sigaction(SIGTERM, &new_sigterm_handler, NULL);
00137 
00138    /* We don't want OpenSER's normal handlers doing anything when
00139     * we die.  As far as OpenSER knows this process never existed.
00140     * So override all signal handlers to the OS default. */
00141    sigemptyset(&default_handlers.sa_mask);
00142    default_handlers.sa_flags = 0;
00143    default_handlers.sa_handler = SIG_DFL;
00144 
00145    sigaction(SIGCHLD, &default_handlers, NULL);
00146    sigaction(SIGINT,  &default_handlers, NULL);
00147    sigaction(SIGHUP,  &default_handlers, NULL);
00148    sigaction(SIGUSR1, &default_handlers, NULL);
00149    sigaction(SIGUSR2, &default_handlers, NULL);
00150 
00151    /* It is possible that the master agent will unregister us if we
00152     * take too long to respond to an SNMP request.  This would
00153     * happen if a large number of users/contacts have been
00154     * registered between snmp requests to the user/contact tables.
00155     * In this situation we may try to write to a closed socket when
00156     * we are done processing, resulting in a SIGPIPE.  This doesn't
00157     * need to be fatal however, because we can re-establish our
00158     * connection.  Therefore we set ourselves up to ignore the
00159     * SIGPIPE. */
00160    sigpipe_handler.sa_flags = SA_RESTART;
00161    sigpipe_handler.sa_handler = SIG_IGN;
00162 
00163    sigaction(SIGPIPE, &sigpipe_handler, NULL);
00164 
00165    initialize_agentx();
00166 }
00167 
00168 
00169 
00170 /*! This function opens up a connection with the master agent specified in
00171  * the snmpstats modules configuration file */
00172 void register_with_master_agent(char *name_to_register_under) 
00173 {
00174    /* Set ourselves up as an AgentX Client. */
00175    netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
00176 
00177    /* Initialize TCP if necessary.  (Its here for WIN32) compatibility. */
00178    SOCK_STARTUP;
00179 
00180    /* Read in our configuration file to determine master agent ping times
00181     * what port communication is to take place over, etc. */
00182    init_agent("snmpstats");
00183 
00184    /* Use a name we can register our agent under. */
00185    init_snmp(name_to_register_under);
00186 }

Generated on Thu May 24 20:00:32 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6