added mmsbox routing resolver: mmsbox_resolve.h
This commit is contained in:
parent
195b7888b9
commit
970badf660
|
@ -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>
|
||||
|
|
|
@ -1281,7 +1281,7 @@ lists all the configuration directives. The column <b>Mode</b>
|
|||
</td>
|
||||
|
||||
<td valign=top >
|
||||
<i>MMSC</i>
|
||||
<i>ALL</i>
|
||||
|
||||
</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.)
|
||||
</td>
|
||||
|
@ -1306,7 +1309,7 @@ lists all the configuration directives. The column <b>Mode</b>
|
|||
</td>
|
||||
|
||||
<td valign=top >
|
||||
<i>MMSC</i>
|
||||
<i>ALL</i>
|
||||
|
||||
</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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,7 +150,7 @@ 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);
|
||||
|
@ -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;
|
||||
Octstr *value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
|
||||
|
||||
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,9 +229,30 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|||
break;
|
||||
|
||||
case MM7_TAG_DeliveryReportReq:
|
||||
desc = mm7_soap_header_value(mreq, octstr_imm("StatusText"));
|
||||
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"));
|
||||
|
||||
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),
|
||||
|
@ -237,16 +260,38 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|||
send_report(from, "delivery-report", NULL,
|
||||
value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
|
||||
|
||||
octstr_destroy(desc);
|
||||
octstr_destroy(value);
|
||||
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:
|
||||
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"));
|
||||
value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
||||
|
||||
send_report(from,
|
||||
"read-report", NULL, value, msgid,
|
||||
|
@ -255,6 +300,7 @@ static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|||
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"));
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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,6 +109,8 @@ 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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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
|
||||
};
|
|
@ -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
|
|
@ -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 ||
|
||||
|
|
Loading…
Reference in New Issue