1
0
Fork 0

added misc logging stuff

This commit is contained in:
bagyenda 2010-10-21 17:51:16 +00:00
parent bf5c6e2c6c
commit 20ae441d94
15 changed files with 1983 additions and 1543 deletions

View File

@ -1,3 +1,7 @@
2010-10-19 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added new func to mms_cfg -- make it easier to implement module-based configuration
* Extended mmsbox_cfg load functions to make it easier to configure using modules
* Added alarm callback, event logging.
2010-09-21 P. A. Bagyenda <bagyenda@dsmagic.com> 2010-09-21 P. A. Bagyenda <bagyenda@dsmagic.com>
* Patch to allow compilation under FreeBSD 8.1 (thanks to Piotr Isajew <pki at ex.com.pl>) * Patch to allow compilation under FreeBSD 8.1 (thanks to Piotr Isajew <pki at ex.com.pl>)
2010-08-09 P. A. Bagyenda <bagyenda@dsmagic.com> 2010-08-09 P. A. Bagyenda <bagyenda@dsmagic.com>

View File

@ -123,6 +123,19 @@ static void check_and_add_field(mCfgGrp *grp, Octstr *field, Octstr *value, int
octstr_get_cstr(field), lineno); octstr_get_cstr(field), lineno);
} }
static mCfg *make_cfg(Octstr *file)
{
mCfg *cfg;
cfg = gw_malloc(sizeof *cfg);
cfg->file = file ? octstr_duplicate(file) : NULL;
cfg->grps = dict_create(7, NULL);
cfg->xcfg = NULL;
cfg->cfg_funcs = NULL;
return cfg;
}
mCfg *mms_cfg_read(Octstr *file) mCfg *mms_cfg_read(Octstr *file)
{ {
Octstr *sf; Octstr *sf;
@ -139,12 +152,7 @@ mCfg *mms_cfg_read(Octstr *file)
return NULL; return NULL;
} }
cfg = gw_malloc(sizeof *cfg); cfg = make_cfg(file);
cfg->file = octstr_duplicate(file);
cfg->grps = dict_create(7, NULL);
cfg->xcfg = NULL;
cfg->cfg_funcs = NULL;
lines = octstr_split(sf, octstr_imm("\n")); lines = octstr_split(sf, octstr_imm("\n"));
for (i = 0, n = gwlist_len(lines); i < n; i++) { for (i = 0, n = gwlist_len(lines); i < n; i++) {
@ -236,6 +244,26 @@ mCfg *mms_cfg_read(Octstr *file)
return cfg; return cfg;
} }
mCfg *mms_cfg_read2(mCfgImpFuncs *cfgfuncs, Octstr *init)
{
mCfg *cfg;
gw_assert(cfgfuncs);
cfg = make_cfg(NULL);
cfg->cfg_funcs = cfgfuncs;
if (cfg->cfg_funcs->read == NULL ||
(cfg->xcfg = cfg->cfg_funcs->read(init)) == NULL) {
mms_error(0, "mms_cfg", NULL, "Failed to load cfg reader: read failed in cfg_read2!");
mms_cfg_destroy(cfg);
cfg = NULL;
}
return cfg;
}
static void mGrp_destroy(mCfgGrp *grp) static void mGrp_destroy(mCfgGrp *grp)
{ {
octstr_destroy(grp->name); octstr_destroy(grp->name);

View File

@ -20,11 +20,14 @@
typedef struct mCfg mCfg; /* config file structure. */ typedef struct mCfg mCfg; /* config file structure. */
typedef struct mCfgGrp mCfgGrp; /* A config group. */ typedef struct mCfgGrp mCfgGrp; /* A config group. */
struct mCfgImpFuncs; /* Defined in mms_cfg-impl.h */
/* Read a config file, return the structure. */ /* Read a config file, return the structure. */
mCfg *mms_cfg_read(Octstr *file); mCfg *mms_cfg_read(Octstr *file);
/* Read conf from a module */
mCfg *mms_cfg_read2(struct mCfgImpFuncs *cfgfuncs, Octstr *init);
/* Destroy it all . */ /* Destroy it all . */
void mms_cfg_destroy(mCfg *cfg); void mms_cfg_destroy(mCfg *cfg);

View File

@ -755,7 +755,7 @@ int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, MM7Version_t *ver, List **hdrs, Octstr
int mm7_msgtype(MSoapMsg_t *m) int mm7_msgtype(MSoapMsg_t *m)
{ {
Octstr *typ = http_header_value(m->envelope, octstr_imm("MessageType")); Octstr *typ = m != NULL ? http_header_value(m->envelope, octstr_imm("MessageType")) : NULL;
int ret; int ret;
if (!typ) if (!typ)
@ -1011,6 +1011,30 @@ static MSoapMsg_t *mm7_soap_create(int msgtype, Octstr *otransid)
return m; return m;
} }
int mm7_msgtype_to_soaptype(int mtype, int isclientside)
{
int t;
switch (mtype) {
case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF:
t = isclientside ? MM7_TAG_SubmitReq : MM7_TAG_DeliverReq;
break;
case MMS_MSGTYPE_READ_ORIG_IND:
t = MM7_TAG_ReadReplyReq;
break;
case MMS_MSGTYPE_DELIVERY_IND:
t = MM7_TAG_DeliveryReportReq;
break;
case -1:
t = isclientside ? MM7_TAG_RSErrorRsp : MM7_TAG_VASPErrorRsp;
break;
default:
t = 0;
break;
}
return t;
}
MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto, MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
Octstr *transid, Octstr *srvcode, Octstr *transid, Octstr *srvcode,
Octstr *linkedid, int isclientside, Octstr *linkedid, int isclientside,
@ -1019,33 +1043,47 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
time_t uaprof_tstamp, time_t uaprof_tstamp,
List *hdrs) List *hdrs)
{ {
int i, n, mtype = mms_messagetype(msg); int i, n, mtype = mms_messagetype(msg), mm7type = mm7_msgtype_to_soaptype(mtype, isclientside);
MSoapMsg_t *m = NULL; MSoapMsg_t *m = NULL;
Octstr *xfrom = (from != NULL) ? octstr_format("+ %S", from) : NULL, *s; Octstr *xfrom = (from != NULL) ? octstr_format("+ %S", from) : NULL, *s;
Octstr *xuaprof_val = (uaprof) ? octstr_format("%S,%ld", uaprof, uaprof_tstamp) : NULL; Octstr *xuaprof_val = (uaprof) ? octstr_format("%S,%ld", uaprof, uaprof_tstamp) : NULL;
int tchanged = 0;
switch(mtype) { switch(mtype) {
case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF: case MMS_MSGTYPE_RETRIEVE_CONF:
m = mm7_soap_create(isclientside ? MM7_TAG_SubmitReq : MM7_TAG_DeliverReq,
transid); s = hdrs ? http_header_value(hdrs, octstr_imm("X-Mbuni-MM7-Type")) : NULL;
m->msg = mms_tomime(msg,1); if (s) { /* Might be Cancel or Replace instead of Send */
mm7type = mms_string_to_mm7tag(s);
gw_assert(mm7type >= 0);
octstr_destroy(s);
tchanged = 1;
}
m = mm7_soap_create(mm7type, transid);
if (mm7type != MM7_TAG_CancelReq) /* No body for cancel */
m->msg = mms_tomime(msg,1);
strip_non_essential_headers(m->msg); strip_non_essential_headers(m->msg);
for (i = 0, n = xto ? gwlist_len(xto) : 0; i < n; i++) { /* Add recipients. */ if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq) /* No recipients for replace and cancel*/
Octstr *xx = octstr_format("+ %S", gwlist_get(xto, i)); for (i = 0, n = xto ? gwlist_len(xto) : 0; i < n; i++) { /* Add recipients. */
http_header_add(m->envelope, "To", Octstr *xx = octstr_format("+ %S", gwlist_get(xto, i));
octstr_get_cstr(xx)); http_header_add(m->envelope, "To",
octstr_destroy(xx); octstr_get_cstr(xx));
octstr_destroy(xx);
}
else if ((s = http_header_value(hdrs, /* For replace and cancel, add message id */
octstr_imm("X-Mbuni-Message-ID"))) != NULL) {
http_header_add(m->envelope, "MessageID", octstr_get_cstr(s));
octstr_destroy(s);
} }
if (srvcode && mm7type != MM7_TAG_CancelReq)
if (srvcode)
http_header_add(m->envelope, http_header_add(m->envelope,
isclientside ? "ServiceCode" : "MMSRelayServerID", isclientside ? "ServiceCode" : "MMSRelayServerID",
octstr_get_cstr(srvcode)); octstr_get_cstr(srvcode));
if (linkedid) if (linkedid && mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "LinkedID", octstr_get_cstr(linkedid)); http_header_add(m->envelope, "LinkedID", octstr_get_cstr(linkedid));
if (xfrom) if (xfrom)
http_header_add(m->envelope, http_header_add(m->envelope,
@ -1062,7 +1100,8 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
http_header_add(m->envelope, "VASID", vasid); http_header_add(m->envelope, "VASID", vasid);
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class"))) != NULL) {
http_header_add(m->envelope, "MessageClass", octstr_get_cstr(s)); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "MessageClass", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} }
@ -1070,26 +1109,28 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Allow-Adaptations"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Allow-Adaptations"))) != NULL) {
char *val = (octstr_case_compare(s, octstr_imm("true")) == 0) ? char *val = (octstr_case_compare(s, octstr_imm("true")) == 0) ?
"true" : "false"; "true" : "false";
http_header_add(m->envelope, "allowAdaptations", val); if (mm7type != MM7_TAG_CancelReq)
http_header_add(m->envelope, "allowAdaptations", val);
octstr_destroy(s); octstr_destroy(s);
} }
if (distrib_indicator) if (distrib_indicator && mm7type != MM7_TAG_CancelReq)
http_header_add(m->envelope, "DistributionIndicator", http_header_add(m->envelope, "DistributionIndicator",
octstr_str_case_compare(distrib_indicator, "true") == 0 ? "true" : "false"); octstr_str_case_compare(distrib_indicator, "true") == 0 ? "true" : "false");
if (cparty) if (cparty && mm7type != MM7_TAG_CancelReq)
http_header_add(m->envelope, "ChargedParty", http_header_add(m->envelope, "ChargedParty",
octstr_get_cstr(cparty)); octstr_get_cstr(cparty));
octstr_destroy(distrib_indicator); octstr_destroy(distrib_indicator);
octstr_destroy(cparty); octstr_destroy(cparty);
} else { /* not clientside. */ } else { /* not clientside. */
if (xuaprof_val) /* only on DeliverReq. */ if (xuaprof_val && mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq) /* only on DeliverReq. */
http_header_add(m->envelope, "UACapabilities", octstr_get_cstr(xuaprof_val)); http_header_add(m->envelope, "UACapabilities", octstr_get_cstr(xuaprof_val));
} }
if ((s = mms_get_header_value(msg, octstr_imm("Date"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("Date"))) != NULL) {
http_header_add(m->envelope, "TimeStamp", octstr_get_cstr(s)); if (mm7type != MM7_TAG_CancelReq)
http_header_add(m->envelope, "TimeStamp", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} }
@ -1097,36 +1138,41 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
* care about the order of XML fields. * care about the order of XML fields.
*/ */
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Expiry"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Expiry"))) != NULL) {
http_header_add(m->envelope, "ExpiryDate", octstr_get_cstr(s)); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "ExpiryDate", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} }
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Delivery-Report"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Delivery-Report"))) != NULL) {
char *val = (octstr_case_compare(s, octstr_imm("Yes")) == 0) ? char *val = (octstr_case_compare(s, octstr_imm("Yes")) == 0) ?
"true" : "false"; "true" : "false";
http_header_add(m->envelope, "DeliveryReport", val); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "DeliveryReport", val);
octstr_destroy(s); octstr_destroy(s);
} }
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Read-Report"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Read-Report"))) != NULL) {
char *val = (octstr_case_compare(s, octstr_imm("Yes")) == 0) ? char *val = (octstr_case_compare(s, octstr_imm("Yes")) == 0) ?
"true" : "false"; "true" : "false";
http_header_add(m->envelope, "ReadReply", val); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "ReadReply", val);
octstr_destroy(s); octstr_destroy(s);
} }
} }
if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"))) != NULL) {
http_header_add(m->envelope, "Priority", octstr_get_cstr(s)); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "Priority", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} }
if ((s = mms_get_header_value(msg, octstr_imm("Subject"))) != NULL) { if ((s = mms_get_header_value(msg, octstr_imm("Subject"))) != NULL) {
http_header_add(m->envelope, "Subject", octstr_get_cstr(s)); if (mm7type != MM7_TAG_CancelReq && mm7type != MM7_TAG_ReplaceReq)
http_header_add(m->envelope, "Subject", octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} }
#if 0 /* handled above. */ #if 0 /* handled above. */
/* Should we bother to strip message part of headers??? */ /* Should we bother to strip message part of headers??? */
headers = mime_entity_headers(m->msg); headers = mime_entity_headers(m->msg);
@ -1144,9 +1190,7 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
break; break;
case MMS_MSGTYPE_READ_ORIG_IND: case MMS_MSGTYPE_READ_ORIG_IND:
case MMS_MSGTYPE_DELIVERY_IND: case MMS_MSGTYPE_DELIVERY_IND:
m = mm7_soap_create((mtype == MMS_MSGTYPE_READ_ORIG_IND) ? m = mm7_soap_create(mm7type, transid);
MM7_TAG_ReadReplyReq : MM7_TAG_DeliveryReportReq,
transid);
if (xfrom) if (xfrom)
http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom)); http_header_add(m->envelope, "Sender", octstr_get_cstr(xfrom));
@ -1188,10 +1232,37 @@ MSoapMsg_t *mm7_mmsmsg_to_soap(MmsMsg *msg, Octstr *from, List *xto,
break; break;
} }
if (m) { /* Add custom headers, hope caller knows what they are doing */
List *l = http_header_find_all(hdrs, "X-Mbuni-MM7-Headers");
int i, n;
for (i = 0, n = gwlist_len(l); i<n; i++) {
Octstr *name = NULL, *value = NULL;
int j;
http_header_get(l, i, &name, &value);
if (value && (j = octstr_search_char(value, ':', 0)) > 0) {
Octstr *h = octstr_copy(value, 0, j - 1);
Octstr *v = octstr_copy(value, j+1, octstr_len(value));
octstr_strip_blanks(h);
octstr_strip_blanks(v);
http_header_add(m->envelope, octstr_get_cstr(h), octstr_get_cstr(v));
octstr_destroy(h);
octstr_destroy(v);
}
octstr_destroy(name);
octstr_destroy(value);
}
http_destroy_headers(l);
}
octstr_destroy(xfrom); octstr_destroy(xfrom);
octstr_destroy(xuaprof_val); octstr_destroy(xuaprof_val);
return m; return m;
} }

View File

@ -39,6 +39,9 @@ typedef struct MM7Version_t {
/* Parse SOAP message given http headers and body. */ /* Parse SOAP message given http headers and body. */
extern MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body); extern MSoapMsg_t *mm7_parse_soap(List *headers, Octstr *body);
/* Convert message type to mm7 type code */
extern int mm7_msgtype_to_soaptype(int mtype, int isclientside);
/* Convert SOAP message to http headers and body. */ /* Convert SOAP message to http headers and body. */
extern int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, MM7Version_t *ver, List **hdrs, Octstr **body); extern int mm7_soapmsg_to_httpmsg(MSoapMsg_t *m, MM7Version_t *ver, List **hdrs, Octstr **body);

View File

@ -1955,7 +1955,7 @@ MmsMsg *mms_deleteconf(int menc, char *transid)
return m; return m;
} }
static int mms_msgsize(MmsMsg *m) int mms_msgsize(MmsMsg *m)
{ {
Octstr *s; Octstr *s;
int n; int n;

View File

@ -130,4 +130,7 @@ int mms_putbody(MmsMsg *msg, void *body, int ismultipart);
* returns 0 on success. * returns 0 on success.
*/ */
int mms_make_sendreq(MmsMsg *retrieveconf); int mms_make_sendreq(MmsMsg *retrieveconf);
/* Compute message size -- not altogether efficiently */
int mms_msgsize(MmsMsg *m);
#endif #endif

View File

@ -1171,77 +1171,80 @@ void mms_collect_envdata_from_msgheaders(List *mh, List **xto,
{ {
Octstr *s; Octstr *s;
List *l = http_header_find_all(mh, "To"); List *l;
if (l) {
int i, n; if (xto) {
for (i = 0, n = gwlist_len(l); i<n; i++) { l = http_header_find_all(mh, "To");
Octstr *name, *value; if (l != NULL) {
http_header_get(l, i, &name, &value); int i, n;
_mms_fixup_address(&value, unified_prefix, strip_prefixes, 1); for (i = 0, n = gwlist_len(l); i<n; i++) {
gwlist_append(*xto, value); Octstr *name, *value;
octstr_destroy(name); http_header_get(l, i, &name, &value);
} _mms_fixup_address(&value, unified_prefix, strip_prefixes, 1);
http_destroy_headers(l); gwlist_append(*xto, value);
} octstr_destroy(name);
}
l = http_header_find_all(mh, "Cc"); http_destroy_headers(l);
if (l) { }
int i, n;
for (i = 0, n = gwlist_len(l); i<n; i++) { l = http_header_find_all(mh, "Cc");
Octstr *name, *value; if (l) {
http_header_get(l, i, &name, &value); int i, n;
_mms_fixup_address(&value, unified_prefix, strip_prefixes, 1); for (i = 0, n = gwlist_len(l); i<n; i++) {
gwlist_append(*xto, value); Octstr *name, *value;
octstr_destroy(name); http_header_get(l, i, &name, &value);
_mms_fixup_address(&value, unified_prefix, strip_prefixes, 1);
} gwlist_append(*xto, value);
http_destroy_headers(l); octstr_destroy(name);
}
}
http_destroy_headers(l);
l = http_header_find_all(mh, "Bcc"); }
if (l) {
int i, n;
l = http_header_find_all(mh, "Bcc");
for (i = 0, n = gwlist_len(l); i<n; i++) { if (l) {
Octstr *name, *value; int i, n;
http_header_get(l, i, &name, &value);
_mms_fixup_address(&value, unified_prefix, strip_prefixes, 1); for (i = 0, n = gwlist_len(l); i<n; i++) {
gwlist_append(*xto, value); Octstr *name, *value;
octstr_destroy(name); http_header_get(l, i, &name, &value);
_mms_fixup_address(&value, unified_prefix, strip_prefixes, 1);
} gwlist_append(*xto, value);
http_destroy_headers(l); octstr_destroy(name);
}
http_destroy_headers(l);
}
} }
/* Find expiry and delivery times */ /* Find expiry and delivery times */
if (expiryt) { if (expiryt) {
s = http_header_value(mh, octstr_imm("X-Mms-Expiry")); s = http_header_value(mh, octstr_imm("X-Mms-Expiry"));
if (s) { if (s) {
*expiryt = date_parse_http(s); *expiryt = date_parse_http(s);
octstr_destroy(s); octstr_destroy(s);
} else } else
*expiryt = time(NULL) + default_msgexpiry; *expiryt = time(NULL) + default_msgexpiry;
if (max_msgexpiry > 0 if (max_msgexpiry > 0
&& (*expiryt - time(NULL)) > max_msgexpiry) && (*expiryt - time(NULL)) > max_msgexpiry)
*expiryt = time(NULL) + max_msgexpiry; *expiryt = time(NULL) + max_msgexpiry;
} }
if (deliveryt) { if (deliveryt) {
s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time")); s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time"));
if (s) { if (s) {
*deliveryt = date_parse_http(s); *deliveryt = date_parse_http(s);
octstr_destroy(s); octstr_destroy(s);
} else } else
*deliveryt = 0; *deliveryt = 0;
} }
if (subject) if (subject)
*subject = http_header_value(mh, octstr_imm("Subject")); *subject = http_header_value(mh, octstr_imm("Subject"));
if (otransid) if (otransid)
*otransid = http_header_value(mh, octstr_imm("X-Mms-Transaction-ID")); *otransid = http_header_value(mh, octstr_imm("X-Mms-Transaction-ID"));
} }
unsigned long _mshash(char *s) unsigned long _mshash(char *s)
@ -2155,41 +2158,41 @@ MIMEEntity *multipart_from_urls(List *url_list)
http_header_add(rh, "User-Agent", MM_NAME "/" VERSION); http_header_add(rh, "User-Agent", MM_NAME "/" VERSION);
for (i = 0, n = gwlist_len(url_list); i<n; i++) { for (i = 0, n = gwlist_len(url_list); i<n; i++) {
List *rph = NULL; List *rph = NULL;
Octstr *rbody = NULL; Octstr *rbody = NULL;
Octstr *url = gwlist_get(url_list, i); Octstr *url = gwlist_get(url_list, i);
if (mms_url_fetch_content(HTTP_METHOD_GET, if (mms_url_fetch_content(HTTP_METHOD_GET,
url, rh, NULL, &rph, &rbody) == HTTP_OK) { url, rh, NULL, &rph, &rbody) == HTTP_OK) {
List *mh = http_create_empty_headers(); List *mh = http_create_empty_headers();
Octstr *x; Octstr *x;
MIMEEntity *mx; MIMEEntity *mx;
if ((x = http_header_value(rph, octstr_imm("Content-Type"))) != NULL) { if ((x = http_header_value(rph, octstr_imm("Content-Type"))) != NULL) {
http_header_add(mh, "Content-Type", octstr_get_cstr(x)); http_header_add(mh, "Content-Type", octstr_get_cstr(x));
octstr_destroy(x); octstr_destroy(x);
} else } else
http_header_add(mh, "Content-Type", "application/content-stream"); http_header_add(mh, "Content-Type", "application/content-stream");
if ((x = http_header_value(rph, octstr_imm("Content-ID"))) != NULL) { if ((x = http_header_value(rph, octstr_imm("Content-ID"))) != NULL) {
http_header_add(mh, "Content-ID", octstr_get_cstr(x)); http_header_add(mh, "Content-ID", octstr_get_cstr(x));
octstr_destroy(x); octstr_destroy(x);
} }
if ((x = http_header_value(rph, octstr_imm("Content-Location"))) != NULL) { if ((x = http_header_value(rph, octstr_imm("Content-Location"))) != NULL) {
http_header_add(mh, "Content-Location", octstr_get_cstr(x)); http_header_add(mh, "Content-Location", octstr_get_cstr(x));
octstr_destroy(x); octstr_destroy(x);
} }
mx = mime_http_to_entity(mh, rbody); mx = mime_http_to_entity(mh, rbody);
mime_entity_add_part(m, mx); mime_entity_add_part(m, mx);
http_destroy_headers(mh); http_destroy_headers(mh);
mime_entity_destroy(mx); mime_entity_destroy(mx);
} else } else
mms_error(0, "multipart_from_urls", NULL, "Failed to load URL content for URL [%s]", mms_error(0, "multipart_from_urls", NULL, "Failed to load URL content for URL [%s]",
octstr_get_cstr(url)); octstr_get_cstr(url));
octstr_destroy(rbody); octstr_destroy(rbody);
http_destroy_headers(rph); http_destroy_headers(rph);
} }
http_destroy_headers(rh); http_destroy_headers(rh);

View File

@ -40,8 +40,6 @@
} while(0) } while(0)
static int auth_check(Octstr *user, Octstr *pass, List *headers, int *has_auth_hdr) static int auth_check(Octstr *user, Octstr *pass, List *headers, int *has_auth_hdr)
{ {
int i, res = -1; int i, res = -1;
@ -145,8 +143,8 @@ static void fixup_relayed_report(MmsMsg *m, MmscGrp *mmc, char *rtype, Octstr *s
(octstr_case_compare(status, octstr_imm("Deferred")) != 0 && (octstr_case_compare(status, octstr_imm("Deferred")) != 0 &&
octstr_case_compare(status, octstr_imm("Forwarded")) != 0)) octstr_case_compare(status, octstr_imm("Forwarded")) != 0))
mms_dlr_url_remove(value, rtype, mmc->group_id); /* only remove if not mms_dlr_url_remove(value, rtype, mmc->group_id); /* only remove if not
* interim status * interim status
*/ */
#endif #endif
} }
octstr_destroy(newmsgid); octstr_destroy(newmsgid);
@ -208,11 +206,16 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
unsigned char *msgtype = (unsigned char *)""; unsigned char *msgtype = (unsigned char *)"";
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL; Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL;
List *qhdr = http_create_empty_headers(); List *qhdr = http_create_empty_headers();
Octstr *r, *s, *transid = NULL, *value = 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) {
msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq)); msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq));
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
} else
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
debug("mmsbox.mm7sendinterface", 0, debug("mmsbox.mm7sendinterface", 0,
" --> Enterred mm7dispatch interface, mreq=[%s] mtype=[%s] <-- ", " --> Enterred mm7dispatch interface, mreq=[%s] mtype=[%s] <-- ",
mreq ? "Ok" : "Null", mreq ? "Ok" : "Null",
@ -230,10 +233,11 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
if (!from) if (!from)
from = octstr_create("anon@anon"); from = octstr_create("anon@anon");
qdir = get_mmsbox_queue_dir(from, to, h->m, &mmc_id); /* get routing info. */ qdir = get_mmsbox_queue_dir(from, to, h->m, &mmc_id); /* get routing info. */
switch (mm7_msgtype(mreq)) { switch (mm7_msgtype(mreq)) {
Octstr *value, *value2; Octstr *value2;
case MM7_TAG_DeliverReq: case MM7_TAG_DeliverReq:
m = mm7_soap_to_mmsmsg(mreq, from); m = mm7_soap_to_mmsmsg(mreq, from);
@ -282,20 +286,23 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
mms_error(0, "MM7", h->m->id, mms_error(0, "MM7", h->m->id,
"Failed to write queue entry for received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", "Failed to write queue entry for received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!",
octstr_get_cstr(h->m->id)); octstr_get_cstr(h->m->id));
} else {
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
} else {
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
msgid = mms_make_msgid(octstr_get_cstr(qf), NULL); msgid = mms_make_msgid(octstr_get_cstr(qf), NULL);
mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox", mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox",
h->ua, NULL); h->ua, NULL);
} }
octstr_destroy(linkedid); octstr_destroy(linkedid);
octstr_destroy(value);
http_destroy_headers(qh); http_destroy_headers(qh);
} else { } else {
mms_error(0, "MM7", h->m->id, mms_error(0, "MM7", h->m->id,
"Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!", "Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!",
octstr_get_cstr(h->m->id)); octstr_get_cstr(h->m->id));
status = 4000; status = 4000;
} }
mresp = mm7_make_resp(mreq, status, NULL,1); mresp = mm7_make_resp(mreq, status, NULL,1);
@ -333,14 +340,17 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
octstr_get_cstr(qdir), octstr_get_cstr(qdir),
"MM7/SOAP-IN", "MM7/SOAP-IN",
NULL); NULL);
if (qf) if (qf) {
/* Log to access log */ /* Log to access log */
mms_log("Received DLR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); mms_log("Received DLR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
else MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
status = 4000; } else {
status = 4000;
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR,3);
}
mresp = mm7_make_resp(mreq, status, NULL,1); mresp = mm7_make_resp(mreq, status, NULL,1);
octstr_destroy(value);
octstr_destroy(value2); octstr_destroy(value2);
break; break;
@ -362,15 +372,16 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
octstr_get_cstr(qdir), octstr_get_cstr(qdir),
"MM7/SOAP-IN", "MM7/SOAP-IN",
NULL); NULL);
if (qf) if (qf) {
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
/* Log to access log */ /* Log to access log */
mms_log("Received RR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); mms_log("Received RR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
else } else {
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
status = 4000; status = 4000;
}
mresp = mm7_make_resp(mreq, status, NULL,1); mresp = mm7_make_resp(mreq, status, NULL,1);
octstr_destroy(value);
octstr_destroy(value2); octstr_destroy(value2);
break; break;
@ -380,12 +391,34 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
break; break;
} }
done:
/* Invoke call back */
s = mm7_soap_header_value(mreq, octstr_imm("MM7Version"));
r = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
transid = mm7_soap_header_value(mreq, octstr_imm("TransactionID"));
mmsbox_event_cb(h->m->id, mm7_msgtype(mreq), 0, s, 0,
octstr_len(h->body), 0, from,
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL, r, transid, NULL, value);
octstr_destroy(s);
octstr_destroy(r);
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
http_close_client(h->client); http_close_client(h->client);
if (mresp) {
Octstr *s = octstr_format("%d.%d.%d", h->m->ver.major, h->m->ver.minor1, h->m->ver.minor2);
Octstr *r = mm7_soap_header_value(mresp, octstr_imm("MessageID"));
mmsbox_event_cb(h->m->id, mm7_msgtype(mresp), 0, s, status,
octstr_len(reply_body), 0, to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
from, r, transid, NULL, NULL);
octstr_destroy(s);
octstr_destroy(r);
} else
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 2);
debug("mmsbox.mm7sendinterface", 0, debug("mmsbox.mm7sendinterface", 0,
" --> leaving mm7dispatch interface, mresp=[%s], body=[%s], mm7_status=[%d] <-- ", " --> leaving mm7dispatch interface, mresp=[%s], body=[%s], mm7_status=[%d] <-- ",
mresp ? "ok" : "(null)", mresp ? "ok" : "(null)",
@ -405,6 +438,8 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
octstr_destroy(mmc_id); octstr_destroy(mmc_id);
http_destroy_headers(qhdr); http_destroy_headers(qhdr);
octstr_destroy(value);
octstr_destroy(transid);
return MM7_SOAP_STATUS_OK(status) ? 0 : -1; return MM7_SOAP_STATUS_OK(status) ? 0 : -1;
} }
@ -446,9 +481,12 @@ static int queue_dlr(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgid, Octs
/* Log to access log */ /* Log to access log */
mms_log("Received DLR", from, lto, -1, msgid, status, mmc ? mmc->id : NULL, "MMSBox", NULL, NULL); mms_log("Received DLR", from, lto, -1, msgid, status, mmc ? mmc->id : NULL, "MMSBox", NULL, NULL);
ret = 0; ret = 0;
} else MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
} else {
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
ret = -1; ret = -1;
}
octstr_destroy(qf); octstr_destroy(qf);
http_destroy_headers(rqh); http_destroy_headers(rqh);
octstr_destroy(rr_uri); octstr_destroy(rr_uri);
@ -470,13 +508,13 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
Octstr *reply_body = NULL, *value = NULL, *value2 = NULL; Octstr *reply_body = NULL, *value = NULL, *value2 = NULL;
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, *s;
Octstr *hfrom = NULL, *rr_uri = NULL; Octstr *hfrom = NULL, *rr_uri = NULL;
time_t expiryt = -1, deliveryt = -1; time_t expiryt = -1, deliveryt = -1;
Octstr *qf = NULL, *xver = NULL, *mmc_id = NULL, *qdir = NULL; Octstr *qf = NULL, *xver = NULL, *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 = -1, mm7type = -1;
debug("mmsbox.mm7eaif.sendinterface", 0, debug("mmsbox.mm7eaif.sendinterface", 0,
" --> Enterred eaif send interface, blen=[%d] <--- ", " --> Enterred eaif send interface, blen=[%d] <--- ",
@ -488,12 +526,15 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
http_header_add(rh, "Content-Type", "text/plain"); http_header_add(rh, "Content-Type", "text/plain");
hstatus = HTTP_BAD_REQUEST; hstatus = HTTP_BAD_REQUEST;
reply_body = octstr_format("Unexpected MMS message, no body?"); reply_body = octstr_format("Unexpected MMS message, no body?");
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE,2);
goto done; goto done;
} } else
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
/* XXXX handle delivery reports differently. */ /* XXXX handle delivery reports differently. */
mtype = mms_messagetype(m); mtype = mms_messagetype(m);
mm7type = mm7_msgtype_to_soaptype(mtype, 1);
mh = mms_message_headers(m); mh = mms_message_headers(m);
/* Now get sender and receiver data. /* Now get sender and receiver data.
* for now we ignore adaptation flags. * for now we ignore adaptation flags.
@ -581,12 +622,13 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
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);
hstatus = HTTP_NO_CONTENT;
} else
hstatus = HTTP_INTERNAL_SERVER_ERROR;
octstr_destroy(value); hstatus = HTTP_NO_CONTENT;
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
} else {
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
hstatus = HTTP_INTERNAL_SERVER_ERROR;
}
octstr_destroy(value2); octstr_destroy(value2);
break; break;
case MMS_MSGTYPE_DELIVERY_IND: case MMS_MSGTYPE_DELIVERY_IND:
@ -613,11 +655,12 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
if (qf) { if (qf) {
/* Log to access log */ /* Log to access log */
mms_log("DeliveryReport", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); mms_log("DeliveryReport", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
hstatus = HTTP_NO_CONTENT; hstatus = HTTP_NO_CONTENT;
} else } else {
hstatus = HTTP_INTERNAL_SERVER_ERROR; hstatus = HTTP_INTERNAL_SERVER_ERROR;
octstr_destroy(value); MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
}
octstr_destroy(value2); octstr_destroy(value2);
break; break;
@ -645,22 +688,37 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
/* Log to access log */ /* Log to access log */
mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
hstatus = HTTP_NO_CONTENT; hstatus = HTTP_NO_CONTENT;
} else MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
} else {
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
hstatus = HTTP_INTERNAL_SERVER_ERROR; hstatus = HTTP_INTERNAL_SERVER_ERROR;
}
octstr_destroy(value);
octstr_destroy(value2); octstr_destroy(value2);
break; break;
} }
done:
s = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-Version"));
mmsbox_event_cb(h->m->id, mm7type, 0, s, 0,
msize, 0, hfrom,
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
msgid, otransid, NULL, value);
octstr_destroy(s);
done:
xver = octstr_format(EAIF_VERSION, h->m->ver.major, h->m->ver.minor1); xver = octstr_format(EAIF_VERSION, h->m->ver.major, h->m->ver.minor1);
http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver));
mmsbox_event_cb(h->m->id, mm7type >= 0 ? mm7type + 1 : MM7_TAG_VASPErrorRsp, 0,
xver, hstatus,
0, 0, to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
hfrom,
msgid, otransid, NULL, reply_body);
http_send_reply(h->client, hstatus, rh, reply_body ? reply_body : octstr_imm(""));
octstr_destroy(xver); octstr_destroy(xver);
http_send_reply(h->client, hstatus, rh, octstr_imm(""));
http_destroy_headers(hto); http_destroy_headers(hto);
http_destroy_headers(rqh); http_destroy_headers(rqh);
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
@ -671,7 +729,8 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
octstr_destroy(qf); octstr_destroy(qf);
octstr_destroy(mmc_id); octstr_destroy(mmc_id);
octstr_destroy(rr_uri); octstr_destroy(rr_uri);
octstr_destroy(value);
http_destroy_headers(mh); http_destroy_headers(mh);
mms_destroy(m); mms_destroy(m);
@ -690,10 +749,10 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
Octstr *hto = NULL, *subject = NULL, *msgid = NULL; Octstr *hto = NULL, *subject = NULL, *msgid = NULL;
Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL; Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL;
time_t expiryt = -1, deliveryt = -1; time_t expiryt = -1, deliveryt = -1;
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *s; Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *value = NULL, *s;
int msize; int msize;
int dlr, rr; int dlr, rr;
int mtype; int mtype = -1, mm7type = -1;
List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers(); List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers();
parse_cgivars(h->headers, h->body, &h->cgivars, &cgivars_ctypes); parse_cgivars(h->headers, h->body, &h->cgivars, &cgivars_ctypes);
@ -712,7 +771,8 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
http_header_add(rh, "Content-Type", "text/plain"); http_header_add(rh, "Content-Type", "text/plain");
hstatus = HTTP_BAD_REQUEST; hstatus = HTTP_BAD_REQUEST;
reply_body = octstr_format("Missing 'to' argument"); reply_body = octstr_format("Missing 'to' argument");
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
goto done; goto done;
} else if (hfrom == NULL) { } else if (hfrom == NULL) {
@ -720,6 +780,7 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
hstatus = HTTP_BAD_REQUEST; hstatus = HTTP_BAD_REQUEST;
reply_body = octstr_format("Missing 'from' argument"); reply_body = octstr_format("Missing 'from' argument");
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
goto done; goto done;
} else if (body == NULL || /* A message is required, and must parse */ } else if (body == NULL || /* A message is required, and must parse */
@ -728,13 +789,16 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
hstatus = HTTP_BAD_REQUEST; hstatus = HTTP_BAD_REQUEST;
reply_body = octstr_format("Unexpected MMS message, no content?"); reply_body = octstr_format("Unexpected MMS message, no content?");
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
goto done; goto done;
} } else
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
to = octstr_split_words(hto); to = octstr_split_words(hto);
mtype = mms_messagetype(m); mtype = mms_messagetype(m);
mm7type = mm7_msgtype_to_soaptype(mtype, 1);
mh = mms_message_headers(m); mh = mms_message_headers(m);
/* find interesting headers. */ /* find interesting headers. */
@ -757,7 +821,7 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */ qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */
switch(mtype) { switch(mtype) {
Octstr *value, *value2; Octstr *value2;
case MMS_MSGTYPE_SEND_REQ: case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF: case MMS_MSGTYPE_RETRIEVE_CONF:
@ -779,7 +843,7 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
rr = 1; rr = 1;
else else
rr = 0; rr = 0;
octstr_destroy(value);
if (deliveryt < 0) if (deliveryt < 0)
deliveryt = time(NULL); deliveryt = time(NULL);
@ -796,8 +860,8 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it
* if a DLR is relayed backwards. * if a DLR is relayed backwards.
*/ */
Octstr *t = mms_maketransid(NULL, octstr_imm(MM_NAME)); /* make a fake transaction id so dlr works*/ Octstr *t = mms_maketransid(NULL, octstr_imm(MM_NAME)); /* make a fake transaction id so dlr works*/
http_header_add(rqh, "X-Mbuni-TransactionID", octstr_get_cstr(t)); http_header_add(rqh, "X-Mbuni-TransactionID", octstr_get_cstr(t));
@ -823,11 +887,14 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
if (qf) { if (qf) {
/* Log to access log */ /* Log to access log */
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
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);
hstatus = HTTP_OK; hstatus = HTTP_OK;
} else } else {
hstatus = HTTP_INTERNAL_SERVER_ERROR; hstatus = HTTP_INTERNAL_SERVER_ERROR;
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
}
break; break;
case MMS_MSGTYPE_DELIVERY_IND: case MMS_MSGTYPE_DELIVERY_IND:
msgid = mms_get_header_value(m, octstr_imm("Message-ID")); msgid = mms_get_header_value(m, octstr_imm("Message-ID"));
@ -854,9 +921,11 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
mms_log("DeliveryReport", hfrom, to, -1, msgid,value, h->m->id, "MMSBox", h->ua, NULL); mms_log("DeliveryReport", hfrom, to, -1, msgid,value, h->m->id, "MMSBox", h->ua, NULL);
hstatus = HTTP_OK; hstatus = HTTP_OK;
} else MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
} else {
hstatus = HTTP_INTERNAL_SERVER_ERROR; hstatus = HTTP_INTERNAL_SERVER_ERROR;
octstr_destroy(value); MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
}
octstr_destroy(value2); octstr_destroy(value2);
break; break;
@ -884,18 +953,32 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
/* Log to access log */ /* Log to access log */
mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL); mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
hstatus = HTTP_NO_CONTENT; hstatus = HTTP_NO_CONTENT;
} else MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
} else {
hstatus = HTTP_INTERNAL_SERVER_ERROR; hstatus = HTTP_INTERNAL_SERVER_ERROR;
octstr_destroy(value); MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
}
octstr_destroy(value2); octstr_destroy(value2);
break; break;
} }
done:
mmsbox_event_cb(h->m->id, mm7type, 0, octstr_imm("1.0"), 0,
msize, 0, hfrom,
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
msgid, octstr_imm("0000"), NULL, value);
done:
mmsbox_event_cb(h->m->id, mm7type >= 0 ? mm7type + 1 : MM7_TAG_VASPErrorRsp, 0,
octstr_imm("1.0"), hstatus,
0, 0, to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
hfrom,
msgid, octstr_imm("0001"), NULL, reply_body);
http_header_add(rh, "X-Mbuni-Version", VERSION); http_header_add(rh, "X-Mbuni-Version", VERSION);
http_send_reply(h->client, hstatus, rh, msgid ? msgid : (qf ? qf : octstr_imm(""))); http_send_reply(h->client, hstatus, rh, msgid ? msgid : reply_body ? reply_body : qf ? qf : octstr_imm(""));
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy); gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
@ -904,13 +987,14 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
octstr_destroy(qf); octstr_destroy(qf);
octstr_destroy(mmc_id); octstr_destroy(mmc_id);
octstr_destroy(msgid); octstr_destroy(msgid);
octstr_destroy(reply_body);
http_destroy_headers(mh); http_destroy_headers(mh);
http_destroy_headers(rh); http_destroy_headers(rh);
http_destroy_headers(rqh); http_destroy_headers(rqh);
octstr_destroy(value);
octstr_destroy(hfrom);
if (m) mms_destroy(m);
mms_destroy(m);
http_destroy_cgiargs(cgivars_ctypes); http_destroy_cgiargs(cgivars_ctypes);
@ -923,6 +1007,7 @@ static void dispatch_mm7_recv(List *rl)
MmsBoxHTTPClientInfo *h; MmsBoxHTTPClientInfo *h;
hmon->register_thread();
while ((h = gwlist_consume(rl)) != NULL) { while ((h = gwlist_consume(rl)) != NULL) {
int ret = -1, has_auth = 0; int ret = -1, has_auth = 0;
MmscGrp *m = h->m; MmscGrp *m = h->m;
@ -956,6 +1041,7 @@ static void dispatch_mm7_recv(List *rl)
h->m->mo_errors++; h->m->mo_errors++;
free_mmsbox_http_clientInfo(h, 1); free_mmsbox_http_clientInfo(h, 1);
} }
hmon->unregister_thread();
} }
void mmsc_receive_func(MmscGrp *m) void mmsc_receive_func(MmscGrp *m)
@ -967,6 +1053,8 @@ void mmsc_receive_func(MmscGrp *m)
gwlist_add_producer(mmsc_incoming_reqs); gwlist_add_producer(mmsc_incoming_reqs);
hmon->register_thread();
for (i = 0; i<maxthreads; i++) for (i = 0; i<maxthreads; i++)
thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs); thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
@ -1000,9 +1088,9 @@ void mmsc_receive_func(MmscGrp *m)
h.ua = http_header_value(h.headers, octstr_imm("User-Agent")); h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
mms_error_ex("auth",0, "MM7", m->id, "HTTP: Incoming IP denied MMSC[%s] ip=[%s], ua=[%s], disconnected", mms_error_ex("auth",0, "MM7", m->id, "HTTP: Incoming IP denied MMSC[%s] ip=[%s], ua=[%s], disconnected",
m->id ? octstr_get_cstr(m->id) : "(none)", m->id ? octstr_get_cstr(m->id) : "(none)",
h.ip ? octstr_get_cstr(h.ip) : "(none)", h.ip ? octstr_get_cstr(h.ip) : "(none)",
h.ua ? octstr_get_cstr(h.ua) : "(none)"); h.ua ? octstr_get_cstr(h.ua) : "(none)");
http_send_reply(h.client, HTTP_FORBIDDEN, NULL, http_send_reply(h.client, HTTP_FORBIDDEN, NULL,
octstr_imm("Access denied.")); octstr_imm("Access denied."));
@ -1019,6 +1107,7 @@ void mmsc_receive_func(MmscGrp *m)
gwlist_destroy(mmsc_incoming_reqs, NULL); gwlist_destroy(mmsc_incoming_reqs, NULL);
gw_free(thids); gw_free(thids);
hmon->unregister_thread();
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id)); debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id));
} }
@ -1033,11 +1122,12 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
Octstr *linkedid, Octstr *linkedid,
char *vasid, char *vasid,
Octstr *service_code, Octstr *service_code,
List *hdrs, MmsEnvelope *e,
MmsMsg *m, Octstr **error, MmsMsg *m, Octstr **error,
List **errl, List **errl,
int *retry) int *retry)
{ {
List *hdrs = e ? e->hdrs : NULL;
Octstr *ret = NULL; Octstr *ret = NULL;
int mtype = mms_messagetype(m); int mtype = mms_messagetype(m);
int hstatus = HTTP_OK, tstatus = -1; int hstatus = HTTP_OK, tstatus = -1;
@ -1045,13 +1135,15 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
MSoapMsg_t *mreq = NULL, *mresp = NULL; MSoapMsg_t *mreq = NULL, *mresp = NULL;
List *rh = NULL, *ph = NULL; List *rh = NULL, *ph = NULL;
Octstr *body = NULL, *rbody = NULL, *url = NULL; Octstr *body = NULL, *rbody = NULL, *url = NULL;
Octstr *s; Octstr *s, *r, *status_details = NULL;
char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL); char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL);
if (e == NULL || mmc == NULL)
goto done1;
mms_info(0, "MM7", mmc->id, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s", mms_info(0, "MM7", mmc->id, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s",
mmc->id ? octstr_get_cstr(mmc->id) : "", mmc->id ? octstr_get_cstr(mmc->id) : "",
mms_message_type_to_cstr(mtype), mms_message_type_to_cstr(mtype),
octstr_get_cstr(from), octstr_get_cstr(to)); octstr_get_cstr(from), octstr_get_cstr(to));
gwlist_append(xto, to); gwlist_append(xto, to);
@ -1078,14 +1170,30 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status=[%d]!", *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status=[%d]!",
mmc->mmsc_url, hstatus); mmc->mmsc_url, hstatus);
if (hstatus < 0)
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
goto done1; goto done1;
} else {
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
} }
/* Invoke call back */
s = mm7_soap_header_value(mreq, octstr_imm("MM7Version"));
r = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
mmsbox_event_cb(mmc->id, mm7_msgtype(mreq), 0, s, 0,
mms_msgsize(m), e->attempts, e->from,
to,r, transid, hdrs, NULL);
octstr_destroy(s);
octstr_destroy(r);
if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) { if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) {
*error = octstr_format("Failed to parse MMSC[url=%S, id=%S] response!", *error = octstr_format("Failed to parse MMSC[url=%S, id=%S] response!",
mmc->mmsc_url, mmc->id); mmc->mmsc_url, mmc->id);
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
goto done1; goto done1;
} } else
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
if (errl) { /* Pick up status stuff -- for DLR */ if (errl) { /* Pick up status stuff -- for DLR */
if (*errl == NULL) if (*errl == NULL)
@ -1105,36 +1213,46 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) { if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) {
tstatus = atoi(octstr_get_cstr(s)); tstatus = atoi(octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
} else if ((s = mm7_soap_header_value(mresp, octstr_imm("faultstring"))) != NULL) { } else if ((s = mm7_soap_header_value(mresp, octstr_imm("faultstring"))) != NULL) {
tstatus = atoi(octstr_get_cstr(s)); tstatus = atoi(octstr_get_cstr(s));
octstr_destroy(s); octstr_destroy(s);
} else MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
} else {
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
tstatus = MM7_SOAP_FORMAT_CORRUPT; tstatus = MM7_SOAP_FORMAT_CORRUPT;
}
if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) { if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) {
Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details"));
char *tmp = (char *)mms_soap_status_to_cstr(tstatus); char *tmp = (char *)mms_soap_status_to_cstr(tstatus);
Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details"));
if (detail == NULL) if (detail == NULL)
detail = mm7_soap_header_value(mresp, octstr_imm("faultcode")); detail = mm7_soap_header_value(mresp, octstr_imm("faultcode"));
ret = NULL; ret = NULL;
mms_info(0, "MM7", mmc->id, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]", mms_info(0, "MM7", mmc->id, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]",
mmc ? octstr_get_cstr(mmc->id) : "", mmc ? octstr_get_cstr(mmc->id) : "",
tstatus, tmp ? tmp : "", tstatus, tmp ? tmp : "",
detail ? octstr_get_cstr(detail) : ""); detail ? octstr_get_cstr(detail) : "");
*error = octstr_format("Failed to deliver to MMC[url=%S, id=%S], status=[%d=>%s]!", *error = octstr_format("Failed to deliver to MMC[url=%S, id=%S], status=[%d=>%s]!",
mmc->mmsc_url, mmc->mmsc_url,
mmc->id, mmc->id,
tstatus, tstatus,
tmp ? tmp : ""); tmp ? tmp : "");
octstr_destroy(detail); status_details = detail ? octstr_duplicate(detail) : tmp ? octstr_create(tmp) : octstr_imm("");
octstr_destroy(detail);
} else { } else {
ret = mm7_soap_header_value(mresp, octstr_imm("MessageID")); ret = mm7_soap_header_value(mresp, octstr_imm("MessageID"));
mms_info(0, "MM7", NULL, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id), mms_info(0, "MM7", NULL, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id),
tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)"); tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)");
} }
s = mm7_soap_header_value(mresp, octstr_imm("MM7Version"));
mmsbox_event_cb(mmc->id, mm7_msgtype(mresp), 0, s, tstatus,
0, e->attempts, e->from,
to, ret, transid, hdrs, status_details);
octstr_destroy(s);
if (ret) if (ret)
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
@ -1148,31 +1266,36 @@ done1:
http_destroy_headers(ph); http_destroy_headers(ph);
octstr_destroy(rbody); octstr_destroy(rbody);
octstr_destroy(url); octstr_destroy(url);
gwlist_destroy(xto, NULL); gwlist_destroy(xto, NULL);
octstr_destroy(status_details);
return ret; return ret;
} }
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to, static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
Octstr *transid, Octstr *transid,
char *vasid, char *vasid,
List *hdrs, MmsEnvelope *e,
MmsMsg *m, Octstr **error, MmsMsg *m, Octstr **error,
int *retry) int *retry)
{ {
List *hdrs = e ? e->hdrs : NULL;
Octstr *ret = NULL, *resp = NULL; Octstr *ret = NULL, *resp = NULL;
int mtype = mms_messagetype(m); int mtype = mms_messagetype(m);
int hstatus = HTTP_OK; int hstatus = HTTP_OK;
List *rh = http_create_empty_headers(), *ph = NULL; List *rh = http_create_empty_headers(), *ph = NULL;
Octstr *body = NULL, *rbody = NULL, *xver = NULL; Octstr *body = NULL, *rbody = NULL, *xver = NULL;
char *msgtype; char *msgtype;
MmsMsg *mresp = NULL;
int mresp_type = -1;
if (e == NULL || mmc == NULL)
goto done;
mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s", mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s",
mmc ? octstr_get_cstr(mmc->id) : "", mmc && mmc->id ? octstr_get_cstr(mmc->id) : "",
mms_message_type_to_cstr(mtype), mms_message_type_to_cstr(mtype),
octstr_get_cstr(from), octstr_get_cstr(to)); octstr_get_cstr(from), octstr_get_cstr(to));
http_header_remove_all(rh, "X-Mms-Allow-Adaptations"); http_header_remove_all(rh, "X-Mms-Allow-Adaptations");
http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to)); http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to));
@ -1180,7 +1303,7 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1); xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1);
http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver)); http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver));
octstr_destroy(xver);
if (mtype == MMS_MSGTYPE_SEND_REQ || if (mtype == MMS_MSGTYPE_SEND_REQ ||
mtype == MMS_MSGTYPE_RETRIEVE_CONF) { mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
@ -1203,24 +1326,32 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
mms_replace_header_value(m,"X-Mms-Transaction-ID", mms_replace_header_value(m,"X-Mms-Transaction-ID",
transid ? octstr_get_cstr(transid) : "000"); transid ? octstr_get_cstr(transid) : "000");
body = mms_tobinary(m); body = mms_tobinary(m);
mmsbox_event_cb(mmc->id, mm7_msgtype_to_soaptype(mtype,1), 0, xver, 0,
octstr_len(body), e->attempts, e->from,
to, NULL, transid, hdrs, NULL);
hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody); hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody);
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !",
mmc->mmsc_url, hstatus); mmc->mmsc_url, hstatus);
if (hstatus < 0)
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
} else { } else {
MmsMsg *mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL; MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL;
mresp_type = mresp ? mms_messagetype(mresp) : -1;
resp = octstr_imm("Ok"); resp = octstr_imm("Ok");
if (mresp && mms_messagetype(mresp) == MMS_MSGTYPE_SEND_CONF) if (mresp_type == MMS_MSGTYPE_SEND_CONF)
resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status")); resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status"));
if (octstr_case_compare(resp, octstr_imm("ok")) != 0) if (octstr_case_compare(resp, octstr_imm("ok")) != 0)
hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */ hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */
else if (mresp) else if (mresp)
ret = mms_get_header_value(mresp, octstr_imm("Message-ID")); ret = mms_get_header_value(mresp, octstr_imm("Message-ID"));
mms_destroy(mresp);
} }
if (hstatus < 0) if (hstatus < 0)
@ -1234,42 +1365,57 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id")); ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id"));
} }
*retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); *retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0));
mmsbox_event_cb(mmc->id,
mm7_msgtype_to_soaptype(mresp_type,1), 0, xver, hstatus,
0, e->attempts, e->from,
to, ret, transid, hdrs, resp);
if (ret) if (ret)
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
#if 0 #if 0
mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]", mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]",
octstr_get_cstr(mmc->id), octstr_get_cstr(mmc->id),
hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)"); hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)");
#endif #endif
done:
mms_destroy(mresp);
http_destroy_headers(rh); http_destroy_headers(rh);
octstr_destroy(body); octstr_destroy(body);
http_destroy_headers(ph); http_destroy_headers(ph);
octstr_destroy(rbody); octstr_destroy(rbody);
octstr_destroy(resp); octstr_destroy(resp);
octstr_destroy(xver);
return ret; return ret;
} }
static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to, static Octstr *mm7http_send(MmscGrp *mmc,
MmsEnvelope *e,
Octstr *from, Octstr *to,
MmsMsg *m, Octstr **error, MmsMsg *m, Octstr **error,
int *retry) int *retry)
{ {
List *hdrs = e ? e->hdrs : NULL;
Octstr *ret = NULL; Octstr *ret = NULL;
int mtype = mms_messagetype(m); int mtype = mms_messagetype(m);
int hstatus = HTTP_OK; int hstatus = HTTP_OK;
List *rh, *ph = NULL; List *rh = NULL, *ph = NULL;
Octstr *body = NULL, *rbody = NULL; Octstr *body = NULL, *rbody = NULL;
Octstr *mms; Octstr *mms = NULL;
MIMEEntity *form_data = make_multipart_formdata(); MIMEEntity *form_data = make_multipart_formdata();
Octstr *transid = e ? octstr_create(e->xqfname) : NULL;
int mm7type = mm7_msgtype_to_soaptype(mtype,1);
if (e == NULL || mmc == NULL)
goto done;
mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s", mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s",
mmc ? octstr_get_cstr(mmc->id) : "", mmc && mmc->id ? octstr_get_cstr(mmc->id) : "",
mms_message_type_to_cstr(mtype), mms_message_type_to_cstr(mtype),
octstr_get_cstr(from), octstr_get_cstr(to)); octstr_get_cstr(from), octstr_get_cstr(to));
mms = mms_tobinary(m); mms = mms_tobinary(m);
@ -1277,7 +1423,11 @@ static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to,
add_multipart_form_field(form_data, "from", "text/plain", NULL, from); add_multipart_form_field(form_data, "from", "text/plain", NULL, from);
add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms); add_multipart_form_field(form_data, "mms", "application/vnd.wap.mms-message", NULL, mms);
mmsbox_event_cb(mmc->id, mm7type, 0, octstr_imm("1.0"), 0,
octstr_len(mms), e->attempts, from,
to, NULL, transid, hdrs, NULL);
rh = mime_entity_headers(form_data); rh = mime_entity_headers(form_data);
body = mime_entity_body(form_data); body = mime_entity_body(form_data);
@ -1286,23 +1436,35 @@ static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to,
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) { if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !", *error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !",
mmc->mmsc_url, hstatus); mmc->mmsc_url, hstatus);
if (hstatus < 0)
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
} else { } else {
ret = rbody ? octstr_duplicate(rbody) : NULL; ret = rbody ? octstr_duplicate(rbody) : NULL;
if (ret) if (ret)
octstr_strip_blanks(ret); octstr_strip_blanks(ret);
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
} }
mmsbox_event_cb(mmc->id, mm7type + 1, /* Always represents response type */
0, octstr_imm("1.0"), hstatus,
0, e->attempts, e->from,
to, ret, transid, hdrs, NULL);
*retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0)); *retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0));
if (ret) if (ret)
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL); mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
done:
http_destroy_headers(rh); http_destroy_headers(rh);
octstr_destroy(body); octstr_destroy(body);
http_destroy_headers(ph); http_destroy_headers(ph);
octstr_destroy(rbody); octstr_destroy(rbody);
octstr_destroy(mms); octstr_destroy(mms);
mime_entity_destroy(form_data); mime_entity_destroy(form_data);
octstr_destroy(transid);
return ret; return ret;
} }
@ -1330,18 +1492,18 @@ static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e, Octstr *to,
mutex_lock(mmc->mutex); { /* Grab a lock on it. */ mutex_lock(mmc->mutex); { /* Grab a lock on it. */
Octstr *err = NULL; Octstr *err = NULL;
if (mmc->type == SOAP_MMSC) if (mmc->type == SOAP_MMSC)
id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, hdrs, m, &err, errhdrs, &retry); id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, e, m, &err, errhdrs, &retry);
else if (mmc->type == EAIF_MMSC) else if (mmc->type == EAIF_MMSC)
id = mm7eaif_send(mmc, from, to, transid, vasid, hdrs, m, &err, &retry); id = mm7eaif_send(mmc, from, to, transid, vasid, e, m, &err, &retry);
else if (mmc->type == HTTP_MMSC) else if (mmc->type == HTTP_MMSC)
id = mm7http_send(mmc, from, to, m, &err, &retry); id = mm7http_send(mmc,e, from, to, m, &err, &retry);
else if (mmc->type == CUSTOM_MMSC && mmc->custom_started) else if (mmc->type == CUSTOM_MMSC && mmc->custom_started)
id = mmc->fns->send_msg(mmc->data, id = mmc->fns->send_msg(mmc->data,
from, to, transid, linkedid, vasid, from, to, transid, linkedid, vasid,
service_code, m, hdrs, &err, &retry); service_code, m, hdrs, &err, &retry);
else else
mms_error_ex("MT", 0, "MM7", mmc->id, "MMC[%s] of unknown type, can't send!", mms_error_ex("MT", 0, "MM7", mmc->id, "MMC[%s] of unknown type, can't send!",
mmc->id ? octstr_get_cstr(mmc->id) : ""); mmc->id ? octstr_get_cstr(mmc->id) : "");
throughput = mmc->throughput; throughput = mmc->throughput;
groupid = mmc->group_id ? octstr_duplicate(mmc->group_id) : NULL; groupid = mmc->group_id ? octstr_duplicate(mmc->group_id) : NULL;
@ -1380,19 +1542,23 @@ static int sendMsg(MmsEnvelope *e)
if ((msg = qfs->mms_queue_getdata(e)) == NULL) { if ((msg = qfs->mms_queue_getdata(e)) == NULL) {
mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname); mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname);
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR, 4);
goto done2; goto done2;
} } else
MMSC_CLEAR_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR);
for (i = 0, n = gwlist_len(e->to); i<n; i++) { for (i = 0, n = gwlist_len(e->to); i<n; i++) {
int res = MMS_SEND_OK; int res = MMS_SEND_OK;
MmsEnvelopeTo *to = gwlist_get(e->to, i); MmsEnvelopeTo *to = gwlist_get(e->to, i);
Octstr *err = NULL; Octstr *err = NULL, *x;
time_t tnow = time(NULL); time_t tnow = time(NULL);
MmscGrp *mmc = NULL; MmscGrp *mmc = NULL;
Octstr *new_msgid = NULL; Octstr *new_msgid = NULL;
List *errl = NULL; List *errl = NULL;
int is_email = 0; int is_email = 0;
Octstr *requested_mmsc = NULL;
if (!to || !to->process) if (!to || !to->process)
continue; continue;
@ -1413,7 +1579,11 @@ static int sendMsg(MmsEnvelope *e)
is_email = (octstr_search_char(to->rcpt, '@', 0) > 0); is_email = (octstr_search_char(to->rcpt, '@', 0) > 0);
if ((mmc = get_handler_mmc(e->viaproxy, to->rcpt, e->from)) == NULL && !is_email) { x = octstr_format("X-Mbuni-Via-%d", i);
requested_mmsc = e->hdrs ? http_header_value(e->hdrs, x) : NULL;
octstr_destroy(x);
if ((mmc = get_handler_mmc(requested_mmsc ? requested_mmsc : e->viaproxy, to->rcpt, e->from)) == NULL &&
!is_email) {
err = octstr_format("MMSBox error: Failed to deliver to " err = octstr_format("MMSBox error: Failed to deliver to "
"%S. Don't know how to route!", "%S. Don't know how to route!",
to->rcpt); to->rcpt);
@ -1456,6 +1626,14 @@ static int sendMsg(MmsEnvelope *e)
&errl); &errl);
if (errl) if (errl)
err = http_header_value(errl, octstr_imm("X-Mbuni-Error")); err = http_header_value(errl, octstr_imm("X-Mbuni-Error"));
if (new_msgid && e->hdrs) { /* Record it */
Octstr *x = octstr_format("X-Mbuni-Received-Message-Id-%d", i);
http_header_remove_all(e->hdrs, octstr_get_cstr(x));
http_header_add(e->hdrs, octstr_get_cstr(x), octstr_get_cstr(new_msgid));
octstr_destroy(x);
}
} }
if (mmc) { if (mmc) {
if (res == MMS_SEND_OK) if (res == MMS_SEND_OK)
@ -1477,7 +1655,7 @@ static int sendMsg(MmsEnvelope *e)
e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */ e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */
queue_dlr(mmc, e->from, to->rcpt, e->msgId, queue_dlr(mmc, e->from, to->rcpt, e->msgId,
(e->expiryt != 0 && e->expiryt < tnow) ? (e->expiryt != 0 && e->expiryt < tnow) ?
octstr_imm("Expired") : octstr_imm("Rejected"), octstr_imm("Expired") : octstr_imm("Rejected"),
"MM7-Out", errl); "MM7-Out", errl);
} }
if (res == MMS_SEND_ERROR_FATAL) if (res == MMS_SEND_ERROR_FATAL)
@ -1527,7 +1705,8 @@ static int sendMsg(MmsEnvelope *e)
octstr_destroy(new_msgid); octstr_destroy(new_msgid);
octstr_destroy(err); octstr_destroy(err);
http_destroy_headers(errl); http_destroy_headers(errl);
octstr_destroy(requested_mmsc);
e->lasttry = tnow; e->lasttry = tnow;
if (qfs->mms_queue_update(e) == 1) { if (qfs->mms_queue_update(e) == 1) {
e = NULL; e = NULL;
@ -1538,7 +1717,7 @@ static int sendMsg(MmsEnvelope *e)
done2: done2:
mms_destroy(msg); mms_destroy(msg);
octstr_destroy(otransid); octstr_destroy(otransid);
if (e) { /* Update the queue if it is still valid (e.g. recipients not handled) if (e) { /* Update the queue if it is still valid (e.g. recipients not handled)
* XXX can this happen here??... * XXX can this happen here??...
*/ */
@ -1556,6 +1735,8 @@ done2:
void mmsbox_outgoing_queue_runner(volatile sig_atomic_t *rstop) void mmsbox_outgoing_queue_runner(volatile sig_atomic_t *rstop)
{ {
hmon->register_thread();
qfs->mms_queue_run(octstr_get_cstr(outgoing_qdir), qfs->mms_queue_run(octstr_get_cstr(outgoing_qdir),
sendMsg, queue_interval, maxthreads, rstop); sendMsg, queue_interval, maxthreads, rstop);
hmon->unregister_thread();
} }

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
#define __MMSBOX_INCLUDED__ #define __MMSBOX_INCLUDED__
#include "mmsbox_cfg.h" #include "mmsbox_cfg.h"
extern volatile sig_atomic_t rstop;
void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url, Octstr *transid); void mms_dlr_url_put(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr *dlr_url, Octstr *transid);
int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_url, Octstr **transid); int mms_dlr_url_get(Octstr *msgid, char *rtype, Octstr *mmc_gid, Octstr **dlr_url, Octstr **transid);
void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid); void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid);

View File

@ -15,7 +15,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "mmsbox_cdr.h" #include "mmsbox_cdr.h"
#include "mmsbox_cfg.h"
static FILE *cdr_file; static FILE *cdr_file;
static List *req_list; static List *req_list;
@ -52,7 +52,7 @@ static void cdr_logger_func(void)
{ {
MmsBoxCdrStruct *cdr; MmsBoxCdrStruct *cdr;
hmon->register_thread();
while ((cdr = gwlist_consume(req_list)) != NULL) { while ((cdr = gwlist_consume(req_list)) != NULL) {
char buf[CBUFSIZE]; char buf[CBUFSIZE];
struct tm tm; struct tm tm;
@ -84,7 +84,7 @@ static void cdr_logger_func(void)
gw_free(cdr); gw_free(cdr);
} }
hmon->unregister_thread();
} }
static int cdr_module_init(char *settings) static int cdr_module_init(char *settings)

View File

@ -37,6 +37,8 @@ List *strip_prefixes = NULL;
Octstr *sendmail_cmd = NULL; Octstr *sendmail_cmd = NULL;
Octstr *myhostname = NULL; Octstr *myhostname = NULL;
volatile sig_atomic_t rstop = 0;
int mt_multipart = 0; int mt_multipart = 0;
MmsQueueHandlerFuncs *qfs; /* queue functions. */ MmsQueueHandlerFuncs *qfs; /* queue functions. */
MmsBoxResolverFuncStruct *rfs; /* resolver functions. */ MmsBoxResolverFuncStruct *rfs; /* resolver functions. */
@ -56,17 +58,42 @@ static Octstr *admin_pass = NULL;
static Octstr *admin_allow_ip = NULL; static Octstr *admin_allow_ip = NULL;
static Octstr *admin_deny_ip = NULL; static Octstr *admin_deny_ip = NULL;
static gwthread_func_t *mmsc_receiver_func;
struct SendMmsPortInfo sendmms_port = {-1}; struct SendMmsPortInfo sendmms_port = {-1};
struct MmsBoxMTfilter *mt_filter = NULL; struct MmsBoxMTfilter *mt_filter = NULL;
static void free_mmsc_struct (MmscGrp *m); /* do nothing func: Vital it returns 0! */
static int do_nothing_func (void) {return 0;}
static gwthread_func_t *mmsc_receiver_func = (void *)do_nothing_func;
static struct MmsBoxHealthMonitors _hmon = {
.register_thread = (void*)do_nothing_func,
.unregister_thread = (void*)do_nothing_func,
.register_port = (void*)do_nothing_func,
.unregister_port = (void*)do_nothing_func};
struct MmsBoxHealthMonitors *hmon = &_hmon; /* Set to useful defaults */
/* Event call back. By default, set to do nothing function */
void (*mmsbox_event_cb)(Octstr *mmsc, int mm7_pkt_type,
int is_mm4,
Octstr *mm7_ver, int status,
int msg_size, int num_retries,
Octstr *from, Octstr *to, Octstr *message_id, Octstr *transid,
List *hdrs, Octstr *value) = (void *)do_nothing_func;
void (*mmsbox_alarm_cb)(Octstr*mmsc, enum MmsBoxAlarms alarm, int alarm_state, int lev) = (void *)do_nothing_func;
static void free_mmsc_struct (MmscGrp *m);
static void admin_handler(void *unused); static void admin_handler(void *unused);
int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func) static MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, List *errors, List *warnings);
int mms_load_mmsbox_settings(struct mCfgImpFuncs *cfg_funcs, Octstr *init,
gwthread_func_t *x_mmsc_handler_func,
MmsQueueHandlerFuncs *_qfs,
MmsEventLoggerFuncs *_ev)
{ {
mCfgGrp *grp; mCfgGrp *grp;
mCfgGrp *cgrp; mCfgGrp *cgrp;
@ -78,11 +105,17 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
void *catchall = NULL, *x; void *catchall = NULL, *x;
if ((cfg = mms_cfg_read(fname)) == NULL) { if (cfg_funcs == NULL)
mms_error(0, "mmsbox", NULL, "Couldn't read configuration from '%s'.", octstr_get_cstr(fname)); cfg = mms_cfg_read(init);
else
cfg = mms_cfg_read2(cfg_funcs, init);
if (cfg == NULL) {
mms_error(0, "mmsbox", NULL, "Couldn't read configuration from '%s'.", octstr_get_cstr(init));
return -1; return -1;
} }
grp = mms_cfg_get_single(cfg, octstr_imm("mbuni")); grp = mms_cfg_get_single(cfg, octstr_imm("mbuni"));
cgrp = mms_cfg_get_single(cfg, octstr_imm("core")); cgrp = mms_cfg_get_single(cfg, octstr_imm("core"));
@ -99,7 +132,9 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
mmsc_del_list = gwlist_create(); mmsc_del_list = gwlist_create();
if ((x = _mms_load_module(cfg, grp, "event-logger-module", "event_logger", NULL)) != NULL) { if (_ev != NULL)
mms_event_logger_init(_ev, NULL);
else if ((x = _mms_load_module(cfg, grp, "event-logger-module", "event_logger", NULL)) != NULL) {
Octstr *s = mms_cfg_get(cfg, grp, octstr_imm("event-logger-module")); Octstr *s = mms_cfg_get(cfg, grp, octstr_imm("event-logger-module"));
if (mms_event_logger_init(x, s) != 0) if (mms_event_logger_init(x, s) != 0)
@ -156,7 +191,9 @@ int mms_load_mmsbox_settings(Octstr *fname, 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 = _mms_load_module(cfg, grp, "queue-manager-module", "qfuncs", NULL)) == NULL) { if (_qfs != NULL)
qfs = _qfs;
else if ((qfs = _mms_load_module(cfg, 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,
octstr_get_cstr(gdir), octstr_get_cstr(gdir),
@ -221,11 +258,13 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
if (sendmms_port.port > 0 && if (sendmms_port.port > 0 &&
http_open_port(sendmms_port.port, send_port_ssl) < 0) { http_open_port(sendmms_port.port, send_port_ssl) < 0) {
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
mms_error(0, "mmsbox", NULL, "Failed to start sendmms HTTP server on %ld: %s!", mms_error(0, "mmsbox", NULL, "Failed to start sendmms HTTP server on %ld: %s!",
sendmms_port.port, sendmms_port.port,
strerror(errno)); strerror(errno));
sendmms_port.port = -1; sendmms_port.port = -1;
} } else
hmon->register_port(sendmms_port.port);
sendmms_port.allow_ip = mms_cfg_get(cfg, grp, octstr_imm("allow-ip")); sendmms_port.allow_ip = mms_cfg_get(cfg, grp, octstr_imm("allow-ip"));
sendmms_port.deny_ip = mms_cfg_get(cfg, grp, octstr_imm("deny-ip")); sendmms_port.deny_ip = mms_cfg_get(cfg, grp, octstr_imm("deny-ip"));
@ -263,7 +302,7 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
} }
gwlist_destroy(l, NULL); gwlist_destroy(l, NULL);
mmsc_receiver_func = mmsc_handler_func; /* save it. */ mmsc_receiver_func = x_mmsc_handler_func; /* save it. */
/* Start MMSCs. */ /* Start MMSCs. */
l = mms_cfg_get_multi(cfg, octstr_imm("mmsc")); l = mms_cfg_get_multi(cfg, octstr_imm("mmsc"));
@ -273,7 +312,7 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
Octstr *x; Octstr *x;
mCfgGrp *xgrp = gwlist_get(l, i); mCfgGrp *xgrp = gwlist_get(l, i);
start_mmsc_from_conf(cfg, xgrp, mmsc_handler_func, errors, warnings); start_mmsc_from_conf(cfg, xgrp, errors, warnings);
while ((x = gwlist_extract_first(errors)) != NULL) { while ((x = gwlist_extract_first(errors)) != NULL) {
mms_error(0, "mmsbox", NULL, "%s", octstr_get_cstr(x)); mms_error(0, "mmsbox", NULL, "%s", octstr_get_cstr(x));
@ -447,17 +486,21 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
admin_deny_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-deny-ip")); admin_deny_ip = mms_cfg_get(cfg, grp, octstr_imm("admin-deny-ip"));
if (admin_port > 0 && if (admin_port > 0 &&
http_open_port(admin_port, admin_port_ssl)< 0) http_open_port(admin_port, admin_port_ssl)< 0) {
mms_error(0, "mmsbox", NULL, "Failed to start admin server on port %d: %s", mms_error(0, "mmsbox", NULL, "Failed to start admin server on port %d: %s",
(int)admin_port, strerror(errno)); (int)admin_port, strerror(errno));
else if (admin_port > 0 && MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_HTTP_DOWN, 1);
} else if (admin_port > 0 &&
(admin_thread = gwthread_create((gwthread_func_t *)admin_handler, NULL)) < 0) { (admin_thread = gwthread_create((gwthread_func_t *)admin_handler, NULL)) < 0) {
mms_error(0, "mmsbox", NULL, "Failed to start admin server thread: %s", mms_error(0, "mmsbox", NULL, "Failed to start admin server thread: %s",
strerror(errno)); strerror(errno));
http_close_port(admin_port); http_close_port(admin_port);
admin_port = 0;
} else if (admin_pass == NULL) } else if (admin_pass == NULL)
mms_warning(0, "mmsbox", NULL, "Empty or no password supplied for admin port. All requests will be allowed!"); mms_warning(0, "mmsbox", NULL, "Empty or no password supplied for admin port. All requests will be allowed!");
if (admin_port > 0)
hmon->register_port(admin_port);
gwlist_destroy(l, NULL); gwlist_destroy(l, NULL);
octstr_destroy(gdir); octstr_destroy(gdir);
@ -466,8 +509,6 @@ int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func)
return 0; return 0;
} }
/* do nothing func: Vital it returns 0! */
static int do_nothing_func (void) {return 0;}
static MmsBoxMmscFuncs dummy_mmsc_funcs = { static MmsBoxMmscFuncs dummy_mmsc_funcs = {
(void *)do_nothing_func, (void *)do_nothing_func,
@ -488,7 +529,9 @@ static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
mmc->fns->stop_conn(mmc->data); mmc->fns->stop_conn(mmc->data);
mmc->custom_started = 0; mmc->custom_started = 0;
} else if (mmc->incoming.port > 0) { } else if (mmc->incoming.port > 0) {
http_close_port(mmc->incoming.port); http_close_port(mmc->incoming.port);
hmon->unregister_port(mmc->incoming.port);
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_HTTP_DOWN, 1);
if (mmc->threadid >= 0) if (mmc->threadid >= 0)
gwthread_join(mmc->threadid); gwthread_join(mmc->threadid);
mmc->threadid = -1; mmc->threadid = -1;
@ -497,8 +540,7 @@ static void mmsbox_stop_mmsc_conn_real(MmscGrp *mmc)
} }
static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_func, static void mmsbox_start_mmsc_conn(MmscGrp *m, List *errors, List *warnings)
List *errors, List *warnings)
{ {
if (m->type == CUSTOM_MMSC) { if (m->type == CUSTOM_MMSC) {
if (m->fns == NULL || if (m->fns == NULL ||
@ -506,20 +548,24 @@ static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_fun
WARNING("MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id)); WARNING("MMSBox: Failed to start custom MMSC [%s]", octstr_get_cstr(m->id));
m->custom_started = 0; m->custom_started = 0;
} else } else
m->custom_started = 1; m->custom_started = 1;
} else { } else {
if (m->incoming.port > 0 && if (m->incoming.port > 0 &&
http_open_port(m->incoming.port, m->incoming.ssl) < 0) { http_open_port(m->incoming.port, m->incoming.ssl) < 0) {
WARNING("MMSBox: Failed to start HTTP server on receive port for " WARNING("MMSBox: Failed to start HTTP server on receive port for "
" MMSC %s, port %ld: %s!", " MMSC %s, port %ld: %s!",
octstr_get_cstr(m->id), m->incoming.port, octstr_get_cstr(m->id), m->incoming.port,
strerror(errno)); strerror(errno));
MMSC_ISSUE_ALARM(m, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
m->incoming.port = 0; /* so we don't listen on it. */ m->incoming.port = 0; /* so we don't listen on it. */
} else {
hmon->register_port(m->incoming.port);
MMSC_CLEAR_ALARM(m, MMSBOX_ALARM_HTTP_DOWN);
MMSC_CLEAR_ALARM(m, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
} }
if (mmsc_receiver_func &&
if (mmsc_handler_func &&
m->incoming.port > 0) { /* Only start threads if func passed and ... */ m->incoming.port > 0) { /* Only start threads if func passed and ... */
if ((m->threadid = gwthread_create(mmsc_handler_func, m)) < 0) if ((m->threadid = gwthread_create(mmsc_receiver_func, m)) < 0)
ERROR("MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!", ERROR("MMSBox: Failed to start MMSC handler thread for MMSC[%s]: %s!",
octstr_get_cstr(m->id), strerror(errno)); octstr_get_cstr(m->id), strerror(errno));
} else } else
@ -531,8 +577,7 @@ static void mmsbox_start_mmsc_conn(MmscGrp *m, gwthread_func_t *mmsc_handler_fun
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func, static MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, List *warnings, List *errors)
List *warnings, List *errors)
{ {
MmscGrp *m = gw_malloc(sizeof *m); MmscGrp *m = gw_malloc(sizeof *m);
@ -667,7 +712,7 @@ MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handl
m->start_time = time(NULL); m->start_time = time(NULL);
/* finally start the thingie. */ /* finally start the thingie. */
mmsbox_start_mmsc_conn(m, mmsc_handler_func, errors, warnings); mmsbox_start_mmsc_conn(m, errors, warnings);
if (dict_put_once(mmscs, m->id, m) == 0) { if (dict_put_once(mmscs, m->id, m) == 0) {
WARNING("Failed to load mmsc [%s]. ID is not unique!", octstr_get_cstr(m->id)); WARNING("Failed to load mmsc [%s]. ID is not unique!", octstr_get_cstr(m->id));
mmsbox_stop_mmsc_conn_real(m); mmsbox_stop_mmsc_conn_real(m);
@ -698,7 +743,7 @@ static void delete_stale_mmsc(int delete_all)
} }
} }
int mmsbox_stop_mmsc_conn(Octstr *mmc_id) int mmsbox_stop_mmsc(Octstr *mmc_id)
{ {
MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */ MmscGrp *mmc = dict_remove(mmscs, mmc_id); /* remove it so no one else can get it. */
@ -714,6 +759,23 @@ int mmsbox_stop_mmsc_conn(Octstr *mmc_id)
return 0; return 0;
} }
int mmsbox_start_mmsc(Octstr *mmc_id)
{
int ret;
MmscGrp *mmc = dict_get(mmscs, mmc_id); /* remove it so no one else can get it. */
List *l = gwlist_create(), *r = gwlist_create();
if (mmc == NULL)
return -1;
mmsbox_start_mmsc_conn(mmc, l, r);
ret = gwlist_len(l) > 0 ? -1 : 0;
gwlist_destroy(l, (void *)octstr_destroy);
gwlist_destroy(r, (void *)octstr_destroy);
return ret;
}
void mmsbox_stop_all_mmsc_conn(void) void mmsbox_stop_all_mmsc_conn(void)
{ {
Octstr *mmc; Octstr *mmc;
@ -722,7 +784,7 @@ void mmsbox_stop_all_mmsc_conn(void)
if (l) { if (l) {
while ((mmc = gwlist_extract_first(l)) != NULL) { while ((mmc = gwlist_extract_first(l)) != NULL) {
mms_info(0, "mmsbox", NULL,"Stopping MMSC [%s]", octstr_get_cstr(mmc)); mms_info(0, "mmsbox", NULL,"Stopping MMSC [%s]", octstr_get_cstr(mmc));
mmsbox_stop_mmsc_conn(mmc); mmsbox_stop_mmsc(mmc);
octstr_destroy(mmc); octstr_destroy(mmc);
} }
gwlist_destroy(l, NULL); gwlist_destroy(l, NULL);
@ -810,6 +872,8 @@ void mmsbox_settings_cleanup(void)
if (admin_port > 0) { if (admin_port > 0) {
http_close_port(admin_port); http_close_port(admin_port);
hmon->unregister_port(admin_port);
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_HTTP_DOWN,1);
if (admin_thread >= 0) if (admin_thread >= 0)
gwthread_join(admin_thread); gwthread_join(admin_thread);
mms_info(0, "mmsbox", NULL,"Admin port on %d, shutdown", (int)admin_port); mms_info(0, "mmsbox", NULL,"Admin port on %d, shutdown", (int)admin_port);
@ -987,7 +1051,7 @@ static void admin_handler(void *unused)
List *cgivars; List *cgivars;
Octstr *pass; Octstr *pass;
hmon->register_thread();
mms_info(0, "mmsbox", NULL,"Admin Interface -- startup on port %d", (int)admin_port); mms_info(0, "mmsbox", NULL,"Admin Interface -- startup on port %d", (int)admin_port);
while((client = http_accept_request(admin_port, while((client = http_accept_request(admin_port,
@ -1033,7 +1097,7 @@ static void admin_handler(void *unused)
List *e = gwlist_create(); List *e = gwlist_create();
List *w = gwlist_create(); List *w = gwlist_create();
Octstr *x; Octstr *x;
MmscGrp *mc = start_mmsc_from_conf(cfg, m, mmsc_receiver_func, e, w); MmscGrp *mc = start_mmsc_from_conf(cfg, m, e, w);
if (mc != NULL) if (mc != NULL)
append_mmsc_status(rbody, mc, w); append_mmsc_status(rbody, mc, w);
@ -1060,7 +1124,7 @@ static void admin_handler(void *unused)
if (l) if (l)
while ((x = gwlist_extract_first(l)) != NULL) { while ((x = gwlist_extract_first(l)) != NULL) {
int ret = mmsbox_stop_mmsc_conn(x); int ret = mmsbox_stop_mmsc(x);
octstr_format_append(rbody, octstr_format_append(rbody,
"<Stop-Mmsc><%s/></Stop-Mmsc>\n", "<Stop-Mmsc><%s/></Stop-Mmsc>\n",
ret == 0 ? "Success" : "Failed"); ret == 0 ? "Success" : "Failed");
@ -1107,7 +1171,7 @@ static void admin_handler(void *unused)
http_destroy_cgiargs(cgivars); http_destroy_cgiargs(cgivars);
http_destroy_headers(headers); http_destroy_headers(headers);
} }
hmon->unregister_thread();
mms_info(0, "mmsbox", NULL,"Admin Interface -- shuttind down on port %d", (int)admin_port); mms_info(0, "mmsbox", NULL,"Admin Interface -- shuttind down on port %d", (int)admin_port);
} }

View File

@ -19,6 +19,20 @@
#include "mmsbox_mmsc.h" #include "mmsbox_mmsc.h"
#include "mmsbox_cdr.h" #include "mmsbox_cdr.h"
#include "mms_cfg.h"
/* Alarm callback mechanism */
enum MmsBoxAlarms {
MMSBOX_ALARM_HTTP_DOWN = 0,
MMSBOX_ALARM_FILE_WRITE_ERROR,
MMSBOX_ALARM_SOCKET_CONNECT_FAILED,
MMSBOX_ALARM_QUEUE_WRITE_ERROR,
MMSBOX_ALARM_STORAGE_API_ERROR,
MMSBOX_ALARM_MM7_PARSING_FAILURE,
MMSBOX_ALARM_MM7_NON_200_RESULT,
MMSBOX_ALARM_RETRIEVE_MMS_ERROR,
MMSBOX_ALARM_MAX_ALARM /* Must be last one */
};
typedef struct MmscGrp { typedef struct MmscGrp {
Octstr *id; /* MMSC id (for logging). */ Octstr *id; /* MMSC id (for logging). */
@ -61,10 +75,12 @@ typedef struct MmscGrp {
time_t last_pdu; /* time of last PDU */ time_t last_pdu; /* time of last PDU */
time_t start_time; /* when was this connection started */ time_t start_time; /* when was this connection started */
time_t last_alarm[MMSBOX_ALARM_MAX_ALARM];
int use_count; /* use counter. */ int use_count; /* use counter. */
time_t delete_after; /* used to control deletion of object -- not ver clean, but... */ time_t delete_after; /* used to control deletion of object -- not ver clean, but... */
} MmscGrp; } MmscGrp;
#define MMSBOX_MMSC_MARK_INUSE(mmc) do {\ #define MMSBOX_MMSC_MARK_INUSE(mmc) do {\
mutex_lock((mmc)->mutex); \ mutex_lock((mmc)->mutex); \
(mmc)->use_count++; \ (mmc)->use_count++; \
@ -145,16 +161,75 @@ extern Octstr *rfs_settings;
extern MmsBoxCdrFuncStruct *cdrfs; extern MmsBoxCdrFuncStruct *cdrfs;
extern int mms_load_mmsbox_settings(Octstr *fname, gwthread_func_t *mmsc_handler_func);
extern struct MmsBoxHealthMonitors {
void (*register_thread)(void); /* Called by each thread to register itself with the health monitor */
void (*unregister_thread)(void); /* Called by each thread to unregister itself with the health monitor */
void (*register_port)(short port); /* Called to register each port on which we listen */
void (*unregister_port)(short port); /* Called to unregister each port on which we listen */
} *hmon; /* This should be set if you want to do any thread and port monitoring */
/* mmsbox_event_cb: Called with each mmsc event.
* mmsc - mmsc ID
* mm7_pkt_type - MM7 packet type (using MM7/SOAP codes)
* mm7_ver - value for SOAP or EAIF only
* status - 0 for Ok, -1 if failed (e.g. for submitack
* msg_size - size of mms
* num_retries - number of retries so far
* from - sender (can be NULL)
* to - recipient (can be NULL)
* transid - transaction ID
* message_id - Message ID (for submitack, deliverreq, deliveryreport or readreport)
* hdrs - List of envelope headers
* value - value associated with pkt type: e.g. for deliveryreport, report type
*/
extern void (*mmsbox_event_cb)(Octstr *mmsc, int mm7_pkt_type,
int is_mm4,
Octstr *mm7_ver, int status,
int msg_size, int num_retries,
Octstr *from, Octstr *to, Octstr *message_id, Octstr *transid,
List *hdrs, Octstr *value);
/* mmsbox_alarm_cb: Called when an alarm is raised or cleared
* mmsc - MMSC ID
* alarm - alarm type
* alarm_state - 0 = alarm cleared, 1 = alarm raised
* lev = severity level, 1 = warning, 2 = minor, 3 = major, 4+ = critical
*/
extern void (*mmsbox_alarm_cb)(Octstr*mmsc, enum MmsBoxAlarms alarm, int alarm_state, int lev);
#define MMSC_ISSUE_ALARM(mmc,alarm,lev) do { \
MmscGrp *_mmc = (mmc); \
if (_mmc) \
_mmc->last_alarm[(alarm)] = time(NULL); \
mmsbox_alarm_cb(_mmc ? _mmc->id : NULL, (alarm), 1, (lev)); \
} while (0)
#define MMSC_CLEAR_ALARM(mmc,alarm) do { \
MmscGrp *_mmc = (mmc); \
if (_mmc && _mmc->last_alarm[(alarm)] > 0 ) { \
mmsbox_alarm_cb(_mmc->id, (alarm), 0, 0); \
_mmc->last_alarm[(alarm)] = 0; \
} \
} while (0)
extern int mms_load_mmsbox_settings(struct mCfgImpFuncs *cfg_funcs, Octstr *init,
gwthread_func_t *mmsc_handler_func,
MmsQueueHandlerFuncs *,
MmsEventLoggerFuncs *);
extern void mmsbox_settings_cleanup(void); extern void mmsbox_settings_cleanup(void);
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 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); #if 0
MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, gwthread_func_t *mmsc_handler_func, MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, List *errors, List *warnings);
List *errors, List *warnings); #endif
int mmsbox_stop_mmsc_conn(Octstr *mmc); int mmsbox_stop_mmsc(Octstr *mmc);
int mmsbox_start_mmsc(Octstr *mmc_id);
void mmsbox_stop_all_mmsc_conn(void); void mmsbox_stop_all_mmsc_conn(void);
typedef struct MmsBoxHTTPClientInfo { typedef struct MmsBoxHTTPClientInfo {
HTTPClient *client; HTTPClient *client;
@ -167,4 +242,6 @@ typedef struct MmsBoxHTTPClientInfo {
MmscGrp *m; MmscGrp *m;
} MmsBoxHTTPClientInfo; } MmsBoxHTTPClientInfo;
void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh); void free_mmsbox_http_clientInfo(MmsBoxHTTPClientInfo *h, int freeh);
extern volatile sig_atomic_t rstop;
#endif #endif

View File

@ -29,7 +29,7 @@ int mmsrelay()
/* Start global queue runner. */ /* Start global queue runner. */
if (settings->svc_list & SvcRelay) { if (settings->svc_list & SvcRelay) {
mms_info(0, "mmsrelay", NULL, "Starting Global Queue Runner..."); mms_info(0, "mmsrelay", NULL, "Starting Global Queue Runner...");
qthread = gwthread_create((gwthread_func_t *)mbuni_global_queue_runner, &rstop); qthread = gwthread_create((gwthread_func_t *)mbuni_global_queue_runner, (void *)&rstop);
} }
if (settings->svc_list & SvcMM1) { if (settings->svc_list & SvcMM1) {