misc changes
This commit is contained in:
parent
c6591fc15b
commit
b7bd482849
|
@ -1,3 +1,6 @@
|
||||||
|
2008-08-29 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
* Changes to doc for config from DLL
|
||||||
|
* Misc. code re-ordering for mmsbox
|
||||||
2008-08-28 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2008-08-28 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
* Added ability to load config from a module rather than from file
|
* Added ability to load config from a module rather than from file
|
||||||
2008-08-20 P. A. Bagyenda <bagyenda@dsmagic.com>
|
2008-08-20 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||||
|
|
|
@ -568,6 +568,34 @@ character syntax works inside quotation marks.</p>
|
||||||
<p >The variable <i>group</i> marks the
|
<p >The variable <i>group</i> marks the
|
||||||
beginning of a new group with the given name.</p>
|
beginning of a new group with the given name.</p>
|
||||||
|
|
||||||
|
<b>Configuring Mbuni using a Loadable Module</b>
|
||||||
|
<p>Mbuni supports configuration using a dynmically linked module.
|
||||||
|
This is particularly useful if you wish to configure Mbuni from a
|
||||||
|
database or a script. <br/><br/>
|
||||||
|
In order to do this, the first (and only) group in the config file
|
||||||
|
must be a <tt>config-source</tt> group. An example is shown below:
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
<tt>
|
||||||
|
group = config-source<br>
|
||||||
|
config-library = <i>path_to_dll</i><br>
|
||||||
|
config-library-init-param = <i>init_param_for_dynamic_lib</i><br>
|
||||||
|
</tt>
|
||||||
|
<br><br>
|
||||||
|
Mbuni will load the supplied DLL and get all subsequent configuration
|
||||||
|
parameters from the module. (See <tt>mms_cfg-imp.h</tt> for DLL requirements.)
|
||||||
|
|
||||||
|
<br><br>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<b>Configuration Items</b>
|
||||||
|
<p>
|
||||||
|
If not using a module as configuration source,
|
||||||
|
the <tt>config-source</tt> group must not exist. The rest of the
|
||||||
|
configuration file must have the format as described above. Groups
|
||||||
|
and respective items are described below.
|
||||||
|
</p>
|
||||||
<p >The core group is
|
<p >The core group is
|
||||||
<i>core</i> and defines the log file location, log level (amount of debugging
|
<i>core</i> and defines the log file location, log level (amount of debugging
|
||||||
information – the lower the number the more debugging
|
information – the lower the number the more debugging
|
||||||
|
|
|
@ -985,6 +985,7 @@ static int sendMsg(MmsEnvelope *e)
|
||||||
&new_msgid,
|
&new_msgid,
|
||||||
&err);
|
&err);
|
||||||
|
|
||||||
|
return_mmsc_conn(mmc); /* important. */
|
||||||
done:
|
done:
|
||||||
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
||||||
to->process = 0;
|
to->process = 0;
|
||||||
|
@ -1029,6 +1030,7 @@ done2:
|
||||||
if (qfs->mms_queue_update(e) != 1)
|
if (qfs->mms_queue_update(e) != 1)
|
||||||
qfs->mms_queue_free_env(e);
|
qfs->mms_queue_free_env(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 1; /* always delete queue entry. */
|
return 1; /* always delete queue entry. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,6 @@
|
||||||
int rstop = 0;
|
int rstop = 0;
|
||||||
static void quit_now(int notused)
|
static void quit_now(int notused)
|
||||||
{
|
{
|
||||||
int i, n;
|
|
||||||
MmscGrp *mmc;
|
|
||||||
rstop = 1;
|
rstop = 1;
|
||||||
|
|
||||||
info(0, "shutdown in progress...");
|
info(0, "shutdown in progress...");
|
||||||
|
@ -40,14 +38,7 @@ static void quit_now(int notused)
|
||||||
if (sendmms_port.port > 0)
|
if (sendmms_port.port > 0)
|
||||||
http_close_port(sendmms_port.port);
|
http_close_port(sendmms_port.port);
|
||||||
|
|
||||||
for (i = 0, n = gwlist_len(mmscs); i < n; i++)
|
mmsbox_stop_all_mmsc_conn();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* manage the SIGHUP signal */
|
/* manage the SIGHUP signal */
|
||||||
|
|
|
@ -24,9 +24,10 @@
|
||||||
#include "mms_queue.h"
|
#include "mms_queue.h"
|
||||||
#include "mmsbox_resolve_shell.h"
|
#include "mmsbox_resolve_shell.h"
|
||||||
|
|
||||||
|
#define WAIT_TIME 0.2
|
||||||
|
|
||||||
List *sendmms_users = NULL; /* list of SendMmsUser structs */
|
List *sendmms_users = NULL; /* list of SendMmsUser structs */
|
||||||
List *mms_services = NULL; /* list of MMS Services */
|
List *mms_services = NULL; /* list of MMS Services */
|
||||||
List *mmscs = NULL;
|
|
||||||
Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir;
|
Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir;
|
||||||
long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry;
|
long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry;
|
||||||
long maxthreads = 0;
|
long maxthreads = 0;
|
||||||
|
@ -42,15 +43,22 @@ MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
|
||||||
void *rfs_data;
|
void *rfs_data;
|
||||||
Octstr *rfs_settings;
|
Octstr *rfs_settings;
|
||||||
|
|
||||||
|
|
||||||
|
static Dict *mmscs = NULL; /* MMSC's indexed by ID. */
|
||||||
|
|
||||||
struct SendMmsPortInfo sendmms_port;
|
struct SendMmsPortInfo sendmms_port;
|
||||||
|
|
||||||
struct MmsBoxMTfilter *mt_filter = NULL;
|
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)
|
int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
||||||
{
|
{
|
||||||
mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
|
mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
|
||||||
mCfgGrp *cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
|
mCfgGrp *cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
|
||||||
Octstr *gdir = NULL, *s, *tmp;
|
Octstr *gdir = NULL, *s;
|
||||||
|
|
||||||
int send_port_ssl = 0;
|
int send_port_ssl = 0;
|
||||||
List *l;
|
List *l;
|
||||||
int i, n, xx;
|
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();
|
sendmms_users = gwlist_create();
|
||||||
mms_services = gwlist_create();
|
mms_services = gwlist_create();
|
||||||
mmscs = gwlist_create();
|
mmscs = dict_create(101, NULL);
|
||||||
|
|
||||||
if (mms_cfg_get_int(cfg, grp,
|
if (mms_cfg_get_int(cfg, grp,
|
||||||
octstr_imm("maximum-send-attempts"), &mmsbox_maxsendattempts) < 0)
|
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. */
|
/* Get mmsc list. */
|
||||||
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
|
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
|
||||||
for (i = 0, n = gwlist_len(l); i < n; i++) {
|
for (i = 0, n = gwlist_len(l); i < n; i++)
|
||||||
mCfgGrp *x = gwlist_get(l, i);
|
start_mmsc_from_conf(cfg, gwlist_get(l, i), mmsc_handler_func);
|
||||||
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);
|
|
||||||
}
|
|
||||||
gwlist_destroy(l, NULL);
|
gwlist_destroy(l, NULL);
|
||||||
|
|
||||||
|
|
||||||
|
@ -480,31 +349,260 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
|
||||||
return 0;
|
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. */
|
/* Get the MMC that should handler this recipient. */
|
||||||
MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from)
|
MmscGrp *get_handler_mmc(Octstr *id, Octstr *to, Octstr *from)
|
||||||
{
|
{
|
||||||
MmscGrp *mmc = NULL, *res = NULL;
|
MmscGrp *res = NULL;
|
||||||
int i, n;
|
int i, n, not_number;
|
||||||
Octstr *phonenum = NULL, *xfrom = NULL;
|
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. */
|
l = dict_keys(mmscs);
|
||||||
for (i = 0, n = gwlist_len(mmscs); i < n; i++)
|
|
||||||
if ((mmc = gwlist_get(mmscs, i)) != NULL &&
|
not_number = (octstr_search_char(to, '@', 0) > 0 ||
|
||||||
mmc->id && octstr_compare(mmc->id, id) == 0)
|
octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0) > 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);
|
|
||||||
|
|
||||||
/* now try allow/deny stuff. */
|
/* now try allow/deny stuff. */
|
||||||
phonenum = extract_phonenum(to, unified_prefix);
|
phonenum = extract_phonenum(to, unified_prefix);
|
||||||
xfrom = extract_phonenum(from, NULL);
|
xfrom = extract_phonenum(from, NULL);
|
||||||
|
|
||||||
for (i = 0, n = gwlist_len(mmscs); i < n; i++) {
|
for (i = 0, n = gwlist_len(l); i < n; i++) {
|
||||||
if ((mmc = gwlist_get(mmscs, i)) == NULL)
|
MmscGrp *mmc = dict_get(mmscs,gwlist_get(l, i));
|
||||||
continue;
|
|
||||||
|
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 &&
|
if (mmc->allowed_prefix &&
|
||||||
does_prefix_match(mmc->allowed_prefix, phonenum) == 0)
|
does_prefix_match(mmc->allowed_prefix, phonenum) == 0)
|
||||||
continue; /* does not match. */
|
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)
|
does_prefix_match(mmc->denied_sender_prefix, xfrom) != 0)
|
||||||
continue; /* matches. */
|
continue; /* matches. */
|
||||||
|
|
||||||
|
loop:
|
||||||
res = mmc; /* otherwise it matches, so go away. */
|
res = mmc; /* otherwise it matches, so go away. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
octstr_destroy(phonenum);
|
octstr_destroy(phonenum);
|
||||||
octstr_destroy(xfrom);
|
octstr_destroy(xfrom);
|
||||||
|
|
||||||
|
gwlist_destroy(l, (void *)octstr_destroy);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (res)
|
||||||
|
MMSBOX_MMSC_MARK_INUSE(res); /* Vital! */
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void return_mmsc_conn(MmscGrp *m)
|
||||||
|
{
|
||||||
|
if (m)
|
||||||
|
MMSBOX_MMSC_UNMARK_INUSE(m); /* Vital! */
|
||||||
|
}
|
||||||
/* handle message routing. */
|
/* handle message routing. */
|
||||||
Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
||||||
Octstr **mmc_id)
|
Octstr **mmc_id)
|
||||||
|
@ -608,3 +717,29 @@ void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh)
|
||||||
|
|
||||||
if (freeh) gw_free(h);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ typedef struct MmscGrp {
|
||||||
Octstr *allow_ip;
|
Octstr *allow_ip;
|
||||||
Octstr *deny_ip;
|
Octstr *deny_ip;
|
||||||
long port;
|
long port;
|
||||||
|
int ssl;
|
||||||
} incoming; /* user, pass, port (and whether SSL) that MMSC uses to connect to us. */
|
} incoming; /* user, pass, port (and whether SSL) that MMSC uses to connect to us. */
|
||||||
Octstr *allowed_prefix, *denied_prefix;
|
Octstr *allowed_prefix, *denied_prefix;
|
||||||
Octstr *allowed_sender_prefix, *denied_sender_prefix;
|
Octstr *allowed_sender_prefix, *denied_sender_prefix;
|
||||||
|
@ -47,8 +48,23 @@ typedef struct MmscGrp {
|
||||||
Octstr *settings; /* settings for the above module. */
|
Octstr *settings; /* settings for the above module. */
|
||||||
void *data; /* data for above module. */
|
void *data; /* data for above module. */
|
||||||
int custom_started; /* set to 1 if custom mmc started. */
|
int custom_started; /* set to 1 if custom mmc started. */
|
||||||
|
|
||||||
|
int use_count; /* use counter. */
|
||||||
} MmscGrp;
|
} 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 {
|
typedef struct MmsServiceUrlParam {
|
||||||
Octstr *name;
|
Octstr *name;
|
||||||
enum {NO_PART, AUDIO_PART, IMAGE_PART, VIDEO_PART,
|
enum {NO_PART, AUDIO_PART, IMAGE_PART, VIDEO_PART,
|
||||||
|
@ -91,7 +107,6 @@ typedef struct SendMmsUser {
|
||||||
/* Basic settings for the mmsbox. */
|
/* Basic settings for the mmsbox. */
|
||||||
extern List *sendmms_users; /* list of SendMmsUser structs */
|
extern List *sendmms_users; /* list of SendMmsUser structs */
|
||||||
extern List *mms_services; /* list of MMS Services */
|
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 *incoming_qdir, *outgoing_qdir, *dlr_dir;
|
||||||
extern Octstr *unified_prefix;
|
extern Octstr *unified_prefix;
|
||||||
extern Octstr *sendmail_cmd;
|
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 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 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,
|
extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
|
||||||
Octstr **mmc_id);
|
Octstr **mmc_id);
|
||||||
extern void mmsbox_cleanup_settings(void);
|
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 {
|
typedef struct MmsBoxHTTPClientInfo {
|
||||||
HTTPClient *client;
|
HTTPClient *client;
|
||||||
Octstr *ua;
|
Octstr *ua;
|
||||||
|
|
Loading…
Reference in New Issue