1
0
Fork 0

added mmsbox routing resolver: mmsbox_resolve.h

This commit is contained in:
bagyenda 2007-09-17 13:07:30 +00:00
parent 195b7888b9
commit 970badf660
13 changed files with 431 additions and 145 deletions

View File

@ -1,3 +1,5 @@
2007-09-17 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added pluggable MMSBOX routing using loadable module or shell script (see mmsbox_resolve.h)
2007-09-14 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added http-interface-name config parameter
2007-09-06 P. A. Bagyenda <bagyenda@dsmagic.com>

View File

@ -1281,7 +1281,7 @@ lists all the configuration directives. The column <b>Mode</b>
&nbsp; &nbsp;</td>
<td valign=top >
<i>MMSC</i>
<i>ALL</i>
&nbsp; &nbsp;
</td>
@ -1291,11 +1291,14 @@ lists all the configuration directives. The column <b>Mode</b>
<td valign=top >
Optional
library containing functions for resolving recipient MSISDN to hostname
of Proxy-Relay that should handle the message. Supplying this libary
of Proxy-Relay that should handle the message (on the MMC side) or
the connected MMC that should (internally) route an incoming MM7
message (on the MMSBOX side). <br> For Mbun MMSC, supplying this libary
over-rides the <tt>local-prefixes</tt> setting given above. If the
Proxy-Relay hostname returned by the module is the hostname of the
local MMSC, then the recipient is considered local. See
<tt>mms_resolve.h</tt> for details. (<a
<tt>mms_resolve.h</tt> for details. (See <tt>mmsbox_resolve.h</tt> for usage under
mmsbox). (<a
href="#builtin"><tt>builtin:shell</tt></a> supported as a special
built-in library.)
&nbsp; &nbsp;</td>
@ -1306,7 +1309,7 @@ lists all the configuration directives. The column <b>Mode</b>
&nbsp; &nbsp;</td>
<td valign=top >
<i>MMSC</i>
<i>ALL</i>
&nbsp; &nbsp;
</td>
@ -1641,7 +1644,7 @@ Mbuni supports one type of built-in modules: Shell script
destination address to determine how to deliver the message. The
script is invoked with one command line parameter (the destination
address) and should output (on standard output) the hostname of the
home MMSC, to which the message should be routed.
home MMSC (or MM7 connection ID in the case of <tt>mmsbox</tt>), to which the message should be routed.
<li>If <tt>detokenizer-library</tt> is set to <tt>builtin:shell</tt>
then <tt>detokenizer-module-parameters</tt> should be set to the
script that should be called to resolve the last part of the MM1

View File

@ -1674,3 +1674,45 @@ void strip_non_essential_headers(MIMEEntity *mime)
http_destroy_headers(h2);
}
void *_mms_load_module(mCfgGrp *grp, char *config_key, char *symbolname,
void *shell_builtin)
{
Octstr *s = NULL;
void *retval = NULL;
s = mms_cfg_get(grp, octstr_imm(config_key));
if (s) {
void *x;
void *y = NULL;
#ifdef __APPLE__
char sbuf[512];
#endif
/* First look for the builtin: keyword.
* For now only builtin:shell is supported.
*/
if (octstr_case_search(s, octstr_imm("builtin:shell"), 0) >= 0)
retval = shell_builtin;
else {
x = dlopen(octstr_get_cstr(s), RTLD_LAZY);
#ifdef __APPLE__
sprintf(sbuf, "_%s", symbolname);
#endif
if (x == NULL || ((y = dlsym(x, symbolname)) == NULL
#ifdef __APPLE__ /* fink version of dlsym has issues it seems. */
&& (y = dlsym(x, sbuf)) == NULL
#endif
))
panic(0, "Unable to load dynamic libary (%s): %s",
octstr_get_cstr(s),
dlerror());
else
retval = y;
}
octstr_destroy(s);
}
return retval;
}

View File

@ -198,6 +198,9 @@ int has_node_children(xmlNodePtr node);
/* strip non-essential headers from top-level */
void strip_non_essential_headers(MIMEEntity *mime);
/* load a shared object, then load a symbol from it. */
void *_mms_load_module(mCfgGrp *grp, char *config_key, char *symbolname,
void *shell_builtin);
#define MAXQTRIES 100
#define BACKOFF_FACTOR 5*60 /* In seconds */
#define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */

View File

@ -1,7 +1,7 @@
libmms = $(top_builddir)/mmlib/libmms.a
bin_PROGRAMS = mmsbox
mmsbox_SOURCES = mmsbox.c mmsbox_cfg.c dlr.c bearerbox.c
mmsbox_SOURCES = mmsbox.c mmsbox_cfg.c dlr.c bearerbox.c mmsbox_resolve.c mmsbox_resolve_shell.c
mmsbox_LDADD = $(libmms)
EXTRA_DIST = mmsbox_cfg.h mmsbox.h mmsbox_mt_filter.h
EXTRA_DIST = mmsbox_cfg.h mmsbox.h mmsbox_mt_filter.h mmsbox_resolve.h

View File

@ -142,7 +142,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
MSoapMsg_t *mreq = NULL, *mresp = NULL;
int hstatus = HTTP_OK;
List *rh = NULL;
Octstr *reply_body = NULL, *value, *desc;
Octstr *reply_body = NULL;
List *to = NULL;
Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL, *uaprof = NULL;
@ -150,8 +150,8 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
MmsMsg *m = NULL;
int status = 1000;
unsigned char *msgtype = (unsigned char *)"";
Octstr *qf = NULL;
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL;
if (h->body)
mreq = mm7_parse_soap(h->headers, h->body);
if (mreq)
@ -171,17 +171,18 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
if (!from)
from = octstr_imm("anon@anon");
qdir = get_mmsbox_queue_dir(from, to, h->m, &mmc_id); /* get routing info. */
switch (mm7_msgtype(mreq)) {
case MM7_TAG_DeliverReq:
m = mm7_soap_to_mmsmsg(mreq, from);
if (m) {
Octstr *value = NULL;
/* Store linked id so we use it in response. */
Octstr *linkedid = mm7_soap_header_value(mreq, octstr_imm("LinkedID"));
List *qh = http_create_empty_headers();
int dlr;
value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
Octstr *value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
if (value &&
octstr_case_compare(value, octstr_imm("Yes")) == 0)
dlr = 1;
@ -200,15 +201,16 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
http_header_add(qh, "X-Mbuni-Timestamp", octstr_get_cstr(sx));
octstr_destroy(sx);
}
qf = qfs->mms_queue_add(from, to, subject,
h->m->id, h->m->reroute ? h->m->reroute_mmsc_id : NULL,
h->m->id, mmc_id,
delivert, expiryt, m, linkedid,
NULL, NULL,
NULL, NULL,
qh,
dlr,
h->m->reroute ? octstr_get_cstr(outgoing_qdir) :
octstr_get_cstr(incoming_qdir),
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
msgid = mms_maketransid(octstr_get_cstr(qf), octstr_imm(MM_NAME));
mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
@ -227,34 +229,78 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
break;
case MM7_TAG_DeliveryReportReq:
desc = mm7_soap_header_value(mreq, octstr_imm("StatusText"));
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
info(0, "Sending delivery-report [FROM:%s] [VALUE:%s] [DESC:%s] [MSGID:%s]",
octstr_get_cstr(from), octstr_get_cstr(value), octstr_get_cstr(desc),
octstr_get_cstr(h->m->id));
send_report(from, "delivery-report", NULL,
value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
if (mmc_id != NULL) { /* internal routing. */
m = mm7_soap_to_mmsmsg(mreq, from);
if (m)
qf = qfs->mms_queue_add(from, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
else
qf = NULL;
if (qf)
/* Log to access log */
mms_log("Received DLR", from, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
else
status = 4000;
} else {
Octstr *desc = mm7_soap_header_value(mreq, octstr_imm("StatusText"));
Octstr *value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
octstr_destroy(desc);
octstr_destroy(value);
mms_log("DeliveryReport",
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
info(0, "Sending delivery-report [FROM:%s] [VALUE:%s] [DESC:%s] [MSGID:%s]",
octstr_get_cstr(from), octstr_get_cstr(value), octstr_get_cstr(desc),
octstr_get_cstr(h->m->id));
send_report(from, "delivery-report", NULL,
value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
mms_log("DeliveryReport",
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
octstr_destroy(desc);
octstr_destroy(value);
}
mresp = mm7_make_resp(mreq, status, NULL,1);
break;
case MM7_TAG_ReadReplyReq:
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
send_report(from,
"read-report", NULL, value, msgid,
h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
octstr_destroy(value);
mms_log("ReadReport",
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
if (mmc_id != NULL) { /* internal routing. */
m = mm7_soap_to_mmsmsg(mreq, from);
if (m)
qf = qfs->mms_queue_add(from, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
else
qf = NULL;
if (qf)
/* Log to access log */
mms_log("Received RR", from, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
else
status = 4000;
} else {
Octstr *value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
send_report(from,
"read-report", NULL, value, msgid,
h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
octstr_destroy(value);
mms_log("ReadReport",
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
}
mresp = mm7_make_resp(mreq, status, NULL,1);
break;
@ -264,7 +310,6 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
}
done:
if (mresp && mm7_soapmsg_to_httpmsg(mresp, &h->m->ver, &rh, &reply_body) == 0)
http_send_reply(h->client, hstatus, rh, reply_body);
else
@ -287,6 +332,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
mm7_soap_destroy(mresp);
mm7_soap_destroy(mreq);
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
octstr_destroy(mmc_id);
}
static void mm7eaif_receive(MmsHTTPClientInfo *h)
@ -295,13 +341,13 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
List *mh = NULL;
int hstatus = HTTP_NO_CONTENT;
List *rh = http_create_empty_headers();
Octstr *reply_body = NULL, *value, *value2;
Octstr *reply_body = NULL, *value;
List *to = gwlist_create(), *hto = NULL;
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL;
Octstr *hfrom = NULL;
time_t expiryt = -1, deliveryt = -1;
Octstr *qf = NULL, *xver;
Octstr *qf = NULL, *xver, *mmc_id = NULL, *qdir = NULL;
int msize = h->body ? octstr_len(h->body) : 0;
int dlr;
int mtype;
@ -355,6 +401,8 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
}
qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */
switch(mtype) {
case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF:
@ -389,42 +437,79 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
/* Save it, put message id in header, return. */
qf = qfs->mms_queue_add(hfrom, to, subject,
h->m->id, h->m->reroute ? h->m->reroute_mmsc_id : NULL,
h->m->id, mmc_id,
deliveryt, expiryt, m, NULL,
NULL, NULL,
NULL, NULL,
NULL,
dlr,
h->m->reroute ? octstr_get_cstr(outgoing_qdir) :
octstr_get_cstr(incoming_qdir),
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
if (qf) {
/* Log to access log */
mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
octstr_destroy(qf);
hstatus = HTTP_NO_CONTENT;
} else
hstatus = HTTP_INTERNAL_SERVER_ERROR;
break;
case MMS_MSGTYPE_DELIVERY_IND:
value = http_header_value(mh, octstr_imm("X-Mms-Status"));
value2 = http_header_value(mh, octstr_imm("Message-ID"));
send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
octstr_destroy(value);
octstr_destroy(value2);
if (mmc_id != NULL) { /* internal routing. */
qf = qfs->mms_queue_add(hfrom, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
if (qf) {
/* Log to access log */
mms_log("Received DLR", hfrom, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
hstatus = HTTP_NO_CONTENT;
} else
hstatus = HTTP_INTERNAL_SERVER_ERROR;
} else {
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Status"));
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
octstr_destroy(value);
octstr_destroy(value2);
}
break;
case MMS_MSGTYPE_READ_ORIG_IND:
value = http_header_value(mh, octstr_imm("X-Mms-Read-Status"));
value2 = http_header_value(mh, octstr_imm("Message-ID"));
send_report(hfrom, "read-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
octstr_destroy(value);
octstr_destroy(value2);
if (mmc_id != NULL) { /* internal routing. */
qf = qfs->mms_queue_add(hfrom, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
NULL, NULL,
NULL, NULL,
NULL,
0,
octstr_get_cstr(qdir),
octstr_imm(MM_NAME));
if (qf) {
/* Log to access log */
mms_log("Received RR", hfrom, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
hstatus = HTTP_NO_CONTENT;
} else
hstatus = HTTP_INTERNAL_SERVER_ERROR;
} else {
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Read-Status"));
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
send_report(hfrom, "read-report", NULL, value, value2, h->m->id,
h->m->group_id, NULL, NULL, -1);
octstr_destroy(value);
octstr_destroy(value2);
}
break;
}
@ -442,6 +527,9 @@ static void mm7eaif_receive(MmsHTTPClientInfo *h)
octstr_destroy(subject);
octstr_destroy(otransid);
octstr_destroy(msgid);
octstr_destroy(qf);
octstr_destroy(mmc_id);
http_destroy_headers(mh);
mms_destroy(m);
}

View File

@ -22,57 +22,26 @@
#include <unistd.h>
#include "mmsbox_cfg.h"
#include "mms_queue.h"
#include "mmsbox_resolve_shell.h"
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;
long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry;
long maxthreads = 0;
double queue_interval = -1;
Octstr *unified_prefix;
int mt_multipart = 0;
MmsQueueHandlerFuncs *qfs; /* queue functions. */
MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
void *rfs_data;
Octstr *rfs_settings;
struct SendMmsPortInfo sendmms_port;
struct MmsBoxMTfilter *mt_filter = NULL;
static void *load_module(mCfgGrp *grp, char *config_key,
char *symbolname)
{
Octstr *s = NULL;
void *retval = NULL;
s = mms_cfg_get(grp, octstr_imm(config_key));
if (s) {
void *x;
void *y = NULL;
#ifdef __APPLE__
char sbuf[512];
#endif
x = dlopen(octstr_get_cstr(s), RTLD_LAZY);
#ifdef __APPLE__
sprintf(sbuf, "_%s", symbolname);
#endif
if (x == NULL || ((y = dlsym(x, symbolname)) == NULL
#ifdef __APPLE__ /* fink version of dlsym has issues it seems. */
&& (y = dlsym(x, sbuf)) == NULL
#endif
))
panic(0, "Unable to load dynamic libary (%s): %s",
octstr_get_cstr(s), dlerror());
else
retval = y;
octstr_destroy(s);
}
return retval;
}
int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
{
mCfgGrp *grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
@ -103,7 +72,7 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
panic(0, "Failed to create MMSBox storage directory: %s - %s!",
octstr_get_cstr(gdir), strerror(errno));
if ((qfs = load_module(grp, "queue-manager-module", "qfuncs")) == NULL) {
if ((qfs = _mms_load_module(grp, "queue-manager-module", "qfuncs", NULL)) == NULL) {
qfs = &default_qfuncs; /* default queue handler. */
qfs->mms_init_queue_module(gdir);
} else {
@ -140,7 +109,9 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
octstr_imm("send-attempt-back-off"), &mmsbox_send_back_off) == -1)
mmsbox_send_back_off = BACKOFF_FACTOR;
if (mms_cfg_get_int(grp, octstr_imm("default-message-expiry"), &default_msgexpiry) == -1)
default_msgexpiry = DEFAULT_EXPIRE;
if (mms_cfg_get_int(grp, octstr_imm("max-send-threads"), &maxthreads) == -1)
maxthreads = 10;
@ -169,13 +140,19 @@ int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func)
sendmms_port.deny_ip = mms_cfg_get(grp, octstr_imm("deny-ip"));
/* load the filter if any. */
if ((mt_filter = load_module(grp, "mmsbox-mt-filter-library", "mmsbox_mt_filter")) != NULL)
if ((mt_filter = _mms_load_module(grp, "mmsbox-mt-filter-library", "mmsbox_mt_filter", NULL)) != NULL)
info(0, "MMSBox: Loaded MT Filter [%s]", mt_filter->name);
mms_cfg_get_bool(grp, octstr_imm("mmsbox-mt-always-multipart"), &mt_multipart);
/* Now get sendmms users. */
/* load the resolver module. */
if ((rfs = _mms_load_module(grp, "resolver-library", "mmsbox_resolver", &mmsbox_resolvefuncs_shell)) == NULL)
rfs = &mmsbox_resolvefuncs;
rfs_settings = _mms_cfg_getx(grp, octstr_imm("resolver-module-parameters"));
rfs_data = rfs->mmsbox_resolvermodule_init(rfs_settings ? octstr_get_cstr(rfs_settings) : NULL);
/* Now get sendmms users. */
l = mms_cfg_get_multi(cfg, octstr_imm("send-mms-user"));
for (i = 0, n = gwlist_len(l); i < n; i++) {
mCfgGrp *x = gwlist_get(l, i);
@ -486,3 +463,37 @@ MmscGrp *get_handler_mmc(Octstr *id, Octstr *to)
octstr_destroy(phonenum);
return NULL;
}
/* handle message routing. */
Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
Octstr **mmc_id) {
*mmc_id = octstr_imm("local");
return outgoing_qdir;
if (m->reroute) {
*mmc_id = octstr_duplicate(m->reroute_mmsc_id);
return outgoing_qdir;
} else {
Octstr *_mcid, *fto = NULL, *qdir = NULL;
if (gwlist_len(to) > 0) { /* we route based on first recipient XXX */
Octstr *r = gwlist_get(to, 0);
fto = r ? octstr_duplicate(r) : NULL;
}
_mcid = rfs->mmsbox_resolve(from,fto,rfs_data, rfs_settings);
if (_mcid == NULL || octstr_len(_mcid) == 0) {
*mmc_id = NULL;
qdir = incoming_qdir;
} else {
*mmc_id = octstr_duplicate(_mcid);
qdir = outgoing_qdir;
}
octstr_destroy(_mcid);
octstr_destroy(fto);
return qdir;
}
return 0;
}

View File

@ -15,6 +15,7 @@
#include "mms_util.h"
#include "mmsbox_mt_filter.h"
#include "mms_queue.h"
#include "mmsbox_resolve.h"
typedef struct MmscGrp {
Octstr *id; /* MMSC id (for logging). */
@ -81,7 +82,7 @@ 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 long mmsbox_maxsendattempts, mmsbox_send_back_off;
extern long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry;
extern long maxthreads;
extern double queue_interval;
extern struct SendMmsPortInfo {
@ -93,6 +94,15 @@ extern struct SendMmsPortInfo {
extern struct MmsBoxMTfilter *mt_filter;
extern MmsQueueHandlerFuncs *qfs;
extern int mt_multipart;
extern MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
extern void *rfs_data;
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);
extern Octstr *get_mmsbox_queue_dir(Octstr *from, List *to, MmscGrp *m,
Octstr **mmc_id);
#endif

View File

@ -0,0 +1,39 @@
/*
* Mbuni - Open Source MMS Gateway
*
* Resolving MSISDNs to local/remote MMSBox MMSC - interface
*
* Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com
*
* Paul Bagyenda <bagyenda@dsmagic.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License, with a few exceptions granted (see LICENSE)
*/
#include <stdio.h>
#include <stdlib.h>
#include "mmsbox_resolve.h"
#include "mmsbox_cfg.h"
static void *_resolvermodule_init(char *settings)
{
return NULL;
}
static int _resolvermodule_fini(void *module_data)
{
return 0;
}
static Octstr *_resolve(Octstr * pfrom, Octstr *pto, void *module_data, void *settings_p)
{
/* route normally to mms-service. */
return NULL;
}
/* The function itself. */
MmsBoxResolverFuncStruct mmsbox_resolvefuncs = {
_resolvermodule_init,
_resolve,
_resolvermodule_fini
};

View File

@ -0,0 +1,42 @@
/*
* Mbuni - Open Source MMS Gateway
*
* Resolving MSISDNs to local/remote MMSBox MMSC - interface
*
* Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com
*
* Paul Bagyenda <bagyenda@dsmagic.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License, with a few exceptions granted (see LICENSE)
*/
#ifndef __MMSBOX_RESOLVE_INCLUDED__
#define __MMSBOX_RESOLVE_INCLUDED__
#include <time.h>
#include "gwlib/gwlib.h"
/* Resolver module. This file provides prototypes for all resolver functions.
* the module is loaded once and _init is called once at load.
* _resolve is called for each incoming message to determine how to route it.
*/
typedef struct MmsBoxResolverFuncStruct {
/* This function is called once to initialise the resolver module. Return a generic object,
* which is passed with each resolution request..
*/
void *(*mmsbox_resolvermodule_init)(char *settings);
/* Looks up the sender and receiver msisdns and returns the ID of the MMC connection through which
* the received message should be sent.
*
* Return NULL or the empty string to send the message to a service (normal behavior)
*/
Octstr *(*mmsbox_resolve)(Octstr *pfrom, Octstr *pto, void *module_data, void *settings);
int (*mmsbox_resolvermodule_fini)(void *module_data);
} MmsBoxResolverFuncStruct;
extern MmsBoxResolverFuncStruct mmsbox_resolvefuncs; /* The module must expose this symbol. */
#endif

View File

@ -0,0 +1,66 @@
/*
* Mbuni - Open Source MMS Gateway
*
* Resolving MSISDNs to local/remote MMSCs - calling shell scripts
*
* Copyright (C) 2003 - 2005, Digital Solutions Ltd. - http://www.dsmagic.com
*
* Paul Bagyenda <bagyenda@dsmagic.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License, with a few exceptions granted (see LICENSE)
*/
#include <stdio.h>
#include <stdlib.h>
#include "mmsbox_resolve.h"
#include "mms_util.h"
static Octstr *script = NULL;
static void *_shell_resolvermodule_init(char *settings)
{
script = octstr_imm(settings);
return NULL;
}
static int _shell_resolvermodule_fini(void *module_data)
{
octstr_destroy(script);
script = NULL;
return 0;
}
static Octstr *_shell_resolve(Octstr *pfrom, Octstr *pto, void *module_data, void *settings_p)
{
Octstr *s;
FILE *fp;
char buf[4096];
if (script == NULL || octstr_len(script) == 0)
return 0;
s = octstr_format("%s '%s' '%s' ",
octstr_get_cstr(script), octstr_get_cstr(pfrom), octstr_get_cstr(pto));
fp = popen(octstr_get_cstr(s), "r");
octstr_destroy(s);
fgets(buf, 4096, fp);
s = octstr_create(buf);
octstr_strip_crlfs(s);
pclose(fp);
if (octstr_len(s) == 0) {
octstr_destroy(s);
return NULL;
}
return s;
}
/* The function struct itself. */
MmsBoxResolverFuncStruct mmsbox_resolvefuncs_shell = {
_shell_resolvermodule_init,
_shell_resolve,
_shell_resolvermodule_fini
};

View File

@ -0,0 +1,22 @@
/*
* Mbuni - Open Source MMS Gateway
*
* Resolving MSISDNs to local/remote MMSCs - interface (shell)
*
* Copyright (C) 2003 - 2007, Digital Solutions Ltd. - http://www.dsmagic.com
*
* Paul Bagyenda <bagyenda@dsmagic.com>
*
* This program is free software, distributed under the terms of
* the GNU General Public License, with a few exceptions granted (see LICENSE)
*/
#ifndef __MMSBOX_RESOLVE_SHELL_INCLUDED__
#define __MMSBOX_RESOLVE_SHELL_INCLUDED__
#include <time.h>
#include "gwlib/gwlib.h"
#include "mmsbox_resolve.h"
extern MmsBoxResolverFuncStruct mmsbox_resolvefuncs_shell;
#endif

View File

@ -28,48 +28,6 @@
static void *load_module(mCfgGrp *grp, char *config_key, char *symbolname,
void *shell_builtin)
{
Octstr *s = NULL;
void *retval = NULL;
s = mms_cfg_get(grp, octstr_imm(config_key));
if (s) {
void *x;
void *y = NULL;
#ifdef __APPLE__
char sbuf[512];
#endif
/* First look for the builtin: keyword.
* For now only builtin:shell is supported.
*/
if (octstr_case_search(s, octstr_imm("builtin:shell"), 0) >= 0)
retval = shell_builtin;
else {
x = dlopen(octstr_get_cstr(s), RTLD_LAZY);
#ifdef __APPLE__
sprintf(sbuf, "_%s", symbolname);
#endif
if (x == NULL || ((y = dlsym(x, symbolname)) == NULL
#ifdef __APPLE__ /* fink version of dlsym has issues it seems. */
&& (y = dlsym(x, sbuf)) == NULL
#endif
))
panic(0, "Unable to load dynamic libary (%s): %s",
octstr_get_cstr(s),
dlerror());
else
retval = y;
}
octstr_destroy(s);
}
return retval;
}
void mms_cleanup_mmsc_settings(MmscSettings *settings)
{
/* eventually we will destroy the object. For now, we only cleanup queue module. */
@ -126,7 +84,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
panic(0, "Failed to create queue directory: %s - %s!",
octstr_get_cstr(qdir), strerror(errno));
if ((m->qfs = load_module(grp, "queue-manager-module", "qfuncs", NULL)) == NULL) {
if ((m->qfs = _mms_load_module(grp, "queue-manager-module", "qfuncs", NULL)) == NULL) {
m->qfs = &default_qfuncs; /* default queue handler. */
m->qfs->mms_init_queue_module(qdir);
} else {
@ -238,7 +196,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
octstr_imm("billing-module-parameters"));
/* Get and load the billing lib if any. */
if ((m->mms_billfuncs = load_module(grp, "billing-library", "mms_billfuncs",
if ((m->mms_billfuncs = _mms_load_module(grp, "billing-library", "mms_billfuncs",
&mms_billfuncs_shell)) != NULL) {
if (m->mms_billfuncs->mms_billingmodule_init == NULL ||
m->mms_billfuncs->mms_billmsg == NULL ||
@ -254,7 +212,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
octstr_imm("resolver-module-parameters"));
/* Get and load the resolver lib if any. */
if ((m->mms_resolvefuncs = load_module(grp, "resolver-library",
if ((m->mms_resolvefuncs = _mms_load_module(grp, "resolver-library",
"mms_resolvefuncs",
&mms_resolvefuncs_shell)) != NULL) {
if (m->mms_resolvefuncs->mms_resolvermodule_init == NULL ||
@ -269,7 +227,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
m->detokenizer_params = _mms_cfg_getx(grp, octstr_imm("detokenizer-module-parameters"));
/* Get and load the detokenizer lib if any. */
if ((m->mms_detokenizefuncs = load_module(grp, "detokenizer-library",
if ((m->mms_detokenizefuncs = _mms_load_module(grp, "detokenizer-library",
"mms_detokenizefuncs",
&mms_detokenizefuncs_shell)) != NULL) {
if (m->mms_detokenizefuncs->mms_detokenizer_init == NULL ||