2005-09-07 10:10:41 +00:00
|
|
|
/*
|
|
|
|
* Mbuni - Open Source MMS Gateway
|
|
|
|
*
|
|
|
|
* MMSC handler functions: Receive and send MMS messages to MMSCs
|
|
|
|
*
|
2007-12-19 06:18:33 +00:00
|
|
|
* Copyright (C) 2003 - 2008, Digital Solutions Ltd. - http://www.dsmagic.com
|
2005-09-07 10:10:41 +00:00
|
|
|
*
|
|
|
|
* 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 <sys/file.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include "mmsbox.h"
|
|
|
|
#include "mms_queue.h"
|
|
|
|
|
|
|
|
#include "mmsbox.h"
|
|
|
|
|
2008-12-04 13:15:44 +00:00
|
|
|
#define MOD_SUBJECT(msg, mmc,xfrom) do { \
|
|
|
|
if ((mmc)->reroute_mod_subject) { \
|
|
|
|
Octstr *s = mms_get_header_value((msg),octstr_imm("Subject")); \
|
|
|
|
Octstr *f = octstr_duplicate(xfrom); \
|
|
|
|
int _i; \
|
|
|
|
if (s == NULL) s = octstr_create(""); \
|
|
|
|
if ((_i = octstr_search(f, octstr_imm("/TYPE="), 0)) >= 0) \
|
|
|
|
octstr_delete(f, _i, octstr_len(f)); \
|
|
|
|
octstr_format_append(s, " (from %S)", (f)); \
|
|
|
|
mms_replace_header_value((msg), "Subject", octstr_get_cstr(s)); \
|
|
|
|
octstr_destroy(s); octstr_destroy(f); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
2007-11-07 07:53:29 +00:00
|
|
|
|
2008-07-18 21:30:18 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
static Octstr *get_dlr_notify_url(Octstr *msgid, char *report_type, Octstr *mmc_gid, Octstr *mmc_id,
|
|
|
|
Octstr *status,
|
|
|
|
Octstr **transid)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
Octstr *xtransid = NULL, *url = NULL;
|
|
|
|
|
|
|
|
mms_dlr_url_get(msgid, report_type, mmc_gid, &url, &xtransid);
|
|
|
|
|
|
|
|
if (transid)
|
|
|
|
*transid = xtransid;
|
2007-08-06 11:57:15 +00:00
|
|
|
else
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(xtransid);
|
2007-08-06 11:57:15 +00:00
|
|
|
|
2008-09-13 06:37:24 +00:00
|
|
|
if (octstr_len(url) == 0) {
|
|
|
|
if (url)
|
|
|
|
mms_info(0, "MM7", NULL,
|
|
|
|
"Sending delivery-report skipped: `url' is empty, `group_id'=[%s], `msgid'=[%s]",
|
|
|
|
octstr_get_cstr(mmc_gid), octstr_get_cstr(msgid));
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(url);
|
|
|
|
url = NULL;
|
2008-09-13 06:37:24 +00:00
|
|
|
goto done;
|
2008-11-12 10:30:30 +00:00
|
|
|
} else if (octstr_search(url, octstr_imm("msgid:"), 0) == 0) { /* a fake one, skip it. */
|
|
|
|
octstr_destroy(url);
|
|
|
|
url = NULL;
|
|
|
|
|
2008-09-13 06:37:24 +00:00
|
|
|
goto done;
|
2007-08-06 11:57:15 +00:00
|
|
|
}
|
2009-06-23 05:14:22 +00:00
|
|
|
#if 0
|
2005-09-07 10:10:41 +00:00
|
|
|
/* At what point do we delete it? For now, when we get a read report,
|
2008-09-29 14:58:23 +00:00
|
|
|
* and also when we get a delivery report that is not 'deferred' or sent or forwarded
|
2005-09-07 10:10:41 +00:00
|
|
|
*/
|
2009-06-23 05:14:22 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if (strcmp(report_type, "read-report") == 0 ||
|
2007-05-05 07:46:03 +00:00
|
|
|
(octstr_case_compare(status, octstr_imm("Deferred")) != 0 &&
|
2008-09-29 14:58:23 +00:00
|
|
|
octstr_case_compare(status, octstr_imm("Forwarded")) != 0))
|
2007-04-02 05:29:00 +00:00
|
|
|
mms_dlr_url_remove(msgid, report_type, mmc_gid);
|
2008-12-26 09:56:43 +00:00
|
|
|
#endif
|
2008-11-12 10:30:30 +00:00
|
|
|
done:
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
return url;
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
|
2008-10-16 14:20:13 +00:00
|
|
|
static void fixup_relayed_report(MmsMsg *m, MmscGrp *mmc, char *rtype, Octstr *status)
|
2008-09-13 06:37:24 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
Octstr *value = mms_get_header_value(m, octstr_imm("Message-ID"));
|
|
|
|
Octstr *newmsgid = NULL, *transid = NULL;
|
|
|
|
|
|
|
|
/* Firstly, take care to look for the record we saved, and re-write the MessageID. */
|
|
|
|
if (value &&
|
|
|
|
mms_dlr_url_get(value, rtype, mmc->group_id, &newmsgid, &transid) == 0) {
|
|
|
|
int x = octstr_search_char(newmsgid, ':', 0);
|
|
|
|
|
|
|
|
if (x>=0)
|
|
|
|
octstr_delete(newmsgid, 0, x+1);
|
|
|
|
|
|
|
|
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(newmsgid));
|
2008-09-14 11:33:59 +00:00
|
|
|
/* Add it back as original. */
|
|
|
|
mms_replace_header_value(m, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value));
|
2008-12-26 09:56:43 +00:00
|
|
|
|
|
|
|
#if 0
|
2008-10-16 14:20:13 +00:00
|
|
|
if (strcmp(rtype, "read-report") == 0 ||
|
|
|
|
(octstr_case_compare(status, octstr_imm("Deferred")) != 0 &&
|
|
|
|
octstr_case_compare(status, octstr_imm("Forwarded")) != 0))
|
2008-12-26 09:56:43 +00:00
|
|
|
mms_dlr_url_remove(value, rtype, mmc->group_id); /* only remove if not
|
2010-10-21 17:51:16 +00:00
|
|
|
* interim status
|
|
|
|
*/
|
2008-12-26 09:56:43 +00:00
|
|
|
#endif
|
2008-09-13 06:37:24 +00:00
|
|
|
}
|
|
|
|
octstr_destroy(newmsgid);
|
|
|
|
octstr_destroy(transid);
|
|
|
|
octstr_destroy(value);
|
|
|
|
}
|
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
/* returns the DLR/RR URL, fills in the queue header info. */
|
|
|
|
Octstr *mmsbox_get_report_info(MmsMsg *m, MmscGrp *mmsc, Octstr *out_mmc_id, char *report_type,
|
|
|
|
Octstr *status, List *qhdr, Octstr *uaprof,
|
|
|
|
time_t uaprof_tstamp,
|
|
|
|
Octstr *msgid)
|
|
|
|
{
|
|
|
|
Octstr *res;
|
2009-08-06 08:39:02 +00:00
|
|
|
|
|
|
|
if (mmsc == NULL)
|
|
|
|
res = NULL;
|
|
|
|
else if (out_mmc_id != NULL) { /* internal routing. */
|
2008-11-21 05:19:43 +00:00
|
|
|
if (m)
|
|
|
|
fixup_relayed_report(m, mmsc, report_type, octstr_imm(""));
|
|
|
|
res = NULL;
|
|
|
|
} else {
|
|
|
|
Octstr *transid = NULL;
|
|
|
|
|
|
|
|
res = get_dlr_notify_url(msgid, report_type,mmsc->group_id, mmsc->id,
|
|
|
|
status, &transid);
|
|
|
|
http_header_add(qhdr, "X-Mbuni-Mmsc-GroupID", octstr_get_cstr(mmsc->group_id));
|
|
|
|
|
|
|
|
if (transid) {
|
|
|
|
http_header_add(qhdr, "X-Mbuni-TransactionID", octstr_get_cstr(transid));
|
|
|
|
octstr_destroy(transid);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uaprof) {
|
|
|
|
Octstr *sx = date_format_http(uaprof_tstamp);
|
|
|
|
http_header_add(qhdr, "X-Mbuni-UAProf", octstr_get_cstr(uaprof));
|
|
|
|
http_header_add(qhdr, "X-Mbuni-Timestamp", octstr_get_cstr(sx));
|
|
|
|
octstr_destroy(sx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
/* These functions are very similar to those in mmsproxy */
|
2008-09-02 11:07:16 +00:00
|
|
|
static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
|
|
|
int hstatus = HTTP_OK;
|
2010-11-05 05:49:56 +00:00
|
|
|
List *rh = NULL, *lh;
|
2007-09-17 13:07:30 +00:00
|
|
|
Octstr *reply_body = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
List *to = NULL;
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *from = NULL, *subject = NULL, *vasid = NULL, *msgid = NULL, *uaprof = NULL;
|
|
|
|
time_t expiryt = -1, delivert = -1, uaprof_tstamp = -1;
|
2005-09-07 10:10:41 +00:00
|
|
|
MmsMsg *m = NULL;
|
|
|
|
int status = 1000;
|
|
|
|
unsigned char *msgtype = (unsigned char *)"";
|
2007-09-17 13:07:30 +00:00
|
|
|
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL;
|
2008-11-20 08:43:52 +00:00
|
|
|
List *qhdr = http_create_empty_headers();
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *r, *s, *transid = NULL, *value = NULL;
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if (h->body)
|
|
|
|
mreq = mm7_parse_soap(h->headers, h->body);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (mreq) {
|
2005-09-07 10:10:41 +00:00
|
|
|
msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq));
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
|
|
|
} else
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
debug("mmsbox.mm7sendinterface", 0,
|
2007-04-02 05:29:00 +00:00
|
|
|
" --> Enterred mm7dispatch interface, mreq=[%s] mtype=[%s] <-- ",
|
2005-09-07 10:10:41 +00:00
|
|
|
mreq ? "Ok" : "Null",
|
|
|
|
mreq ? (char *)msgtype : "Null");
|
|
|
|
|
|
|
|
if (!mreq) {
|
2007-04-12 08:40:24 +00:00
|
|
|
mresp = mm7_make_resp(NULL, MM7_SOAP_FORMAT_CORRUPT, NULL,1);
|
2008-09-02 11:07:16 +00:00
|
|
|
status = 4000;
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2007-11-07 07:53:29 +00:00
|
|
|
mm7_get_envelope(mreq, &from, &to, &subject, &vasid,
|
|
|
|
&expiryt, &delivert, &uaprof, &uaprof_tstamp);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (!from)
|
2010-07-02 13:39:27 +00:00
|
|
|
from = octstr_create("anon@anon");
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2007-09-17 13:07:30 +00:00
|
|
|
qdir = get_mmsbox_queue_dir(from, to, h->m, &mmc_id); /* get routing info. */
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
switch (mm7_msgtype(mreq)) {
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *value2;
|
2008-11-20 08:43:52 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
case MM7_TAG_DeliverReq:
|
|
|
|
m = mm7_soap_to_mmsmsg(mreq, from);
|
|
|
|
if (m) {
|
2005-09-09 13:11:38 +00:00
|
|
|
/* Store linked id so we use it in response. */
|
|
|
|
Octstr *linkedid = mm7_soap_header_value(mreq, octstr_imm("LinkedID"));
|
2007-08-06 11:57:15 +00:00
|
|
|
List *qh = http_create_empty_headers();
|
2005-09-07 10:10:41 +00:00
|
|
|
int dlr;
|
2008-10-16 14:20:13 +00:00
|
|
|
|
|
|
|
value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
|
2007-09-17 13:07:30 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
if (value &&
|
|
|
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
|
|
|
dlr = 1;
|
|
|
|
else
|
|
|
|
dlr = 0;
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if (delivert < 0)
|
|
|
|
delivert = time(NULL);
|
|
|
|
|
|
|
|
if (expiryt < 0)
|
|
|
|
expiryt = time(NULL) + DEFAULT_EXPIRE;
|
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
if (uaprof) {
|
|
|
|
Octstr *sx = date_format_http(uaprof_tstamp);
|
|
|
|
http_header_add(qh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof));
|
|
|
|
http_header_add(qh, "X-Mbuni-Timestamp", octstr_get_cstr(sx));
|
|
|
|
octstr_destroy(sx);
|
|
|
|
}
|
2008-08-14 11:44:58 +00:00
|
|
|
|
2007-11-07 07:53:29 +00:00
|
|
|
MOD_SUBJECT(m, h->m, from);
|
|
|
|
|
2007-08-20 11:49:30 +00:00
|
|
|
qf = qfs->mms_queue_add(from, to, subject,
|
2007-09-17 13:07:30 +00:00
|
|
|
h->m->id, mmc_id,
|
2007-08-27 10:16:26 +00:00
|
|
|
delivert, expiryt, m, linkedid,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
qh,
|
|
|
|
dlr,
|
2007-09-17 13:07:30 +00:00
|
|
|
octstr_get_cstr(qdir),
|
2008-06-24 10:01:03 +00:00
|
|
|
"MM7/SOAP-IN",
|
2008-09-11 17:47:58 +00:00
|
|
|
NULL);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2008-11-19 04:59:37 +00:00
|
|
|
if (qf == NULL) {
|
|
|
|
status = 4000;
|
|
|
|
mms_error(0, "MM7", h->m->id,
|
|
|
|
"Failed to write queue entry for received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!",
|
|
|
|
octstr_get_cstr(h->m->id));
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
} else {
|
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
|
2008-11-19 04:59:37 +00:00
|
|
|
msgid = mms_make_msgid(octstr_get_cstr(qf), NULL);
|
|
|
|
mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox",
|
|
|
|
h->ua, NULL);
|
|
|
|
}
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(linkedid);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
http_destroy_headers(qh);
|
2007-04-12 08:40:24 +00:00
|
|
|
} else {
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_error(0, "MM7", h->m->id,
|
2010-10-21 17:51:16 +00:00
|
|
|
"Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!",
|
|
|
|
octstr_get_cstr(h->m->id));
|
2005-09-07 10:10:41 +00:00
|
|
|
status = 4000;
|
2007-04-12 08:40:24 +00:00
|
|
|
}
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, status, NULL,1);
|
2007-08-06 11:57:15 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MM7_TAG_DeliveryReportReq:
|
2008-10-16 14:20:13 +00:00
|
|
|
value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
2008-11-12 10:30:30 +00:00
|
|
|
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
|
|
|
|
2008-11-20 08:43:52 +00:00
|
|
|
if ((value2 = mm7_soap_header_value(mreq, octstr_imm("StatusText"))) != NULL) {
|
|
|
|
|
|
|
|
http_header_add(qhdr, "X-Mbuni-StatusText", octstr_get_cstr(value2));
|
|
|
|
octstr_destroy(value2);
|
|
|
|
value2 = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((value2 = mm7_soap_header_value(mreq, octstr_imm("Details"))) != NULL) {
|
|
|
|
|
|
|
|
http_header_add(qhdr, "X-Mbuni-StatusDetails", octstr_get_cstr(value2));
|
|
|
|
octstr_destroy(value2);
|
|
|
|
value2 = NULL;
|
|
|
|
}
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
m = mm7_soap_to_mmsmsg(mreq, from);
|
2008-11-21 05:19:43 +00:00
|
|
|
value2 = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report",
|
|
|
|
value, qhdr, uaprof, uaprof_tstamp, msgid);
|
2008-11-12 10:30:30 +00:00
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
value2, NULL,
|
2008-11-20 08:43:52 +00:00
|
|
|
qhdr,
|
2008-11-12 10:30:30 +00:00
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/SOAP-IN",
|
|
|
|
NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (qf) {
|
2008-11-12 10:30:30 +00:00
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received DLR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
status = 4000;
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR,3);
|
|
|
|
}
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, status, NULL,1);
|
2008-11-12 10:30:30 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(value2);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MM7_TAG_ReadReplyReq:
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
m = mm7_soap_to_mmsmsg(mreq, from);
|
|
|
|
value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
|
|
|
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
value2 = mmsbox_get_report_info(m, h->m, mmc_id, "read-report", value, qhdr, uaprof, uaprof_tstamp, msgid);
|
2008-11-12 10:30:30 +00:00
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
value2, NULL,
|
2008-11-20 08:43:52 +00:00
|
|
|
qhdr,
|
2008-11-12 10:30:30 +00:00
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/SOAP-IN",
|
|
|
|
NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (qf) {
|
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
2008-11-12 10:30:30 +00:00
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received RR", from, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
2008-11-12 10:30:30 +00:00
|
|
|
status = 4000;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, status, NULL,1);
|
2008-11-12 10:30:30 +00:00
|
|
|
|
|
|
|
octstr_destroy(value2);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, MM7_SOAP_UNSUPPORTED_OPERATION, NULL,1);
|
2008-09-02 11:07:16 +00:00
|
|
|
status = MM7_SOAP_UNSUPPORTED_OPERATION;
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
/* 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"));
|
2010-11-05 05:49:56 +00:00
|
|
|
lh = mm7_soap_headers(mreq);
|
2010-10-26 10:18:13 +00:00
|
|
|
mmsbox_event_cb(h->m->id, mm7_msgtype(mreq), 0, s, 200,
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_len(h->body), 0, from,
|
2010-11-05 05:49:56 +00:00
|
|
|
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL, r, transid, lh, value);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(s);
|
|
|
|
octstr_destroy(r);
|
2010-11-05 05:49:56 +00:00
|
|
|
http_destroy_headers(lh);
|
2010-10-21 17:51:16 +00:00
|
|
|
done:
|
2007-04-10 09:56:46 +00:00
|
|
|
if (mresp && mm7_soapmsg_to_httpmsg(mresp, &h->m->ver, &rh, &reply_body) == 0)
|
2005-09-07 10:10:41 +00:00
|
|
|
http_send_reply(h->client, hstatus, rh, reply_body);
|
|
|
|
else
|
|
|
|
http_close_client(h->client);
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
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"));
|
2010-11-05 05:49:56 +00:00
|
|
|
List *lh = mm7_soap_headers(mresp);
|
2010-10-21 17:51:16 +00:00
|
|
|
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,
|
2010-11-05 05:49:56 +00:00
|
|
|
from, r, transid, lh, NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(s);
|
|
|
|
octstr_destroy(r);
|
2010-11-05 05:49:56 +00:00
|
|
|
http_destroy_headers(lh);
|
2010-10-21 17:51:16 +00:00
|
|
|
} else
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 2);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
debug("mmsbox.mm7sendinterface", 0,
|
2007-03-27 10:23:47 +00:00
|
|
|
" --> leaving mm7dispatch interface, mresp=[%s], body=[%s], mm7_status=[%d] <-- ",
|
2005-09-07 10:10:41 +00:00
|
|
|
mresp ? "ok" : "(null)",
|
2006-11-18 06:20:05 +00:00
|
|
|
reply_body ? "ok" : "(null)", status);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(from);
|
|
|
|
octstr_destroy(subject);
|
|
|
|
octstr_destroy(vasid);
|
|
|
|
octstr_destroy(msgid);
|
|
|
|
octstr_destroy(qf);
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(uaprof);
|
2007-07-27 16:39:19 +00:00
|
|
|
mms_destroy(m);
|
|
|
|
http_destroy_headers(rh);
|
|
|
|
octstr_destroy(reply_body);
|
|
|
|
mm7_soap_destroy(mresp);
|
|
|
|
mm7_soap_destroy(mreq);
|
|
|
|
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
2007-09-17 13:07:30 +00:00
|
|
|
octstr_destroy(mmc_id);
|
2008-11-20 08:43:52 +00:00
|
|
|
http_destroy_headers(qhdr);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(value);
|
|
|
|
octstr_destroy(transid);
|
2008-09-02 11:07:16 +00:00
|
|
|
|
|
|
|
return MM7_SOAP_STATUS_OK(status) ? 0 : -1;
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2008-09-14 11:33:59 +00:00
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
/* helper function for queueing delivery reports. */
|
2008-11-20 08:43:52 +00:00
|
|
|
static int queue_dlr(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *msgid, Octstr *status, char *interf, List *errl)
|
2008-09-29 14:58:23 +00:00
|
|
|
{
|
|
|
|
Octstr *mmc_id = NULL, *qdir;
|
|
|
|
MmsMsg *m = mms_deliveryreport(msgid, from, to, time(NULL), status);
|
|
|
|
List *lto = gwlist_create();
|
|
|
|
int ret;
|
2008-11-12 10:30:30 +00:00
|
|
|
Octstr *qf, *rr_uri = NULL;
|
|
|
|
List *rqh = http_create_empty_headers();
|
2008-12-01 05:14:56 +00:00
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
|
2008-11-20 08:43:52 +00:00
|
|
|
if (errl)
|
|
|
|
http_header_combine(rqh, errl); /* add status stuff. */
|
|
|
|
|
2008-12-01 05:14:56 +00:00
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
gwlist_append(lto, octstr_duplicate(to));
|
2008-12-01 05:14:56 +00:00
|
|
|
|
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
qdir = get_mmsbox_queue_dir(from, lto, mmc, &mmc_id); /* get routing info. */
|
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
rr_uri = mmsbox_get_report_info(m, mmc, mmc_id, "delivery-report", status, rqh, NULL, 0, msgid);
|
2010-10-26 10:18:13 +00:00
|
|
|
|
2010-10-26 17:40:49 +00:00
|
|
|
mmsbox_event_cb(mmc ? mmc->id : NULL, MM7_TAG_DeliveryReportReq, 0,octstr_imm("5.3.0"), 200,
|
2010-10-26 10:18:13 +00:00
|
|
|
0, 0, from,
|
|
|
|
lto && gwlist_len(lto) > 0 ? gwlist_get(lto,0) : NULL,
|
|
|
|
msgid, NULL, NULL, status);
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
qf = qfs->mms_queue_add(from, lto, NULL,
|
2009-08-06 08:39:02 +00:00
|
|
|
mmc ? mmc->id : NULL, mmc_id,
|
2008-11-12 10:30:30 +00:00
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
interf,
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
2009-08-06 08:39:02 +00:00
|
|
|
mms_log("Received DLR", from, lto, -1, msgid, status, mmc ? mmc->id : NULL, "MMSBox", NULL, NULL);
|
2008-11-12 10:30:30 +00:00
|
|
|
ret = 0;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
2008-11-12 10:30:30 +00:00
|
|
|
ret = -1;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(qf);
|
|
|
|
http_destroy_headers(rqh);
|
2008-11-20 08:43:52 +00:00
|
|
|
octstr_destroy(rr_uri);
|
2008-11-12 10:30:30 +00:00
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
gwlist_destroy(lto, (void *)octstr_destroy);
|
|
|
|
octstr_destroy(mmc_id);
|
|
|
|
mms_destroy(m);
|
2008-12-01 05:14:56 +00:00
|
|
|
|
2008-09-29 14:58:23 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-09-02 11:07:16 +00:00
|
|
|
static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
MmsMsg *m = NULL;
|
|
|
|
List *mh = NULL;
|
|
|
|
int hstatus = HTTP_NO_CONTENT;
|
2010-11-05 05:49:56 +00:00
|
|
|
List *rh = http_create_empty_headers(), *lh;
|
2008-11-12 10:30:30 +00:00
|
|
|
List *rqh = http_create_empty_headers();
|
|
|
|
Octstr *reply_body = NULL, *value = NULL, *value2 = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
List *to = gwlist_create(), *hto = NULL;
|
2010-11-05 05:49:56 +00:00
|
|
|
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL, *s = NULL;
|
2008-11-12 10:30:30 +00:00
|
|
|
Octstr *hfrom = NULL, *rr_uri = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
time_t expiryt = -1, deliveryt = -1;
|
2008-12-04 13:15:44 +00:00
|
|
|
Octstr *qf = NULL, *xver = NULL, *mmc_id = NULL, *qdir = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
int msize = h->body ? octstr_len(h->body) : 0;
|
|
|
|
int dlr;
|
2010-11-05 05:49:56 +00:00
|
|
|
int i, mtype = -1, mm7type = -1;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
debug("mmsbox.mm7eaif.sendinterface", 0,
|
2007-03-27 10:23:47 +00:00
|
|
|
" --> Enterred eaif send interface, blen=[%d] <--- ",
|
2005-09-07 10:10:41 +00:00
|
|
|
msize);
|
|
|
|
|
|
|
|
hfrom = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-From"));
|
|
|
|
if (!h->body || /* A body is required, and must parse */
|
|
|
|
(m = mms_frombinary(h->body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) {
|
|
|
|
http_header_add(rh, "Content-Type", "text/plain");
|
|
|
|
hstatus = HTTP_BAD_REQUEST;
|
|
|
|
reply_body = octstr_format("Unexpected MMS message, no body?");
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE,2);
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
/* XXXX handle delivery reports differently. */
|
|
|
|
mtype = mms_messagetype(m);
|
2010-10-26 17:40:49 +00:00
|
|
|
mm7type = mm7_msgtype_to_soaptype(mtype, 0);
|
2005-09-07 10:10:41 +00:00
|
|
|
mh = mms_message_headers(m);
|
|
|
|
/* Now get sender and receiver data.
|
|
|
|
* for now we ignore adaptation flags.
|
|
|
|
*/
|
|
|
|
mms_collect_envdata_from_msgheaders(mh, &to, &subject,
|
|
|
|
&otransid, &expiryt, &deliveryt,
|
2008-05-05 20:25:13 +00:00
|
|
|
DEFAULT_EXPIRE,
|
2009-02-16 07:30:54 +00:00
|
|
|
-1,
|
2008-05-05 20:25:13 +00:00
|
|
|
octstr_get_cstr(unified_prefix),
|
|
|
|
strip_prefixes);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && gwlist_len(hto) > 0) { /* To address is in headers. */
|
2005-09-07 10:10:41 +00:00
|
|
|
int i, n;
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
2006-10-12 15:21:46 +00:00
|
|
|
to = gwlist_create();
|
|
|
|
for (i = 0, n = gwlist_len(hto); i < n; i++) {
|
2005-09-07 10:10:41 +00:00
|
|
|
Octstr *h = NULL, *v = NULL;
|
|
|
|
List *l;
|
2008-12-04 13:15:44 +00:00
|
|
|
void *x;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
http_header_get(hto,i, &h, &v);
|
|
|
|
l = http_header_split_value(v);
|
|
|
|
|
2008-12-04 13:15:44 +00:00
|
|
|
while ((x = gwlist_extract_first(l)) != NULL)
|
|
|
|
gwlist_append(to, x);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
gwlist_destroy(l, NULL);
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(h);
|
|
|
|
octstr_destroy(v);
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-09-17 13:07:30 +00:00
|
|
|
qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
switch(mtype) {
|
|
|
|
case MMS_MSGTYPE_SEND_REQ:
|
2006-07-17 06:52:10 +00:00
|
|
|
case MMS_MSGTYPE_RETRIEVE_CONF:
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
/* Get Message ID */
|
|
|
|
if ((msgid = http_header_value(h->headers, octstr_imm("X-NOKIA-MMSC-Message-Id"))) == NULL)
|
|
|
|
msgid = http_header_value(mh, octstr_imm("Message-ID"));
|
2006-09-01 14:35:04 +00:00
|
|
|
else
|
|
|
|
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid)); /* replace it in the message.*/
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"));
|
|
|
|
if (value &&
|
|
|
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
|
|
|
dlr = 1;
|
|
|
|
else
|
|
|
|
dlr = 0;
|
2008-12-10 11:13:58 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (deliveryt < 0)
|
|
|
|
deliveryt = time(NULL);
|
|
|
|
|
|
|
|
if (expiryt < 0)
|
|
|
|
expiryt = time(NULL) + DEFAULT_EXPIRE;
|
|
|
|
|
|
|
|
if (hfrom == NULL)
|
|
|
|
hfrom = http_header_value(mh, octstr_imm("From"));
|
|
|
|
|
|
|
|
mms_remove_headers(m, "Bcc");
|
|
|
|
mms_remove_headers(m, "X-Mms-Delivery-Time");
|
|
|
|
mms_remove_headers(m, "X-Mms-Expiry");
|
|
|
|
mms_remove_headers(m, "X-Mms-Sender-Visibility");
|
|
|
|
|
2007-11-07 07:53:29 +00:00
|
|
|
MOD_SUBJECT(m, h->m, hfrom);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
/* Save it, put message id in header, return. */
|
2007-08-20 11:49:30 +00:00
|
|
|
qf = qfs->mms_queue_add(hfrom, to, subject,
|
2007-09-17 13:07:30 +00:00
|
|
|
h->m->id, mmc_id,
|
2007-08-27 10:16:26 +00:00
|
|
|
deliveryt, expiryt, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
dlr,
|
2007-09-17 13:07:30 +00:00
|
|
|
octstr_get_cstr(qdir),
|
2008-06-24 10:01:03 +00:00
|
|
|
"MM7/EAIF-IN",
|
2008-09-11 17:47:58 +00:00
|
|
|
NULL);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
hstatus = HTTP_NO_CONTENT;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
2005-09-07 10:10:41 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(value2);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
case MMS_MSGTYPE_DELIVERY_IND:
|
2008-11-12 10:30:30 +00:00
|
|
|
msgid = mms_get_header_value(m, octstr_imm("Message-ID"));
|
|
|
|
value = mms_get_header_value(m, octstr_imm("X-Mms-Status"));
|
|
|
|
value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
|
|
|
|
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (value2 && mmc_id == NULL)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/EAIF-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("DeliveryReport", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_NO_CONTENT;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else {
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(value2);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MMS_MSGTYPE_READ_ORIG_IND:
|
2008-11-12 10:30:30 +00:00
|
|
|
msgid = mms_get_header_value(m, octstr_imm("Message-ID"));
|
|
|
|
value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status"));
|
|
|
|
value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
2007-07-27 16:39:19 +00:00
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (value2 && mmc_id == NULL)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
2008-11-12 10:30:30 +00:00
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/EAIF-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
2008-12-04 13:15:44 +00:00
|
|
|
mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_NO_CONTENT;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
2008-12-04 13:15:44 +00:00
|
|
|
octstr_destroy(value2);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-11-05 05:49:56 +00:00
|
|
|
lh = http_create_empty_headers(); /* Collect extension headers */
|
|
|
|
for (i = 0; i<gwlist_len(h->headers); i++) {
|
|
|
|
Octstr *n = NULL, *v = NULL;
|
|
|
|
|
|
|
|
http_header_get(h->headers, i, &n, &v);
|
|
|
|
if (n && octstr_case_search(n, octstr_imm("X-NOKIA-"), 0) == 0)
|
|
|
|
http_header_add(lh, octstr_get_cstr(n), octstr_get_cstr(v));
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2010-11-05 05:49:56 +00:00
|
|
|
if (octstr_case_compare(n, octstr_imm("X-NOKIA-MMSC-Version")) == 0)
|
|
|
|
s = octstr_duplicate(v); /* Get mmsc version */
|
|
|
|
octstr_destroy(n);
|
|
|
|
octstr_destroy(v);
|
|
|
|
}
|
2010-10-26 10:18:13 +00:00
|
|
|
mmsbox_event_cb(h->m->id, mm7type, 0, s, hstatus,
|
2010-10-21 17:51:16 +00:00
|
|
|
msize, 0, hfrom,
|
|
|
|
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
|
2010-11-05 05:49:56 +00:00
|
|
|
msgid, otransid, lh, value);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(s);
|
2010-11-05 05:49:56 +00:00
|
|
|
http_destroy_headers(lh);
|
2010-10-21 17:51:16 +00:00
|
|
|
done:
|
2007-04-10 09:56:46 +00:00
|
|
|
|
|
|
|
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));
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
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,
|
2010-11-05 05:49:56 +00:00
|
|
|
msgid, otransid, rh, reply_body);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
http_send_reply(h->client, hstatus, rh, reply_body ? reply_body : octstr_imm(""));
|
|
|
|
|
|
|
|
octstr_destroy(xver);
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(hto);
|
2008-11-12 10:30:30 +00:00
|
|
|
http_destroy_headers(rqh);
|
2007-07-27 16:39:19 +00:00
|
|
|
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
|
|
|
octstr_destroy(hfrom);
|
|
|
|
octstr_destroy(subject);
|
|
|
|
octstr_destroy(otransid);
|
|
|
|
octstr_destroy(msgid);
|
2007-09-17 13:07:30 +00:00
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(mmc_id);
|
2008-11-21 05:19:43 +00:00
|
|
|
octstr_destroy(rr_uri);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(value);
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(mh);
|
2008-09-02 11:07:16 +00:00
|
|
|
mms_destroy(m);
|
|
|
|
|
|
|
|
return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
static int mm7http_receive(MmsBoxHTTPClientInfo *h)
|
|
|
|
{
|
|
|
|
MmsMsg *m = NULL;
|
|
|
|
List *mh = NULL;
|
|
|
|
int hstatus = HTTP_OK;
|
|
|
|
List *rh = http_create_empty_headers();
|
2008-11-12 10:30:30 +00:00
|
|
|
Octstr *reply_body = NULL;
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
List *to = NULL;
|
|
|
|
Octstr *hto = NULL, *subject = NULL, *msgid = NULL;
|
2008-09-13 06:37:24 +00:00
|
|
|
Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL;
|
2008-09-11 09:03:59 +00:00
|
|
|
time_t expiryt = -1, deliveryt = -1;
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *value = NULL, *s;
|
2008-09-11 09:03:59 +00:00
|
|
|
int msize;
|
2008-09-13 06:37:24 +00:00
|
|
|
int dlr, rr;
|
2010-10-21 17:51:16 +00:00
|
|
|
int mtype = -1, mm7type = -1;
|
2008-09-13 06:37:24 +00:00
|
|
|
List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers();
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
parse_cgivars(h->headers, h->body, &h->cgivars, &cgivars_ctypes);
|
|
|
|
|
|
|
|
hfrom = http_cgi_variable(h->cgivars, "from");
|
|
|
|
hto = http_cgi_variable(h->cgivars, "to");
|
|
|
|
body = http_cgi_variable(h->cgivars, "mms");
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
msize = octstr_len(body);
|
|
|
|
|
|
|
|
debug("mmsbox.mm7http.sendinterface", 0,
|
|
|
|
" --> Enterred http-mmsc send interface, blen=[%d] <--- ",
|
|
|
|
msize);
|
|
|
|
|
|
|
|
if (hto == NULL) {
|
|
|
|
http_header_add(rh, "Content-Type", "text/plain");
|
|
|
|
hstatus = HTTP_BAD_REQUEST;
|
|
|
|
reply_body = octstr_format("Missing 'to' argument");
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
2008-09-11 09:03:59 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
} else if (hfrom == NULL) {
|
|
|
|
http_header_add(rh, "Content-Type", "text/plain");
|
|
|
|
hstatus = HTTP_BAD_REQUEST;
|
|
|
|
reply_body = octstr_format("Missing 'from' argument");
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
2008-09-11 09:03:59 +00:00
|
|
|
goto done;
|
|
|
|
|
|
|
|
} else if (body == NULL || /* A message is required, and must parse */
|
|
|
|
(m = mms_frombinary(body, hfrom ? hfrom : octstr_imm("anon@anon"))) == NULL) {
|
|
|
|
http_header_add(rh, "Content-Type", "text/plain");
|
|
|
|
hstatus = HTTP_BAD_REQUEST;
|
|
|
|
reply_body = octstr_format("Unexpected MMS message, no content?");
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
2008-09-11 09:03:59 +00:00
|
|
|
goto done;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
to = octstr_split_words(hto);
|
|
|
|
|
|
|
|
mtype = mms_messagetype(m);
|
2010-10-26 17:40:49 +00:00
|
|
|
mm7type = mm7_msgtype_to_soaptype(mtype, 0);
|
2008-09-11 09:03:59 +00:00
|
|
|
mh = mms_message_headers(m);
|
|
|
|
|
|
|
|
/* find interesting headers. */
|
|
|
|
subject = http_header_value(mh, octstr_imm("Subject"));
|
|
|
|
|
|
|
|
/* Find expiry and delivery times */
|
|
|
|
|
|
|
|
if ((s = http_header_value(mh, octstr_imm("X-Mms-Expiry"))) != NULL) {
|
|
|
|
expiryt = date_parse_http(s);
|
|
|
|
octstr_destroy(s);
|
|
|
|
} else
|
|
|
|
expiryt = time(NULL) + DEFAULT_EXPIRE;
|
|
|
|
|
|
|
|
if ((s = http_header_value(mh, octstr_imm("X-Mms-Delivery-Time"))) != NULL) {
|
|
|
|
deliveryt = date_parse_http(s);
|
|
|
|
octstr_destroy(s);
|
|
|
|
} else
|
|
|
|
deliveryt = 0;
|
|
|
|
|
|
|
|
qdir = get_mmsbox_queue_dir(hfrom, to, h->m, &mmc_id); /* get routing info. */
|
|
|
|
|
|
|
|
switch(mtype) {
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *value2;
|
2008-09-11 09:03:59 +00:00
|
|
|
case MMS_MSGTYPE_SEND_REQ:
|
|
|
|
case MMS_MSGTYPE_RETRIEVE_CONF:
|
|
|
|
|
2008-09-13 06:37:24 +00:00
|
|
|
/* Get/make a Message ID */
|
|
|
|
if ((msgid = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL) { /* Make a message id for it directly. We need it below. */
|
|
|
|
msgid = mms_make_msgid(NULL, NULL);
|
|
|
|
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid));
|
|
|
|
}
|
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
if ((value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"))) != NULL &&
|
|
|
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
|
|
|
dlr = 1;
|
|
|
|
else
|
|
|
|
dlr = 0;
|
|
|
|
octstr_destroy(value);
|
2008-09-13 06:37:24 +00:00
|
|
|
|
|
|
|
if ((value = http_header_value(mh, octstr_imm("X-Mms-Read-Report"))) != NULL &&
|
|
|
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
|
|
|
rr = 1;
|
|
|
|
else
|
|
|
|
rr = 0;
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
if (deliveryt < 0)
|
|
|
|
deliveryt = time(NULL);
|
|
|
|
|
|
|
|
if (expiryt < 0)
|
|
|
|
expiryt = time(NULL) + DEFAULT_EXPIRE;
|
|
|
|
|
|
|
|
mms_remove_headers(m, "Bcc");
|
|
|
|
mms_remove_headers(m, "X-Mms-Delivery-Time");
|
|
|
|
mms_remove_headers(m, "X-Mms-Expiry");
|
|
|
|
mms_remove_headers(m, "X-Mms-Sender-Visibility");
|
|
|
|
|
|
|
|
MOD_SUBJECT(m, h->m, hfrom);
|
2008-09-13 06:37:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it
|
2010-10-21 17:51:16 +00:00
|
|
|
* if a DLR is relayed backwards.
|
|
|
|
*/
|
2008-09-13 06:37:24 +00:00
|
|
|
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));
|
|
|
|
if (dlr)
|
|
|
|
dlr_uri = octstr_format("msgid:%S", msgid);
|
|
|
|
if (rr)
|
|
|
|
rr_uri = octstr_format("msgid:%S", msgid);
|
|
|
|
|
|
|
|
octstr_destroy(t);
|
|
|
|
}
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
/* Save it, put message id in header, return. */
|
|
|
|
qf = qfs->mms_queue_add(hfrom, to, subject,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
deliveryt, expiryt, m, NULL,
|
|
|
|
NULL, NULL,
|
2008-09-13 06:37:24 +00:00
|
|
|
dlr_uri, rr_uri,
|
|
|
|
rqh,
|
2008-09-11 09:03:59 +00:00
|
|
|
dlr,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/HTTP-IN",
|
2008-09-11 17:47:58 +00:00
|
|
|
NULL);
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
2008-09-11 09:03:59 +00:00
|
|
|
mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
|
|
|
|
hstatus = HTTP_OK;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else {
|
2008-09-11 09:03:59 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
2008-09-11 09:03:59 +00:00
|
|
|
break;
|
|
|
|
case MMS_MSGTYPE_DELIVERY_IND:
|
2008-11-12 10:30:30 +00:00
|
|
|
msgid = mms_get_header_value(m, octstr_imm("Message-ID"));
|
|
|
|
value = mms_get_header_value(m, octstr_imm("X-Mms-Status"));
|
|
|
|
value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "delivery-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (mmc_id == NULL && value2)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/HTTP-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("DeliveryReport", hfrom, to, -1, msgid,value, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
|
|
|
|
hstatus = HTTP_OK;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(value2);
|
2008-09-11 09:03:59 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MMS_MSGTYPE_READ_ORIG_IND:
|
2008-11-12 10:30:30 +00:00
|
|
|
msgid = mms_get_header_value(m, octstr_imm("Message-ID"));
|
|
|
|
value = mms_get_header_value(m, octstr_imm("X-Mms-Read-Status"));
|
|
|
|
value2 = mms_get_header_value(m, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
2008-09-11 09:03:59 +00:00
|
|
|
|
2008-11-21 05:19:43 +00:00
|
|
|
rr_uri = mmsbox_get_report_info(m, h->m, mmc_id, "read-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (mmc_id == NULL && value2)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2008-11-12 10:30:30 +00:00
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/HTTP-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received RR", hfrom, to, -1, msgid, value, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
hstatus = HTTP_NO_CONTENT;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
2008-11-12 10:30:30 +00:00
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(h->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
2008-11-12 10:30:30 +00:00
|
|
|
octstr_destroy(value2);
|
2008-09-11 09:03:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
|
2010-10-26 10:18:13 +00:00
|
|
|
mmsbox_event_cb(h->m->id, mm7type, 0, octstr_imm("1.0"), 200,
|
2010-10-21 17:51:16 +00:00
|
|
|
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);
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
http_header_add(rh, "X-Mbuni-Version", VERSION);
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
http_send_reply(h->client, hstatus, rh, msgid ? msgid : reply_body ? reply_body : qf ? qf : octstr_imm(""));
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
|
|
|
|
|
|
|
octstr_destroy(subject);
|
|
|
|
|
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(mmc_id);
|
2008-09-13 06:37:24 +00:00
|
|
|
octstr_destroy(msgid);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(reply_body);
|
2008-09-11 09:03:59 +00:00
|
|
|
http_destroy_headers(mh);
|
|
|
|
http_destroy_headers(rh);
|
2008-09-13 06:37:24 +00:00
|
|
|
http_destroy_headers(rqh);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(value);
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
mms_destroy(m);
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
http_destroy_cgiargs(cgivars_ctypes);
|
|
|
|
|
|
|
|
return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
static int mm7mm1_receive(MmsBoxHTTPClientInfo *);
|
2008-07-18 21:30:18 +00:00
|
|
|
static void dispatch_mm7_recv(List *rl)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
|
2008-07-18 21:30:18 +00:00
|
|
|
MmsBoxHTTPClientInfo *h;
|
|
|
|
|
2010-11-22 09:03:26 +00:00
|
|
|
/* hmon->register_thread( "dispatch_mm7" ); */
|
2008-07-18 21:30:18 +00:00
|
|
|
while ((h = gwlist_consume(rl)) != NULL) {
|
|
|
|
MmscGrp *m = h->m;
|
2011-09-20 03:59:02 +00:00
|
|
|
char *user = m->incoming.user ? octstr_get_cstr(m->incoming.user) : NULL;
|
|
|
|
char *pass = m->incoming.pass ? octstr_get_cstr(m->incoming.pass) : NULL;
|
2011-03-24 12:58:11 +00:00
|
|
|
int ret = -1, has_auth = (m->type != MM1_MMSC); /* We dont authenticate mm1. right? */
|
|
|
|
|
2011-09-20 03:59:02 +00:00
|
|
|
if (!has_auth && http_auth_check(user,
|
|
|
|
pass,
|
2008-09-08 11:50:24 +00:00
|
|
|
h->headers, &has_auth) != 0) { /* Ask it to authenticate... */
|
2008-07-18 21:30:18 +00:00
|
|
|
List *hh = http_create_empty_headers();
|
|
|
|
http_header_add(hh, "WWW-Authenticate",
|
|
|
|
"Basic realm=\"" MM_NAME "\"");
|
|
|
|
http_send_reply(h->client, HTTP_UNAUTHORIZED, hh,
|
|
|
|
octstr_imm("Authentication failed"));
|
|
|
|
http_destroy_headers(hh);
|
2008-09-08 11:50:24 +00:00
|
|
|
if (!has_auth)
|
|
|
|
mms_info_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]",
|
|
|
|
m->id ? octstr_get_cstr(m->id) : "(none)");
|
|
|
|
else
|
|
|
|
mms_error_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]",
|
|
|
|
m->id ? octstr_get_cstr(m->id) : "(none)");
|
2008-07-18 21:30:18 +00:00
|
|
|
} else if (h->m->type == SOAP_MMSC)
|
2008-09-02 11:07:16 +00:00
|
|
|
ret = mm7soap_receive(h);
|
2008-09-11 09:03:59 +00:00
|
|
|
else if (h->m->type == EAIF_MMSC)
|
2008-09-02 11:07:16 +00:00
|
|
|
ret = mm7eaif_receive(h);
|
2011-03-24 12:58:11 +00:00
|
|
|
else if (h->m->type == MM1_MMSC)
|
|
|
|
ret = mm7mm1_receive(h);
|
|
|
|
else
|
2008-09-11 09:03:59 +00:00
|
|
|
ret = mm7http_receive(h);
|
|
|
|
|
2008-09-02 11:07:16 +00:00
|
|
|
h->m->last_pdu = time(NULL);
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
h->m->mo_pdus++;
|
|
|
|
else
|
|
|
|
h->m->mo_errors++;
|
2008-07-18 21:30:18 +00:00
|
|
|
free_mmsbox_http_clientInfo(h, 1);
|
|
|
|
}
|
2010-11-22 09:03:26 +00:00
|
|
|
/* hmon->unregister_thread( "dispatch_mm7" ); */
|
2008-07-18 21:30:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mmsc_receive_func(MmscGrp *m)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
MmsBoxHTTPClientInfo h = {NULL};
|
|
|
|
List *mmsc_incoming_reqs = gwlist_create();
|
2008-09-02 11:07:16 +00:00
|
|
|
long *thids = gw_malloc((maxthreads + 1)*sizeof thids[0]);
|
2008-07-18 21:30:18 +00:00
|
|
|
|
|
|
|
gwlist_add_producer(mmsc_incoming_reqs);
|
|
|
|
|
2010-11-18 06:51:17 +00:00
|
|
|
hmon->register_thread( "mmsc_receive" );
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2008-07-18 21:30:18 +00:00
|
|
|
for (i = 0; i<maxthreads; i++)
|
2008-09-02 11:07:16 +00:00
|
|
|
thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
|
2007-01-30 17:06:29 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
h.m = m;
|
|
|
|
while(rstop == 0 &&
|
|
|
|
(h.client = http_accept_request(m->incoming.port,
|
|
|
|
&h.ip, &h.url, &h.headers,
|
|
|
|
&h.body, &h.cgivars)) != NULL)
|
2007-01-30 17:06:29 +00:00
|
|
|
if (is_allowed_ip(m->incoming.allow_ip, m->incoming.deny_ip, h.ip)) {
|
2008-07-18 21:30:18 +00:00
|
|
|
MmsBoxHTTPClientInfo *hx = gw_malloc(sizeof hx[0]);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
2008-07-18 21:30:18 +00:00
|
|
|
|
|
|
|
*hx = h;
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
debug("mmsbox", 0,
|
2007-03-27 10:23:47 +00:00
|
|
|
" MM7 Incoming, IP=[%s], MMSC=[%s], dest_port=[%ld] ",
|
2005-09-07 10:10:41 +00:00
|
|
|
h.ip ? octstr_get_cstr(h.ip) : "",
|
2007-03-27 10:23:47 +00:00
|
|
|
octstr_get_cstr(m->id),
|
|
|
|
m->incoming.port);
|
2008-07-18 21:30:18 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
/* Dump headers, url etc. */
|
2007-09-19 13:06:26 +00:00
|
|
|
#if 0
|
2005-09-07 10:10:41 +00:00
|
|
|
http_header_dump(h.headers);
|
|
|
|
if (h.body) octstr_dump(h.body, 0);
|
|
|
|
if (h.ip) octstr_dump(h.ip, 0);
|
|
|
|
#endif
|
2008-07-18 21:30:18 +00:00
|
|
|
|
|
|
|
gwlist_produce(mmsc_incoming_reqs, hx);
|
2007-01-30 17:06:29 +00:00
|
|
|
} else {
|
|
|
|
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
2008-07-18 21:30:18 +00:00
|
|
|
|
2008-09-08 11:50:24 +00:00
|
|
|
mms_error_ex("auth",0, "MM7", m->id, "HTTP: Incoming IP denied MMSC[%s] ip=[%s], ua=[%s], disconnected",
|
2010-10-21 17:51:16 +00:00
|
|
|
m->id ? octstr_get_cstr(m->id) : "(none)",
|
|
|
|
h.ip ? octstr_get_cstr(h.ip) : "(none)",
|
|
|
|
h.ua ? octstr_get_cstr(h.ua) : "(none)");
|
2008-07-18 21:30:18 +00:00
|
|
|
|
2007-01-30 17:06:29 +00:00
|
|
|
http_send_reply(h.client, HTTP_FORBIDDEN, NULL,
|
|
|
|
octstr_imm("Access denied."));
|
2008-07-18 21:30:18 +00:00
|
|
|
free_mmsbox_http_clientInfo(&h, 0);
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2010-11-22 09:03:26 +00:00
|
|
|
hmon->unregister_thread( "mmsc_receive" );
|
|
|
|
|
2008-09-02 11:07:16 +00:00
|
|
|
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down...", octstr_get_cstr(m->id));
|
2008-07-18 21:30:18 +00:00
|
|
|
gwlist_remove_producer(mmsc_incoming_reqs);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2008-09-02 11:07:16 +00:00
|
|
|
for (i = 0; i<maxthreads; i++)
|
|
|
|
if (thids[i] >= 0)
|
|
|
|
gwthread_join(thids[i]);
|
|
|
|
|
|
|
|
gwlist_destroy(mmsc_incoming_reqs, NULL);
|
|
|
|
gw_free(thids);
|
|
|
|
|
|
|
|
debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id));
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* XXX Returns msgid in mmsc or NULL if error. Caller uses this for DLR issues.
|
|
|
|
* Caller must make sure throughput issues
|
|
|
|
* are observed!
|
|
|
|
* Don't remove from queue on fail, just leave it to expire.
|
|
|
|
*/
|
2010-12-09 10:36:29 +00:00
|
|
|
static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, List *lto,
|
2005-09-09 13:11:38 +00:00
|
|
|
Octstr *transid,
|
|
|
|
Octstr *linkedid,
|
2005-09-07 10:10:41 +00:00
|
|
|
char *vasid,
|
2006-08-11 10:05:46 +00:00
|
|
|
Octstr *service_code,
|
2010-10-21 17:51:16 +00:00
|
|
|
MmsEnvelope *e,
|
2007-07-27 16:39:19 +00:00
|
|
|
MmsMsg *m, Octstr **error,
|
2008-11-20 08:43:52 +00:00
|
|
|
List **errl,
|
2007-07-27 16:39:19 +00:00
|
|
|
int *retry)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
2010-10-21 17:51:16 +00:00
|
|
|
List *hdrs = e ? e->hdrs : NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
Octstr *ret = NULL;
|
2010-12-09 10:36:29 +00:00
|
|
|
int mtype = mms_messagetype(m);
|
2007-07-27 16:39:19 +00:00
|
|
|
int hstatus = HTTP_OK, tstatus = -1;
|
2005-09-07 10:10:41 +00:00
|
|
|
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
|
|
|
List *rh = NULL, *ph = NULL;
|
|
|
|
Octstr *body = NULL, *rbody = NULL, *url = NULL;
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *s, *r, *status_details = NULL;
|
2008-11-20 08:43:52 +00:00
|
|
|
char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL);
|
2010-12-09 10:36:29 +00:00
|
|
|
Octstr *to;
|
|
|
|
|
|
|
|
LINEARISE_STR_LIST(to,lto,", ");
|
2008-09-11 19:06:49 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
if (e == NULL || mmc == NULL)
|
|
|
|
goto done1;
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_info(0, "MM7", mmc->id, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s",
|
2010-10-21 17:51:16 +00:00
|
|
|
mmc->id ? octstr_get_cstr(mmc->id) : "",
|
|
|
|
mms_message_type_to_cstr(mtype),
|
|
|
|
octstr_get_cstr(from), octstr_get_cstr(to));
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
|
2008-04-11 07:01:35 +00:00
|
|
|
if ((mreq = mm7_mmsmsg_to_soap(m, (mmc == NULL || mmc->no_senderaddress == 0) ? from : NULL,
|
2010-12-09 10:36:29 +00:00
|
|
|
lto, transid,
|
2006-08-11 10:05:46 +00:00
|
|
|
service_code,
|
2005-09-09 13:11:38 +00:00
|
|
|
linkedid,
|
2008-10-02 13:49:07 +00:00
|
|
|
1, octstr_get_cstr(mmc->vasp_id), xvasid, NULL, 0,/* UA N/A on this side. */
|
2009-02-26 12:42:39 +00:00
|
|
|
hdrs)) == NULL) {
|
2007-06-25 10:33:47 +00:00
|
|
|
*error = octstr_format("Failed to convert Msg[%S] 2 SOAP message!",
|
|
|
|
mms_message_type_to_string(mtype));
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
|
|
|
}
|
|
|
|
|
2007-04-10 09:56:46 +00:00
|
|
|
if (mm7_soapmsg_to_httpmsg(mreq, &mmc->ver, &rh, &body) < 0) {
|
2007-01-24 17:47:53 +00:00
|
|
|
*error = octstr_format("Failed to convert SOAP message to HTTP Msg!");
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
|
|
|
}
|
2006-05-03 13:52:40 +00:00
|
|
|
|
|
|
|
if (hdrs)
|
|
|
|
http_header_combine(rh, hdrs); /* If specified, then update and pass on. */
|
|
|
|
|
2005-09-09 13:11:38 +00:00
|
|
|
hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph,&rbody);
|
2006-10-12 15:21:46 +00:00
|
|
|
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
|
2007-06-25 10:33:47 +00:00
|
|
|
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status=[%d]!",
|
|
|
|
mmc->mmsc_url, hstatus);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (hstatus < 0)
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else {
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
2010-10-21 17:51:16 +00:00
|
|
|
/* Invoke call back */
|
|
|
|
s = mm7_soap_header_value(mreq, octstr_imm("MM7Version"));
|
|
|
|
r = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
2010-11-05 05:49:56 +00:00
|
|
|
|
2010-10-26 10:18:13 +00:00
|
|
|
mmsbox_event_cb(mmc->id, mm7_msgtype(mreq), 0, s, hstatus,
|
2010-10-21 17:51:16 +00:00
|
|
|
mms_msgsize(m), e->attempts, e->from,
|
|
|
|
to,r, transid, hdrs, NULL);
|
|
|
|
octstr_destroy(s);
|
|
|
|
octstr_destroy(r);
|
2010-11-05 05:49:56 +00:00
|
|
|
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if ((mresp = mm7_parse_soap(ph, rbody)) == NULL) {
|
2007-06-25 10:33:47 +00:00
|
|
|
*error = octstr_format("Failed to parse MMSC[url=%S, id=%S] response!",
|
|
|
|
mmc->mmsc_url, mmc->id);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
2008-11-20 08:43:52 +00:00
|
|
|
|
|
|
|
if (errl) { /* Pick up status stuff -- for DLR */
|
|
|
|
if (*errl == NULL)
|
|
|
|
*errl = http_create_empty_headers();
|
|
|
|
if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusText"))) != NULL) {
|
|
|
|
http_header_add(*errl, "X-Mbuni-StatusText", octstr_get_cstr(s));
|
|
|
|
octstr_destroy(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((s = mm7_soap_header_value(mresp, octstr_imm("Details"))) != NULL) {
|
|
|
|
http_header_add(*errl, "X-Mbuni-StatusDetails", octstr_get_cstr(s));
|
|
|
|
octstr_destroy(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
/* Now look at response code and use it to tell you what you want. */
|
|
|
|
if ((s = mm7_soap_header_value(mresp, octstr_imm("StatusCode"))) != NULL) {
|
|
|
|
tstatus = atoi(octstr_get_cstr(s));
|
|
|
|
octstr_destroy(s);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
2006-03-28 08:37:25 +00:00
|
|
|
} else if ((s = mm7_soap_header_value(mresp, octstr_imm("faultstring"))) != NULL) {
|
|
|
|
tstatus = atoi(octstr_get_cstr(s));
|
|
|
|
octstr_destroy(s);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_PARSING_FAILURE, 3);
|
2005-09-07 10:10:41 +00:00
|
|
|
tstatus = MM7_SOAP_FORMAT_CORRUPT;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-03-21 15:41:31 +00:00
|
|
|
if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) {
|
2007-06-25 10:33:47 +00:00
|
|
|
char *tmp = (char *)mms_soap_status_to_cstr(tstatus);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details"));
|
2006-03-28 08:37:25 +00:00
|
|
|
if (detail == NULL)
|
2007-06-22 10:49:38 +00:00
|
|
|
detail = mm7_soap_header_value(mresp, octstr_imm("faultcode"));
|
2005-09-07 10:10:41 +00:00
|
|
|
ret = NULL;
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_info(0, "MM7", mmc->id, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]",
|
2010-10-21 17:51:16 +00:00
|
|
|
mmc ? octstr_get_cstr(mmc->id) : "",
|
|
|
|
tstatus, tmp ? tmp : "",
|
|
|
|
detail ? octstr_get_cstr(detail) : "");
|
2007-06-22 10:49:38 +00:00
|
|
|
|
2007-07-17 08:26:38 +00:00
|
|
|
*error = octstr_format("Failed to deliver to MMC[url=%S, id=%S], status=[%d=>%s]!",
|
2007-06-25 12:48:14 +00:00
|
|
|
mmc->mmsc_url,
|
|
|
|
mmc->id,
|
2005-09-07 10:10:41 +00:00
|
|
|
tstatus,
|
2010-10-21 17:51:16 +00:00
|
|
|
tmp ? tmp : "");
|
|
|
|
status_details = detail ? octstr_duplicate(detail) : tmp ? octstr_create(tmp) : octstr_imm("");
|
|
|
|
octstr_destroy(detail);
|
2007-06-22 10:49:38 +00:00
|
|
|
} else {
|
|
|
|
ret = mm7_soap_header_value(mresp, octstr_imm("MessageID"));
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_info(0, "MM7", NULL, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id),
|
2010-10-21 17:51:16 +00:00
|
|
|
tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)");
|
2007-06-22 10:49:38 +00:00
|
|
|
}
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
s = mm7_soap_header_value(mresp, octstr_imm("MM7Version"));
|
2010-11-05 05:49:56 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
mmsbox_event_cb(mmc->id, mm7_msgtype(mresp), 0, s, tstatus,
|
|
|
|
0, e->attempts, e->from,
|
2010-11-05 05:49:56 +00:00
|
|
|
to, ret, transid,hdrs, status_details);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(s);
|
2007-07-27 16:39:19 +00:00
|
|
|
|
2010-11-05 05:49:56 +00:00
|
|
|
|
2005-09-12 09:51:31 +00:00
|
|
|
if (ret)
|
|
|
|
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
|
|
|
|
done1:
|
2007-07-27 16:39:19 +00:00
|
|
|
*retry = (ret == NULL && (!MM7_SOAP_CLIENT_ERROR(tstatus) || tstatus < 0));
|
|
|
|
|
2007-06-22 10:49:38 +00:00
|
|
|
mm7_soap_destroy(mreq);
|
|
|
|
mm7_soap_destroy(mresp);
|
|
|
|
http_destroy_headers(rh);
|
|
|
|
octstr_destroy(body);
|
|
|
|
http_destroy_headers(ph);
|
|
|
|
octstr_destroy(rbody);
|
|
|
|
octstr_destroy(url);
|
2010-12-09 10:36:29 +00:00
|
|
|
octstr_destroy(to);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(status_details);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, List *lto,
|
2006-03-21 10:46:27 +00:00
|
|
|
Octstr *transid,
|
|
|
|
char *vasid,
|
2010-10-21 17:51:16 +00:00
|
|
|
MmsEnvelope *e,
|
2007-07-27 16:39:19 +00:00
|
|
|
MmsMsg *m, Octstr **error,
|
|
|
|
int *retry)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
2010-10-21 17:51:16 +00:00
|
|
|
List *hdrs = e ? e->hdrs : NULL;
|
2005-09-14 07:01:09 +00:00
|
|
|
Octstr *ret = NULL, *resp = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
int mtype = mms_messagetype(m);
|
|
|
|
int hstatus = HTTP_OK;
|
|
|
|
List *rh = http_create_empty_headers(), *ph = NULL;
|
2008-12-04 13:15:44 +00:00
|
|
|
Octstr *body = NULL, *rbody = NULL, *xver = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
char *msgtype;
|
2010-10-21 17:51:16 +00:00
|
|
|
MmsMsg *mresp = NULL;
|
2010-12-09 10:36:29 +00:00
|
|
|
int mresp_type = -1, i;
|
|
|
|
Octstr *to;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
LINEARISE_STR_LIST(to,lto,", ");
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
if (e == NULL || mmc == NULL)
|
|
|
|
goto done;
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_info(0, "MM7", mmc->id, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s",
|
2010-10-21 17:51:16 +00:00
|
|
|
mmc && mmc->id ? octstr_get_cstr(mmc->id) : "",
|
|
|
|
mms_message_type_to_cstr(mtype),
|
|
|
|
octstr_get_cstr(from), octstr_get_cstr(to));
|
2007-01-31 04:44:09 +00:00
|
|
|
|
|
|
|
http_header_remove_all(rh, "X-Mms-Allow-Adaptations");
|
2010-12-09 10:36:29 +00:00
|
|
|
for (i = 0; i < gwlist_len(lto); i++) {
|
|
|
|
Octstr *to = gwlist_get(lto, i);
|
|
|
|
http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to));
|
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from));
|
2007-04-10 09:56:46 +00:00
|
|
|
|
|
|
|
xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1);
|
|
|
|
http_header_add(rh, "X-NOKIA-MMSC-Version", octstr_get_cstr(xver));
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2006-07-17 06:52:10 +00:00
|
|
|
if (mtype == MMS_MSGTYPE_SEND_REQ ||
|
|
|
|
mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
|
2005-09-07 10:10:41 +00:00
|
|
|
msgtype = "MultiMediaMessage";
|
2006-07-17 06:52:10 +00:00
|
|
|
mms_make_sendreq(m); /* ensure it is a sendreq. */
|
|
|
|
} else if (mtype == MMS_MSGTYPE_DELIVERY_IND)
|
2005-09-07 10:10:41 +00:00
|
|
|
msgtype = "DeliveryReport";
|
|
|
|
else
|
|
|
|
msgtype = "ReadReply";
|
|
|
|
http_header_add(rh, "X-NOKIA-MMSC-Message-Type", msgtype);
|
2006-05-03 13:52:40 +00:00
|
|
|
|
|
|
|
if (hdrs)
|
|
|
|
http_header_combine(rh, hdrs); /* If specified, then update and pass on. */
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
http_header_add(rh, "Content-Type", "application/vnd.wap.mms-message");
|
|
|
|
|
2005-09-14 07:01:09 +00:00
|
|
|
/* Patch the message FROM and TO fields. */
|
|
|
|
mms_replace_header_value(m, "From", octstr_get_cstr(from));
|
2010-12-09 10:36:29 +00:00
|
|
|
#if 0
|
2005-09-14 07:01:09 +00:00
|
|
|
mms_replace_header_value(m, "To", octstr_get_cstr(to));
|
2010-12-09 10:36:29 +00:00
|
|
|
#endif
|
2006-03-21 10:46:27 +00:00
|
|
|
mms_replace_header_value(m,"X-Mms-Transaction-ID",
|
|
|
|
transid ? octstr_get_cstr(transid) : "000");
|
2005-09-07 10:10:41 +00:00
|
|
|
body = mms_tobinary(m);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
mmsbox_event_cb(mmc->id, mm7_msgtype_to_soaptype(mtype,1), 0, xver, 0,
|
|
|
|
octstr_len(body), e->attempts, e->from,
|
2010-11-05 05:49:56 +00:00
|
|
|
to, NULL, transid,hdrs, NULL);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2005-09-09 13:11:38 +00:00
|
|
|
hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
|
2007-06-25 10:33:47 +00:00
|
|
|
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !",
|
|
|
|
mmc->mmsc_url, hstatus);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (hstatus < 0)
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
|
2005-09-14 07:01:09 +00:00
|
|
|
} else {
|
2010-10-21 17:51:16 +00:00
|
|
|
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;
|
2005-09-14 07:01:09 +00:00
|
|
|
resp = octstr_imm("Ok");
|
2010-10-21 17:51:16 +00:00
|
|
|
if (mresp_type == MMS_MSGTYPE_SEND_CONF)
|
2005-09-14 07:01:09 +00:00
|
|
|
resp = mms_get_header_value(mresp, octstr_imm("X-Mms-Response-Status"));
|
|
|
|
if (octstr_case_compare(resp, octstr_imm("ok")) != 0)
|
|
|
|
hstatus = HTTP_STATUS_SERVER_ERROR; /* error. */
|
|
|
|
else if (mresp)
|
|
|
|
ret = mms_get_header_value(mresp, octstr_imm("Message-ID"));
|
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (hstatus < 0)
|
|
|
|
ret = NULL;
|
|
|
|
else {
|
|
|
|
hstatus = http_status_class(hstatus);
|
2007-07-27 16:39:19 +00:00
|
|
|
if (hstatus == HTTP_STATUS_SERVER_ERROR ||
|
|
|
|
hstatus == HTTP_STATUS_CLIENT_ERROR)
|
2005-09-07 10:10:41 +00:00
|
|
|
ret = NULL;
|
2005-09-14 07:01:09 +00:00
|
|
|
else if (!ret)
|
2005-09-07 10:10:41 +00:00
|
|
|
ret = http_header_value(ph, octstr_imm("X-Nokia-MMSC-Message-Id"));
|
|
|
|
}
|
2007-07-27 16:39:19 +00:00
|
|
|
*retry = (ret == NULL && (hstatus == HTTP_STATUS_SERVER_ERROR || hstatus < 0));
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2005-09-12 09:51:31 +00:00
|
|
|
if (ret)
|
|
|
|
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
|
2005-09-14 07:01:09 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
#if 0
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_info(0, "MM7", mmc->id,"Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]",
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_get_cstr(mmc->id),
|
|
|
|
hstatus, resp ? octstr_get_cstr(resp) : "(none)", ret ? octstr_get_cstr(ret) : "(none)");
|
2007-08-06 11:57:15 +00:00
|
|
|
#endif
|
2007-07-27 16:39:19 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
done:
|
|
|
|
mms_destroy(mresp);
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(rh);
|
|
|
|
octstr_destroy(body);
|
|
|
|
http_destroy_headers(ph);
|
|
|
|
octstr_destroy(rbody);
|
2010-12-09 10:36:29 +00:00
|
|
|
octstr_destroy(to);
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(resp);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(xver);
|
2005-09-07 10:10:41 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
static Octstr *mm7http_send(MmscGrp *mmc,
|
|
|
|
MmsEnvelope *e,
|
2010-12-09 10:36:29 +00:00
|
|
|
Octstr *from, List *lto,
|
2008-09-11 09:03:59 +00:00
|
|
|
MmsMsg *m, Octstr **error,
|
|
|
|
int *retry)
|
|
|
|
{
|
2010-10-21 17:51:16 +00:00
|
|
|
List *hdrs = e ? e->hdrs : NULL;
|
2008-09-11 09:03:59 +00:00
|
|
|
Octstr *ret = NULL;
|
|
|
|
int mtype = mms_messagetype(m);
|
|
|
|
int hstatus = HTTP_OK;
|
2010-10-21 17:51:16 +00:00
|
|
|
List *rh = NULL, *ph = NULL;
|
2008-09-11 09:03:59 +00:00
|
|
|
Octstr *body = NULL, *rbody = NULL;
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *mms = NULL;
|
2008-09-11 09:03:59 +00:00
|
|
|
MIMEEntity *form_data = make_multipart_formdata();
|
2010-10-21 17:51:16 +00:00
|
|
|
Octstr *transid = e ? octstr_create(e->xqfname) : NULL;
|
|
|
|
int mm7type = mm7_msgtype_to_soaptype(mtype,1);
|
2010-12-09 10:36:29 +00:00
|
|
|
Octstr *to;
|
|
|
|
|
|
|
|
LINEARISE_STR_LIST(to,lto," ");
|
2010-10-21 17:51:16 +00:00
|
|
|
|
|
|
|
if (e == NULL || mmc == NULL)
|
|
|
|
goto done;
|
2008-09-11 09:03:59 +00:00
|
|
|
mms_info(0, "MM7", mmc->id, "MMSBox: Send [http] to MMC[%s], msg type [%s], from %s, to %s",
|
2010-10-21 17:51:16 +00:00
|
|
|
mmc && mmc->id ? octstr_get_cstr(mmc->id) : "",
|
|
|
|
mms_message_type_to_cstr(mtype),
|
|
|
|
octstr_get_cstr(from), octstr_get_cstr(to));
|
2008-09-11 09:03:59 +00:00
|
|
|
|
|
|
|
mms = mms_tobinary(m);
|
|
|
|
|
|
|
|
add_multipart_form_field(form_data, "to", "text/plain", NULL, to);
|
|
|
|
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);
|
2008-09-13 06:37:24 +00:00
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
mmsbox_event_cb(mmc->id, mm7type, 0, octstr_imm("1.0"), 0,
|
|
|
|
octstr_len(mms), e->attempts, from,
|
|
|
|
to, NULL, transid, hdrs, NULL);
|
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
rh = mime_entity_headers(form_data);
|
|
|
|
body = mime_entity_body(form_data);
|
|
|
|
|
|
|
|
hstatus = mmsbox_url_fetch_content(HTTP_METHOD_POST, mmc->mmsc_url, rh, body, &ph, &rbody);
|
|
|
|
|
|
|
|
if (http_status_class(hstatus) != HTTP_STATUS_SUCCESSFUL) {
|
|
|
|
*error = octstr_format("Failed to contact MMC[url=%S] => HTTP returned status = %d !",
|
|
|
|
mmc->mmsc_url, hstatus);
|
2010-10-21 17:51:16 +00:00
|
|
|
if (hstatus < 0)
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED, 3);
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
|
2008-09-11 09:03:59 +00:00
|
|
|
} else {
|
|
|
|
ret = rbody ? octstr_duplicate(rbody) : NULL;
|
|
|
|
if (ret)
|
|
|
|
octstr_strip_blanks(ret);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_SOCKET_CONNECT_FAILED);
|
2008-09-11 09:03:59 +00:00
|
|
|
}
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
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);
|
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
*retry = (ret == NULL && (http_status_class(hstatus) == HTTP_STATUS_SERVER_ERROR || hstatus < 0));
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
mms_log2("Sent", from, to, -1, ret, NULL, mmc->id, "MMSBox", NULL, NULL);
|
|
|
|
|
2010-10-21 17:51:16 +00:00
|
|
|
done:
|
2008-09-11 09:03:59 +00:00
|
|
|
http_destroy_headers(rh);
|
|
|
|
octstr_destroy(body);
|
|
|
|
http_destroy_headers(ph);
|
|
|
|
octstr_destroy(rbody);
|
|
|
|
octstr_destroy(mms);
|
|
|
|
mime_entity_destroy(form_data);
|
2010-10-21 17:51:16 +00:00
|
|
|
octstr_destroy(transid);
|
2010-12-09 10:36:29 +00:00
|
|
|
octstr_destroy(to);
|
|
|
|
|
2008-09-11 09:03:59 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
static Octstr *mm7mm1_send(MmscGrp *mmc, Octstr *from, List *lto,
|
|
|
|
Octstr *transid,
|
|
|
|
Octstr *linkedid, char *vasid, Octstr *service_code,
|
|
|
|
MmsMsg *m, List *hdrs, Octstr **err, int *retry);
|
2010-12-09 10:36:29 +00:00
|
|
|
static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e,
|
|
|
|
List *lto, /* Of Octstr * */
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *orig_transid,
|
2008-11-26 09:16:20 +00:00
|
|
|
MmsMsg *m,
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr **new_msgid,
|
2008-11-20 08:43:52 +00:00
|
|
|
List **errhdrs)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
2007-05-02 07:30:16 +00:00
|
|
|
Octstr *id = NULL, *groupid = NULL;
|
2007-07-27 16:39:19 +00:00
|
|
|
int ret = 0, retry = 0;
|
2008-02-17 14:33:00 +00:00
|
|
|
double throughput = 0;
|
2008-11-26 09:16:20 +00:00
|
|
|
Octstr *from = e->from;
|
|
|
|
Octstr *transid = e->msgId;
|
|
|
|
Octstr *linkedid = e->token; /* token = linkedid */
|
|
|
|
char *vasid = e->vasid ? octstr_get_cstr(e->vasid) : NULL;
|
|
|
|
Octstr *service_code = e->vaspid;
|
|
|
|
Octstr *dlr_url = e->url1;
|
|
|
|
Octstr *rr_url = e->url2;
|
|
|
|
List *hdrs = e->hdrs;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
mutex_lock(mmc->mutex); { /* Grab a lock on it. */
|
2008-11-20 08:43:52 +00:00
|
|
|
Octstr *err = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
if (mmc->type == SOAP_MMSC)
|
2010-12-09 10:36:29 +00:00
|
|
|
id = mm7soap_send(mmc, from, lto, transid, linkedid, vasid, service_code, e, m, &err, errhdrs, &retry);
|
2005-09-07 10:10:41 +00:00
|
|
|
else if (mmc->type == EAIF_MMSC)
|
2010-12-09 10:36:29 +00:00
|
|
|
id = mm7eaif_send(mmc, from, lto, transid, vasid, e, m, &err, &retry);
|
2008-09-11 09:03:59 +00:00
|
|
|
else if (mmc->type == HTTP_MMSC)
|
2010-12-09 10:36:29 +00:00
|
|
|
id = mm7http_send(mmc,e, from, lto, m, &err, &retry);
|
2011-03-24 12:58:11 +00:00
|
|
|
else if (mmc->type == MM1_MMSC)
|
|
|
|
id = mm7mm1_send(mmc, from, lto, transid, linkedid, vasid,
|
|
|
|
service_code, m, hdrs, &err, &retry);
|
2010-12-09 10:36:29 +00:00
|
|
|
else if (mmc->type == CUSTOM_MMSC && mmc->started) {
|
|
|
|
Octstr *to = gwlist_get(lto, 0); /* XXX Send one at a time*/
|
2007-09-19 13:06:26 +00:00
|
|
|
id = mmc->fns->send_msg(mmc->data,
|
|
|
|
from, to, transid, linkedid, vasid,
|
2008-11-20 08:43:52 +00:00
|
|
|
service_code, m, hdrs, &err, &retry);
|
2010-12-09 10:36:29 +00:00
|
|
|
}
|
2010-10-26 10:18:13 +00:00
|
|
|
#if 0
|
|
|
|
else if (mmc->type == MM4_MMSC && mmc->started)
|
|
|
|
(void )0; /* Already sent above */
|
|
|
|
#endif
|
|
|
|
else
|
|
|
|
mms_error_ex("MT", 0, "MM7", mmc->id, "Can't send to MMC[%s]!",
|
2010-10-21 17:51:16 +00:00
|
|
|
mmc->id ? octstr_get_cstr(mmc->id) : "");
|
2007-05-02 07:30:16 +00:00
|
|
|
|
|
|
|
throughput = mmc->throughput;
|
|
|
|
groupid = mmc->group_id ? octstr_duplicate(mmc->group_id) : NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2008-11-20 08:43:52 +00:00
|
|
|
if (err && errhdrs) {
|
|
|
|
if (*errhdrs == NULL)
|
|
|
|
*errhdrs = http_create_empty_headers();
|
|
|
|
http_header_add(*errhdrs, "X-Mbuni-Error", octstr_get_cstr(err));
|
|
|
|
}
|
|
|
|
octstr_destroy(err);
|
2005-09-07 10:10:41 +00:00
|
|
|
} mutex_unlock(mmc->mutex); /* release lock */
|
|
|
|
|
|
|
|
if (id) {
|
2007-08-06 11:57:15 +00:00
|
|
|
if (dlr_url) /* remember the url's for reporting purposes. */
|
|
|
|
mms_dlr_url_put(id, "delivery-report", groupid, dlr_url, orig_transid);
|
2005-09-07 10:10:41 +00:00
|
|
|
if (rr_url)
|
2007-08-06 11:57:15 +00:00
|
|
|
mms_dlr_url_put(id, "read-report", groupid, rr_url, orig_transid);
|
2007-05-02 07:30:16 +00:00
|
|
|
ret = MMS_SEND_OK;
|
2011-01-03 06:57:50 +00:00
|
|
|
} else {
|
2007-07-27 16:39:19 +00:00
|
|
|
ret = retry ? MMS_SEND_ERROR_TRANSIENT : MMS_SEND_ERROR_FATAL;
|
2011-01-03 06:57:50 +00:00
|
|
|
if (!retry && dlr_url)
|
|
|
|
mms_dlr_url_put(e->msgId, "delivery-report", groupid, dlr_url, orig_transid);
|
|
|
|
}
|
2007-08-06 11:57:15 +00:00
|
|
|
*new_msgid = id;
|
2008-11-26 09:16:20 +00:00
|
|
|
|
2007-05-02 07:30:16 +00:00
|
|
|
octstr_destroy(groupid);
|
2008-02-14 14:46:21 +00:00
|
|
|
if (throughput > 0)
|
2007-05-02 07:30:16 +00:00
|
|
|
gwthread_sleep(1.0/throughput);
|
|
|
|
return ret;
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
typedef struct MRcpt_t {
|
|
|
|
int smtp_flag;
|
|
|
|
MmscGrp *mmc;
|
|
|
|
List *rto; /* List of envelope */
|
|
|
|
} MRcpt_t;
|
|
|
|
|
|
|
|
static int cmp_mrcpt(struct MRcpt_t *m, MmscGrp *mmc)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (mmc == NULL && m->smtp_flag)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return (mmc && mmc->id && m->mmc && m->mmc->id) && (octstr_case_compare(m->mmc->id, mmc->id) == 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void process_send_res(MmsEnvelope *e, MmsMsg *msg,
|
|
|
|
MmsEnvelopeTo *to, MmscGrp *mmc,
|
|
|
|
int res, Octstr *err, List *errl, Octstr *new_msgid,
|
2011-01-06 05:55:35 +00:00
|
|
|
int first_one)
|
2010-12-09 10:36:29 +00:00
|
|
|
{
|
2011-01-06 05:55:35 +00:00
|
|
|
Octstr *rcpt = to->_x ? to->_x : to->rcpt; /* Might have a cleaned up recipient address */
|
2010-12-09 10:36:29 +00:00
|
|
|
time_t tnow = time(NULL);
|
2011-01-06 06:10:20 +00:00
|
|
|
Octstr *xfrom = octstr_duplicate(e->from); /* Because it might change below */
|
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
|
|
|
to->process = 0;
|
|
|
|
|
|
|
|
if (e->msgtype == MMS_MSGTYPE_SEND_REQ ||
|
|
|
|
e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */
|
2011-01-06 06:13:12 +00:00
|
|
|
queue_dlr(mmc, e->from, rcpt, new_msgid, octstr_imm("Forwarded"), "MM7-Out", errl);
|
2010-12-09 10:36:29 +00:00
|
|
|
} else if (res == MMS_SEND_ERROR_FATAL && mmc) {
|
|
|
|
if (e->msgtype == MMS_MSGTYPE_SEND_REQ ||
|
|
|
|
e->msgtype == MMS_MSGTYPE_RETRIEVE_CONF) /* queue dlr as needed. */
|
2011-01-06 06:13:12 +00:00
|
|
|
queue_dlr(mmc, e->from, rcpt, e->msgId,
|
2010-12-09 10:36:29 +00:00
|
|
|
(e->expiryt != 0 && e->expiryt < tnow) ?
|
|
|
|
octstr_imm("Expired") : octstr_imm("Rejected"),
|
|
|
|
"MM7-Out", errl);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mmc) {
|
|
|
|
if (first_one) {
|
|
|
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED)
|
|
|
|
mmc->mt_pdus++;
|
|
|
|
else
|
|
|
|
mmc->mt_errors++;
|
|
|
|
}
|
|
|
|
mmc->last_pdu = time(NULL);
|
|
|
|
return_mmsc_conn(mmc); /* important. */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (res == MMS_SEND_ERROR_FATAL)
|
|
|
|
to->process = 0; /* No more attempts. */
|
|
|
|
|
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
/* handle CDR */
|
2010-12-09 10:36:29 +00:00
|
|
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED || res == MMS_SEND_ERROR_FATAL) {
|
|
|
|
Octstr *mclass = mms_get_header_value(msg, octstr_imm("X-Mms-Message-Class"));
|
|
|
|
Octstr *prio = mms_get_header_value(msg, octstr_imm("X-Mms-Priority"));
|
|
|
|
Octstr *mstatus = mms_get_header_value(msg, octstr_imm("X-Mms-Status"));
|
|
|
|
|
|
|
|
/* Do CDR */
|
|
|
|
cdrfs->logcdr(e->created,
|
2011-01-06 06:10:20 +00:00
|
|
|
octstr_get_cstr(xfrom),
|
2011-01-06 05:55:35 +00:00
|
|
|
octstr_get_cstr(rcpt),
|
2010-12-09 10:36:29 +00:00
|
|
|
octstr_get_cstr(e->msgId),
|
|
|
|
mmc ? octstr_get_cstr(mmc->id) : NULL, /* Should we touch mmc here? XXX */
|
|
|
|
e->src_interface,
|
2011-03-24 12:58:11 +00:00
|
|
|
"MM7",
|
2010-12-09 10:36:29 +00:00
|
|
|
e->msize,
|
|
|
|
(char *)mms_message_type_to_cstr(e->msgtype),
|
|
|
|
|
|
|
|
prio ? octstr_get_cstr(prio) : NULL,
|
|
|
|
mclass ? octstr_get_cstr(mclass) : NULL,
|
|
|
|
res == MMS_SEND_ERROR_FATAL ? "dropped" : (mstatus ? octstr_get_cstr(mstatus) : "sent"),
|
|
|
|
e->dlr,
|
|
|
|
0);
|
|
|
|
|
|
|
|
octstr_destroy(mclass);
|
|
|
|
octstr_destroy(prio);
|
|
|
|
octstr_destroy(mstatus);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err == NULL)
|
|
|
|
mms_info(0, "MM7", NULL, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: msgid=[%s]",
|
|
|
|
SEND_ERROR_STR(res),
|
2011-01-06 06:10:20 +00:00
|
|
|
octstr_get_cstr(xfrom), octstr_get_cstr(rcpt), e->msize,
|
2010-12-09 10:36:29 +00:00
|
|
|
new_msgid ? octstr_get_cstr(new_msgid) : "N/A");
|
|
|
|
else
|
|
|
|
mms_error_ex("MT", 0,
|
|
|
|
"MM7", NULL,
|
|
|
|
"%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: %s",
|
|
|
|
SEND_ERROR_STR(res),
|
2011-01-06 06:10:20 +00:00
|
|
|
octstr_get_cstr(xfrom), octstr_get_cstr(rcpt), e->msize, octstr_get_cstr(err));
|
|
|
|
octstr_destroy(xfrom);
|
2010-12-09 10:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Make a list of recpients up to max_rcpt */
|
|
|
|
static inline List *make_srcpt_list(List *rto, int max_rcpt)
|
|
|
|
{
|
|
|
|
List *l = gwlist_create();
|
|
|
|
MmsEnvelopeTo *xto;
|
|
|
|
while ((max_rcpt > 0) && (xto = gwlist_extract_first(rto)) != NULL) {
|
|
|
|
gwlist_append(l, xto);
|
|
|
|
max_rcpt--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gwlist_len(l) == 0) {
|
|
|
|
gwlist_destroy(l, NULL);
|
|
|
|
l = NULL;
|
|
|
|
}
|
|
|
|
return l;
|
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
static int sendMsg(MmsEnvelope *e)
|
|
|
|
{
|
|
|
|
MmsMsg *msg = NULL;
|
|
|
|
int i, n;
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL;
|
2010-12-09 10:36:29 +00:00
|
|
|
MmscGrp _mmc_smtp = {.max_recipients = DEFAULT_SIMUL_RCPTS, .mutex = mutex_create()};
|
|
|
|
MRcpt_t smtp_h = {.mmc = &_mmc_smtp, .smtp_flag = 1, .rto = gwlist_create()}; /* Signals that recipient is on other end of smtp pipe */
|
|
|
|
List *mlist = NULL; /* List of MMScs */
|
|
|
|
MmsEnvelopeTo *to;
|
|
|
|
time_t tnow = time(NULL);
|
|
|
|
|
2008-07-18 21:30:18 +00:00
|
|
|
if ((msg = qfs->mms_queue_getdata(e)) == NULL) {
|
2008-09-04 17:20:42 +00:00
|
|
|
mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname);
|
2010-10-21 17:51:16 +00:00
|
|
|
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR, 4);
|
2008-07-18 21:30:18 +00:00
|
|
|
goto done2;
|
2010-10-21 17:51:16 +00:00
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR);
|
2008-08-14 11:44:58 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
mlist = gwlist_create_ex(&smtp_h);
|
|
|
|
|
|
|
|
/* First split by mmc */
|
|
|
|
for (i = 0, n = gwlist_len(e->to); i<n; i++)
|
|
|
|
if ((to = gwlist_get(e->to, i)) != NULL && to->process && to->rcpt) {
|
|
|
|
Octstr *x, *err = NULL;
|
|
|
|
int is_email = (octstr_search_char(to->rcpt, '@', 0) > 0);
|
|
|
|
Octstr *requested_mmsc = NULL;
|
|
|
|
MmscGrp *mmc = NULL;
|
|
|
|
int res = MMS_SEND_OK;
|
|
|
|
MRcpt_t *m;
|
2008-08-14 11:44:58 +00:00
|
|
|
|
2011-01-06 05:55:35 +00:00
|
|
|
to->_x = NULL; /* Clear it. */
|
2010-12-09 10:36:29 +00:00
|
|
|
if (e->expiryt != 0 && /* Handle message expiry. */
|
|
|
|
e->expiryt < tnow) {
|
|
|
|
err = octstr_format("MMSC error: Message expired while sending to %S!", to->rcpt);
|
|
|
|
res = MMS_SEND_ERROR_FATAL;
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
goto done_route;
|
|
|
|
} else if (e->attempts >= maxsendattempts) {
|
|
|
|
err = octstr_format("MMSBox error: Failed to deliver to "
|
|
|
|
"%S after %ld attempts. (max attempts allowed is %ld)!",
|
|
|
|
to->rcpt, e->attempts,
|
|
|
|
maxsendattempts);
|
|
|
|
res = MMS_SEND_ERROR_FATAL;
|
|
|
|
goto done_route;
|
2010-10-21 17:51:16 +00:00
|
|
|
}
|
2010-10-26 17:40:49 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
x = octstr_format("X-Mbuni-Via-%d", i);
|
|
|
|
requested_mmsc = e->hdrs ? http_header_value(e->hdrs, x) : NULL;
|
|
|
|
octstr_destroy(x);
|
2010-10-26 17:40:49 +00:00
|
|
|
|
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
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 "
|
|
|
|
"%S. Don't know how to route!",
|
|
|
|
to->rcpt);
|
|
|
|
res = MMS_SEND_ERROR_TRANSIENT;
|
|
|
|
goto done_route;
|
|
|
|
}
|
|
|
|
|
2008-09-12 12:02:40 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
/* We know how to route: If mmc is null at this point, means mm4 recipient. */
|
|
|
|
if ((m = gwlist_search(mlist, mmc, (void *)cmp_mrcpt)) == NULL) { /* A new route, add recipient zone */
|
|
|
|
m = gw_malloc(sizeof *m);
|
|
|
|
m->smtp_flag = 0;
|
|
|
|
m->mmc = mmc;
|
|
|
|
m->rto = gwlist_create();
|
2008-09-12 12:02:40 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
gwlist_append(mlist, m);
|
|
|
|
}
|
2008-11-26 09:16:20 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
gwlist_append(m->rto, to); /* Record route. */
|
|
|
|
|
|
|
|
done_route:
|
|
|
|
if (res != MMS_SEND_OK)
|
|
|
|
process_send_res(e, msg, to, mmc, res, err, NULL, NULL, 0);
|
|
|
|
octstr_destroy(err);
|
|
|
|
octstr_destroy(requested_mmsc);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, n = gwlist_len(mlist); i<n && (e != NULL); i++) { /* Pass through MMSCs, delivering to one at a time. */
|
|
|
|
MRcpt_t *m = gwlist_get(mlist, i);
|
|
|
|
int maxrcpt = m->mmc->max_recipients;
|
|
|
|
List *lto;
|
|
|
|
|
|
|
|
/* Hive off maxrcpt each time and send. */
|
|
|
|
while (e != NULL && (lto = make_srcpt_list(m->rto, maxrcpt)) != NULL) {
|
|
|
|
MmscGrp *mmc = m->mmc;
|
|
|
|
Octstr *err = NULL;
|
|
|
|
Octstr *new_msgid = NULL;
|
|
|
|
List *errl = NULL;
|
|
|
|
int j, res = MMS_SEND_OK;
|
|
|
|
int is_email = m->smtp_flag;
|
|
|
|
int is_mm4 = (mmc && mmc->type == MM4_MMSC && mmc->started);
|
|
|
|
List *xto = gwlist_create();
|
|
|
|
Octstr *zto = NULL;
|
2011-01-06 05:55:35 +00:00
|
|
|
Octstr *oldfrom = octstr_duplicate(e->from); /* Save old from address */
|
|
|
|
|
|
|
|
if (mmc && mmc->strip_prefixes) /* strip prefixes from sender address */
|
|
|
|
_mms_fixup_address(&e->from, NULL, mmc->strip_prefixes, 1);
|
2010-12-09 10:36:29 +00:00
|
|
|
|
|
|
|
/* Make recipient list */
|
|
|
|
for (j = 0; j < gwlist_len(lto); j++) {
|
|
|
|
MmsEnvelopeTo *to = gwlist_get(lto, j);
|
|
|
|
Octstr *x = octstr_duplicate(to->rcpt);
|
|
|
|
int is_email = (octstr_search_char(to->rcpt, '@', 0) > 0);
|
|
|
|
if (is_mm4 && !is_email) /* Add host name of recipient domain */
|
|
|
|
octstr_format_append(x, "@%S",
|
|
|
|
mmc && octstr_str_compare(mmc->mmsc_url, "*") != 0 ? mmc->mmsc_url :
|
|
|
|
octstr_imm("unknown"));
|
2011-01-05 05:53:14 +00:00
|
|
|
|
|
|
|
if (mmc && mmc->strip_prefixes) /* strip prefixes */
|
|
|
|
_mms_fixup_address(&x, NULL, mmc->strip_prefixes, 1);
|
|
|
|
if (x)
|
|
|
|
gwlist_append(xto, x);
|
2010-12-09 10:36:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LINEARISE_STR_LIST(zto,xto,", ");
|
|
|
|
if (is_mm4 || is_email) { /* Handle mm4 as well */
|
|
|
|
int j = octstr_case_search(e->from, octstr_imm("/TYPE=PLMN"), 0);
|
|
|
|
int k = octstr_case_search(e->from, octstr_imm("/TYPE=IPv"), 0);
|
|
|
|
int len = octstr_len(e->from);
|
|
|
|
Octstr *pfrom;
|
|
|
|
|
|
|
|
|
|
|
|
if (j > 0 && j - 1 + sizeof "/TYPE=PLMN" == len)
|
|
|
|
pfrom = octstr_copy(e->from, 0, j);
|
|
|
|
else if (k > 0 && k + sizeof "/TYPE=IPv" == len)
|
|
|
|
pfrom = octstr_copy(e->from, 0, k);
|
|
|
|
else
|
|
|
|
pfrom = octstr_duplicate(e->from);
|
|
|
|
|
|
|
|
if (octstr_search_char(e->from, '@', 0) < 0)
|
|
|
|
octstr_format_append(pfrom,"@%S", myhostname);
|
|
|
|
|
|
|
|
res = mms_sendtoemail(pfrom, xto,
|
|
|
|
e->subject ? e->subject : octstr_imm(""),
|
|
|
|
e->msgId, msg, 0, &err, octstr_get_cstr(sendmail_cmd),
|
|
|
|
myhostname, 0, 0,
|
|
|
|
"",
|
|
|
|
"", 0,
|
|
|
|
e->xqfname,
|
|
|
|
e->hdrs, smtp_relay.host, smtp_relay.port);
|
|
|
|
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
|
|
|
new_msgid = e->msgId ? octstr_duplicate(e->msgId) : octstr_create("00001"); /* Fake it */
|
|
|
|
mmsbox_event_cb(NULL, MM7_TAG_SubmitReq, 1, octstr_imm("1.0"), 200,
|
|
|
|
mms_msgsize(msg), e->attempts, pfrom,
|
|
|
|
zto,NULL, NULL, e->hdrs, NULL);
|
|
|
|
}
|
|
|
|
octstr_destroy(pfrom);
|
|
|
|
} else {
|
|
|
|
res = mms_sendtommsc(mmc, e,
|
|
|
|
xto,
|
|
|
|
otransid,
|
|
|
|
msg,
|
|
|
|
&new_msgid,
|
|
|
|
&errl);
|
|
|
|
if (errl)
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For each recipient, process result */
|
|
|
|
for (j = 0; j < gwlist_len(lto); j++) {
|
|
|
|
MmsEnvelopeTo *to = gwlist_get(lto, j);
|
2011-01-06 05:55:35 +00:00
|
|
|
if (to)
|
|
|
|
to->_x = gwlist_get(xto, j);
|
|
|
|
process_send_res(e, msg, to, mmc, res, err, errl, new_msgid, j == 0);
|
2010-12-09 10:36:29 +00:00
|
|
|
}
|
|
|
|
octstr_destroy(zto);
|
|
|
|
gwlist_destroy(xto, (void *)octstr_destroy);
|
|
|
|
octstr_destroy(new_msgid);
|
|
|
|
octstr_destroy(err);
|
|
|
|
http_destroy_headers(errl);
|
2011-01-05 05:53:14 +00:00
|
|
|
gwlist_destroy(lto, NULL);
|
2008-11-26 09:16:20 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
e->lasttry = tnow;
|
2011-01-06 05:55:35 +00:00
|
|
|
|
|
|
|
octstr_destroy(e->from);
|
|
|
|
e->from = oldfrom; /* restore old from address */
|
2010-12-09 10:36:29 +00:00
|
|
|
if (qfs->mms_queue_update(e) == 1) {
|
|
|
|
e = NULL;
|
|
|
|
break; /* Queue entry gone. */
|
|
|
|
}
|
2008-09-12 12:02:40 +00:00
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2008-07-18 21:30:18 +00:00
|
|
|
done2:
|
2007-07-27 16:39:19 +00:00
|
|
|
mms_destroy(msg);
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(otransid);
|
2010-10-21 17:51:16 +00:00
|
|
|
|
2010-12-09 10:36:29 +00:00
|
|
|
/* Clear out mlist: */
|
|
|
|
for (i = 0; i < gwlist_len(mlist); i++) {
|
|
|
|
MRcpt_t *m = gwlist_get(mlist, i);
|
|
|
|
|
|
|
|
gwlist_destroy(m->rto, NULL); /* Clear list */
|
|
|
|
if (m != &smtp_h)
|
|
|
|
gw_free(m);
|
|
|
|
else
|
|
|
|
mutex_destroy(smtp_h.mmc->mutex);
|
|
|
|
}
|
|
|
|
gwlist_destroy(mlist, NULL);
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
if (e) { /* Update the queue if it is still valid (e.g. recipients not handled)
|
|
|
|
* XXX can this happen here??...
|
|
|
|
*/
|
|
|
|
e->lasttry = time(NULL);
|
|
|
|
e->attempts++; /* Update count of number of delivery attempts. */
|
|
|
|
e->sendt = e->lasttry + mmsbox_send_back_off * e->attempts;
|
|
|
|
|
2007-08-20 11:49:30 +00:00
|
|
|
if (qfs->mms_queue_update(e) != 1)
|
|
|
|
qfs->mms_queue_free_env(e);
|
2007-07-27 16:39:19 +00:00
|
|
|
}
|
2008-08-29 10:23:17 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
|
|
|
|
return 1; /* always delete queue entry. */
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
2010-05-26 10:36:27 +00:00
|
|
|
void mmsbox_outgoing_queue_runner(volatile sig_atomic_t *rstop)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
2010-11-18 06:51:17 +00:00
|
|
|
hmon->register_thread( "outgoing_queue" );
|
2007-08-20 11:49:30 +00:00
|
|
|
qfs->mms_queue_run(octstr_get_cstr(outgoing_qdir),
|
2010-10-21 17:51:16 +00:00
|
|
|
sendMsg, queue_interval, maxthreads, rstop);
|
2010-11-18 06:51:17 +00:00
|
|
|
hmon->unregister_thread( "outgoing_queue" );
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
2010-10-26 10:18:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* MM4 handler stuff */
|
|
|
|
static void fixup_addresses(List *headers)
|
|
|
|
{
|
|
|
|
fixup_address_type(headers, "To",
|
|
|
|
octstr_get_cstr(unified_prefix), strip_prefixes);
|
|
|
|
fixup_address_type(headers, "From",
|
|
|
|
octstr_get_cstr(unified_prefix), strip_prefixes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int send_mm4_res(int mtype, Octstr *to, Octstr *sender, Octstr *transid,
|
|
|
|
char *status, Octstr *msgid,
|
|
|
|
char *sendmail_cmd)
|
|
|
|
{
|
|
|
|
char tmp[32];
|
|
|
|
List *h = http_create_empty_headers();
|
|
|
|
MIMEEntity *m = mime_entity_create();
|
|
|
|
Octstr *err = NULL;
|
|
|
|
|
|
|
|
/* Make headers */
|
|
|
|
sprintf(tmp, "%d.%d.%d",
|
|
|
|
MAJOR_VERSION(MMS_3GPP_VERSION),
|
|
|
|
MINOR1_VERSION(MMS_3GPP_VERSION),
|
|
|
|
MINOR2_VERSION(MMS_3GPP_VERSION));
|
|
|
|
|
|
|
|
http_header_add(h, "X-Mms-3GPP-MMS-Version", tmp);
|
|
|
|
http_header_add(h, "X-Mms-Transaction-ID", octstr_get_cstr(transid));
|
|
|
|
http_header_add(h, "X-Mms-Message-Type", mm4_types[mtype].mm4str);
|
|
|
|
if (msgid)
|
|
|
|
http_header_add(h, "X-Mms-Message-ID", octstr_get_cstr(msgid));
|
|
|
|
http_header_add(h, "X-Mms-Request-Status-Code", status);
|
|
|
|
http_header_add(h, "Sender", octstr_get_cstr(sender));
|
|
|
|
http_header_add(h, "To", octstr_get_cstr(to));
|
|
|
|
|
|
|
|
mime_replace_headers(m, h);
|
|
|
|
http_destroy_headers(h);
|
|
|
|
|
|
|
|
mm_send_to_email(to, sender, octstr_imm(""), msgid, m, 0,
|
|
|
|
&err, sendmail_cmd,
|
2010-10-27 06:08:50 +00:00
|
|
|
myhostname, smtp_relay.host, smtp_relay.port);
|
2010-10-26 10:18:13 +00:00
|
|
|
if (err) {
|
|
|
|
mms_warning(0, "MM4", NULL, "send.RES reported: %s!", octstr_get_cstr(err));
|
|
|
|
octstr_destroy(err);
|
|
|
|
}
|
|
|
|
mime_entity_destroy(m);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Octstr *handle_msg(MIMEEntity *mm, Octstr *from, List *to, MmscGrp *mmc)
|
|
|
|
{
|
|
|
|
char *err = NULL;
|
2010-11-05 05:49:56 +00:00
|
|
|
List *headers = NULL, *h2;
|
2010-10-26 10:18:13 +00:00
|
|
|
Octstr *mm4_type;
|
|
|
|
Octstr *transid = NULL, *orig_sys = NULL, *ack = NULL, *res = NULL, *me = NULL, *rstatus = NULL;
|
|
|
|
int i, mtype = -1, mm1_type = -1, mm7type;
|
|
|
|
MmsMsg *msg = NULL;
|
|
|
|
Octstr *qdir = NULL, *mmc_id = NULL, *value = NULL, *msgid = NULL;
|
|
|
|
|
|
|
|
Octstr *xproxy = mmc != NULL && octstr_str_compare(mmc->mmsc_url, "*") != 0 ? mmc->mmsc_url : NULL;
|
|
|
|
|
|
|
|
/* Taken largely from mmsfromeamil.c */
|
|
|
|
/* Take the entity, recode it --> remove base64 stuff, split headers. */
|
|
|
|
unbase64_mimeparts(mm);
|
|
|
|
unpack_mimeheaders(mm);
|
|
|
|
|
|
|
|
/* Delete some headers... */
|
|
|
|
headers = mime_entity_headers(mm);
|
|
|
|
http_header_remove_all(headers, "Received");
|
|
|
|
http_header_remove_all(headers, "X-MimeOLE");
|
|
|
|
http_header_remove_all(headers, "X-Mailer");
|
|
|
|
|
|
|
|
/* rebuild headers, removing nasty looking ones. */
|
|
|
|
h2 = http_create_empty_headers();
|
|
|
|
for (i = 0; i<gwlist_len(headers); i++) {
|
|
|
|
Octstr *name = NULL, *value = NULL;
|
|
|
|
http_header_get(headers, i, &name, &value);
|
|
|
|
|
|
|
|
if (!name ||
|
|
|
|
octstr_case_search(name, octstr_imm("spam"), 0) >= 0 ||
|
|
|
|
octstr_case_search(name, octstr_imm("mailscanner"), 0) >= 0)
|
|
|
|
goto loop;
|
|
|
|
|
|
|
|
http_header_add(h2, octstr_get_cstr(name), octstr_get_cstr(value));
|
|
|
|
loop:
|
|
|
|
octstr_destroy(name);
|
|
|
|
octstr_destroy(value);
|
|
|
|
}
|
|
|
|
http_destroy_headers(headers);
|
|
|
|
headers = h2;
|
|
|
|
|
|
|
|
/* Look for MM4 headers... */
|
|
|
|
mm4_type = http_header_value(headers, octstr_imm("X-Mms-Message-Type"));
|
|
|
|
ack = http_header_value(headers, octstr_imm("X-Mms-Ack-Request"));
|
|
|
|
rstatus = http_header_value(headers, octstr_imm("X-Mms-Request-Status-Code"));
|
|
|
|
|
|
|
|
if ((transid = http_header_value(headers, octstr_imm("X-Mms-Transaction-ID"))) == NULL)
|
|
|
|
transid = octstr_create("001");
|
|
|
|
/* get originator system. */
|
|
|
|
if ((orig_sys = http_header_value(headers, octstr_imm("X-Mms-Originator-System"))) == NULL)
|
|
|
|
orig_sys = http_header_value(headers, octstr_imm("Sender"));
|
|
|
|
|
|
|
|
if ((msgid = http_header_value(headers, octstr_imm("X-Mms-Message-ID"))) == NULL)
|
|
|
|
msgid = http_header_value(headers, octstr_imm("Message-ID"));
|
|
|
|
|
|
|
|
strip_quoted_string(msgid);
|
|
|
|
strip_quoted_string(transid);
|
|
|
|
|
|
|
|
|
|
|
|
debug("mmsbox.MM4receive", 0,
|
|
|
|
"Received [message type: %s] [transaction id: %s] [msgid: %s]",
|
|
|
|
mm4_type ? octstr_get_cstr(mm4_type) : "",
|
|
|
|
transid ? octstr_get_cstr(transid) : "",
|
|
|
|
msgid ? octstr_get_cstr(msgid) : "");
|
|
|
|
|
|
|
|
/* ... and remove non-essential ones */
|
|
|
|
http_header_remove_all(headers, "X-Mms-3GPP-MMS-Version");
|
|
|
|
http_header_remove_all(headers, "MIME-Version");
|
|
|
|
http_header_remove_all(headers, "X-Mms-Message-ID");
|
|
|
|
http_header_remove_all(headers, "Message-ID");
|
|
|
|
http_header_remove_all(headers, "X-Mms-Ack-Request");
|
|
|
|
http_header_remove_all(headers, "X-Mms-Originator-System");
|
|
|
|
|
|
|
|
http_header_remove_all(headers, "Sender");
|
|
|
|
|
|
|
|
/* msgid was there, put it back in proper form. */
|
|
|
|
if (msgid)
|
|
|
|
http_header_add(headers, "Message-ID", octstr_get_cstr(msgid));
|
|
|
|
|
|
|
|
fixup_addresses(headers);
|
|
|
|
|
|
|
|
|
|
|
|
if (mm4_type) {
|
|
|
|
unsigned char *x = NULL;
|
|
|
|
Octstr *y;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
http_header_remove_all(headers, "X-Mms-Message-Type");
|
|
|
|
for (i = 0; mm4_types[i].mm4str; i++)
|
|
|
|
if (octstr_str_case_compare(mm4_type, mm4_types[i].mm4str) == 0) {
|
|
|
|
mtype = i;
|
|
|
|
mm1_type = mm4_types[i].mm1_type;
|
|
|
|
x = mms_message_type_to_cstr(mm1_type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x) {
|
|
|
|
http_header_add(headers, "X-Mms-Message-Type", (char *)x);
|
|
|
|
if (orig_sys == NULL) /* Make it up! */
|
|
|
|
orig_sys = octstr_format("system-user@%S",
|
|
|
|
xproxy ? xproxy : octstr_imm("unknown"));
|
|
|
|
} else {
|
|
|
|
octstr_destroy(mm4_type);
|
|
|
|
mm4_type = NULL; /* So that we assume normal message below. */
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((y = http_header_value(headers, octstr_imm("X-Mms-MM-Status-Code"))) != NULL) {
|
|
|
|
/* This field is different on MM1. */
|
|
|
|
http_header_remove_all(headers, "X-Mms-MM-Status-Code");
|
|
|
|
http_header_add(headers, "X-Mms-Status", octstr_get_cstr(y));
|
|
|
|
octstr_destroy(y);
|
|
|
|
}
|
|
|
|
}
|
2011-09-29 09:33:23 +00:00
|
|
|
if (mm4_type == NULL && mtype < 0) { /* else assume a normal send message. */
|
2010-10-26 10:18:13 +00:00
|
|
|
http_header_add(headers, "X-Mms-Message-Type", "m-send-req");
|
|
|
|
mm1_type = MMS_MSGTYPE_SEND_REQ;
|
|
|
|
mtype = MM4_FORWARD_REQ;
|
|
|
|
}
|
|
|
|
|
|
|
|
mime_replace_headers(mm, headers);
|
|
|
|
|
|
|
|
/* Now convert from mime to MMS message, if we should */
|
|
|
|
if (mm1_type >= 0) {
|
|
|
|
if ((msg = mms_frommime(mm)) == NULL) {
|
|
|
|
mms_error(0, "MM4", mmc ? mmc->id : NULL, "Unable to parse Message!");
|
|
|
|
MMSC_ISSUE_ALARM(mmc ? mmc : NULL, MMSBOX_ALARM_MM4_PARSING_FAILURE, 3);
|
|
|
|
res = NULL;
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(mmc ? mmc : NULL, MMSBOX_ALARM_MM4_PARSING_FAILURE);
|
|
|
|
} else
|
|
|
|
msg = NULL;
|
|
|
|
|
2010-10-26 17:40:49 +00:00
|
|
|
mm7type = mm7_msgtype_to_soaptype(mm1_type,0);
|
2010-10-26 10:18:13 +00:00
|
|
|
me = octstr_format("system-user@%S", myhostname);
|
|
|
|
|
|
|
|
qdir = get_mmsbox_queue_dir(from, to, mmc, &mmc_id); /* get routing info. */
|
|
|
|
switch(mtype) {
|
|
|
|
case MM4_FORWARD_REQ:
|
|
|
|
{
|
|
|
|
Octstr *qf;
|
|
|
|
Octstr *dreport = mms_get_header_value(msg, octstr_imm("X-Mms-Delivery-Report"));
|
|
|
|
Octstr *subject = mms_get_header_value(msg, octstr_imm("Subject"));
|
|
|
|
int dlr;
|
|
|
|
|
|
|
|
if (dreport &&
|
|
|
|
octstr_case_compare(dreport, octstr_imm("Yes")) == 0)
|
|
|
|
dlr = 1;
|
|
|
|
else
|
|
|
|
dlr = 0;
|
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(from, to, subject, mmc ? mmc->id : NULL, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, msg, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
dlr,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/MM4-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
res = mms_make_msgid(octstr_get_cstr(qf), NULL);
|
|
|
|
mms_log("Received", from, to, -1, res, NULL, mmc->id, "MMSBox", octstr_imm("smtp"), NULL);
|
|
|
|
err = "Ok";
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
err = "Error-network-problem";
|
|
|
|
}
|
|
|
|
octstr_destroy(dreport);
|
|
|
|
octstr_destroy(subject);
|
|
|
|
octstr_destroy(qf);
|
|
|
|
}
|
2011-03-24 12:58:11 +00:00
|
|
|
break;
|
2010-10-26 10:18:13 +00:00
|
|
|
case MM4_DELIVERY_REPORT_REQ:
|
|
|
|
{
|
|
|
|
Octstr *qf;
|
|
|
|
Octstr *value2 = NULL, *rr_uri = NULL;
|
|
|
|
List *rqh = http_create_empty_headers();
|
|
|
|
|
|
|
|
value = mms_get_header_value(msg, octstr_imm("X-Mms-Status"));
|
|
|
|
value2 = mms_get_header_value(msg, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
|
|
|
|
|
|
|
|
|
|
|
rr_uri = mmsbox_get_report_info(msg, mmc, mmc_id, "delivery-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (value2 && mmc_id == NULL)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
mmc ? mmc->id : NULL, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, msg, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/MM4-IN",
|
|
|
|
NULL);
|
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
if (qf) {
|
|
|
|
mms_log("DeliveryReport", from, to, -1, msgid, value, mmc->id, "MMSBox", octstr_imm("smtp"), NULL);
|
|
|
|
err = "Ok";
|
|
|
|
res = octstr_duplicate(qf);
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
err = "Error-network-problem";
|
|
|
|
}
|
2010-10-26 10:18:13 +00:00
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(value2);
|
|
|
|
octstr_destroy(rr_uri);
|
|
|
|
http_destroy_headers(rqh);
|
2010-10-26 10:18:13 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MM4_READ_REPLY_REPORT_REQ:
|
|
|
|
{
|
|
|
|
Octstr *qf;
|
|
|
|
Octstr *value2 = NULL, *rr_uri = NULL;
|
|
|
|
List *rqh = http_create_empty_headers();
|
|
|
|
|
|
|
|
value = mms_get_header_value(msg, octstr_imm("X-Mms-Read-Status"));
|
|
|
|
value2 = mms_get_header_value(msg, octstr_imm("X-Mbuni-Orig-Message-ID"));
|
|
|
|
|
|
|
|
rr_uri = mmsbox_get_report_info(msg, mmc, mmc_id, "read-report",
|
|
|
|
value, rqh, NULL, 0, msgid);
|
|
|
|
if (value2 && mmc_id == NULL)
|
|
|
|
http_header_add(rqh, "X-Mbuni-Orig-Message-ID", octstr_get_cstr(value2));
|
|
|
|
|
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
mmc->id,mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, msg, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
rr_uri, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/MM4-IN",
|
|
|
|
NULL);
|
|
|
|
if (qf) {
|
|
|
|
mms_log("Received RR", from, to, -1, msgid, value, mmc->id, "MMSBox", octstr_imm("smtp"), NULL);
|
|
|
|
res = octstr_duplicate(qf);
|
|
|
|
err = "Ok";
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
err = "Error-network-problem";
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(value2);
|
|
|
|
octstr_destroy(rr_uri);
|
|
|
|
http_destroy_headers(rqh);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case MM4_FORWARD_RES:
|
|
|
|
case MM4_READ_REPLY_REPORT_RES:
|
|
|
|
case MM4_DELIVERY_REPORT_RES: /* remove corresponding queue entry. */
|
|
|
|
/* Do nothing */
|
2011-03-24 12:58:11 +00:00
|
|
|
break;
|
2010-10-26 10:18:13 +00:00
|
|
|
default:
|
|
|
|
mms_warning(0, "MM4", xproxy, "Unexpected message type: %s",
|
|
|
|
mm4_type ? octstr_get_cstr(mm4_type) : "not given!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-10-26 17:40:49 +00:00
|
|
|
|
2010-11-05 05:49:56 +00:00
|
|
|
if (mm7type >= 0) /* Issue event call back */
|
2010-10-26 10:18:13 +00:00
|
|
|
mmsbox_event_cb(mmc->id, mm7type, 1, octstr_imm("1.0"), 200,
|
|
|
|
mms_msgsize(msg), 0, from,
|
|
|
|
to && gwlist_len(to) > 0 ? gwlist_get(to,0) : NULL,
|
2010-11-05 05:49:56 +00:00
|
|
|
msgid, transid, headers, value);
|
2010-10-26 10:18:13 +00:00
|
|
|
|
|
|
|
/* respond to the sender as necessary. */
|
|
|
|
if (mm4_type &&
|
|
|
|
err &&
|
|
|
|
ack && octstr_str_case_compare(ack, "Yes") == 0) {
|
2011-03-24 12:58:11 +00:00
|
|
|
int size = send_mm4_res(mtype+1, orig_sys, me, transid, err, res, octstr_get_cstr(sendmail_cmd));
|
2010-10-26 10:18:13 +00:00
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
mmsbox_event_cb(mmc->id, mm7type >= 0 ? mm7type + 1 : MM7_TAG_VASPErrorRsp,
|
|
|
|
1, octstr_imm("1.0"), 200,
|
|
|
|
size, 0, me, orig_sys, res, NULL, NULL, NULL);
|
2010-10-26 17:40:49 +00:00
|
|
|
} else if (mtype == MM4_FORWARD_REQ) /* Or straight up SMTP */
|
|
|
|
mmsbox_event_cb(mmc->id, mm7type >= 0 ? mm7type + 1 : MM7_TAG_VASPErrorRsp,
|
|
|
|
1, octstr_imm("1.0"), 200,
|
|
|
|
0, 0, me, orig_sys, res, NULL, NULL, NULL);
|
|
|
|
|
2010-10-26 10:18:13 +00:00
|
|
|
octstr_destroy(mm4_type);
|
|
|
|
octstr_destroy(transid);
|
|
|
|
octstr_destroy(orig_sys);
|
|
|
|
octstr_destroy(msgid);
|
|
|
|
|
|
|
|
octstr_destroy(rstatus);
|
|
|
|
octstr_destroy(ack);
|
|
|
|
|
|
|
|
octstr_destroy(me);
|
|
|
|
|
|
|
|
octstr_destroy(mmc_id);
|
|
|
|
octstr_destroy(value);
|
|
|
|
mms_destroy(msg);
|
2010-11-05 05:49:56 +00:00
|
|
|
http_destroy_headers(headers);
|
2010-10-26 10:18:13 +00:00
|
|
|
done:
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void clean_address(Octstr **addr, int *isphone, Octstr **xproxy)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
octstr_strip_blanks(*addr);
|
|
|
|
*isphone = 1;
|
|
|
|
if ((i = octstr_search_char(*addr, '<', 0)) >= 0) {
|
|
|
|
octstr_delete(*addr, 0, i+1);
|
|
|
|
|
|
|
|
i = octstr_search_char(*addr, '>', 0);
|
|
|
|
if (i > 0)
|
|
|
|
octstr_delete(*addr, i, octstr_len(*addr));
|
|
|
|
|
|
|
|
}
|
|
|
|
/* Find number type */
|
|
|
|
i = octstr_case_search(*addr, octstr_imm("/TYPE="), 0);
|
|
|
|
if (i>0) {
|
|
|
|
int j = octstr_search_char(*addr, '@', 0);
|
|
|
|
if (j > i) { /* we have @, remove it */
|
|
|
|
*xproxy = octstr_copy(*addr, j+1, octstr_len(*addr));
|
|
|
|
octstr_delete(*addr, j, octstr_len(*addr));
|
|
|
|
}
|
|
|
|
} else if (isphonenum(*addr)) /* Add the TYPE element if missing. */
|
|
|
|
octstr_append(*addr, octstr_imm("/TYPE=PLMN"));
|
|
|
|
else {
|
|
|
|
i = octstr_search_char(*addr, '@', 0);
|
|
|
|
if (i<0)
|
|
|
|
octstr_format_append(*addr, "@unknown");
|
|
|
|
else if (*xproxy == NULL)
|
|
|
|
*xproxy = octstr_copy(*addr, i+1, octstr_len(*addr));
|
|
|
|
*isphone = 0;
|
|
|
|
}
|
|
|
|
/* clean the number. */
|
|
|
|
if (*isphone)
|
|
|
|
_mms_fixup_address(addr,
|
|
|
|
octstr_get_cstr(unified_prefix),
|
|
|
|
strip_prefixes, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-10-27 06:08:50 +00:00
|
|
|
static void smtp_process(int fd, Octstr *ip,
|
|
|
|
Octstr *(*handle_msg)(MIMEEntity *m, Octstr *from, List *to, MmscGrp *mmc))
|
2010-10-26 10:18:13 +00:00
|
|
|
{
|
|
|
|
enum smtp_state_t {MLISTEN, MFROM, MTO, MDATA,MERROR};
|
|
|
|
int i, state = MLISTEN;
|
|
|
|
Connection *c = conn_wrap_fd(fd,0);
|
|
|
|
Octstr *from = NULL;
|
|
|
|
MmscGrp *mmc = NULL;
|
|
|
|
List *to = NULL;
|
|
|
|
Octstr *body = NULL;
|
|
|
|
MIMEEntity *m = NULL;
|
|
|
|
Octstr *line;
|
|
|
|
|
|
|
|
socket_set_blocking(fd,1); /* Because we want each line as it comes */
|
|
|
|
|
|
|
|
/* Issue greeting */
|
|
|
|
line = octstr_format("220 %S SMTP Mbuni %s\r\n", myhostname, MMSC_VERSION);
|
|
|
|
conn_write(c, line);
|
|
|
|
octstr_destroy(line);
|
|
|
|
|
|
|
|
do {
|
|
|
|
Octstr *res;
|
|
|
|
Octstr *cmd = NULL, *arg = NULL;
|
|
|
|
int stop, max_size;
|
|
|
|
|
|
|
|
line = conn_read_line(c);
|
|
|
|
if (line == NULL)
|
|
|
|
state = MERROR;
|
|
|
|
else if (state != MDATA) {
|
|
|
|
i = octstr_search_char(line, ' ', 0);
|
|
|
|
if (i > 0) {
|
|
|
|
cmd = octstr_copy(line, 0, i);
|
|
|
|
arg = octstr_copy(line, i+1, octstr_len(line));
|
|
|
|
} else {
|
|
|
|
cmd = octstr_copy(line, 0, octstr_len(line));
|
|
|
|
arg = octstr_create("");
|
|
|
|
}
|
|
|
|
octstr_strip_blanks(cmd);
|
|
|
|
octstr_strip_blanks(arg);
|
|
|
|
}
|
|
|
|
switch(state) {
|
|
|
|
|
|
|
|
case MLISTEN:
|
|
|
|
if (octstr_str_case_compare(cmd, "HELO") == 0)
|
|
|
|
conn_write(c, octstr_imm("250 Hello and welcome\r\n")); /* ... and stay in same state */
|
|
|
|
else if (octstr_str_case_compare(cmd, "MAIL") == 0) { /* Sender */
|
|
|
|
if ((i = octstr_case_search(arg, octstr_imm("FROM:"), 0)) < 0) /* No From? */
|
|
|
|
conn_write(c, octstr_imm("500 Error. Missing FROM:\r\n"));
|
|
|
|
else {
|
|
|
|
int isphone = 1;
|
|
|
|
Octstr *xproxy = NULL;
|
|
|
|
from = octstr_copy(arg, i+5, octstr_len(arg));
|
|
|
|
|
|
|
|
clean_address(&from, &isphone, &xproxy);
|
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
/* We now have the sender domain and the number. Find a matching MMSC */
|
|
|
|
if (!isphone || xproxy == NULL)
|
|
|
|
mmc = mmsbox_get_mmsc_by_url(octstr_imm("*"));
|
|
|
|
else
|
|
|
|
mmc = mmsbox_get_mmsc_by_url(xproxy);
|
|
|
|
|
|
|
|
/* Check that we have an mmsc and the sender IP is allowed. */
|
|
|
|
if (mmc == NULL || xproxy == NULL ||
|
|
|
|
!is_allowed_ip(mmc->incoming.allow_ip, mmc->incoming.deny_ip, ip)) {
|
|
|
|
conn_write(c, octstr_imm("421 Sender not allowed\r\n"));
|
|
|
|
state = MERROR;
|
|
|
|
} else {
|
2010-10-26 10:18:13 +00:00
|
|
|
|
2011-03-24 12:58:11 +00:00
|
|
|
if (!mmc->strip_domain && isphone)
|
|
|
|
octstr_format_append(from, "@%S", xproxy);
|
|
|
|
conn_write(c, octstr_imm("250 Ok\r\n"));
|
|
|
|
state = MTO;
|
|
|
|
}
|
|
|
|
octstr_destroy(xproxy);
|
2010-10-26 10:18:13 +00:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
conn_write(c, octstr_imm("500 Error.\r\n"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MTO:
|
|
|
|
if (octstr_str_case_compare(cmd, "DATA") == 0) {
|
|
|
|
if (gwlist_len(to) == 0) {
|
|
|
|
conn_write(c, octstr_imm("421 No recipients? Go away!\r\n"));
|
|
|
|
state = MERROR;
|
|
|
|
} else {
|
|
|
|
state = MDATA;
|
|
|
|
conn_write(c, octstr_imm("354 Proceed\r\n"));
|
|
|
|
body = octstr_create("");
|
|
|
|
}
|
|
|
|
} else if (octstr_str_case_compare(cmd, "RCPT") != 0) /* recipient */
|
|
|
|
conn_write(c, octstr_imm("500 send recipient please\r\n")); /* ... and stay in same state */
|
|
|
|
else if ((i = octstr_case_search(arg, octstr_imm("TO:"), 0)) < 0) /* No To? */
|
|
|
|
conn_write(c, octstr_imm("500 send TO field\r\n")); /* ... and stay in same state */
|
|
|
|
else { /* Got it. Clean it up */
|
|
|
|
Octstr *xto = octstr_copy(arg, i+3, octstr_len(arg));
|
|
|
|
int isphone = 1;
|
|
|
|
Octstr *xproxy = NULL;
|
|
|
|
|
|
|
|
clean_address(&xto, &isphone, &xproxy);
|
|
|
|
|
|
|
|
if (mmc && !mmc->strip_domain && isphone && xproxy)
|
|
|
|
octstr_format_append(from, "@%S", xproxy);
|
|
|
|
|
|
|
|
if (xproxy == NULL)
|
|
|
|
conn_write(c, octstr_imm("500 send correct recipient please\r\n")); /* ... and stay in same state */
|
|
|
|
else { /* Stay in same state */
|
|
|
|
conn_write(c, octstr_imm("250 Ok\r\n")); /* Accept recipient */
|
|
|
|
if (to == NULL)
|
|
|
|
to = gwlist_create();
|
|
|
|
gwlist_append(to, xto);
|
|
|
|
xto = NULL;
|
|
|
|
}
|
|
|
|
octstr_destroy(xproxy);
|
|
|
|
octstr_destroy(xto);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MDATA:
|
|
|
|
stop = 0;
|
|
|
|
max_size = (mmc ? mmc->max_pkt_size : DEFAULT_MAX_PKT_SIZE);
|
|
|
|
do {
|
|
|
|
if (octstr_get_char(line, 0) == '.') {
|
|
|
|
if (octstr_get_char(line, 1) != '.') {
|
|
|
|
stop = 1;
|
|
|
|
goto end_loop;
|
|
|
|
} else
|
|
|
|
octstr_delete(line, 0, 1); /* Remove period */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (octstr_len(body) < max_size)
|
|
|
|
octstr_format_append(body, "%S\r\n", line);
|
|
|
|
else if (octstr_len(body) == max_size)
|
|
|
|
octstr_append_char(body, ' '); /* So we exceed length */
|
|
|
|
end_loop:
|
|
|
|
octstr_destroy(line);
|
|
|
|
line = NULL; /* So no double free below */
|
|
|
|
} while (!stop && !conn_eof(c) && (line = conn_read_line(c)) != NULL);
|
|
|
|
|
|
|
|
if (octstr_len(body) > max_size) {
|
|
|
|
conn_write(c, octstr_imm("452 Message too large\r\n"));
|
|
|
|
state = MERROR;
|
|
|
|
goto loop;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We got message, time to process it */
|
|
|
|
if ((m = mime_octstr_to_entity(body)) == NULL) {
|
|
|
|
conn_write(c, octstr_imm("501 Invalid MIME content\r\n"));
|
|
|
|
state = MERROR;
|
|
|
|
goto loop;
|
|
|
|
} else {
|
|
|
|
octstr_destroy(body); /* Release space */
|
|
|
|
body = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((res = handle_msg(m, from, to, mmc)) != NULL) {
|
|
|
|
Octstr *x = octstr_format("250 Ok: %S\r\n", res);
|
|
|
|
|
|
|
|
conn_write(c, x);
|
|
|
|
octstr_destroy(x);
|
|
|
|
octstr_destroy(res);
|
|
|
|
} else
|
|
|
|
conn_write(c, octstr_imm("451 Invalid message content\r\n"));
|
|
|
|
state = MERROR; /* Not really, but we gotta go */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Do nothing */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
loop:
|
|
|
|
octstr_destroy(cmd);
|
|
|
|
octstr_destroy(arg);
|
|
|
|
octstr_destroy(line);
|
|
|
|
} while (state != MERROR);
|
|
|
|
|
|
|
|
octstr_destroy(body);
|
|
|
|
octstr_destroy(from);
|
|
|
|
gwlist_destroy(to, (void *)octstr_destroy);
|
|
|
|
if (m)
|
|
|
|
mime_entity_destroy(m);
|
|
|
|
|
|
|
|
conn_destroy(c);
|
|
|
|
if (mmc)
|
|
|
|
return_mmsc_conn(mmc);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct mm4_req_t {
|
|
|
|
Octstr *ip;
|
|
|
|
int fd;
|
|
|
|
};
|
|
|
|
|
|
|
|
static List *slist = NULL; /* Request list */
|
|
|
|
|
|
|
|
static void smtp_thread(void *unused)
|
|
|
|
{
|
|
|
|
struct mm4_req_t *m;
|
|
|
|
|
|
|
|
while ((m = gwlist_consume(slist)) != NULL) {
|
2010-10-27 06:08:50 +00:00
|
|
|
smtp_process(m->fd, m->ip, handle_msg);
|
2010-10-26 10:18:13 +00:00
|
|
|
octstr_destroy(m->ip);
|
|
|
|
gw_free(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void mm4_receive_func(int *sock)
|
|
|
|
{
|
|
|
|
int i, fd, tcount = 0;
|
|
|
|
Octstr *ip;
|
|
|
|
/* Start the threads, then receive requests, build, go */
|
|
|
|
slist = gwlist_create();
|
|
|
|
|
|
|
|
gwlist_add_producer(slist);
|
|
|
|
|
|
|
|
for (i = 0; i < maxthreads; i++)
|
|
|
|
if (gwthread_create((void *)smtp_thread, NULL) >= 0)
|
|
|
|
tcount++;
|
|
|
|
if (tcount > 0)
|
|
|
|
while (!rstop && ((fd = gw_accept(*sock, &ip)) >= 0 ||
|
|
|
|
errno == EINTR)) {
|
|
|
|
struct mm4_req_t *m;
|
|
|
|
|
|
|
|
if (fd < 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
m = gw_malloc(sizeof *m);
|
|
|
|
m->ip = ip;
|
|
|
|
m->fd = fd;
|
|
|
|
|
|
|
|
gwlist_produce(slist, m);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mms_error(0, "MM4", NULL, "Failed to start SMTP listener threads: %s!", strerror(errno));
|
|
|
|
gwlist_remove_producer(slist);
|
|
|
|
|
|
|
|
gwthread_join_every((void *)smtp_thread);
|
|
|
|
|
2010-11-05 05:49:56 +00:00
|
|
|
gwlist_destroy(slist, NULL);
|
2010-10-26 10:18:13 +00:00
|
|
|
}
|
2011-03-24 12:58:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* MM1 functions and data */
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
enum {MM1_GET, MM1_PUSH} type;
|
|
|
|
int waiter_exists; /* set to true if after handling, should signal and NOT destroy struct.*/
|
|
|
|
pthread_cond_t cond;
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
union {
|
|
|
|
MmsMsg *m; /* for push. */
|
|
|
|
Octstr *url; /* for get */
|
|
|
|
} u;
|
|
|
|
void *result; /* set to the result for a PUSH */
|
|
|
|
Octstr *err;
|
|
|
|
} MM1Request;
|
|
|
|
|
|
|
|
static long start_gprs(Octstr *cmd, Octstr *id, Octstr *pid_cmd);
|
|
|
|
static Octstr *fetch_content_with_curl(MmscGrp *mmc, Octstr *url, Octstr *body, int *hstatus);
|
|
|
|
static void stop_gprs(Octstr *cmd);
|
|
|
|
|
|
|
|
static Octstr *mm7mm1_send(MmscGrp *mmc, Octstr *from, List *lto,
|
|
|
|
Octstr *transid,
|
|
|
|
Octstr *linkedid, char *vasid, Octstr *service_code,
|
|
|
|
MmsMsg *m, List *hdrs, Octstr **err, int *retry)
|
|
|
|
{
|
|
|
|
MM1Request *r = gw_malloc(sizeof *r);
|
|
|
|
Octstr *id;
|
|
|
|
struct MM1Info_t *s = &mmc->mm1;
|
|
|
|
|
|
|
|
gw_assert(m);
|
|
|
|
|
|
|
|
if (!s->sender_alive) {
|
|
|
|
*err = octstr_imm("internal error, mm1 notify not started!");
|
|
|
|
*retry = 1;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove the from address first of all, replace the to address as well */
|
|
|
|
mms_replace_header_value(m, "From", "#insert");
|
|
|
|
mms_replace_header_values(m, "To", lto); /* Put in recipient list */
|
|
|
|
mms_remove_headers(m, "Message-ID");
|
|
|
|
|
|
|
|
r->u.m = m;
|
|
|
|
pthread_cond_init(&r->cond, NULL);
|
|
|
|
pthread_mutex_init(&r->mutex, NULL);
|
|
|
|
r->waiter_exists = 1;
|
|
|
|
r->type = MM1_PUSH;
|
|
|
|
r->result = NULL;
|
|
|
|
r->err = NULL;
|
|
|
|
|
|
|
|
pthread_mutex_lock(&r->mutex); /* at pickup, must grab mutex before signalling. otherwise race condition.*/
|
|
|
|
|
|
|
|
gwlist_produce(s->requests, r);
|
|
|
|
|
|
|
|
pthread_cond_wait(&r->cond, &r->mutex);
|
|
|
|
|
|
|
|
*err = r->err;
|
|
|
|
|
|
|
|
id = r->result;
|
|
|
|
mms_info(0, "MM1", mmc->id, "mm1_send: sent message, type=%s, result=%s",
|
|
|
|
mms_message_type_to_cstr(mms_messagetype(m)),
|
|
|
|
r->err ? octstr_get_cstr(r->err) : "(none)");
|
|
|
|
/* destroy the structure. */
|
|
|
|
if(r->err && (octstr_compare(r->err, octstr_imm("Error-service-denied")) == 0 ||
|
|
|
|
octstr_compare(r->err, octstr_imm("Error-permanent-failure")) == 0))
|
|
|
|
*retry = 0;
|
|
|
|
else
|
|
|
|
*retry = 1;
|
|
|
|
|
|
|
|
pthread_cond_destroy(&r->cond);
|
|
|
|
pthread_mutex_destroy(&r->mutex);
|
|
|
|
gw_free(r);
|
|
|
|
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
void handle_mm1_mt_requests(MmscGrp *mmsc)
|
|
|
|
{
|
|
|
|
/* stop smsc, start GPRS, transact, stop GPRS, start SMSC. And so on. */
|
|
|
|
MM1Request *r;
|
|
|
|
|
|
|
|
mms_info(0, "MM7", mmsc->id, "handle_mm1 [%s] started", octstr_get_cstr(mmsc->id));
|
|
|
|
mmsc->mm1.sender_alive++;
|
|
|
|
while ((r = gwlist_consume(mmsc->mm1.requests)) != NULL) {
|
|
|
|
long n, pid = -1;
|
|
|
|
if (mmsc->mm1.smsc_off) {
|
|
|
|
n = system(octstr_get_cstr(mmsc->mm1.smsc_off));
|
|
|
|
gwthread_sleep(5); /* allow it to die. */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mmsc->mm1.gprs_on)
|
|
|
|
pid = start_gprs(mmsc->mm1.gprs_on, mmsc->id, mmsc->mm1.gprs_pid);
|
|
|
|
|
|
|
|
if (pid < 0) {
|
|
|
|
mms_warning(0, "MM7", mmsc->id,
|
|
|
|
"Failed to start GPRS connection. waiting...");
|
|
|
|
gwthread_sleep(2);
|
|
|
|
goto kill_gprs;
|
|
|
|
} else
|
|
|
|
mms_info(0, "MM7", mmsc->id, "handle_mm1 [start_gprs] returned PID: %ld", pid);
|
|
|
|
|
|
|
|
do {
|
|
|
|
Octstr *body;
|
|
|
|
Octstr *url;
|
|
|
|
int hstatus = 0;
|
|
|
|
Octstr *ms;
|
|
|
|
MmsMsg *m;
|
|
|
|
int msize;
|
|
|
|
pid_t wp;
|
|
|
|
int st;
|
|
|
|
|
|
|
|
if (r->waiter_exists)
|
|
|
|
pthread_mutex_lock(&r->mutex); /* grab lock to avoid race condition */
|
|
|
|
|
|
|
|
body = (r->type == MM1_PUSH) ? mms_tobinary(r->u.m) : NULL;
|
|
|
|
url = (r->type == MM1_PUSH) ? mmsc->mmsc_url : r->u.url;
|
|
|
|
ms = fetch_content_with_curl(mmsc, url, body, &hstatus);
|
|
|
|
msize = ms ? octstr_len(ms) : 0;
|
|
|
|
m = (hstatus == 0 && ms) ? mms_frombinary(ms, mmsc->mm1.msisdn) : NULL;
|
|
|
|
|
|
|
|
if (r->type == MM1_GET) {
|
|
|
|
if (m == NULL)
|
|
|
|
mms_error(0, "MM7", mmsc->id, "failed to fetch mms from URL: %s!",
|
|
|
|
octstr_get_cstr(url));
|
|
|
|
else {
|
|
|
|
List *mh = mms_message_headers(m), *to = gwlist_create();
|
|
|
|
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL, *value;
|
|
|
|
Octstr *hfrom = mh ? http_header_value(mh, octstr_imm("From")) : octstr_imm("anon@anon");
|
|
|
|
Octstr *qf = NULL, *qdir = NULL, *mmc_id = NULL;
|
|
|
|
time_t expiryt = -1, deliveryt = -1;
|
|
|
|
int dlr;
|
|
|
|
|
|
|
|
/* we assume it is a true message (send_req|retrieve_conf) */
|
|
|
|
mms_collect_envdata_from_msgheaders(mh, &to, &subject,
|
|
|
|
&otransid, &expiryt, &deliveryt,
|
|
|
|
DEFAULT_EXPIRE, -1,
|
|
|
|
octstr_get_cstr(unified_prefix),
|
|
|
|
strip_prefixes);
|
|
|
|
|
|
|
|
msgid = http_header_value(mh, octstr_imm("Message-ID"));
|
|
|
|
value = http_header_value(mh, octstr_imm("X-Mms-Delivery-Report"));
|
|
|
|
if (value &&
|
|
|
|
octstr_case_compare(value, octstr_imm("Yes")) == 0)
|
|
|
|
dlr = 1;
|
|
|
|
else
|
|
|
|
dlr = 0;
|
|
|
|
octstr_destroy(value);
|
|
|
|
|
|
|
|
if (deliveryt < 0)
|
|
|
|
deliveryt = time(NULL);
|
|
|
|
|
|
|
|
if (expiryt < 0)
|
|
|
|
expiryt = time(NULL) + DEFAULT_EXPIRE;
|
|
|
|
|
|
|
|
if (hfrom == NULL)
|
|
|
|
hfrom = http_header_value(mh, octstr_imm("From"));
|
|
|
|
|
|
|
|
mms_remove_headers(m, "Bcc");
|
|
|
|
mms_remove_headers(m, "X-Mms-Delivery-Time");
|
|
|
|
mms_remove_headers(m, "X-Mms-Expiry");
|
|
|
|
mms_remove_headers(m, "X-Mms-Sender-Visibility");
|
|
|
|
|
|
|
|
qdir = get_mmsbox_queue_dir(hfrom, to, mmsc, &mmc_id); /* get routing info. */
|
|
|
|
/* Save it, put message id in header, return. */
|
|
|
|
qf = qfs->mms_queue_add(hfrom, to, subject,
|
|
|
|
mmsc->id, mmc_id,
|
|
|
|
deliveryt, expiryt, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
dlr,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/MM1-IN",
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received", hfrom, to, msize,
|
|
|
|
msgid, NULL, mmsc->id, "MMSBox",octstr_imm("MM1"), NULL);
|
|
|
|
MMSC_CLEAR_ALARM(mmsc, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
mms_error(0, "MM7", mmsc->id, "handle_mm1: failed to create queue entry for URL %s",
|
|
|
|
octstr_get_cstr(url));
|
|
|
|
MMSC_ISSUE_ALARM(mmsc, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (otransid) { /* tell mmsc that we fetched fine. */
|
|
|
|
int _status;
|
|
|
|
MmsMsg *mresp = mms_notifyresp_ind(octstr_get_cstr(otransid),
|
|
|
|
mms_message_enc(m), "Retrieved", 1);
|
|
|
|
Octstr *sm = mms_tobinary(mresp);
|
|
|
|
Octstr *_x = fetch_content_with_curl(mmsc,
|
|
|
|
NULL,
|
|
|
|
sm,
|
|
|
|
&_status);
|
|
|
|
|
|
|
|
octstr_destroy(_x);
|
|
|
|
octstr_destroy(sm);
|
|
|
|
mms_destroy(mresp);
|
|
|
|
}
|
|
|
|
gwlist_destroy(to, (void *)octstr_destroy);
|
|
|
|
octstr_destroy(hfrom);
|
|
|
|
octstr_destroy(subject);
|
|
|
|
octstr_destroy(otransid);
|
|
|
|
octstr_destroy(msgid);
|
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(mmc_id);
|
|
|
|
|
|
|
|
http_destroy_headers(mh);
|
|
|
|
}
|
|
|
|
octstr_destroy(r->u.url); /* For GET only, because caller doesn't wait */
|
|
|
|
} else if (r->type == MM1_PUSH) {
|
|
|
|
Octstr *xs = NULL;
|
|
|
|
/* we expect a send-conf. */
|
|
|
|
if (ms) {
|
|
|
|
octstr_dump(ms, 0);
|
|
|
|
|
|
|
|
mms_msgdump(m, 1);
|
|
|
|
} else
|
|
|
|
mms_warning(0, "MM7", mmsc->id,"handle_mm1: No send-conf returned by operator");
|
|
|
|
|
|
|
|
if (m == NULL ||
|
|
|
|
(r->result = mms_get_header_value(m, octstr_imm("Message-ID"))) == NULL ||
|
|
|
|
octstr_compare((xs = mms_get_header_value(m, octstr_imm("X-Mms-Response-Status"))),
|
|
|
|
octstr_imm("Ok")) != 0) {
|
|
|
|
Octstr *err = m ? mms_get_header_value(m, octstr_imm("X-Mms-Response-Text")) : NULL;
|
|
|
|
Octstr *status = m ? mms_get_header_value(m, octstr_imm("X-Mms-Response-Status")) : NULL;
|
|
|
|
if(status && (octstr_compare(status, octstr_imm("Error-service-denied")) == 0 ||
|
|
|
|
octstr_compare(status, octstr_imm("Error-permanent-failure")) == 0)) {
|
|
|
|
r->err = octstr_duplicate(status);
|
|
|
|
}
|
|
|
|
r->result = NULL; /* indicate failure to bearerbox */
|
|
|
|
mms_error(0, "MM7", mmsc->id, "Sending failed: %s, %s!",
|
|
|
|
err ? octstr_get_cstr(err) : "(none)",
|
|
|
|
status ? octstr_get_cstr(status) : "(none)");
|
|
|
|
octstr_destroy(err);
|
|
|
|
octstr_destroy(status);
|
|
|
|
}
|
|
|
|
octstr_destroy(xs);
|
|
|
|
} else
|
|
|
|
mms_error(0, "MM7", mmsc->id, "unknown type: %d", r->type);
|
|
|
|
|
|
|
|
if (r->waiter_exists) {
|
|
|
|
pthread_mutex_unlock(&r->mutex);
|
|
|
|
pthread_cond_signal(&r->cond);
|
|
|
|
} else /* no waiter, so we free it ourselves. */
|
|
|
|
gw_free(r);
|
|
|
|
|
|
|
|
octstr_destroy(body);
|
|
|
|
octstr_destroy(ms);
|
|
|
|
mms_destroy(m);
|
|
|
|
r = NULL;
|
|
|
|
|
|
|
|
if (pid > 0) {
|
|
|
|
wp = waitpid(pid, &st, WNOHANG);
|
|
|
|
if(wp == pid && WIFEXITED(st)) {
|
|
|
|
mms_info(0, "MM7", mmsc->id, "GPRS pid (%d) appears to be dead - quitting loop", pid);
|
|
|
|
goto after_gprs_dead;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gwthread_sleep(2); /* according to Piotr Isajew, this makes life better */
|
|
|
|
} while (gwlist_len(mmsc->mm1.requests) > 0 &&
|
|
|
|
(r = gwlist_consume(mmsc->mm1.requests)) != NULL);
|
|
|
|
|
|
|
|
kill_gprs:
|
|
|
|
if(r != NULL) {
|
|
|
|
if(r->waiter_exists) {
|
|
|
|
pthread_mutex_unlock(&r->mutex);
|
|
|
|
pthread_cond_signal(&r->cond);
|
|
|
|
} else{
|
|
|
|
gw_free(r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mmsc->mm1.gprs_off) {
|
|
|
|
stop_gprs(mmsc->mm1.gprs_off);
|
|
|
|
} else if (pid > 0) { /* stop GPRS, restart SMSC connection. */
|
|
|
|
int xkill, status;
|
|
|
|
pid_t wpid;
|
|
|
|
do {
|
|
|
|
xkill = kill(pid, SIGTERM);
|
|
|
|
mms_info(0, "MM7", mmsc->id, "GPRS turned off returned: %d", xkill);
|
|
|
|
if (xkill < 0 && errno == ESRCH)
|
|
|
|
break;
|
|
|
|
wpid = waitpid(pid, &status, 0);
|
|
|
|
if (wpid == pid && WIFEXITED(status))
|
|
|
|
break;
|
|
|
|
else if (wpid < 0 && errno == ECHILD)
|
|
|
|
break;
|
|
|
|
} while (1);
|
|
|
|
gwthread_sleep(2);
|
|
|
|
}
|
|
|
|
after_gprs_dead:
|
|
|
|
if (mmsc->mm1.smsc_on) {
|
|
|
|
system(octstr_get_cstr(mmsc->mm1.smsc_on));
|
|
|
|
gwthread_sleep(5);
|
|
|
|
mms_info(0, "MM7", mmsc->id, "SMSC turned on");
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
mmsc->mm1.sender_alive--;
|
|
|
|
mms_info(0, "MM7", mmsc->id, "handle_mm1 exits");
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_LIBCURL
|
|
|
|
#include <curl/curl.h>
|
|
|
|
static int write_octstr_data(void *buffer, size_t size, size_t nmemb, void *userp)
|
|
|
|
{
|
|
|
|
Octstr *out = userp;
|
|
|
|
|
|
|
|
octstr_append_data(out, buffer, size*nmemb);
|
|
|
|
mms_info(0, "mmsbox-mm1", NULL, "write_data called with nmemn=%ld, size=%ld",
|
|
|
|
nmemb, size);
|
|
|
|
return size*nmemb;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static Octstr *fetch_content_with_curl(MmscGrp *mmc, Octstr *url, Octstr *body, int *hstatus)
|
|
|
|
{
|
|
|
|
Octstr *s = octstr_create("");
|
|
|
|
#ifdef HAVE_LIBCURL
|
|
|
|
|
|
|
|
Octstr *proxy = mmc->mm1.proxy;
|
|
|
|
Octstr *ua = mmc->mm1.ua;
|
|
|
|
|
|
|
|
CURL *cl;
|
|
|
|
struct curl_slist *h = NULL;
|
|
|
|
char errbuf[512];
|
|
|
|
static int curl_inited = 0;
|
|
|
|
|
|
|
|
Octstr *xurl = url ? url : mmc->mmsc_url;
|
|
|
|
if (curl_inited == 0) {
|
|
|
|
curl_global_init(CURL_GLOBAL_ALL);
|
|
|
|
curl_inited = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cl = curl_easy_init();
|
|
|
|
curl_easy_setopt(cl, CURLOPT_URL, octstr_get_cstr(xurl));
|
|
|
|
if (octstr_len(proxy) > 0)
|
|
|
|
curl_easy_setopt(cl, CURLOPT_PROXY, octstr_get_cstr(proxy));
|
|
|
|
curl_easy_setopt(cl, CURLOPT_WRITEFUNCTION, write_octstr_data);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_WRITEDATA, s);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_NOSIGNAL, 1L);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_TIMEOUT, 120L);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_FORBID_REUSE, 1L);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_CONNECTTIMEOUT, 40L);
|
|
|
|
|
|
|
|
h = curl_slist_append(h, "Accept: */*");
|
|
|
|
if (body) { /* POST. */
|
|
|
|
h = curl_slist_append(h, "Content-Type: application/vnd.wap.mms-message");
|
|
|
|
curl_easy_setopt(cl, CURLOPT_POSTFIELDS, octstr_get_cstr(body));
|
|
|
|
curl_easy_setopt(cl, CURLOPT_POSTFIELDSIZE, octstr_len(body));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ua) {
|
|
|
|
Octstr *x = octstr_format("User-Agent: %S", ua);
|
|
|
|
h = curl_slist_append(h, octstr_get_cstr(x));
|
|
|
|
octstr_destroy(x);
|
|
|
|
}
|
|
|
|
|
|
|
|
curl_easy_setopt(cl, CURLOPT_HTTPHEADER, h);
|
|
|
|
curl_easy_setopt(cl, CURLOPT_ERRORBUFFER, errbuf);
|
|
|
|
|
|
|
|
*hstatus = curl_easy_perform(cl); /* post away! */
|
|
|
|
if (*hstatus != 0) {
|
|
|
|
MMSC_ISSUE_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT, 3);
|
|
|
|
|
|
|
|
mms_error(0, "mmsbox-mm1", NULL, "failed to fetch/post content to host %s [proxy: %s] [http_status=%d] : %.256s",
|
|
|
|
octstr_get_cstr(url), octstr_len(proxy) > 0 ? octstr_get_cstr(proxy) : "n/a",
|
|
|
|
*hstatus, errbuf);
|
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(mmc, MMSBOX_ALARM_MM7_NON_200_RESULT);
|
|
|
|
curl_slist_free_all(h); /* free the header list */
|
|
|
|
curl_easy_setopt(cl, CURLOPT_NOSIGNAL, 0L); /* Stop blocking signals */
|
|
|
|
curl_easy_cleanup(cl);
|
|
|
|
#else
|
|
|
|
panic(0, "Libcurl not linked in.");
|
|
|
|
#endif
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void stop_gprs(Octstr *cmd)
|
|
|
|
{
|
|
|
|
char *xcmd = octstr_get_cstr(cmd);
|
|
|
|
FILE *f = popen(xcmd, "r");
|
|
|
|
|
|
|
|
if (f)
|
|
|
|
pclose(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define MAX_GPRS_WAIT 80
|
|
|
|
#define GPRS_POLL 5
|
|
|
|
static long start_gprs(Octstr *cmd, Octstr *id, Octstr *pid_cmd)
|
|
|
|
{
|
|
|
|
int ct = 0;
|
|
|
|
char *xcmd = octstr_get_cstr(cmd);
|
|
|
|
char *pcmd = pid_cmd ? octstr_get_cstr(pid_cmd) : NULL;
|
|
|
|
FILE *f = popen(xcmd, "r");
|
|
|
|
|
|
|
|
if (f == NULL) {
|
|
|
|
mms_error(0, "MM7", id, "start_gprs: failed to start process!");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
pclose(f);
|
|
|
|
|
|
|
|
if (pid_cmd != NULL)
|
|
|
|
do { /* Wait for it. */
|
|
|
|
long xpid = -1;
|
|
|
|
|
|
|
|
gwthread_sleep(GPRS_POLL); /* wait a little. */
|
|
|
|
if ((f = popen(pcmd, "r")) != NULL) {
|
|
|
|
fscanf(f, "%ld", &xpid);
|
|
|
|
pclose(f);
|
|
|
|
if (xpid >= 0)
|
|
|
|
return xpid;
|
|
|
|
}
|
|
|
|
mms_info(0, "MM7", id,
|
|
|
|
"start_gprs: waiting for connection: %d",ct);
|
|
|
|
} while (GPRS_POLL*ct++ < MAX_GPRS_WAIT);
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
mms_error(0, "MM7", id, "start_gprs: failed to get PID!");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int mm7mm1_receive(MmsBoxHTTPClientInfo *hci)
|
|
|
|
{
|
|
|
|
HTTPClient *client = hci->client;
|
|
|
|
List *cgivar_ctypes = NULL;
|
|
|
|
Octstr *text, *rb = NULL, *s = NULL, *loc = NULL;
|
|
|
|
MmsMsg *m = NULL;
|
|
|
|
int hdrlen, status = HTTP_ACCEPTED, mtype;
|
|
|
|
List *mh = NULL, *to = gwlist_create(), *rh = http_create_empty_headers();
|
|
|
|
time_t expiryt = -1, deliveryt = -1;
|
|
|
|
Octstr *from = NULL, *subject = NULL, *otransid = NULL, *mmc_id = NULL;
|
|
|
|
Octstr *qdir;
|
|
|
|
|
|
|
|
parse_cgivars(hci->headers, hci->body, &hci->cgivars, &cgivar_ctypes);
|
|
|
|
|
|
|
|
if ((text = http_cgi_variable(hci->cgivars, "text")) == NULL) {
|
|
|
|
rb = octstr_imm("mmsbox-mm1: missing 'text' CGI parameter!");
|
|
|
|
status = HTTP_NOT_FOUND;
|
|
|
|
MMSC_ISSUE_ALARM(hci->m, MMSBOX_ALARM_MM7_PARSING_FAILURE,2);
|
|
|
|
goto done;
|
|
|
|
} else
|
|
|
|
MMSC_CLEAR_ALARM(hci->m, MMSBOX_ALARM_MM7_PARSING_FAILURE);
|
|
|
|
|
|
|
|
hdrlen = octstr_get_char(text, 2);
|
|
|
|
if ((s = octstr_copy(text, 3 + hdrlen, octstr_len(text))) != NULL)
|
|
|
|
m = mms_frombinary(s, hci->m->mm1.msisdn);
|
|
|
|
else
|
|
|
|
m = NULL;
|
|
|
|
|
|
|
|
if (m == NULL) {
|
|
|
|
rb = octstr_imm("mmsbox-mm1: mal-formed mms packet on interface!");
|
|
|
|
status = HTTP_FORBIDDEN;
|
|
|
|
goto done;
|
|
|
|
} else
|
|
|
|
mms_msgdump(m, 1);
|
|
|
|
|
|
|
|
/* rest of this copied largely from EAIF code. */
|
|
|
|
mh = mms_message_headers(m);
|
|
|
|
mtype = mms_messagetype(m);
|
|
|
|
mms_collect_envdata_from_msgheaders(mh, &to, &subject,
|
|
|
|
&otransid, &expiryt, &deliveryt,
|
|
|
|
DEFAULT_EXPIRE, -1,
|
|
|
|
octstr_get_cstr(unified_prefix),
|
|
|
|
strip_prefixes);
|
|
|
|
from = http_header_value(mh, octstr_imm("From"));
|
|
|
|
qdir = get_mmsbox_queue_dir(from, to, hci->m, &mmc_id); /* get routing info. */
|
|
|
|
switch (mtype) {
|
|
|
|
Octstr *qf;
|
|
|
|
Octstr *dlr_url, *status_value, *msgid;
|
|
|
|
List *rqh;
|
|
|
|
case MMS_MSGTYPE_DELIVERY_IND: /* notification of a delivery. */
|
|
|
|
case MMS_MSGTYPE_READ_ORIG_IND: /* message read. */
|
|
|
|
msgid = http_header_value(mh, octstr_imm("Message-ID"));
|
|
|
|
status_value = http_header_value(mh,
|
|
|
|
(mtype == MMS_MSGTYPE_DELIVERY_IND) ?
|
|
|
|
octstr_imm("X-Mms-Status") :
|
|
|
|
octstr_imm("X-Mms-Read-Status"));
|
|
|
|
|
|
|
|
rqh = http_create_empty_headers();
|
|
|
|
|
|
|
|
dlr_url = mmsbox_get_report_info(m, hci->m, mmc_id,
|
|
|
|
(mtype == MMS_MSGTYPE_DELIVERY_IND) ?
|
|
|
|
"delivery-report" : "read-report",
|
|
|
|
status_value, rqh, NULL, 0, msgid);
|
|
|
|
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
hci->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
dlr_url, NULL,
|
|
|
|
rqh,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
"MM7/MM1-IN",
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log((mtype == MMS_MSGTYPE_DELIVERY_IND) ? "Received DLR" : "Received RR",
|
|
|
|
from, to, -1, msgid, status_value, hci->m->id,
|
|
|
|
"MMSBox", octstr_imm("MM1"), NULL);
|
|
|
|
MMSC_CLEAR_ALARM(hci->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR);
|
|
|
|
} else {
|
|
|
|
MMSC_ISSUE_ALARM(hci->m, MMSBOX_ALARM_QUEUE_WRITE_ERROR, 4);
|
|
|
|
status = HTTP_INTERNAL_SERVER_ERROR;
|
|
|
|
}
|
|
|
|
octstr_destroy(qf);
|
|
|
|
octstr_destroy(msgid);
|
|
|
|
octstr_destroy(dlr_url);
|
|
|
|
octstr_destroy(status_value);
|
|
|
|
http_destroy_headers(rqh);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MMS_MSGTYPE_NOTIFICATION_IND: /* notification of an incoming message. */
|
|
|
|
if ((loc = http_header_value(mh, octstr_imm("X-Mms-Content-Location"))) != NULL) {
|
|
|
|
MM1Request *r = gw_malloc(sizeof *r);
|
|
|
|
|
|
|
|
memset(r, 0, sizeof *r);
|
|
|
|
r->type = MM1_GET;
|
|
|
|
r->u.url = loc;
|
|
|
|
r->waiter_exists = 0;
|
|
|
|
loc = NULL;
|
|
|
|
gw_assert(hci->m->mm1.requests);
|
|
|
|
gwlist_produce(hci->m->mm1.requests, r);
|
|
|
|
} else
|
|
|
|
rb = octstr_format("mmsbox-mm1: notification with content-location??");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rb = octstr_format("mmsbox-mm1: unexpected message type: %s",
|
|
|
|
mms_message_type_to_cstr(mtype));
|
|
|
|
status = HTTP_NOT_FOUND;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
done:
|
|
|
|
/* send reply. */
|
|
|
|
http_header_add(rh, "Content-Type", "text/plain");
|
|
|
|
http_send_reply(client, status, rh, rb ? rb : octstr_imm(""));
|
|
|
|
|
|
|
|
octstr_destroy(s);
|
|
|
|
octstr_destroy(loc);
|
|
|
|
octstr_destroy(mmc_id);
|
|
|
|
octstr_destroy(from);
|
|
|
|
octstr_destroy(subject);
|
|
|
|
octstr_destroy(otransid);
|
|
|
|
|
|
|
|
octstr_destroy(rb);
|
|
|
|
gwlist_destroy(to, (void *)octstr_destroy);
|
|
|
|
|
|
|
|
http_destroy_headers(rh);
|
|
|
|
http_destroy_headers(mh);
|
|
|
|
http_destroy_cgiargs(cgivar_ctypes);
|
|
|
|
mms_destroy(m);
|
|
|
|
|
|
|
|
return http_status_class(status) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
|
|
|
|
}
|