bearerbox.c

来自「mms client」· C语言 代码 · 共 730 行 · 第 1/2 页

C
730
字号
/* * 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 "sms.h"#include "bearerbox.h"#include "wapbox.h"#include "shared.h"#include "dlr.h"#include "smscconn.h"/* global variables; included to other modules as needed */List *incoming_sms;List *outgoing_sms;List *incoming_wdp;List *outgoing_wdp;List *sms8bitreassembly;Counter *incoming_sms_counter;Counter *outgoing_sms_counter;Counter *incoming_wdp_counter;Counter *outgoing_wdp_counter;SMSCConn *modemConn;/* 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;/* own global variables */static Mutex *status_mutex;Mutex *boxid_mutex;static time_t start_time;/* 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:            mutex_lock(status_mutex);            if (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {                warning(0, "Killing signal received, shutting down...");                mutex_unlock(status_mutex);                bb_shutdown();                return;            } else if (bb_status == BB_SHUTDOWN) {                warning(0, "New killing signal received, killing neverthless...");                bb_status = BB_DEAD;            } else if (bb_status == BB_DEAD) {                panic(0, "cannot die by its own will");            }            mutex_unlock(status_mutex);            break;        case SIGHUP:            warning(0, "SIGHUP received, catching and re-opening logs");            log_reopen();            alog_reopen();            store_load();            break;            /*              * It would be more proper to use SIGUSR1 for this, but on some             * platforms that's reserved by the pthread support.              */        case SIGQUIT:            warning(0, "SIGQUIT received, reporting memory usage.");            gw_check_leaks();            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, outgoing_sms, incoming_sms);    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, outgoing_wdp, incoming_wdp);    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;    grp = cfg_get_single_group(cfg, octstr_imm("core"));    if (grp == NULL)        return -1;        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;#ifdef HAVE_LIBSSL    Octstr *ssl_server_cert_file;    Octstr *ssl_server_key_file;    int ssl_enabled = 0;#endif /* HAVE_LIBSSL */    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);        octstr_destroy(log);    }    if (check_config(cfg) == -1)        panic(0, "Cannot start with corrupted configuration");    log = cfg_get(grp, octstr_imm("access-log"));    if (log != NULL) {        alog_open(octstr_get_cstr(log), 1);        /* use localtime; XXX let user choose that */        octstr_destroy(log);    }    log = cfg_get(grp, octstr_imm("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();    sms8bitreassembly = 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();    boxid_mutex = mutex_create();    setup_signal_handlers();    /* http-admin is REQUIRED */    httpadmin_start(cfg);    {        List *list;        list = cfg_get_multi_group(cfg, octstr_imm("smsc"));        if (list != NULL) {            start_smsc(cfg);            list_destroy(list, NULL);        }    }    grp = cfg_get_single_group(cfg, octstr_imm("core"));    val = cfg_get(grp, octstr_imm("wdp-interface-name"));    if (val != NULL && octstr_len(val) > 0)        start_udp(cfg);    octstr_destroy(val);    /* always start wap */    start_wap(cfg);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?