1
0
Fork 0

DLR relay

This commit is contained in:
bagyenda 2008-09-13 06:37:24 +00:00
parent b480d170a5
commit 0dfdfdc305
7 changed files with 195 additions and 116 deletions

View File

@ -1,6 +1,7 @@
2008-09-12 P. A. Bagyenda <bagyenda@dsmagic.com>
* Added facility for appending special response header to each message (mime) part in MM7 response
* Added mmsbox cdr logging
* Improved DLR relay when mmsbox relay used -- msgid rewrite
2008-09-11 P. A. Bagyenda <bagyenda@dsmagic.com>
* MMSBox HTTP MMSC type added, for inter-mmsbox message relay
* MM5 support, basic infrastructure on the MMSC side.

View File

@ -378,7 +378,7 @@ static int append_address(Octstr *p, Octstr *addr_spec, char *prefix, int add_ty
j = octstr_case_search(v, octstr_imm("/TYPE=PLMN"),0);
if (j >= 0) {
z = octstr_copy(v, 2, j-2); /* skip the initial char that is only for info purposes. */
typ = "Number";
typ = octstr_len(z) <= 6 ? "ShortCode" : "Number";
} else {
z = octstr_copy(v, 2, octstr_len(v));
typ = "RFC2822Address";

View File

@ -86,7 +86,7 @@ int mmsbox_send_report(Octstr *from, char *report_type,
{
Octstr *url = NULL;
List *rh, *rph = NULL;
List *rh = NULL, *rph = NULL;
Octstr *rb = NULL;
Octstr *xtransid = NULL;
@ -95,11 +95,14 @@ int mmsbox_send_report(Octstr *from, char *report_type,
else
mms_dlr_url_get(msgid, report_type, mmc_gid, &url, &xtransid);
if (!url || octstr_len(url) == 0) {
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));
return 0;
}
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));
goto done;
} else if (octstr_search(url, octstr_imm("msgid:"), 0) == 0) /* a fake one, skip it. */
goto done;
rh = http_create_empty_headers();
@ -121,13 +124,6 @@ int mmsbox_send_report(Octstr *from, char *report_type,
octstr_destroy(sx);
}
mms_url_fetch_content(HTTP_METHOD_GET, url, rh, octstr_imm(""), &rph, &rb);
octstr_destroy(rb);
octstr_destroy(url);
octstr_destroy(xtransid);
http_destroy_headers(rph);
http_destroy_headers(rh);
/* At what point do we delete it? For now, when we get a read report,
* and also when we get a delivery report that is not 'deferred' or sent
@ -136,9 +132,41 @@ int mmsbox_send_report(Octstr *from, char *report_type,
(octstr_case_compare(status, octstr_imm("Deferred")) != 0 &&
octstr_case_compare(status, octstr_imm("Sent")) != 0))
mms_dlr_url_remove(msgid, report_type, mmc_gid);
done:
octstr_destroy(rb);
octstr_destroy(url);
octstr_destroy(xtransid);
http_destroy_headers(rph);
http_destroy_headers(rh);
return 0;
}
static void fixup_relayed_report(MmsMsg *m, MmscGrp *mmc, char *rtype)
{
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));
mms_dlr_url_remove(value, "delivery-report", mmc->group_id);
}
octstr_destroy(newmsgid);
octstr_destroy(transid);
octstr_destroy(value);
}
/* These functions are very similar to those in mmsproxy */
static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
{
@ -240,7 +268,8 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
case MM7_TAG_DeliveryReportReq:
if (mmc_id != NULL) { /* internal routing. */
m = mm7_soap_to_mmsmsg(mreq, from);
if (m)
if (m) {
fixup_relayed_report(m, h->m, "delivery-report"); /* fix it up if it is relayed. */
qf = qfs->mms_queue_add(from, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
@ -251,7 +280,7 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
octstr_get_cstr(qdir),
"MM7/SOAP-IN",
NULL);
else
} else
qf = NULL;
if (qf)
/* Log to access log */
@ -282,7 +311,9 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
case MM7_TAG_ReadReplyReq:
if (mmc_id != NULL) { /* internal routing. */
m = mm7_soap_to_mmsmsg(mreq, from);
if (m)
if (m) {
fixup_relayed_report(m, h->m, "read-report"); /* fix it up if it is relayed. */
qf = qfs->mms_queue_add(from, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
@ -293,7 +324,7 @@ static int mm7soap_receive(MmsBoxHTTPClientInfo *h)
octstr_get_cstr(qdir),
"MM7/SOAP-IN",
NULL);
else
} else
qf = NULL;
if (qf)
/* Log to access log */
@ -475,6 +506,7 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
break;
case MMS_MSGTYPE_DELIVERY_IND:
if (mmc_id != NULL) { /* internal routing. */
fixup_relayed_report(m, h->m, "delivery-report"); /* fix it up if it is relayed. */
qf = qfs->mms_queue_add(hfrom, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
@ -505,6 +537,7 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
case MMS_MSGTYPE_READ_ORIG_IND:
if (mmc_id != NULL) { /* internal routing. */
fixup_relayed_report(m, h->m, "read-report"); /* fix it up if it is relayed. */
qf = qfs->mms_queue_add(hfrom, to, NULL,
h->m->id, mmc_id,
0, time(NULL) + default_msgexpiry, m, NULL,
@ -567,19 +600,20 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
List *to = NULL;
Octstr *hto = NULL, *subject = NULL, *msgid = NULL;
Octstr *hfrom = NULL, *body;
Octstr *hfrom = NULL, *body, *rr_uri = NULL, *dlr_uri = NULL;
time_t expiryt = -1, deliveryt = -1;
Octstr *qf = NULL, *mmc_id = NULL, *qdir = NULL, *s;
int msize;
int dlr;
int dlr, rr;
int mtype;
List *cgivars_ctypes = NULL;
List *cgivars_ctypes = NULL, *rqh = http_create_empty_headers();
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");
msize = octstr_len(body);
debug("mmsbox.mm7http.sendinterface", 0,
@ -638,16 +672,25 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
case MMS_MSGTYPE_SEND_REQ:
case MMS_MSGTYPE_RETRIEVE_CONF:
/* Get Message ID */
if ((msgid = http_cgi_variable(h->cgivars, "message-id")) != NULL)
mms_replace_header_value(m, "Message-ID", octstr_get_cstr(msgid));
/* 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));
}
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);
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;
octstr_destroy(value);
if (deliveryt < 0)
deliveryt = time(NULL);
@ -661,14 +704,29 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
mms_remove_headers(m, "X-Mms-Sender-Visibility");
MOD_SUBJECT(m, h->m, hfrom);
if (qdir == outgoing_qdir) { /* We need to remember the old message ID so we can re-write it
* if a DLR is relayed backwards.
*/
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);
}
/* 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,
NULL, NULL,
NULL,
dlr_uri, rr_uri,
rqh,
dlr,
octstr_get_cstr(qdir),
"MM7/HTTP-IN",
@ -684,12 +742,15 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
break;
case MMS_MSGTYPE_DELIVERY_IND:
if (mmc_id != NULL) { /* internal routing. */
fixup_relayed_report(m, h->m, "delivery-report"); /* fix it up if it is relayed. */
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,
rqh,
0,
octstr_get_cstr(qdir),
"MM7/HTTP-IN",
@ -704,6 +765,7 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
} else {
Octstr *value = http_header_value(mh, octstr_imm("X-Mms-Status"));
Octstr *value2 = http_header_value(mh, octstr_imm("Message-ID"));
mmsbox_send_report(hfrom, "delivery-report", NULL, value, value2,
h->m->id, h->m->group_id, NULL, NULL, -1);
@ -715,12 +777,14 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
case MMS_MSGTYPE_READ_ORIG_IND:
if (mmc_id != NULL) { /* internal routing. */
fixup_relayed_report(m, h->m, "read-report"); /* fix it up if it is relayed. */
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,
rqh,
0,
octstr_get_cstr(qdir),
"MM7/HTTP-IN",
@ -747,7 +811,7 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
http_header_add(rh, "X-Mbuni-Version", VERSION);
http_send_reply(h->client, hstatus, rh, qf ? qf : octstr_imm(""));
http_send_reply(h->client, hstatus, rh, msgid ? msgid : (qf ? qf : octstr_imm("")));
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
@ -755,9 +819,12 @@ static int mm7http_receive(MmsBoxHTTPClientInfo *h)
octstr_destroy(qf);
octstr_destroy(mmc_id);
octstr_destroy(msgid);
http_destroy_headers(mh);
http_destroy_headers(rh);
http_destroy_headers(rqh);
if (m)
mms_destroy(m);
@ -1112,7 +1179,7 @@ static Octstr *mm7http_send(MmscGrp *mmc, Octstr *from, Octstr *to,
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);
rh = mime_entity_headers(form_data);
body = mime_entity_body(form_data);
@ -1300,23 +1367,21 @@ static int sendMsg(MmsEnvelope *e)
/* handle CDR */
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED || res == MMS_SEND_ERROR_FATAL) {
MmsBoxCdrStruct cdr;
/* Do CDR */
mmsbox_fill_cdr_struct(&cdr, e->created,
octstr_get_cstr(e->from),
octstr_get_cstr(to->rcpt),
octstr_get_cstr(e->msgId),
mmc ? octstr_get_cstr(mmc->id) : NULL, /* Should we touch mmc here? XXX */
e->src_interface,
"MM7",
e->msize,
(char *)mms_message_type_to_cstr(e->msgtype),
NULL, NULL, /* XXX will add these later. */
res == MMS_SEND_ERROR_FATAL ? "dropped" : "sent",
e->dlr,
0);
cdrfs->logcdr(&cdr);
cdrfs->logcdr(e->created,
octstr_get_cstr(e->from),
octstr_get_cstr(to->rcpt),
octstr_get_cstr(e->msgId),
mmc ? octstr_get_cstr(mmc->id) : NULL, /* Should we touch mmc here? XXX */
e->src_interface,
"MM7",
e->msize,
(char *)mms_message_type_to_cstr(e->msgtype),
NULL, NULL, /* XXX will add these later. */
res == MMS_SEND_ERROR_FATAL ? "dropped" : "sent",
e->dlr,
0);
}
if (err == NULL)

View File

@ -127,8 +127,11 @@ void mms_dlr_url_remove(Octstr *msgid, char *rtype, Octstr *mmc_gid)
Octstr *fname = NULL;
int fd = dlr_entry_fname(octstr_get_cstr(msgid), rtype, mmc_gid, &fname);
if (fname)
if (fname) {
unlink(octstr_get_cstr(fname));
octstr_destroy(fname);
}
if (fd >= 0)
close(fd);
close(fd);
}

View File

@ -555,25 +555,24 @@ done:
if (res == -1 || res == 0) /* Fatal error, or success delete queue entry. */
for (i = 0, n = gwlist_len(e->to); i < n; i++) {
MmsBoxCdrStruct cdr;
MmsEnvelopeTo *r = gwlist_get(e->to,i);
if (r)
r->process = 0;
/* Do CDR */
mmsbox_fill_cdr_struct(&cdr, e->created,
octstr_get_cstr(e->from),
octstr_get_cstr(r->rcpt),
octstr_get_cstr(e->msgId),
e->fromproxy ? octstr_get_cstr(e->fromproxy) : NULL,
e->src_interface,
"mms-service",
e->msize,
(char *)mms_message_type_to_cstr(e->msgtype),
NULL, NULL, /* XXX will add these later. */
res == 0 ? "forwarded" : "dropped",
e->dlr,
0);
cdrfs->logcdr(&cdr);
cdrfs->logcdr(e->created,
octstr_get_cstr(e->from),
octstr_get_cstr(r->rcpt),
octstr_get_cstr(e->msgId),
e->fromproxy ? octstr_get_cstr(e->fromproxy) : NULL,
e->src_interface,
"mms-service",
e->msize,
(char *)mms_message_type_to_cstr(e->msgtype),
NULL, NULL, /* XXX will add these later. */
res == 0 ? "forwarded" : "dropped",
e->dlr,
0);
}
else { /* Not succeeded so we need to wait a bit and try later. */
e->lasttry = time(NULL);

View File

@ -22,6 +22,32 @@ static List *req_list;
static long th_id;
#define CBUFSIZE 256
typedef struct MmsBoxCdrStruct {
time_t sdate;
char from[CBUFSIZE];
char to[CBUFSIZE];
#if 0
char src_ip[CBUFSIZE/4];
char dest_ip[CBUFSIZE/4];
#endif
char msgid[CBUFSIZE];
char mmsc_id[CBUFSIZE];
char src_int[CBUFSIZE/4];
char dst_int[CBUFSIZE/4];
unsigned long msg_size;
char msgtype[CBUFSIZE/8];
char prio[CBUFSIZE/8];
char mclass[CBUFSIZE/8];
char status[CBUFSIZE/8];
unsigned char dlr;
unsigned char rr;
} MmsBoxCdrStruct;
static void cdr_logger_func(void)
{
@ -93,23 +119,8 @@ static int module_fini(void)
return 0;
}
static int cdr_module_logcdr(MmsBoxCdrStruct *cdr)
{
MmsBoxCdrStruct *xcdr = gw_malloc(sizeof *xcdr);
gw_assert(req_list);
*xcdr = *cdr;
gwlist_produce(req_list, xcdr);
return 0;
}
/* utility function. */
void mmsbox_fill_cdr_struct(MmsBoxCdrStruct *cdr,
static void fill_cdr_struct(MmsBoxCdrStruct *cdr,
time_t sdate, char *from, char *to, char *msgid,
char *mmsc_id, char *src_int, char *dst_int,
#if 0
@ -143,6 +154,33 @@ void mmsbox_fill_cdr_struct(MmsBoxCdrStruct *cdr,
cdr->msg_size = msg_size;
}
static int cdr_module_logcdr(time_t sdate, char *from, char *to, char *msgid,
char *mmsc_id, char *src_int, char *dst_int,
#if 0
char *src_ip, char *dst_ip,
#endif
unsigned long msg_size,
char *msgtype, char *prio, char *mclass,
char *status,
int dlr, int rr)
{
MmsBoxCdrStruct *xcdr = gw_malloc(sizeof *xcdr);
gw_assert(req_list);
fill_cdr_struct(xcdr, sdate, from, to, msgid, mmsc_id, src_int, dst_int,
#if 0
src_ip, dst_ip,
#endif
msg_size, msgtype, prio, mclass, status, dlr, rr);
gwlist_produce(req_list, xcdr);
return 0;
}
MmsBoxCdrFuncStruct mmsbox_cdrfuncs = {
cdr_module_init,

View File

@ -21,30 +21,6 @@
/* MMSBOX CDR module. This file provides prototypes for all CDR functions.
*
*/
#define CBUFSIZE 256
typedef struct MmsBoxCdrStruct {
time_t sdate;
char from[CBUFSIZE];
char to[CBUFSIZE];
#if 0
char src_ip[CBUFSIZE/4];
char dest_ip[CBUFSIZE/4];
#endif
char msgid[CBUFSIZE];
char mmsc_id[CBUFSIZE];
char src_int[CBUFSIZE/4];
char dst_int[CBUFSIZE/4];
unsigned long msg_size;
char msgtype[CBUFSIZE/8];
char prio[CBUFSIZE/8];
char mclass[CBUFSIZE/8];
char status[CBUFSIZE/8];
unsigned char dlr;
unsigned char rr;
} MmsBoxCdrStruct;
typedef struct MmsBoxCdrFuncStruct {
@ -52,22 +28,19 @@ typedef struct MmsBoxCdrFuncStruct {
int (*init)(char *settings);
/* This function logs a cdr to wherever it is logging to. */
int (*logcdr)(MmsBoxCdrStruct *cdr);
int (*logcdr)(time_t sdate, char *from, char *to, char *msgid,
char *mmsc_id, char *src_int, char *dst_int,
#if 0
char *src_ip, char *dst_ip,
#endif
unsigned long msg_size,
char *msgtype, char *prio, char *mclass,
char *status,
int dlr, int rr);
int (*cleanup)(void);
} MmsBoxCdrFuncStruct;
extern MmsBoxCdrFuncStruct mmsbox_cdrfuncs; /* The module must expose a symbol 'cdr_funcs' */
/* utility function. */
void mmsbox_fill_cdr_struct(MmsBoxCdrStruct *cdr,
time_t sdate, char *from, char *to, char *msgid,
char *mmsc_id, char *src_int, char *dst_int,
#if 0
char *src_ip, char *dst_ip,
#endif
unsigned long msg_size,
char *msgtype, char *prio, char *mclass,
char *status,
int dlr, int rr);
#endif