📄 bearerbox.c
字号:
/* ==================================================================== * The Kannel Software License, Version 1.0 * * Copyright (c) 2001-2004 Kannel Group * Copyright (c) 1998-2001 WapIT Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Kannel Group (http://www.kannel.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Kannel" and "Kannel Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact org@kannel.org. * * 5. Products derived from this software may not be called "Kannel", * nor may "Kannel" appear in their name, without prior written * permission of the Kannel Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Kannel Group. For more information on * the Kannel Group, please see <http://www.kannel.org/>. * * Portions of this software are based upon software originally written at * WapIT Ltd., Helsinki, Finland for the Kannel project. */ /* * bearerbox.c * * this is the core module of the bearerbox. It starts everything and * listens to HTTP requests and traps signals. * All started modules are responsible for the rest. * * Kalle Marjola <rpr@wapit.com> 2000 for project Kannel */#include <errno.h>#include <stdlib.h>#include <stdio.h>#include <time.h>#include <string.h>#include <signal.h>#include <unistd.h>#include "gwlib/gwlib.h"#include "msg.h"#include "bearerbox.h"#include "shared.h"#include "dlr.h"/* global variables; included to other modules as needed */List *incoming_sms;List *outgoing_sms;List *incoming_wdp;List *outgoing_wdp;Counter *incoming_sms_counter;Counter *outgoing_sms_counter;Counter *incoming_wdp_counter;Counter *outgoing_wdp_counter;/* incoming/outgoing sms queue control */long max_incoming_sms_qlength;/* this is not a list of items; instead it is used as * indicator to note how many threads we have. * ALL flow threads must exit before we may safely change * bb_status from BB_SHUTDOWN to BB_DEAD * * XXX: prehaps we could also have items in this list, as * descriptors of each thread? */List *flow_threads;/* and still more abuse; we use this list to put us into * 'suspend' state - if there are any producers (only core adds/removes them) * receiver/sender systems just sit, blocked in list_consume */List *suspended;/* this one is like 'suspended', but only for receiving UDP/SMSC * (suspended state puts producers for both lists) */List *isolated;volatile sig_atomic_t bb_status;/* * Flags for main thread to check what is to do. */enum { BB_LOGREOPEN = 1, BB_CHECKLEAKS = 2};/* Here we will set above flags */static volatile sig_atomic_t bb_todo = 0;/* own global variables */static Mutex *status_mutex;static time_t start_time;volatile sig_atomic_t restart = 0;/* to avoid copied code */static void set_shutdown_status(void){ sig_atomic_t old = bb_status; bb_status = BB_SHUTDOWN; if (old == BB_SUSPENDED) list_remove_producer(suspended); if (old == BB_SUSPENDED || old == BB_ISOLATED) list_remove_producer(isolated);}/*------------------------------------------------------- * signals */static void signal_handler(int signum){ /* On some implementations (i.e. linuxthreads), signals are delivered * to all threads. We only want to handle each signal once for the * entire box, and we let the gwthread wrapper take care of choosing * one. */ if (!gwthread_shouldhandlesignal(signum)) return; switch (signum) { case SIGINT: case SIGTERM: if (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) { bb_status = BB_SHUTDOWN; } else if (bb_status == BB_SHUTDOWN) { bb_status = BB_DEAD; } else if (bb_status == BB_DEAD) { panic(0, "Cannot die by its own will"); } break; case SIGHUP: bb_todo |= BB_LOGREOPEN; break; /* * It would be more proper to use SIGUSR1 for this, but on some * platforms that's reserved by the pthread support. */ case SIGQUIT: bb_todo |= BB_CHECKLEAKS; break; }}static void setup_signal_handlers(void){ struct sigaction act; act.sa_handler = signal_handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); sigaction(SIGQUIT, &act, NULL); sigaction(SIGHUP, &act, NULL); sigaction(SIGPIPE, &act, NULL);}/*-------------------------------------------------------- * functions to start/init sub-parts of the bearerbox * * these functions are NOT thread safe but they have no need to be, * as there is only one core bearerbox thread */static int start_smsc(Cfg *cfg){ static int started = 0; if (started) return 0; smsbox_start(cfg); smsc2_start(cfg); started = 1; return 0;}static void wdp_router(void *arg){ Msg *msg; list_add_producer(flow_threads); while(bb_status != BB_DEAD) { if ((msg = list_consume(outgoing_wdp)) == NULL) break; gw_assert(msg_type(msg) == wdp_datagram); /* if (msg->list == sms) smsc_addwdp(msg); else */ udp_addwdp(msg); } udp_die(); /* smsc_endwdp(); */ list_remove_producer(flow_threads);}static int start_wap(Cfg *cfg){ static int started = 0; if (started) return 0; wapbox_start(cfg); debug("bb", 0, "starting WDP router"); if (gwthread_create(wdp_router, NULL) == -1) panic(0, "Failed to start a new thread for WDP routing"); started = 1; return 0;}static int start_udp(Cfg *cfg){ static int started = 0; if (started) return 0; udp_start(cfg); start_wap(cfg); started = 1; return 0;}/* * check that there is basic thingies in configuration */static int check_config(Cfg *cfg){ CfgGroup *grp; long smsp, wapp; grp = cfg_get_single_group(cfg, octstr_imm("core")); if (grp == NULL) return -1; if (cfg_get_integer(&smsp, grp, octstr_imm("smsbox-port")) == -1) smsp = -1; if (cfg_get_integer(&wapp, grp, octstr_imm("wapbox-port")) == -1) wapp = -1; #ifndef NO_SMS grp = cfg_get_single_group(cfg, octstr_imm("smsbox")); if (smsp != -1 && grp == NULL) { error(0, "No 'smsbox' group in configuration, but smsbox-port set"); return -1; }#endif #ifndef NO_WAP grp = cfg_get_single_group(cfg, octstr_imm("wapbox")); if (wapp != -1 && grp == NULL) { error(0, "No 'wapbox' group in configuration, but wapbox-port set"); return -1; }#endif return 0;}/* * check our own variables */static int check_args(int i, int argc, char **argv) { if (strcmp(argv[i], "-S")==0 || strcmp(argv[i], "--suspended")==0) bb_status = BB_SUSPENDED; else if (strcmp(argv[i], "-I")==0 || strcmp(argv[i], "--isolated")==0) bb_status = BB_ISOLATED; else return -1; return 0;}static Cfg *init_bearerbox(Cfg *cfg){ CfgGroup *grp; Octstr *log, *val; long loglevel; int lf, m;#ifdef HAVE_LIBSSL Octstr *ssl_server_cert_file; Octstr *ssl_server_key_file; int ssl_enabled = 0;#endif /* HAVE_LIBSSL */ /* defaults: use localtime and markers for access-log */ lf = m = 1; grp = cfg_get_single_group(cfg, octstr_imm("core")); log = cfg_get(grp, octstr_imm("log-file")); if (log != NULL) { if (cfg_get_integer(&loglevel, grp, octstr_imm("log-level")) == -1) loglevel = 0; log_open(octstr_get_cstr(log), loglevel, GW_NON_EXCL); octstr_destroy(log); } if (check_config(cfg) == -1) panic(0, "Cannot start with corrupted configuration"); /* determine which timezone we use for access logging */ if ((log = cfg_get(grp, octstr_imm("access-log-time"))) != NULL) { lf = (octstr_case_compare(log, octstr_imm("gmt")) == 0) ? 0 : 1; octstr_destroy(log); } /* should predefined markers be used, ie. prefixing timestamp */ cfg_get_bool(&m, grp, octstr_imm("access-log-clean")); /* custom access-log format */ if ((log = cfg_get(grp, octstr_imm("access-log-format"))) != NULL) { bb_alog_init(log); octstr_destroy(log); } /* open access-log file */ if ((log = cfg_get(grp, octstr_imm("access-log"))) != NULL) { alog_open(octstr_get_cstr(log), lf, m ? 0 : 1); octstr_destroy(log); } log = cfg_get(grp, octstr_imm("store-file")); /* initialize the store file */ if (log != NULL) { store_init(log); octstr_destroy(log); } conn_config_ssl (grp); /* * Make sure we have "ssl-server-cert-file" and "ssl-server-key-file" specified * in the core group since we need it to run SSL-enabled internal box * connections configured via "smsbox-port-ssl = yes" and "wapbox-port-ssl = yes". * Check only these, because for "admin-port-ssl" and "sendsms-port-ssl" for the * SSL-enabled HTTP servers are probed within gw/bb_http.c:httpadmin_start() */#ifdef HAVE_LIBSSL ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file")); ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file")); if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) { /* we are fine, at least files are specified in the configuration */ } else { cfg_get_bool(&ssl_enabled, grp, octstr_imm("smsbox-port-ssl")); cfg_get_bool(&ssl_enabled, grp, octstr_imm("wapbox-port-ssl")); if (ssl_enabled) { panic(0, "You MUST specify cert and key files within core group for SSL-enabled inter-box connections!"); } } octstr_destroy(ssl_server_cert_file); octstr_destroy(ssl_server_key_file);#endif /* HAVE_LIBSSL */ /* if all seems to be OK by the first glimpse, real start-up */ outgoing_sms = list_create(); incoming_sms = list_create(); outgoing_wdp = list_create(); incoming_wdp = list_create(); outgoing_sms_counter = counter_create(); incoming_sms_counter = counter_create(); outgoing_wdp_counter = counter_create(); incoming_wdp_counter = counter_create(); status_mutex = mutex_create(); setup_signal_handlers(); /* http-admin is REQUIRED */ httpadmin_start(cfg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -