2005-09-07 10:10:41 +00:00
|
|
|
/*
|
|
|
|
* Mbuni - Open Source MMS Gateway
|
|
|
|
*
|
|
|
|
* MMSC handler functions: Receive and send MMS messages to MMSCs
|
|
|
|
*
|
2007-09-19 13:06:26 +00:00
|
|
|
* Copyright (C) 2003 - 2007, 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"
|
|
|
|
|
2007-11-07 07:53:29 +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)
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
typedef struct MmsHTTPClientInfo {
|
|
|
|
HTTPClient *client;
|
|
|
|
Octstr *ua;
|
|
|
|
Octstr *ip;
|
|
|
|
List *headers;
|
|
|
|
Octstr *url;
|
|
|
|
Octstr *body;
|
|
|
|
List *cgivars;
|
|
|
|
MmscGrp *m;
|
|
|
|
} MmsHTTPClientInfo;
|
|
|
|
|
|
|
|
static void free_clientInfo(MmsHTTPClientInfo *h, int freeh);
|
|
|
|
|
|
|
|
static int auth_check(Octstr *user, Octstr *pass, List *headers)
|
|
|
|
{
|
|
|
|
int i, res = -1;
|
|
|
|
Octstr *v = http_header_value(headers, octstr_imm("Authorization"));
|
|
|
|
Octstr *p = NULL, *q = NULL;
|
2006-05-23 12:38:24 +00:00
|
|
|
|
|
|
|
if (user == NULL ||
|
|
|
|
octstr_len(user) == 0) {
|
|
|
|
res = 0;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if (!v ||
|
|
|
|
octstr_search(v, octstr_imm("Basic "), 0) != 0)
|
|
|
|
goto done;
|
|
|
|
p = octstr_copy(v, sizeof "Basic", octstr_len(v));
|
|
|
|
octstr_base64_to_binary(p);
|
|
|
|
|
|
|
|
i = octstr_search_char(p, ':', 0);
|
|
|
|
q = octstr_copy(p, i+1, octstr_len(p));
|
|
|
|
octstr_delete(p, i, octstr_len(p));
|
|
|
|
|
|
|
|
/* p = user, q = pass. */
|
|
|
|
|
|
|
|
if (octstr_compare(user, p) != 0 ||
|
|
|
|
octstr_compare(pass, q) != 0)
|
|
|
|
res = -1;
|
|
|
|
else
|
|
|
|
res = 0;
|
|
|
|
done:
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(v);
|
|
|
|
octstr_destroy(p);
|
|
|
|
octstr_destroy(q);
|
2005-09-07 10:10:41 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2007-09-19 13:06:26 +00:00
|
|
|
int mmsbox_send_report(Octstr *from, char *report_type,
|
2007-07-27 16:39:19 +00:00
|
|
|
Octstr *dlr_url, Octstr *status,
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *msgid, Octstr *mmc_id, Octstr *mmc_gid,
|
|
|
|
Octstr *orig_transid, Octstr *uaprof,
|
|
|
|
time_t uaprof_tstamp)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *url = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
List *rh, *rph = NULL;
|
2007-04-10 17:45:44 +00:00
|
|
|
Octstr *rb = NULL;
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *xtransid = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
if (dlr_url)
|
|
|
|
url = octstr_duplicate(dlr_url);
|
|
|
|
else
|
|
|
|
mms_dlr_url_get(msgid, report_type, mmc_gid, &url, &xtransid);
|
|
|
|
|
|
|
|
if (!url || octstr_len(url) == 0) {
|
|
|
|
info(0, "Sending delivery-report skipped: `url' is empty, `group_id'=[%s], `msgid'=[%s]",
|
2007-05-05 07:46:03 +00:00
|
|
|
octstr_get_cstr(mmc_gid), octstr_get_cstr(msgid));
|
2005-09-07 10:10:41 +00:00
|
|
|
return 0;
|
2007-04-02 05:29:00 +00:00
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
rh = http_create_empty_headers();
|
|
|
|
|
|
|
|
http_header_add(rh, "X-Mbuni-Report-Type", report_type);
|
|
|
|
http_header_add(rh, "X-Mbuni-MM-Status", octstr_get_cstr(status));
|
|
|
|
http_header_add(rh, "X-Mbuni-MMSC-ID", octstr_get_cstr(mmc_id));
|
2007-05-05 07:46:03 +00:00
|
|
|
http_header_add(rh, "X-Mbuni-MMSC-GID", octstr_get_cstr(mmc_gid));
|
2005-09-07 10:10:41 +00:00
|
|
|
http_header_add(rh, "X-Mbuni-From", octstr_get_cstr(from));
|
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
if (xtransid || orig_transid)
|
|
|
|
http_header_add(rh, "X-Mbuni-TransactionID",
|
|
|
|
octstr_get_cstr(xtransid ? xtransid : orig_transid));
|
|
|
|
if (msgid)
|
|
|
|
http_header_add(rh, "X-Mbuni-Message-ID", octstr_get_cstr(msgid));
|
|
|
|
if (uaprof) {
|
|
|
|
Octstr *sx = date_format_http(uaprof_tstamp);
|
|
|
|
http_header_add(rh, "X-Mbuni-UAProf", octstr_get_cstr(uaprof));
|
|
|
|
http_header_add(rh, "X-Mbuni-Timestamp", octstr_get_cstr(sx));
|
|
|
|
octstr_destroy(sx);
|
|
|
|
}
|
2007-04-10 17:45:44 +00:00
|
|
|
mms_url_fetch_content(HTTP_METHOD_GET, url, rh, octstr_imm(""), &rph, &rb);
|
2007-08-06 11:57:15 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(rb);
|
2005-09-07 10:10:41 +00:00
|
|
|
octstr_destroy(url);
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(xtransid);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(rph);
|
2005-09-07 10:10:41 +00:00
|
|
|
http_destroy_headers(rh);
|
|
|
|
|
|
|
|
/* At what point do we delete it? For now, when we get a read report,
|
2007-05-05 07:46:03 +00:00
|
|
|
* and also when we get a delivery report that is not 'deferred' or sent
|
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 &&
|
|
|
|
octstr_case_compare(status, octstr_imm("Sent")) != 0))
|
2007-04-02 05:29:00 +00:00
|
|
|
mms_dlr_url_remove(msgid, report_type, mmc_gid);
|
2005-09-07 10:10:41 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* These functions are very similar to those in mmsproxy */
|
|
|
|
static void mm7soap_receive(MmsHTTPClientInfo *h)
|
|
|
|
{
|
|
|
|
|
|
|
|
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
|
|
|
int hstatus = HTTP_OK;
|
|
|
|
List *rh = NULL;
|
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;
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
if (h->body)
|
|
|
|
mreq = mm7_parse_soap(h->headers, h->body);
|
|
|
|
if (mreq)
|
|
|
|
msgtype = mms_mm7tag_to_cstr(mm7_msgtype(mreq));
|
|
|
|
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);
|
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)
|
|
|
|
from = octstr_imm("anon@anon");
|
|
|
|
|
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)) {
|
|
|
|
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;
|
2007-09-17 13:07:30 +00:00
|
|
|
Octstr *value = mms_get_header_value(m, octstr_imm("X-Mms-Delivery-Report"));
|
|
|
|
|
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);
|
|
|
|
}
|
2007-09-17 13:07:30 +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),
|
2007-08-27 10:16:26 +00:00
|
|
|
octstr_imm(MM_NAME));
|
2005-09-07 10:10:41 +00:00
|
|
|
msgid = mms_maketransid(octstr_get_cstr(qf), octstr_imm(MM_NAME));
|
|
|
|
mms_log("Received", from, to, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(linkedid);
|
2005-09-07 10:10:41 +00:00
|
|
|
octstr_destroy(value);
|
2007-08-06 11:57:15 +00:00
|
|
|
http_destroy_headers(qh);
|
2007-04-12 08:40:24 +00:00
|
|
|
} else {
|
2007-08-06 11:57:15 +00:00
|
|
|
error(0,
|
|
|
|
"Failed to convert received MM7/SOAP DeliverReq message from mmc=%s to MMS Message!",
|
2007-04-12 08:40:24 +00:00
|
|
|
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:
|
2007-09-17 13:07:30 +00:00
|
|
|
if (mmc_id != NULL) { /* internal routing. */
|
|
|
|
m = mm7_soap_to_mmsmsg(mreq, from);
|
|
|
|
if (m)
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
else
|
|
|
|
qf = NULL;
|
|
|
|
if (qf)
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received DLR", from, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
else
|
|
|
|
status = 4000;
|
|
|
|
} else {
|
|
|
|
Octstr *desc = mm7_soap_header_value(mreq, octstr_imm("StatusText"));
|
|
|
|
Octstr *value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-09-17 13:07:30 +00:00
|
|
|
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
|
|
|
|
|
|
|
info(0, "Sending delivery-report [FROM:%s] [VALUE:%s] [DESC:%s] [MSGID:%s]",
|
|
|
|
octstr_get_cstr(from), octstr_get_cstr(value), octstr_get_cstr(desc),
|
|
|
|
octstr_get_cstr(h->m->id));
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(from, "delivery-report", NULL,
|
2007-09-17 13:07:30 +00:00
|
|
|
value, msgid, h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
|
|
|
|
|
|
|
|
mms_log("DeliveryReport",
|
|
|
|
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
octstr_destroy(desc);
|
|
|
|
octstr_destroy(value);
|
|
|
|
|
|
|
|
}
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, status, NULL,1);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MM7_TAG_ReadReplyReq:
|
2007-09-17 13:07:30 +00:00
|
|
|
if (mmc_id != NULL) { /* internal routing. */
|
|
|
|
m = mm7_soap_to_mmsmsg(mreq, from);
|
|
|
|
if (m)
|
|
|
|
qf = qfs->mms_queue_add(from, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
else
|
|
|
|
qf = NULL;
|
|
|
|
if (qf)
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received RR", from, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
else
|
|
|
|
status = 4000;
|
|
|
|
} else {
|
|
|
|
Octstr *value = mm7_soap_header_value(mreq, octstr_imm("MMStatus"));
|
|
|
|
msgid = mm7_soap_header_value(mreq, octstr_imm("MessageID"));
|
|
|
|
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(from,
|
2007-09-17 13:07:30 +00:00
|
|
|
"read-report", NULL, value, msgid,
|
|
|
|
h->m->id, h->m->group_id, NULL, uaprof, uaprof_tstamp);
|
|
|
|
|
|
|
|
octstr_destroy(value);
|
|
|
|
mms_log("ReadReport",
|
|
|
|
from, NULL, -1, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
}
|
2006-11-28 12:00:20 +00:00
|
|
|
mresp = mm7_make_resp(mreq, status, NULL,1);
|
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);
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void mm7eaif_receive(MmsHTTPClientInfo *h)
|
|
|
|
{
|
|
|
|
MmsMsg *m = NULL;
|
|
|
|
List *mh = NULL;
|
|
|
|
int hstatus = HTTP_NO_CONTENT;
|
|
|
|
List *rh = http_create_empty_headers();
|
2007-09-17 13:07:30 +00:00
|
|
|
Octstr *reply_body = NULL, *value;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
List *to = gwlist_create(), *hto = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
Octstr *subject = NULL, *otransid = NULL, *msgid = NULL;
|
|
|
|
Octstr *hfrom = NULL;
|
|
|
|
time_t expiryt = -1, deliveryt = -1;
|
2007-09-17 13:07:30 +00:00
|
|
|
Octstr *qf = NULL, *xver, *mmc_id = NULL, *qdir = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
int msize = h->body ? octstr_len(h->body) : 0;
|
|
|
|
int dlr;
|
|
|
|
int mtype;
|
|
|
|
|
|
|
|
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?");
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXXX handle delivery reports differently. */
|
|
|
|
mtype = mms_messagetype(m);
|
|
|
|
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,
|
|
|
|
DEFAULT_EXPIRE);
|
|
|
|
|
|
|
|
|
|
|
|
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL &&
|
2006-10-12 15:21:46 +00:00
|
|
|
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;
|
|
|
|
int j, m;
|
|
|
|
|
|
|
|
http_header_get(hto,i, &h, &v);
|
|
|
|
l = http_header_split_value(v);
|
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
for (j = 0, m = gwlist_len(l); j < m; j++)
|
|
|
|
gwlist_append(to, gwlist_get(l, j));
|
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;
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(value);
|
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),
|
2007-08-27 10:16:26 +00:00
|
|
|
octstr_imm(MM_NAME));
|
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);
|
|
|
|
|
|
|
|
hstatus = HTTP_NO_CONTENT;
|
|
|
|
} else
|
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
|
|
|
break;
|
|
|
|
case MMS_MSGTYPE_DELIVERY_IND:
|
2007-09-17 13:07:30 +00:00
|
|
|
if (mmc_id != NULL) { /* internal routing. */
|
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received DLR", hfrom, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
|
|
|
|
hstatus = HTTP_NO_CONTENT;
|
|
|
|
} else
|
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
|
|
|
} else {
|
|
|
|
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Status"));
|
|
|
|
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(hfrom, "delivery-report", NULL, value, value2, h->m->id, h->m->group_id, NULL, NULL, -1);
|
2007-09-17 13:07:30 +00:00
|
|
|
|
|
|
|
octstr_destroy(value);
|
|
|
|
octstr_destroy(value2);
|
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case MMS_MSGTYPE_READ_ORIG_IND:
|
2007-07-27 16:39:19 +00:00
|
|
|
|
2007-09-17 13:07:30 +00:00
|
|
|
if (mmc_id != NULL) { /* internal routing. */
|
|
|
|
qf = qfs->mms_queue_add(hfrom, to, NULL,
|
|
|
|
h->m->id, mmc_id,
|
|
|
|
0, time(NULL) + default_msgexpiry, m, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
octstr_get_cstr(qdir),
|
|
|
|
octstr_imm(MM_NAME));
|
|
|
|
if (qf) {
|
|
|
|
/* Log to access log */
|
|
|
|
mms_log("Received RR", hfrom, to, -1, NULL, NULL, h->m->id, "MMSBox", h->ua, NULL);
|
|
|
|
hstatus = HTTP_NO_CONTENT;
|
|
|
|
} else
|
|
|
|
hstatus = HTTP_INTERNAL_SERVER_ERROR;
|
|
|
|
} else {
|
|
|
|
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Read-Status"));
|
|
|
|
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(hfrom, "read-report", NULL, value, value2, h->m->id,
|
2007-09-17 13:07:30 +00:00
|
|
|
h->m->group_id, NULL, NULL, -1);
|
|
|
|
|
|
|
|
|
|
|
|
octstr_destroy(value);
|
|
|
|
octstr_destroy(value2);
|
|
|
|
}
|
2005-09-07 10:10:41 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
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));
|
|
|
|
octstr_destroy(xver);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
http_send_reply(h->client, hstatus, rh, octstr_imm(""));
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(hto);
|
|
|
|
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);
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
http_destroy_headers(mh);
|
|
|
|
mms_destroy(m);
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void mmsc_receive_func(MmscGrp *m)
|
|
|
|
{
|
|
|
|
|
|
|
|
MmsHTTPClientInfo h = {NULL};
|
2007-01-30 17:06:29 +00:00
|
|
|
Octstr *err = NULL;
|
|
|
|
|
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)) {
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
|
|
|
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);
|
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
|
|
|
|
if (auth_check(m->incoming.user,
|
|
|
|
m->incoming.pass,
|
|
|
|
h.headers) != 0) { /* Ask it to authenticate... */
|
|
|
|
List *hh = http_create_empty_headers();
|
|
|
|
http_header_add(hh, "WWW-Authenticate",
|
|
|
|
"Basic realm=\"" MM_NAME "\"");
|
|
|
|
http_send_reply(h.client, HTTP_UNAUTHORIZED, hh,
|
2007-01-30 17:06:29 +00:00
|
|
|
octstr_imm("Authentication failed"));
|
2005-09-07 10:10:41 +00:00
|
|
|
http_destroy_headers(hh);
|
2007-03-27 10:23:47 +00:00
|
|
|
info(0, "MMSBox: Auth failed, incoming connection, MMC group=[%s]",
|
2006-04-18 04:25:55 +00:00
|
|
|
m->id ? octstr_get_cstr(m->id) : "(none)");
|
2005-09-07 10:10:41 +00:00
|
|
|
} else if (m->type == SOAP_MMSC)
|
|
|
|
mm7soap_receive(&h);
|
|
|
|
else
|
|
|
|
mm7eaif_receive(&h);
|
|
|
|
free_clientInfo(&h, 0);
|
2007-01-30 17:06:29 +00:00
|
|
|
} else {
|
|
|
|
h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
|
|
|
|
err = octstr_format("HTTP: Incoming IP denied MMSC[%s] ip=[%s], ua=[%s], disconnected",
|
|
|
|
m->id ? octstr_get_cstr(m->id) : "(none)",
|
|
|
|
h.ip ? octstr_get_cstr(h.ip) : "(none)",
|
|
|
|
h.ua ? octstr_get_cstr(h.ua) : "(none)");
|
|
|
|
if (err) {
|
|
|
|
error(0, "%s", octstr_get_cstr(err));
|
|
|
|
octstr_destroy(err);
|
|
|
|
}
|
|
|
|
http_send_reply(h.client, HTTP_FORBIDDEN, NULL,
|
|
|
|
octstr_imm("Access denied."));
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
free_clientInfo(&h, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
debug("proxy", 0, "MMSBox: MM7 Shutting down...");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_clientInfo(MmsHTTPClientInfo *h, int freeh)
|
|
|
|
{
|
|
|
|
|
|
|
|
debug("free info", 0,
|
2007-03-27 10:23:47 +00:00
|
|
|
" entered free_clientinfo %d, ip=[%ld]", freeh, (long)h->ip);
|
2006-04-18 04:25:55 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
octstr_destroy(h->ip);
|
|
|
|
octstr_destroy(h->url);
|
|
|
|
octstr_destroy(h->ua);
|
|
|
|
octstr_destroy(h->body);
|
|
|
|
http_destroy_cgiargs(h->cgivars);
|
|
|
|
http_destroy_headers(h->headers);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
if (freeh) gw_free(h);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
debug("free info", 0, " left free_clientinfo");
|
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.
|
|
|
|
*/
|
2005-09-09 13:11:38 +00:00
|
|
|
static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|
|
|
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,
|
2006-05-03 13:52:40 +00:00
|
|
|
List *hdrs,
|
2007-07-27 16:39:19 +00:00
|
|
|
MmsMsg *m, Octstr **error,
|
|
|
|
int *retry)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
|
|
|
Octstr *ret = NULL;
|
|
|
|
int mtype = mms_messagetype(m);
|
2007-07-27 16:39:19 +00:00
|
|
|
int hstatus = HTTP_OK, tstatus = -1;
|
2006-10-12 15:21:46 +00:00
|
|
|
List *xto = gwlist_create();
|
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;
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *s, *distrib = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
info(0, "MMSBox: Send[soap] to MMSC[%s], msg type [%s], from %s, to %s",
|
|
|
|
mmc->id ? octstr_get_cstr(mmc->id) : "",
|
|
|
|
mms_message_type_to_cstr(mtype),
|
|
|
|
octstr_get_cstr(from), octstr_get_cstr(to));
|
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
gwlist_append(xto, to);
|
2007-08-06 11:57:15 +00:00
|
|
|
|
|
|
|
if (hdrs)
|
|
|
|
distrib = http_header_value(hdrs, octstr_imm("X-Mbuni-DistributionIndicator"));
|
2005-09-09 13:11:38 +00:00
|
|
|
if ((mreq = mm7_mmsmsg_to_soap(m, from, xto, transid,
|
2006-08-11 10:05:46 +00:00
|
|
|
service_code,
|
2005-09-09 13:11:38 +00:00
|
|
|
linkedid,
|
2007-08-06 11:57:15 +00:00
|
|
|
1, octstr_get_cstr(mmc->id), vasid, NULL, 0,/* UA N/A on this side. */
|
|
|
|
distrib)) == 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);
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2005-09-07 10:10:41 +00:00
|
|
|
goto done1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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);
|
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);
|
|
|
|
} else
|
2005-09-07 10:10:41 +00:00
|
|
|
tstatus = MM7_SOAP_FORMAT_CORRUPT;
|
|
|
|
|
2007-03-21 15:41:31 +00:00
|
|
|
if (!MM7_SOAP_STATUS_OK(tstatus) && tstatus != MM7_SOAP_COMMAND_REJECTED) {
|
2005-09-07 10:10:41 +00:00
|
|
|
Octstr *detail = mm7_soap_header_value(mresp, octstr_imm("Details"));
|
2007-06-25 10:33:47 +00:00
|
|
|
char *tmp = (char *)mms_soap_status_to_cstr(tstatus);
|
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;
|
2007-03-27 10:23:47 +00:00
|
|
|
info(0, "Send to MMSC[%s], failed, code=[%d=>%s], detail=[%s]",
|
2005-09-07 10:10:41 +00:00
|
|
|
mmc ? octstr_get_cstr(mmc->id) : "",
|
2007-06-25 12:48:14 +00:00
|
|
|
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,
|
2007-06-26 13:15:20 +00:00
|
|
|
tmp ? tmp : "");
|
2007-06-22 10:49:38 +00:00
|
|
|
octstr_destroy(detail);
|
|
|
|
} else {
|
|
|
|
ret = mm7_soap_header_value(mresp, octstr_imm("MessageID"));
|
|
|
|
info(0, "Sent to MMC[%s], code=[%d=>%s], msgid=[%s]", octstr_get_cstr(mmc->id),
|
|
|
|
tstatus, mms_soap_status_to_cstr(tstatus), ret ? octstr_get_cstr(ret) : "(none)");
|
|
|
|
}
|
|
|
|
|
2007-07-27 16:39:19 +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);
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(distrib);
|
2006-10-12 15:21:46 +00:00
|
|
|
gwlist_destroy(xto, NULL);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
2006-03-21 10:46:27 +00:00
|
|
|
Octstr *transid,
|
|
|
|
char *vasid,
|
2006-05-03 13:52:40 +00:00
|
|
|
List *hdrs,
|
2007-07-27 16:39:19 +00:00
|
|
|
MmsMsg *m, Octstr **error,
|
|
|
|
int *retry)
|
2005-09-07 10:10:41 +00:00
|
|
|
{
|
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;
|
2007-04-10 09:56:46 +00:00
|
|
|
Octstr *body = NULL, *rbody = NULL, *url = NULL, *xver;
|
2005-09-07 10:10:41 +00:00
|
|
|
char *msgtype;
|
|
|
|
|
|
|
|
|
|
|
|
info(0, "MMSBox: Send [eaif] to MMC[%s], msg type [%s], from %s, to %s",
|
|
|
|
mmc ? 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");
|
2005-09-07 10:10:41 +00:00
|
|
|
http_header_add(rh, "X-NOKIA-MMSC-To", octstr_get_cstr(to));
|
|
|
|
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));
|
|
|
|
octstr_destroy(xver);
|
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));
|
|
|
|
mms_replace_header_value(m, "To", octstr_get_cstr(to));
|
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);
|
|
|
|
|
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);
|
2005-09-14 07:01:09 +00:00
|
|
|
} else {
|
|
|
|
MmsMsg *mresp = rbody ? mms_frombinary(rbody, octstr_imm("anon@anon")) : NULL;
|
|
|
|
|
|
|
|
resp = octstr_imm("Ok");
|
|
|
|
if (mresp && mms_messagetype(mresp) == MMS_MSGTYPE_SEND_CONF)
|
|
|
|
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"));
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
mms_destroy(mresp);
|
2005-09-14 07:01:09 +00:00
|
|
|
}
|
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));
|
2005-09-07 10:10:41 +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);
|
2005-09-14 07:01:09 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
#if 0
|
2007-07-17 08:26:38 +00:00
|
|
|
info(0, "Sent to MMC[%s], code=[%d], resp=[%s] msgid [%s]",
|
|
|
|
octstr_get_cstr(mmc->id),
|
2005-09-14 07:01:09 +00:00
|
|
|
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
|
|
|
|
|
|
|
http_destroy_headers(rh);
|
|
|
|
octstr_destroy(body);
|
|
|
|
http_destroy_headers(ph);
|
|
|
|
octstr_destroy(rbody);
|
|
|
|
octstr_destroy(url);
|
|
|
|
octstr_destroy(resp);
|
2005-09-07 10:10:41 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-09-09 13:11:38 +00:00
|
|
|
static int mms_sendtommsc(MmscGrp *mmc, Octstr *from, Octstr *to, Octstr *transid,
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *orig_transid,
|
2007-07-27 16:39:19 +00:00
|
|
|
Octstr *linkedid, char *vasid, Octstr *service_code,
|
|
|
|
MmsMsg *m, Octstr *dlr_url, Octstr *rr_url,
|
2007-08-06 11:57:15 +00:00
|
|
|
List *hdrs,
|
|
|
|
Octstr **new_msgid,
|
|
|
|
Octstr **err)
|
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;
|
2007-05-02 07:30:16 +00:00
|
|
|
unsigned long throughput = 0;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
mutex_lock(mmc->mutex); { /* Grab a lock on it. */
|
|
|
|
if (mmc->type == SOAP_MMSC)
|
2007-07-27 16:39:19 +00:00
|
|
|
id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, hdrs, m, err, &retry);
|
2005-09-07 10:10:41 +00:00
|
|
|
else if (mmc->type == EAIF_MMSC)
|
2007-07-27 16:39:19 +00:00
|
|
|
id = mm7eaif_send(mmc, from, to, transid, vasid, hdrs, m, err, &retry);
|
2007-09-19 13:06:26 +00:00
|
|
|
else if (mmc->type == CUSTOM_MMSC && mmc->custom_started)
|
|
|
|
id = mmc->fns->send_msg(mmc->data,
|
|
|
|
from, to, transid, linkedid, vasid,
|
|
|
|
service_code, m, hdrs, err, &retry);
|
2005-09-07 10:10:41 +00:00
|
|
|
else
|
|
|
|
error(0, "MMC[%s] of unknown type, can't send!",
|
|
|
|
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
|
|
|
|
|
|
|
} 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;
|
2005-09-07 10:10:41 +00:00
|
|
|
} else
|
2007-07-27 16:39:19 +00:00
|
|
|
ret = retry ? MMS_SEND_ERROR_TRANSIENT : MMS_SEND_ERROR_FATAL;
|
2007-05-02 07:30:16 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
*new_msgid = id;
|
|
|
|
|
2007-05-02 07:30:16 +00:00
|
|
|
octstr_destroy(groupid);
|
|
|
|
if (id && throughput > 0)
|
|
|
|
gwthread_sleep(1.0/throughput);
|
|
|
|
return ret;
|
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;
|
2007-08-20 11:49:30 +00:00
|
|
|
msg = qfs->mms_queue_getdata(e);
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2006-10-12 15:21:46 +00:00
|
|
|
for (i = 0, n = gwlist_len(e->to); i<n; i++) {
|
2005-09-07 10:10:41 +00:00
|
|
|
int res = MMS_SEND_OK;
|
2006-10-12 15:21:46 +00:00
|
|
|
MmsEnvelopeTo *to = gwlist_get(e->to, i);
|
2005-09-07 10:10:41 +00:00
|
|
|
Octstr *err = NULL;
|
|
|
|
time_t tnow = time(NULL);
|
|
|
|
MmscGrp *mmc = NULL;
|
2007-08-06 11:57:15 +00:00
|
|
|
Octstr *new_msgid = NULL;
|
2005-09-07 10:10:41 +00:00
|
|
|
|
|
|
|
if (!to || !to->process)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
} else if (e->attempts >= mmsbox_maxsendattempts) {
|
|
|
|
err = octstr_format("MMSBox error: Failed to deliver to "
|
|
|
|
"%S after %ld attempts. (max attempts allowed is %ld)!",
|
|
|
|
to->rcpt, e->attempts,
|
|
|
|
mmsbox_maxsendattempts);
|
|
|
|
res = MMS_SEND_ERROR_FATAL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((mmc = get_handler_mmc(e->viaproxy, to->rcpt)) == NULL) {
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = mms_sendtommsc(mmc, e->from, to->rcpt,
|
|
|
|
e->msgId,
|
2007-08-06 11:57:15 +00:00
|
|
|
otransid,
|
2005-09-09 13:11:38 +00:00
|
|
|
e->token, /* token = linkedid */
|
2005-09-07 10:10:41 +00:00
|
|
|
e->vasid ? octstr_get_cstr(e->vasid) : NULL,
|
2006-08-11 10:05:46 +00:00
|
|
|
e->vaspid,
|
2005-09-07 10:10:41 +00:00
|
|
|
msg,
|
|
|
|
e->url1, e->url2,
|
2006-05-03 13:52:40 +00:00
|
|
|
e->hdrs,
|
2007-08-06 11:57:15 +00:00
|
|
|
&new_msgid,
|
2005-09-07 10:10:41 +00:00
|
|
|
&err);
|
|
|
|
|
|
|
|
done:
|
2007-08-06 11:57:15 +00:00
|
|
|
if (res == MMS_SEND_OK) {
|
2005-09-07 10:10:41 +00:00
|
|
|
to->process = 0;
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(to->rcpt, "delivery-report", e->url1,
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_imm("Sent"), new_msgid, mmc->id, mmc->group_id, otransid, NULL, -1);
|
|
|
|
|
|
|
|
} else if (res == MMS_SEND_ERROR_FATAL && mmc)
|
2007-09-19 13:06:26 +00:00
|
|
|
mmsbox_send_report(to->rcpt, "delivery-report",
|
2007-07-27 16:39:19 +00:00
|
|
|
e->url1,
|
2005-09-07 10:10:41 +00:00
|
|
|
(e->expiryt != 0 && e->expiryt < tnow) ?
|
|
|
|
octstr_imm("Expired") : octstr_imm("Rejected"),
|
2007-08-06 11:57:15 +00:00
|
|
|
e->msgId, mmc->id, mmc->group_id, otransid, NULL, -1);
|
2005-09-07 10:10:41 +00:00
|
|
|
if (res == MMS_SEND_ERROR_FATAL)
|
|
|
|
to->process = 0; /* No more attempts. */
|
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
info(0, "%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: msgid=[%s], err=%s",
|
2005-09-07 10:10:41 +00:00
|
|
|
SEND_ERROR_STR(res),
|
|
|
|
octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize,
|
2007-08-06 11:57:15 +00:00
|
|
|
new_msgid ? octstr_get_cstr(new_msgid) : NULL,
|
2007-04-20 17:01:24 +00:00
|
|
|
err ? octstr_get_cstr(err) : "(none)");
|
2005-09-07 10:10:41 +00:00
|
|
|
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(new_msgid);
|
|
|
|
|
2005-09-07 10:10:41 +00:00
|
|
|
e->lasttry = tnow;
|
2007-08-20 11:49:30 +00:00
|
|
|
if (qfs->mms_queue_update(e) == 1) {
|
2005-09-07 10:10:41 +00:00
|
|
|
e = NULL;
|
|
|
|
break; /* Queue entry gone. */
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-07-27 16:39:19 +00:00
|
|
|
mms_destroy(msg);
|
2007-08-06 11:57:15 +00:00
|
|
|
octstr_destroy(otransid);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
return 1; /* always delete queue entry. */
|
2005-09-07 10:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void mmsbox_outgoing_queue_runner(int *rstop)
|
|
|
|
{
|
2007-08-20 11:49:30 +00:00
|
|
|
qfs->mms_queue_run(octstr_get_cstr(outgoing_qdir),
|
2005-09-07 10:10:41 +00:00
|
|
|
sendMsg, queue_interval, maxthreads, rstop);
|
|
|
|
}
|