From b7bd482849a2a3d640977cfd0cb7d6446923e40a Mon Sep 17 00:00:00 2001 From: bagyenda <> Date: Fri, 29 Aug 2008 10:23:17 +0000 Subject: [PATCH] misc changes --- mbuni/ChangeLog | 3 + mbuni/doc/userguide.shtml | 28 +++ mbuni/mmsbox/bearerbox.c | 2 + mbuni/mmsbox/mmsbox.c | 11 +- mbuni/mmsbox/mmsbox_cfg.c | 455 ++++++++++++++++++++++++-------------- mbuni/mmsbox/mmsbox_cfg.h | 22 +- 6 files changed, 349 insertions(+), 172 deletions(-) diff --git a/mbuni/ChangeLog b/mbuni/ChangeLog index 7e25a22..d44f812 100644 --- a/mbuni/ChangeLog +++ b/mbuni/ChangeLog @@ -1,3 +1,6 @@ +2008-08-29 P. A. Bagyenda + * Changes to doc for config from DLL + * Misc. code re-ordering for mmsbox 2008-08-28 P. A. Bagyenda * Added ability to load config from a module rather than from file 2008-08-20 P. A. Bagyenda diff --git a/mbuni/doc/userguide.shtml b/mbuni/doc/userguide.shtml index b324dcd..b97eb66 100644 --- a/mbuni/doc/userguide.shtml +++ b/mbuni/doc/userguide.shtml @@ -568,6 +568,34 @@ character syntax works inside quotation marks.

The variable group marks the beginning of a new group with the given name.

+Configuring Mbuni using a Loadable Module +

Mbuni supports configuration using a dynmically linked module. + This is particularly useful if you wish to configure Mbuni from a + database or a script.

+ In order to do this, the first (and only) group in the config file + must be a config-source group. An example is shown below: +

+ + +group = config-source
+config-library = path_to_dll
+config-library-init-param = init_param_for_dynamic_lib
+
+

+Mbuni will load the supplied DLL and get all subsequent configuration +parameters from the module. (See mms_cfg-imp.h for DLL requirements.) + +

+ +

+ +Configuration Items +

+If not using a module as configuration source, +the config-source group must not exist. The rest of the +configuration file must have the format as described above. Groups +and respective items are described below. +

The core group is core and defines the log file location, log level (amount of debugging information – the lower the number the more debugging diff --git a/mbuni/mmsbox/bearerbox.c b/mbuni/mmsbox/bearerbox.c index da9b16d..aa30d9f 100644 --- a/mbuni/mmsbox/bearerbox.c +++ b/mbuni/mmsbox/bearerbox.c @@ -985,6 +985,7 @@ static int sendMsg(MmsEnvelope *e) &new_msgid, &err); + return_mmsc_conn(mmc); /* important. */ done: if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) { to->process = 0; @@ -1029,6 +1030,7 @@ done2: if (qfs->mms_queue_update(e) != 1) qfs->mms_queue_free_env(e); } + return 1; /* always delete queue entry. */ } diff --git a/mbuni/mmsbox/mmsbox.c b/mbuni/mmsbox/mmsbox.c index 9ee8240..6b7fbcd 100644 --- a/mbuni/mmsbox/mmsbox.c +++ b/mbuni/mmsbox/mmsbox.c @@ -31,8 +31,6 @@ int rstop = 0; static void quit_now(int notused) { - int i, n; - MmscGrp *mmc; rstop = 1; info(0, "shutdown in progress..."); @@ -40,14 +38,7 @@ static void quit_now(int notused) if (sendmms_port.port > 0) http_close_port(sendmms_port.port); - for (i = 0, n = gwlist_len(mmscs); i < n; i++) - if ((mmc = gwlist_get(mmscs, i)) != NULL) { - if (mmc->type == CUSTOM_MMSC && mmc->fns && mmc->custom_started) { - mmc->fns->stop_conn(mmc->data); - mmc->custom_started = 0; - } else if (mmc->incoming.port > 0) - http_close_port(mmc->incoming.port); - } + mmsbox_stop_all_mmsc_conn(); } /* manage the SIGHUP signal */ diff --git a/mbuni/mmsbox/mmsbox_cfg.c b/mbuni/mmsbox/mmsbox_cfg.c index 645ab27..1f357e8 100644 --- a/mbuni/mmsbox/mmsbox_cfg.c +++ b/mbuni/mmsbox/mmsbox_cfg.c @@ -24,9 +24,10 @@ #include "mms_queue.h" #include "mmsbox_resolve_shell.h" +#define WAIT_TIME 0.2 + List *sendmms_users = NULL; /* list of SendMmsUser structs */ List *mms_services = NULL; /* list of MMS Services */ -List *mmscs = NULL; Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir; long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry; long maxthreads = 0; @@ -42,15 +43,22 @@ MmsBoxResolverFuncStruct *rfs; /* resolver functions. */ void *rfs_data; Octstr *rfs_settings; + +static Dict *mmscs = NULL; /* MMSC's indexed by ID. */ + struct SendMmsPortInfo sendmms_port; struct MmsBoxMTfilter *mt_filter = NULL; +static void free_mmsc_struct (MmscGrp *m); +static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func); +static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc); int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func) { mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni")); mCfgGrp *cgrp = mms_cfg_get_single(cfg, octstr_imm("core")); - Octstr *gdir = NULL, *s, *tmp; + Octstr *gdir = NULL, *s; + int send_port_ssl = 0; List *l; int i, n, xx; @@ -63,7 +71,7 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func) sendmms_users = gwlist_create(); mms_services = gwlist_create(); - mmscs = gwlist_create(); + mmscs = dict_create(101, NULL); if (mms_cfg_get_int(cfg, grp, octstr_imm("maximum-send-attempts"), &mmsbox_maxsendattempts) < 0) @@ -190,148 +198,9 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func) /* Get mmsc list. */ l = mms_cfg_get_multi(cfg, octstr_imm("mmsc")); - for (i = 0, n = gwlist_len(l); i < n; i++) { - mCfgGrp *x = gwlist_get(l, i); - MmscGrp *m = gw_malloc(sizeof *m); - int ssl = 0; - Octstr *type; - Octstr *xver; - Octstr *s; - - memset(m, 0, sizeof *m); - - m->id = _mms_cfg_getx(cfg, x, octstr_imm("id")); - if (octstr_len(m->id) < 1) - panic(0,"Missing required value `id' in config file!"); - m->group_id = mms_cfg_get(cfg, x, octstr_imm("group-id")); - if (m->group_id == NULL) - m->group_id = octstr_duplicate(m->id); - - m->mmsc_url = _mms_cfg_getx(cfg, x, octstr_imm("mmsc-url")); - - m->allowed_prefix = mms_cfg_get(cfg, x, octstr_imm("allowed-prefix")); - m->denied_prefix = mms_cfg_get(cfg, x, octstr_imm("denied-prefix")); - - m->allowed_sender_prefix = mms_cfg_get(cfg, x, octstr_imm("allowed-sender-prefix")); - m->denied_sender_prefix = mms_cfg_get(cfg, x, octstr_imm("denied-sender-prefix")); - - m->incoming.allow_ip = mms_cfg_get(cfg, x, octstr_imm("allow-ip")); - m->incoming.deny_ip = mms_cfg_get(cfg, x, octstr_imm("deny-ip")); - - info(0, "MMSC[%s], allow=[%s], deny=[%s] group_id=[%s]", - octstr_get_cstr(m->id), - octstr_get_cstr(m->incoming.allow_ip), - octstr_get_cstr(m->incoming.deny_ip), - octstr_get_cstr(m->group_id)); - - m->incoming.user = _mms_cfg_getx(cfg, x, octstr_imm("incoming-username")); - m->incoming.pass = _mms_cfg_getx(cfg, x, octstr_imm("incoming-password")); - mms_cfg_get_int(cfg, x, octstr_imm("incoming-port"), &m->incoming.port); -#ifdef HAVE_LIBSSL - mms_cfg_get_bool(cfg, x, octstr_imm("incoming-port-ssl"), &ssl); -#endif - if ((tmp = mms_cfg_get(cfg, x, octstr_imm("max-throughput"))) != NULL) { - if (octstr_parse_double(&m->throughput, tmp, 0) == -1) - m->throughput = 0; - info(0, "Set throughput to %.3f for mmsc id <%s>", - m->throughput, octstr_get_cstr(m->id)); - octstr_destroy(tmp); - } - - type = _mms_cfg_getx(cfg, x, octstr_imm("type")); - if (octstr_case_compare(type, octstr_imm("eaif")) == 0) - m->type = EAIF_MMSC; - else if (octstr_case_compare(type, octstr_imm("soap")) == 0) - m->type = SOAP_MMSC; - else if (octstr_case_compare(type, octstr_imm("custom")) == 0) { - m->type = CUSTOM_MMSC; - m->settings = _mms_cfg_getx(cfg, x, octstr_imm("custom-settings")); - /* also load the libary. */ - if ((m->fns = _mms_load_module(cfg, x, "mmsc-library", "mmsc_funcs", NULL)) == NULL) - panic(0, "failed to load MMSC libary functions from module!"); - } else - warning(0, "MMSBox: Unknown MMSC type [%s]!", - octstr_get_cstr(type)); - if ((xver = _mms_cfg_getx(cfg, x, octstr_imm("mm7-version"))) != NULL && - octstr_len(xver) > 0) - sscanf(octstr_get_cstr(xver), - "%d.%d.%d", - &m->ver.major, &m->ver.minor1, &m->ver.minor2); - else { /* Put in some defaults. */ - if (m->type == SOAP_MMSC) { - m->ver.major = MAJOR_VERSION(DEFAULT_MM7_VERSION); - m->ver.minor1 = MINOR1_VERSION(DEFAULT_MM7_VERSION); - m->ver.minor2 = MINOR2_VERSION(DEFAULT_MM7_VERSION); - } else if (m->type == EAIF_MMSC) { - m->ver.major = 3; - m->ver.minor1 = 0; - } - } - - if ((s = mms_cfg_get(cfg, x, octstr_imm("mm7-soap-xmlns"))) != NULL) { - strncpy(m->ver.xmlns, octstr_get_cstr(s), sizeof m->ver.xmlns); - m->ver.xmlns[-1 + sizeof m->ver.xmlns] = 0; /* NULL terminate, just in case. */ - octstr_destroy(s); - } else - m->ver.xmlns[0] = 0; - - m->ver.use_mm7_namespace = 1; - mms_cfg_get_bool(cfg, x, octstr_imm("use-mm7-soap-namespace-prefix"), &m->ver.use_mm7_namespace); - - octstr_destroy(xver); - octstr_destroy(type); - - /* Init for filter. */ - if ((s = mms_cfg_get(cfg, x, octstr_imm("mm7-mt-filter-params"))) != NULL) { - if (mt_filter) - m->use_mt_filter = (mt_filter->init(m->mmsc_url, m->id, s) == 1); - else - panic(0, "MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib " - "specified!", - octstr_get_cstr(m->id)); - if (!m->use_mt_filter) - warning(0, "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed", - octstr_get_cstr(m->id)); - octstr_destroy(s); - } else - m->use_mt_filter = 0; - - mms_cfg_get_bool(cfg, x, octstr_imm("reroute"), &m->reroute); - mms_cfg_get_bool(cfg, x, octstr_imm("reroute-add-sender-to-subject"), &m->reroute_mod_subject); - m->reroute_mmsc_id = mms_cfg_get(cfg, x, octstr_imm("reroute-mmsc-id")); - if (m->reroute_mmsc_id != NULL && m->reroute == 0) - warning(0, "MMSBox: reroute-mmsc-id parameter set but reroute=false!"); - - mms_cfg_get_bool(cfg, x, octstr_imm("no-sender-address"), &m->no_senderaddress); - m->mutex = mutex_create(); - - /* finally start the thingie. */ - if (m->type == CUSTOM_MMSC) { - if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) { - warning(0, "MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id)); - m->custom_started = 0; - } else - m->custom_started = 1; - } else { - if (m->incoming.port > 0 && - http_open_port(m->incoming.port, ssl) < 0) { - warning(0, "MMSBox: Failed to start HTTP server on receive port for " - " MMSC %s, port %ld: %s!", - octstr_get_cstr(m->id), m->incoming.port, - strerror(errno)); - m->incoming.port = 0; /* so we don't listen on it. */ - } - - if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */ - if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0) - error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!", - octstr_get_cstr(m->id), strerror(errno)); - } else - m->threadid = -1; - } - - gwlist_append(mmscs, m); - } + for (i = 0, n = gwlist_len(l); i < n; i++) + start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func); + gwlist_destroy(l, NULL); @@ -480,31 +349,260 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func) return 0; } +/* do nothing func. */ +static int do_nothing_func (void) {return 0;} + +static MmsBoxMmscFuncs dummy_mmsc_funcs = { + (void *)do_nothing_func, + (void *)do_nothing_func, + (void *)do_nothing_func +}; + +void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func) +{ + + MmscGrp *m = gw_malloc(sizeof *m); + int ssl = 0; + Octstr *type, *tmp; + Octstr *xver; + Octstr *s; + + memset(m, 0, sizeof *m); + + m->id = _mms_cfg_getx(cfg, x, octstr_imm("id")); + if (octstr_len(m->id) < 1) { + error(0,"mmsbox.mmsc_config: Missing required field value `id' in config file!"); + octstr_destroy(m->id); + gw_free(m); + + return; + } + + m->group_id = mms_cfg_get(cfg, x, octstr_imm("group-id")); + if (m->group_id == NULL) + m->group_id = octstr_duplicate(m->id); + + m->mmsc_url = _mms_cfg_getx(cfg, x, octstr_imm("mmsc-url")); + + m->allowed_prefix = mms_cfg_get(cfg, x, octstr_imm("allowed-prefix")); + m->denied_prefix = mms_cfg_get(cfg, x, octstr_imm("denied-prefix")); + + m->allowed_sender_prefix = mms_cfg_get(cfg, x, octstr_imm("allowed-sender-prefix")); + m->denied_sender_prefix = mms_cfg_get(cfg, x, octstr_imm("denied-sender-prefix")); + + m->incoming.allow_ip = mms_cfg_get(cfg, x, octstr_imm("allow-ip")); + m->incoming.deny_ip = mms_cfg_get(cfg, x, octstr_imm("deny-ip")); + + info(0, "Loaded MMSC[%s], allow=[%s], deny=[%s] group_id=[%s]", + octstr_get_cstr(m->id), + octstr_get_cstr(m->incoming.allow_ip), + octstr_get_cstr(m->incoming.deny_ip), + octstr_get_cstr(m->group_id)); + + m->incoming.user = _mms_cfg_getx(cfg, x, octstr_imm("incoming-username")); + m->incoming.pass = _mms_cfg_getx(cfg, x, octstr_imm("incoming-password")); + mms_cfg_get_int(cfg, x, octstr_imm("incoming-port"), &m->incoming.port); +#ifdef HAVE_LIBSSL + mms_cfg_get_bool(cfg, x, octstr_imm("incoming-port-ssl"), &ssl); +#endif + if ((tmp = mms_cfg_get(cfg, x, octstr_imm("max-throughput"))) != NULL) { + if (octstr_parse_double(&m->throughput, tmp, 0) == -1) + m->throughput = 0; + info(0, "Set throughput to %.3f for mmsc id <%s>", + m->throughput, octstr_get_cstr(m->id)); + octstr_destroy(tmp); + } + + type = _mms_cfg_getx(cfg, x, octstr_imm("type")); + if (octstr_case_compare(type, octstr_imm("eaif")) == 0) + m->type = EAIF_MMSC; + else if (octstr_case_compare(type, octstr_imm("soap")) == 0) + m->type = SOAP_MMSC; + else if (octstr_case_compare(type, octstr_imm("custom")) == 0) { + m->type = CUSTOM_MMSC; + m->settings = _mms_cfg_getx(cfg, x, octstr_imm("custom-settings")); + /* also load the libary. */ + if ((m->fns = _mms_load_module(cfg, x, "mmsc-library", "mmsc_funcs", NULL)) == NULL) { + error(0, "failed to load MMSC libary functions from module!"); + m->fns = &dummy_mmsc_funcs; + } + } else + warning(0, "MMSBox: Unknown MMSC type [%s]!", + octstr_get_cstr(type)); + if ((xver = _mms_cfg_getx(cfg, x, octstr_imm("mm7-version"))) != NULL && + octstr_len(xver) > 0) + sscanf(octstr_get_cstr(xver), + "%d.%d.%d", + &m->ver.major, &m->ver.minor1, &m->ver.minor2); + else { /* Put in some defaults. */ + if (m->type == SOAP_MMSC) { + m->ver.major = MAJOR_VERSION(DEFAULT_MM7_VERSION); + m->ver.minor1 = MINOR1_VERSION(DEFAULT_MM7_VERSION); + m->ver.minor2 = MINOR2_VERSION(DEFAULT_MM7_VERSION); + } else if (m->type == EAIF_MMSC) { + m->ver.major = 3; + m->ver.minor1 = 0; + } + } + + if ((s = mms_cfg_get(cfg, x, octstr_imm("mm7-soap-xmlns"))) != NULL) { + strncpy(m->ver.xmlns, octstr_get_cstr(s), sizeof m->ver.xmlns); + m->ver.xmlns[-1 + sizeof m->ver.xmlns] = 0; /* NULL terminate, just in case. */ + octstr_destroy(s); + } else + m->ver.xmlns[0] = 0; + + m->ver.use_mm7_namespace = 1; + mms_cfg_get_bool(cfg, x, octstr_imm("use-mm7-soap-namespace-prefix"), &m->ver.use_mm7_namespace); + + octstr_destroy(xver); + octstr_destroy(type); + + /* Init for filter. */ + if ((s = mms_cfg_get(cfg, x, octstr_imm("mm7-mt-filter-params"))) != NULL) { + if (mt_filter) + m->use_mt_filter = (mt_filter->init(m->mmsc_url, m->id, s) == 1); + else + panic(0, "MMSBox: mt-filter-params set for MMSC[%s] but no MT-filter lib " + "specified!", + octstr_get_cstr(m->id)); + if (!m->use_mt_filter) + warning(0, "MMSBox: MT MMS filter turned off for MMSC[%s]. Init failed", + octstr_get_cstr(m->id)); + octstr_destroy(s); + } else + m->use_mt_filter = 0; + + mms_cfg_get_bool(cfg, x, octstr_imm("reroute"), &m->reroute); + mms_cfg_get_bool(cfg, x, octstr_imm("reroute-add-sender-to-subject"), &m->reroute_mod_subject); + m->reroute_mmsc_id = mms_cfg_get(cfg, x, octstr_imm("reroute-mmsc-id")); + if (m->reroute_mmsc_id != NULL && m->reroute == 0) + warning(0, "MMSBox: reroute-mmsc-id parameter set but reroute=false!"); + + mms_cfg_get_bool(cfg, x, octstr_imm("no-sender-address"), &m->no_senderaddress); + m->mutex = mutex_create(); + m->incoming.ssl = ssl; + + /* finally start the thingie. */ + mmsbox_start_mmsc_conn(m, mmsc_handler_func); + if (dict_put_once(mmscs, m->id, m) == 0) { + error(0, "Failed to load mmsc <%s>. ID is not unique!", octstr_get_cstr(m->id)); + mmsbox_stop_mmsc_conn_real(m); + free_mmsc_struct(m); + } +} + +static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func) +{ + if (m->type == CUSTOM_MMSC) { + if (m->fns->start_conn(m, qfs, unified_prefix, strip_prefixes, &m->data) != 0) { + warning(0, "MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id)); + m->custom_started = 0; + } else + m->custom_started = 1; + } else { + if (m->incoming.port > 0 && + http_open_port(m->incoming.port, m->incoming.ssl) < 0) { + warning(0, "MMSBox: Failed to start HTTP server on receive port for " + " MMSC %s, port %ld: %s!", + octstr_get_cstr(m->id), m->incoming.port, + strerror(errno)); + m->incoming.port = 0; /* so we don't listen on it. */ + } + + if (mmsc_handler_func && m->incoming.port > 0) { /* Only start threads if func passed and ... */ + if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0) + error(0, "MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!", + octstr_get_cstr(m->id), strerror(errno)); + } else + m->threadid = -1; + } + + info(0, "Startup for mmsc [%s] complete", octstr_get_cstr(m->id)); +} + +static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc) +{ + + if (mmc->type == CUSTOM_MMSC && mmc->fns + && mmc->custom_started) { + mmc->fns->stop_conn(mmc->data); + mmc->custom_started = 0; + } else if (mmc->incoming.port > 0) { + http_close_port(mmc->incoming.port); + if (mmc->threadid >= 0) + gwthread_join(mmc->threadid); + mmc->threadid = -1; + } + info(0, "Shutdown for mmsc [%s] complete", octstr_get_cstr(mmc->id)); +} + +void mmsbox_stop_mmsc_conn(Octstr *mmc_id) +{ + MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */ + + if (mmc == NULL) + return; + + mmsbox_stop_mmsc_conn_real(mmc); + + while (mmc->use_count > 0) /* wait for use count to reach 0, then delete it. */ + gwthread_sleep(WAIT_TIME); + + free_mmsc_struct(mmc); +} + +void mmsbox_stop_all_mmsc_conn(void) +{ + Octstr *mmc; + List *l = dict_keys(mmscs); + + while ((mmc = gwlist_extract_first(l)) != NULL) { + info(0, "Stopping MMSC [%s]", octstr_get_cstr(mmc)); + mmsbox_stop_mmsc_conn(mmc); + octstr_destroy(mmc); + } + + gwlist_destroy(l, NULL); +} + /* Get the MMC that should handler this recipient. */ MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from) { - MmscGrp *mmc = NULL, *res = NULL; - int i, n; + MmscGrp *res = NULL; + int i, n, not_number; Octstr *phonenum = NULL, *xfrom = NULL; + List *l; + + if (id) { /* If ID is set, use it. */ + res = dict_get(mmscs, id); + goto done; + } - if (id) /* If ID is set, use it. */ - for (i = 0, n = gwlist_len(mmscs); i < n; i++) - if ((mmc = gwlist_get(mmscs, i)) != NULL && - mmc->id && octstr_compare(mmc->id, id) == 0) - return mmc; - - if (octstr_search_char(to, '@', 0) > 0 || - octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0) > 0) /* For emails, or ip take first mmsc. */ - return gwlist_get(mmscs, 0); + l = dict_keys(mmscs); + + not_number = (octstr_search_char(to, '@', 0) > 0 || + octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0) > 0); /* now try allow/deny stuff. */ phonenum = extract_phonenum(to, unified_prefix); xfrom = extract_phonenum(from, NULL); - for (i = 0, n = gwlist_len(mmscs); i < n; i++) { - if ((mmc = gwlist_get(mmscs, i)) == NULL) - continue; + for (i = 0, n = gwlist_len(l); i < n; i++) { + MmscGrp *mmc = dict_get(mmscs,gwlist_get(l, i)); + + if (mmc == NULL) + continue; /* mmsc not there anymore. */ + if (not_number && + mmc->allowed_prefix == NULL && + mmc->denied_prefix == NULL && + mmc->allowed_sender_prefix == NULL && + mmc->denied_sender_prefix == NULL) + goto loop; + else if (not_number) /* don't do tests below if not number. */ + continue; + if (mmc->allowed_prefix && does_prefix_match(mmc->allowed_prefix, phonenum) == 0) continue; /* does not match. */ @@ -521,16 +619,27 @@ MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from) does_prefix_match(mmc->denied_sender_prefix, xfrom) != 0) continue; /* matches. */ + loop: res = mmc; /* otherwise it matches, so go away. */ break; } octstr_destroy(phonenum); octstr_destroy(xfrom); - + + gwlist_destroy(l, (void *)octstr_destroy); + +done: + if (res) + MMSBOX_MMSC_MARK_INUSE(res); /* Vital! */ return res; } +void return_mmsc_conn(MmscGrp *m) +{ + if (m) + MMSBOX_MMSC_UNMARK_INUSE(m); /* Vital! */ +} /* handle message routing. */ Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m, Octstr **mmc_id) @@ -608,3 +717,29 @@ void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh) if (freeh) gw_free(h); } + +static void free_mmsc_struct (MmscGrp *m) +{ + + gw_assert(m->use_count == 0); + + octstr_destroy(m->id); + octstr_destroy(m->group_id); + octstr_destroy(m->mmsc_url); + + octstr_destroy(m->incoming.user); + octstr_destroy(m->incoming.pass); + octstr_destroy(m->incoming.allow_ip); + octstr_destroy(m->incoming.deny_ip); + octstr_destroy(m->allowed_prefix); + octstr_destroy(m->denied_prefix); + octstr_destroy(m->allowed_sender_prefix); + octstr_destroy(m->denied_sender_prefix); + + octstr_destroy(m->reroute_mmsc_id); + + octstr_destroy(m->settings); + mutex_destroy(m->mutex); + + gw_free(m); +} diff --git a/mbuni/mmsbox/mmsbox_cfg.h b/mbuni/mmsbox/mmsbox_cfg.h index d8416b5..00100d3 100644 --- a/mbuni/mmsbox/mmsbox_cfg.h +++ b/mbuni/mmsbox/mmsbox_cfg.h @@ -28,6 +28,7 @@ typedef struct MmscGrp { Octstr *allow_ip; Octstr *deny_ip; long port; + int ssl; } incoming; /* user, pass, port (and whether SSL) that MMSC uses to connect to us. */ Octstr *allowed_prefix, *denied_prefix; Octstr *allowed_sender_prefix, *denied_sender_prefix; @@ -47,8 +48,23 @@ typedef struct MmscGrp { Octstr *settings; /* settings for the above module. */ void *data; /* data for above module. */ int custom_started; /* set to 1 if custom mmc started. */ + + int use_count; /* use counter. */ } MmscGrp; +#define MMSBOX_MMSC_MARK_INUSE(mmc) do {\ + mutex_lock((mmc)->mutex); \ + (mmc)->use_count++; \ + mutex_unlock(mmc->mutex); \ + } while (0) + +#define MMSBOX_MMSC_UNMARK_INUSE(mmc) do {\ + mutex_lock((mmc)->mutex); \ + (mmc)->use_count--; \ + mutex_unlock(mmc->mutex); \ + } while (0) + + typedef struct MmsServiceUrlParam { Octstr *name; enum {NO_PART, AUDIO_PART, IMAGE_PART, VIDEO_PART, @@ -91,7 +107,6 @@ typedef struct SendMmsUser { /* Basic settings for the mmsbox. */ extern List *sendmms_users; /* list of SendMmsUser structs */ extern List *mms_services; /* list of MMS Services */ -extern List *mmscs; /* MMSC list. Perhaps turn into a Dict instead? */ extern Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir; extern Octstr *unified_prefix; extern Octstr *sendmail_cmd; @@ -117,11 +132,14 @@ extern Octstr *rfs_settings; extern int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func); extern MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from); +extern void return_mmsc_conn(MmscGrp *m); extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m, Octstr **mmc_id); extern void mmsbox_cleanup_settings(void); - +void start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func); +void mmsbox_stop_mmsc_conn(Octstr *mmc); +void mmsbox_stop_all_mmsc_conn(void); typedef struct MmsBoxHTTPClientInfo { HTTPClient *client; Octstr *ua;