sub_agent.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
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 
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 "snmpSIPCommonObjects.h"
00055 #include "snmpSIPServerObjects.h"
00056 #include "snmpObjects.h"
00057 
00058 /* Bring in the initialization functions for all tables */
00059 #include "snmpSIPPortTable.h"
00060 #include "snmpSIPMethodSupportedTable.h"
00061 #include "snmpSIPStatusCodesTable.h"
00062 #include "snmpSIPRegUserTable.h"
00063 #include "snmpSIPContactTable.h"
00064 #include "snmpSIPRegUserLookupTable.h"
00065 #include "snmpMIBNotifications.h"
00066 
00067 #include "../../dprint.h"
00068 #include "../../cfg/cfg_struct.h"
00069 
00070 static int keep_running;
00071 
00073 static void sigterm_handler(int signal) 
00074 {
00075         /* Just exit.  The master agent will clean everything up for us */
00076         exit(0);
00077 }
00078 
00090 static int initialize_agentx(void) 
00091 {
00092         /* We register with a master agent */
00093         register_with_master_agent(AGENT_PROCESS_NAME);
00094         
00095         /* Initialize all scalars, and let the master agent know we want to
00096          * handle all OID's pertaining to these scalars. */
00097         init_openserSIPCommonObjects();
00098         init_openserSIPServerObjects();
00099         init_openserObjects();
00100 
00101         /* Initialiaze all the tables, and let the master agent know we want to
00102          * handle all the OID's pertaining to these tables */
00103         init_openserSIPPortTable();
00104         init_openserSIPMethodSupportedTable();
00105         init_openserSIPStatusCodesTable();
00106         init_openserSIPRegUserTable();
00107         init_openserSIPContactTable();
00108         init_openserSIPRegUserLookupTable();
00109 
00110         /* In case we recevie a request to stop (kill -TERM or kill -INT) */
00111         keep_running = 1;
00112 
00113         while(keep_running) {
00114                 /* update the local config framework structures */
00115                 cfg_update();
00116 
00117                 agent_check_and_process(1); /* 0 == don't block */
00118         }
00119 
00120         snmp_shutdown(AGENT_PROCESS_NAME);
00121         SOCK_CLEANUP;
00122         exit (0);
00123 
00124         return 0;
00125 }
00126 
00130 void agentx_child(int rank)
00131 {
00132         struct sigaction new_sigterm_handler;
00133         struct sigaction default_handlers;
00134         struct sigaction sigpipe_handler;
00135 
00136         /* Setup a SIGTERM handler */
00137         sigfillset(&new_sigterm_handler.sa_mask);
00138         new_sigterm_handler.sa_flags   = 0;
00139         new_sigterm_handler.sa_handler = sigterm_handler;
00140         sigaction(SIGTERM, &new_sigterm_handler, NULL);
00141 
00142         /* We don't want OpenSER's normal handlers doing anything when
00143          * we die.  As far as OpenSER knows this process never existed.
00144          * So override all signal handlers to the OS default. */
00145         sigemptyset(&default_handlers.sa_mask);
00146         default_handlers.sa_flags = 0;
00147         default_handlers.sa_handler = SIG_DFL;
00148 
00149         sigaction(SIGCHLD, &default_handlers, NULL);
00150         sigaction(SIGINT,  &default_handlers, NULL);
00151         sigaction(SIGHUP,  &default_handlers, NULL);
00152         sigaction(SIGUSR1, &default_handlers, NULL);
00153         sigaction(SIGUSR2, &default_handlers, NULL);
00154 
00155         /* It is possible that the master agent will unregister us if we
00156          * take too long to respond to an SNMP request.  This would
00157          * happen if a large number of users/contacts have been
00158          * registered between snmp requests to the user/contact tables.
00159          * In this situation we may try to write to a closed socket when
00160          * we are done processing, resulting in a SIGPIPE.  This doesn't
00161          * need to be fatal however, because we can re-establish our
00162          * connection.  Therefore we set ourselves up to ignore the
00163          * SIGPIPE. */
00164         sigpipe_handler.sa_flags = SA_RESTART;
00165         sigpipe_handler.sa_handler = SIG_IGN;
00166 
00167         sigaction(SIGPIPE, &sigpipe_handler, NULL);
00168 
00169         initialize_agentx();
00170 }
00171 
00172 
00173 
00176 void register_with_master_agent(char *name_to_register_under) 
00177 {
00178         /* Set ourselves up as an AgentX Client. */
00179         netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
00180 
00181         /* Initialize TCP if necessary.  (Its here for WIN32) compatibility. */
00182         SOCK_STARTUP;
00183 
00184         /* Read in our configuration file to determine master agent ping times
00185          * what port communication is to take place over, etc. */
00186         init_agent("snmpstats");
00187 
00188         /* Use a name we can register our agent under. */
00189         init_snmp(name_to_register_under);
00190 }