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> 2007-09-14 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added http-interface-name config parameter * Added http-interface-name config parameter
2007-09-06 P. A. Bagyenda <bagyenda@dsmagic.com> 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> &nbsp; &nbsp;</td>
<td valign=top > <td valign=top >
<i>MMSC</i> <i>ALL</i>
&nbsp; &nbsp; &nbsp; &nbsp;
</td> </td>
@ -1291,11 +1291,14 @@ lists all the configuration directives. The column <b>Mode</b>
<td valign=top > <td valign=top >
Optional Optional
library containing functions for resolving recipient MSISDN to hostname 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 over-rides the <tt>local-prefixes</tt> setting given above. If the
Proxy-Relay hostname returned by the module is the hostname of the Proxy-Relay hostname returned by the module is the hostname of the
local MMSC, then the recipient is considered local. See 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 href="#builtin"><tt>builtin:shell</tt></a> supported as a special
built-in library.) built-in library.)
&nbsp; &nbsp;</td> &nbsp; &nbsp;</td>
@ -1306,7 +1309,7 @@ lists all the configuration directives. The column <b>Mode</b>
&nbsp; &nbsp;</td> &nbsp; &nbsp;</td>
<td valign=top > <td valign=top >
<i>MMSC</i> <i>ALL</i>
&nbsp; &nbsp; &nbsp; &nbsp;
</td> </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 destination address to determine how to deliver the message. The
script is invoked with one command line parameter (the destination script is invoked with one command line parameter (the destination
address) and should output (on standard output) the hostname of the 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> <li>If <tt>detokenizer-library</tt> is set to <tt>builtin:shell</tt>
then <tt>detokenizer-module-parameters</tt> should be set to the then <tt>detokenizer-module-parameters</tt> should be set to the
script that should be called to resolve the last part of the MM1 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); 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 */ /* strip non-essential headers from top-level */
void strip_non_essential_headers(MIMEEntity *mime); 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 MAXQTRIES 100
#define BACKOFF_FACTOR 5*60 /* In seconds */ #define BACKOFF_FACTOR 5*60 /* In seconds */
#define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */ #define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */

View File

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

View File

@ -22,57 +22,26 @@
#include <unistd.h> #include <unistd.h>
#include "mmsbox_cfg.h" #include "mmsbox_cfg.h"
#include "mms_queue.h" #include "mms_queue.h"
#include "mmsbox_resolve_shell.h"
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; List *mmscs = NULL;
Octstr *incoming_qdir, *outgoing_qdir, *dlr_dir; 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; long maxthreads = 0;
double queue_interval = -1; double queue_interval = -1;
Octstr *unified_prefix; Octstr *unified_prefix;
int mt_multipart = 0; int mt_multipart = 0;
MmsQueueHandlerFuncs *qfs; /* queue functions. */ MmsQueueHandlerFuncs *qfs; /* queue functions. */
MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
void *rfs_data;
Octstr *rfs_settings;
struct SendMmsPortInfo sendmms_port; struct SendMmsPortInfo sendmms_port;
struct MmsBoxMTfilter *mt_filter = NULL; 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) 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"));
@ -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!", panic(0, "Failed to create MMSBox storage directory: %s - %s!",
octstr_get_cstr(gdir), strerror(errno)); 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 = &default_qfuncs; /* default queue handler. */
qfs->mms_init_queue_module(gdir); qfs->mms_init_queue_module(gdir);
} else { } 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) octstr_imm("send-attempt-back-off"), &mmsbox_send_back_off) == -1)
mmsbox_send_back_off = BACKOFF_FACTOR; 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) if (mms_cfg_get_int(grp, octstr_imm("max-send-threads"), &maxthreads) == -1)
maxthreads = 10; 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")); sendmms_port.deny_ip = mms_cfg_get(grp, octstr_imm("deny-ip"));
/* load the filter if any. */ /* 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); info(0, "MMSBox: Loaded MT Filter [%s]", mt_filter->name);
mms_cfg_get_bool(grp, octstr_imm("mmsbox-mt-always-multipart"), &mt_multipart); 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")); l = mms_cfg_get_multi(cfg, octstr_imm("send-mms-user"));
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); mCfgGrp *x = gwlist_get(l, i);
@ -486,3 +463,37 @@ MmscGrp *get_handler_mmc(Octstr *id, Octstr *to)
octstr_destroy(phonenum); octstr_destroy(phonenum);
return NULL; 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 "mms_util.h"
#include "mmsbox_mt_filter.h" #include "mmsbox_mt_filter.h"
#include "mms_queue.h" #include "mms_queue.h"
#include "mmsbox_resolve.h"
typedef struct MmscGrp { typedef struct MmscGrp {
Octstr *id; /* MMSC id (for logging). */ 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 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 long mmsbox_maxsendattempts, mmsbox_send_back_off; extern long mmsbox_maxsendattempts, mmsbox_send_back_off, default_msgexpiry;
extern long maxthreads; extern long maxthreads;
extern double queue_interval; extern double queue_interval;
extern struct SendMmsPortInfo { extern struct SendMmsPortInfo {
@ -93,6 +94,15 @@ extern struct SendMmsPortInfo {
extern struct MmsBoxMTfilter *mt_filter; extern struct MmsBoxMTfilter *mt_filter;
extern MmsQueueHandlerFuncs *qfs; extern MmsQueueHandlerFuncs *qfs;
extern int mt_multipart; 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 int mms_load_mmsbox_settings(mCfg *cfg, gwthread_func_t *mmsc_handler_func);
extern MmscGrp *get_handler_mmc(Octstr *id, Octstr *to); 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 #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) void mms_cleanup_mmsc_settings(MmscSettings *settings)
{ {
/* eventually we will destroy the object. For now, we only cleanup queue module. */ /* 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!", panic(0, "Failed to create queue directory: %s - %s!",
octstr_get_cstr(qdir), strerror(errno)); 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 = &default_qfuncs; /* default queue handler. */
m->qfs->mms_init_queue_module(qdir); m->qfs->mms_init_queue_module(qdir);
} else { } else {
@ -238,7 +196,7 @@ MmscSettings *mms_load_mmsc_settings(mCfg *cfg, List **proxyrelays)
octstr_imm("billing-module-parameters")); octstr_imm("billing-module-parameters"));
/* Get and load the billing lib if any. */ /* 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) { &mms_billfuncs_shell)) != NULL) {
if (m->mms_billfuncs->mms_billingmodule_init == NULL || if (m->mms_billfuncs->mms_billingmodule_init == NULL ||
m->mms_billfuncs->mms_billmsg == 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")); octstr_imm("resolver-module-parameters"));
/* Get and load the resolver lib if any. */ /* 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",
&mms_resolvefuncs_shell)) != NULL) { &mms_resolvefuncs_shell)) != NULL) {
if (m->mms_resolvefuncs->mms_resolvermodule_init == 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")); m->detokenizer_params = _mms_cfg_getx(grp, octstr_imm("detokenizer-module-parameters"));
/* Get and load the detokenizer lib if any. */ /* 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",
&mms_detokenizefuncs_shell)) != NULL) { &mms_detokenizefuncs_shell)) != NULL) {
if (m->mms_detokenizefuncs->mms_detokenizer_init == NULL || if (m->mms_detokenizefuncs->mms_detokenizer_init == NULL ||