mmsbox now sends multiple recipients per transaction
This commit is contained in:
parent
18dd46568f
commit
cdabed7443
|
@ -1,3 +1,5 @@
|
|||
2010-12-09 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Changes to mmsbox to allow it send multiple recipients per MM7 transaction
|
||||
2010-11-30 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
* Minor fix in RFC 2047 text handling
|
||||
2010-11-29 P. A. Bagyenda <bagyenda@dsmagic.com>
|
||||
|
|
|
@ -2755,6 +2755,22 @@ string
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>max-recipients</tt>
|
||||
</td>
|
||||
<td valign=top >
|
||||
Number
|
||||
</td>
|
||||
<td valign=top >
|
||||
Maximum number of recipients per transaction for this MMSC
|
||||
(ignored for custom MMSC type). This controls how many <tt>To</tt>
|
||||
addresses are included in each send transaction. Default is
|
||||
1. Note that failure of of the MMSC to accept any of the
|
||||
recipients can result in the entire send request being retried.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td valign=top >
|
||||
<tt>reroute</tt>
|
||||
|
|
|
@ -194,6 +194,8 @@ MULTI_GROUP(mmsc,
|
|||
OCTSTR(default-vasid)
|
||||
OCTSTR(maximum-request-size)
|
||||
OCTSTR(strip-domain)
|
||||
|
||||
OCTSTR(max-recipients)
|
||||
)
|
||||
|
||||
MULTI_GROUP(mms-service,
|
||||
|
|
|
@ -529,7 +529,7 @@ static void addmmscname(Octstr *s, Octstr *myhostname)
|
|||
|
||||
}
|
||||
|
||||
static int send2email(Octstr *to, Octstr *from, Octstr *subject,
|
||||
static int send2email(List *xto, Octstr *from, Octstr *subject,
|
||||
Octstr *msgid,
|
||||
MIMEEntity *m, int append_hostname, Octstr **error,
|
||||
char *sendmail_cmd, Octstr *myhostname,
|
||||
|
@ -543,8 +543,9 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
|
|||
|
||||
Octstr *cmd = octstr_create("");
|
||||
List *headers = mime_entity_headers(m); /* we don't want the mime version header removed. */
|
||||
Octstr *to = NULL;
|
||||
|
||||
fname[0] = 0;
|
||||
/* Make to address */
|
||||
|
||||
if (append_hostname) { /* Add our hostname to all phone numbers. */
|
||||
List *l = http_create_empty_headers();
|
||||
|
@ -607,11 +608,7 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
|
|||
s = mime_entity_to_octstr(m);
|
||||
|
||||
if (relay_host && relay_port > 0) {
|
||||
List *lto = gwlist_create();
|
||||
gwlist_append(lto, octstr_duplicate(to));
|
||||
|
||||
ret = smtp_send(octstr_get_cstr(relay_host), relay_port, from, lto, s);
|
||||
gwlist_destroy(lto, (void *)octstr_destroy);
|
||||
ret = smtp_send(octstr_get_cstr(relay_host), relay_port, from, xto, s);
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
|
@ -622,6 +619,7 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
|
|||
* m - message id
|
||||
*/
|
||||
|
||||
LINEARISE_STR_LIST(to,xto," ");
|
||||
i = 0;
|
||||
for (;;) {
|
||||
Octstr *tmp;
|
||||
|
@ -679,6 +677,7 @@ static int send2email(Octstr *to, Octstr *from, Octstr *subject,
|
|||
i += 2;
|
||||
}
|
||||
|
||||
|
||||
if ((fd = mkstemp(fname)) < 0) {
|
||||
*error = octstr_format("mkstemp: Failed to create temporary file: %s",
|
||||
strerror(errno));
|
||||
|
@ -721,6 +720,7 @@ done:
|
|||
http_destroy_headers(headers);
|
||||
octstr_destroy(cmd);
|
||||
octstr_destroy(s);
|
||||
octstr_destroy(to);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -804,11 +804,14 @@ int mm_send_to_email(Octstr *to, Octstr *from, Octstr *subject,
|
|||
char *sendmail_cmd, Octstr *myhostname,
|
||||
Octstr *relay_host, int relay_port)
|
||||
{
|
||||
return send2email(to,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname, relay_host, relay_port);
|
||||
List *lto = gwlist_create_ex(to);
|
||||
int ret = send2email(lto,from,subject,msgid,m,append_hostname,error,sendmail_cmd,myhostname, relay_host, relay_port);
|
||||
gwlist_destroy(lto, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Send this message to email recipient. */
|
||||
int mms_sendtoemail(Octstr *from, Octstr *to,
|
||||
int mms_sendtoemail(Octstr *from, List *lto,
|
||||
Octstr *subject, Octstr *msgid,
|
||||
MmsMsg *msg, int dlr,
|
||||
Octstr **error, char *sendmail_cmd,
|
||||
|
@ -824,13 +827,18 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
|
|||
List *headers = NULL;
|
||||
List *newhdrs = http_create_empty_headers();
|
||||
int ret = 0, mtype;
|
||||
Octstr *to;
|
||||
|
||||
gw_assert(msg);
|
||||
mtype = mms_messagetype(msg);
|
||||
|
||||
/* Make 'to' header field in case we need it. */
|
||||
LINEARISE_STR_LIST(to, lto, ", ");
|
||||
|
||||
if (!to ||
|
||||
octstr_search_char(to, '@', 0) < 0) {
|
||||
*error = octstr_format("Invalid email address %S!", to);
|
||||
octstr_destroy(to);
|
||||
return MMS_SEND_ERROR_FATAL;
|
||||
}
|
||||
|
||||
|
@ -840,6 +848,7 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
|
|||
m == NULL) {
|
||||
mms_warning(0, "send2email", NULL, "Failed to format message (msg=%s,ret=%d)",
|
||||
m ? "OK" : "Not transformed",ret);
|
||||
octstr_destroy(to);
|
||||
return -ret;
|
||||
}
|
||||
|
||||
|
@ -855,8 +864,10 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
|
|||
http_header_add(newhdrs, "Subject", subject ? octstr_get_cstr(subject) : "MMS Message");
|
||||
http_header_remove_all(headers, "From");
|
||||
http_header_add(newhdrs, "From", octstr_get_cstr(from));
|
||||
#if 0 /* Should we reveal recipients ?? */
|
||||
http_header_remove_all(headers, "To");
|
||||
http_header_add(newhdrs, "To", octstr_get_cstr(to));
|
||||
#endif
|
||||
http_header_add(newhdrs, "Message-ID", msgid ? octstr_get_cstr(msgid) : "");
|
||||
http_header_add(newhdrs, "MIME-Version", "1.0");
|
||||
} else {
|
||||
|
@ -947,9 +958,9 @@ int mms_sendtoemail(Octstr *from, Octstr *to,
|
|||
done:
|
||||
http_destroy_headers(headers);
|
||||
http_destroy_headers(newhdrs);
|
||||
|
||||
octstr_destroy(to);
|
||||
if (ret == 0)
|
||||
ret = send2email(to,
|
||||
ret = send2email(lto,
|
||||
from, subject, msgid, m, mm4 == 0, error, sendmail_cmd, myhostname, relay_host, relay_port);
|
||||
mime_entity_destroy(m);
|
||||
|
||||
|
@ -2535,3 +2546,16 @@ Octstr *pack_rfc2047_text(Octstr *in, int charset_mib_enum)
|
|||
octstr_append_cstr(xs, "?=");
|
||||
return xs;
|
||||
}
|
||||
|
||||
List *gwlist_create_ex_real(const char *file, const char *func, int line,...)
|
||||
{
|
||||
va_list ap;
|
||||
List *l = gwlist_create();
|
||||
void *v;
|
||||
|
||||
va_start(ap, line);
|
||||
|
||||
while ((v = va_arg(ap, void *)) != NULL)
|
||||
gwlist_append(l, v);
|
||||
return l;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ void base64_mimeparts(MIMEEntity *m, int all);
|
|||
/* Send this message to email recipient: Returns 0 on success 1 or 2 on profile error
|
||||
* (negate to get right one), -ve on some other error
|
||||
*/
|
||||
int mms_sendtoemail(Octstr *from, Octstr *to,
|
||||
int mms_sendtoemail(Octstr *from, List *lto,
|
||||
Octstr *subject, Octstr *msgid,
|
||||
MmsMsg *msg, int dlr, Octstr **error,
|
||||
char *sendmail_cmd, Octstr *myhostname,
|
||||
|
@ -266,8 +266,24 @@ Octstr *parse_rfc2047_text(Octstr *in, int *mibenum);
|
|||
#define QUEUERUN_INTERVAL 1*60 /* 1 minutes. */
|
||||
#define DEFAULT_EXPIRE 3600*24*7 /* One week */
|
||||
|
||||
#define DEFAULT_SIMUL_RCPTS 10
|
||||
|
||||
#define HTTP_REPLACE_HEADER(hdr, hname, value) do { \
|
||||
http_header_remove_all((hdr), (hname)); \
|
||||
http_header_add((hdr), (hname), (value)); \
|
||||
} while (0)
|
||||
|
||||
List *gwlist_create_ex_real(const char *file, const char *func, int line,...);
|
||||
|
||||
#define gwlist_create_ex(...) gwlist_create_ex_real(__FILE__,__FUNCTION__,__LINE__, __VA_ARGS__, NULL)
|
||||
|
||||
#define LINEARISE_STR_LIST(res,lst,sep) do { \
|
||||
Octstr *__res; \
|
||||
int __i; \
|
||||
for (__res = octstr_create(""), __i = 0; __i < gwlist_len(lst); __i++) \
|
||||
octstr_format_append(__res, "%s%S", \
|
||||
octstr_len(__res) == 0 ? "" : (sep), gwlist_get((lst), __i)); \
|
||||
(res) = __res; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -555,8 +555,7 @@ static int mm7eaif_receive(MmsBoxHTTPClientInfo *h)
|
|||
strip_prefixes);
|
||||
|
||||
|
||||
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL &&
|
||||
gwlist_len(hto) > 0) { /* To address is in headers. */
|
||||
if ((hto = http_header_find_all(h->headers, "X-NOKIA-MMSC-To")) != NULL && gwlist_len(hto) > 0) { /* To address is in headers. */
|
||||
int i, n;
|
||||
|
||||
gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);
|
||||
|
@ -1137,7 +1136,7 @@ void mmsc_receive_func(MmscGrp *m)
|
|||
* are observed!
|
||||
* Don't remove from queue on fail, just leave it to expire.
|
||||
*/
|
||||
static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
||||
static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, List *lto,
|
||||
Octstr *transid,
|
||||
Octstr *linkedid,
|
||||
char *vasid,
|
||||
|
@ -1151,12 +1150,14 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|||
Octstr *ret = NULL;
|
||||
int mtype = mms_messagetype(m);
|
||||
int hstatus = HTTP_OK, tstatus = -1;
|
||||
List *xto = gwlist_create();
|
||||
MSoapMsg_t *mreq = NULL, *mresp = NULL;
|
||||
List *rh = NULL, *ph = NULL;
|
||||
Octstr *body = NULL, *rbody = NULL, *url = NULL;
|
||||
Octstr *s, *r, *status_details = NULL;
|
||||
char *xvasid = vasid ? vasid : (mmc->default_vasid ? octstr_get_cstr(mmc->default_vasid) : NULL);
|
||||
Octstr *to;
|
||||
|
||||
LINEARISE_STR_LIST(to,lto,", ");
|
||||
|
||||
if (e == NULL || mmc == NULL)
|
||||
goto done1;
|
||||
|
@ -1165,10 +1166,9 @@ static Octstr *mm7soap_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|||
mms_message_type_to_cstr(mtype),
|
||||
octstr_get_cstr(from), octstr_get_cstr(to));
|
||||
|
||||
gwlist_append(xto, to);
|
||||
|
||||
if ((mreq = mm7_mmsmsg_to_soap(m, (mmc == NULL || mmc->no_senderaddress == 0) ? from : NULL,
|
||||
xto, transid,
|
||||
lto, transid,
|
||||
service_code,
|
||||
linkedid,
|
||||
1, octstr_get_cstr(mmc->vasp_id), xvasid, NULL, 0,/* UA N/A on this side. */
|
||||
|
@ -1291,13 +1291,13 @@ done1:
|
|||
http_destroy_headers(ph);
|
||||
octstr_destroy(rbody);
|
||||
octstr_destroy(url);
|
||||
gwlist_destroy(xto, NULL);
|
||||
octstr_destroy(to);
|
||||
octstr_destroy(status_details);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
||||
static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, List *lto,
|
||||
Octstr *transid,
|
||||
char *vasid,
|
||||
MmsEnvelope *e,
|
||||
|
@ -1312,8 +1312,10 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|||
Octstr *body = NULL, *rbody = NULL, *xver = NULL;
|
||||
char *msgtype;
|
||||
MmsMsg *mresp = NULL;
|
||||
int mresp_type = -1;
|
||||
int mresp_type = -1, i;
|
||||
Octstr *to;
|
||||
|
||||
LINEARISE_STR_LIST(to,lto,", ");
|
||||
|
||||
if (e == NULL || mmc == NULL)
|
||||
goto done;
|
||||
|
@ -1323,7 +1325,10 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|||
octstr_get_cstr(from), octstr_get_cstr(to));
|
||||
|
||||
http_header_remove_all(rh, "X-Mms-Allow-Adaptations");
|
||||
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));
|
||||
}
|
||||
http_header_add(rh, "X-NOKIA-MMSC-From", octstr_get_cstr(from));
|
||||
|
||||
xver = octstr_format(EAIF_VERSION, mmc->ver.major, mmc->ver.minor1);
|
||||
|
@ -1347,7 +1352,9 @@ static Octstr *mm7eaif_send(MmscGrp *mmc, Octstr *from, Octstr *to,
|
|||
|
||||
/* Patch the message FROM and TO fields. */
|
||||
mms_replace_header_value(m, "From", octstr_get_cstr(from));
|
||||
#if 0
|
||||
mms_replace_header_value(m, "To", octstr_get_cstr(to));
|
||||
#endif
|
||||
mms_replace_header_value(m,"X-Mms-Transaction-ID",
|
||||
transid ? octstr_get_cstr(transid) : "000");
|
||||
body = mms_tobinary(m);
|
||||
|
@ -1411,7 +1418,7 @@ done:
|
|||
octstr_destroy(body);
|
||||
http_destroy_headers(ph);
|
||||
octstr_destroy(rbody);
|
||||
|
||||
octstr_destroy(to);
|
||||
octstr_destroy(resp);
|
||||
octstr_destroy(xver);
|
||||
return ret;
|
||||
|
@ -1420,7 +1427,7 @@ done:
|
|||
|
||||
static Octstr *mm7http_send(MmscGrp *mmc,
|
||||
MmsEnvelope *e,
|
||||
Octstr *from, Octstr *to,
|
||||
Octstr *from, List *lto,
|
||||
MmsMsg *m, Octstr **error,
|
||||
int *retry)
|
||||
{
|
||||
|
@ -1434,6 +1441,9 @@ static Octstr *mm7http_send(MmscGrp *mmc,
|
|||
MIMEEntity *form_data = make_multipart_formdata();
|
||||
Octstr *transid = e ? octstr_create(e->xqfname) : NULL;
|
||||
int mm7type = mm7_msgtype_to_soaptype(mtype,1);
|
||||
Octstr *to;
|
||||
|
||||
LINEARISE_STR_LIST(to,lto," ");
|
||||
|
||||
if (e == NULL || mmc == NULL)
|
||||
goto done;
|
||||
|
@ -1448,7 +1458,6 @@ static Octstr *mm7http_send(MmscGrp *mmc,
|
|||
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);
|
||||
|
||||
|
||||
mmsbox_event_cb(mmc->id, mm7type, 0, octstr_imm("1.0"), 0,
|
||||
octstr_len(mms), e->attempts, from,
|
||||
to, NULL, transid, hdrs, NULL);
|
||||
|
@ -1490,14 +1499,15 @@ done:
|
|||
octstr_destroy(mms);
|
||||
mime_entity_destroy(form_data);
|
||||
octstr_destroy(transid);
|
||||
octstr_destroy(to);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e, Octstr *to,
|
||||
static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e,
|
||||
List *lto, /* Of Octstr * */
|
||||
Octstr *orig_transid,
|
||||
|
||||
MmsMsg *m,
|
||||
Octstr **new_msgid,
|
||||
List **errhdrs)
|
||||
|
@ -1517,15 +1527,17 @@ static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e, Octstr *to,
|
|||
mutex_lock(mmc->mutex); { /* Grab a lock on it. */
|
||||
Octstr *err = NULL;
|
||||
if (mmc->type == SOAP_MMSC)
|
||||
id = mm7soap_send(mmc, from, to, transid, linkedid, vasid, service_code, e, m, &err, errhdrs, &retry);
|
||||
id = mm7soap_send(mmc, from, lto, transid, linkedid, vasid, service_code, e, m, &err, errhdrs, &retry);
|
||||
else if (mmc->type == EAIF_MMSC)
|
||||
id = mm7eaif_send(mmc, from, to, transid, vasid, e, m, &err, &retry);
|
||||
id = mm7eaif_send(mmc, from, lto, transid, vasid, e, m, &err, &retry);
|
||||
else if (mmc->type == HTTP_MMSC)
|
||||
id = mm7http_send(mmc,e, from, to, m, &err, &retry);
|
||||
else if (mmc->type == CUSTOM_MMSC && mmc->started)
|
||||
id = mm7http_send(mmc,e, from, lto, m, &err, &retry);
|
||||
else if (mmc->type == CUSTOM_MMSC && mmc->started) {
|
||||
Octstr *to = gwlist_get(lto, 0); /* XXX Send one at a time*/
|
||||
id = mmc->fns->send_msg(mmc->data,
|
||||
from, to, transid, linkedid, vasid,
|
||||
service_code, m, hdrs, &err, &retry);
|
||||
}
|
||||
#if 0
|
||||
else if (mmc->type == MM4_MMSC && mmc->started)
|
||||
(void )0; /* Already sent above */
|
||||
|
@ -1562,124 +1574,27 @@ static int mms_sendtommsc(MmscGrp *mmc, MmsEnvelope *e, Octstr *to,
|
|||
return ret;
|
||||
}
|
||||
|
||||
typedef struct MRcpt_t {
|
||||
int smtp_flag;
|
||||
MmscGrp *mmc;
|
||||
List *rto; /* List of envelope */
|
||||
} MRcpt_t;
|
||||
|
||||
static int sendMsg(MmsEnvelope *e)
|
||||
static int cmp_mrcpt(struct MRcpt_t *m, MmscGrp *mmc)
|
||||
{
|
||||
MmsMsg *msg = NULL;
|
||||
int i, n;
|
||||
Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL;
|
||||
|
||||
if ((msg = qfs->mms_queue_getdata(e)) == NULL) {
|
||||
mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname);
|
||||
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR, 4);
|
||||
goto done2;
|
||||
} else
|
||||
MMSC_CLEAR_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR);
|
||||
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);
|
||||
}
|
||||
|
||||
for (i = 0, n = gwlist_len(e->to); i<n; i++) {
|
||||
int res = MMS_SEND_OK;
|
||||
MmsEnvelopeTo *to = gwlist_get(e->to, i);
|
||||
Octstr *err = NULL, *x;
|
||||
static void process_send_res(MmsEnvelope *e, MmsMsg *msg,
|
||||
MmsEnvelopeTo *to, MmscGrp *mmc,
|
||||
int res, Octstr *err, List *errl, Octstr *new_msgid,
|
||||
int first_one)
|
||||
{
|
||||
time_t tnow = time(NULL);
|
||||
MmscGrp *mmc = NULL;
|
||||
Octstr *new_msgid = NULL;
|
||||
List *errl = NULL;
|
||||
int is_email = 0;
|
||||
Octstr *requested_mmsc = NULL;
|
||||
|
||||
|
||||
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 >= 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;
|
||||
}
|
||||
|
||||
is_email = (octstr_search_char(to->rcpt, '@', 0) > 0);
|
||||
|
||||
x = octstr_format("X-Mbuni-Via-%d", i);
|
||||
requested_mmsc = e->hdrs ? http_header_value(e->hdrs, x) : NULL;
|
||||
octstr_destroy(x);
|
||||
if ((mmc = get_handler_mmc(requested_mmsc ? requested_mmsc : e->viaproxy, to->rcpt, e->from)) == NULL &&
|
||||
!is_email) {
|
||||
err = octstr_format("MMSBox error: Failed to deliver to "
|
||||
"%S. Don't know how to route!",
|
||||
to->rcpt);
|
||||
res = MMS_SEND_ERROR_TRANSIENT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (is_email || (mmc->type == MM4_MMSC && mmc->started)) { /* Handle MM4 recipient here 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, *xto;
|
||||
|
||||
|
||||
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 (!is_email)
|
||||
xto = octstr_format("%S@%S", to->rcpt,
|
||||
mmc && octstr_str_compare(mmc->mmsc_url, "*") != 0 ? mmc->mmsc_url :
|
||||
octstr_imm("unknown"));
|
||||
else
|
||||
xto = octstr_duplicate(to->rcpt);
|
||||
|
||||
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,
|
||||
to->rcpt,NULL, NULL, e->hdrs, NULL);
|
||||
}
|
||||
octstr_destroy(pfrom);
|
||||
octstr_destroy(xto);
|
||||
} else {
|
||||
res = mms_sendtommsc(mmc, e,
|
||||
to->rcpt,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (res == MMS_SEND_OK || res == MMS_SEND_QUEUED) {
|
||||
to->process = 0;
|
||||
|
||||
|
@ -1696,10 +1611,12 @@ static int sendMsg(MmsEnvelope *e)
|
|||
}
|
||||
|
||||
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. */
|
||||
}
|
||||
|
@ -1747,23 +1664,224 @@ static int sendMsg(MmsEnvelope *e)
|
|||
"%s MMSBox Outgoing Queue MMS Send: From %s, to %s, msgsize=%ld: %s",
|
||||
SEND_ERROR_STR(res),
|
||||
octstr_get_cstr(e->from), octstr_get_cstr(to->rcpt), e->msize, octstr_get_cstr(err));
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static int sendMsg(MmsEnvelope *e)
|
||||
{
|
||||
MmsMsg *msg = NULL;
|
||||
int i, n;
|
||||
Octstr *otransid = e->hdrs ? http_header_value(e->hdrs, octstr_imm("X-Mbuni-TransactionID")) : NULL;
|
||||
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);
|
||||
|
||||
if ((msg = qfs->mms_queue_getdata(e)) == NULL) {
|
||||
mms_error(0, "MM7", NULL, "MMSBox queue error: Failed to load message for queue id [%s]!", e->xqfname);
|
||||
MMSC_ISSUE_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR, 4);
|
||||
goto done2;
|
||||
} else
|
||||
MMSC_CLEAR_ALARM(NULL, MMSBOX_ALARM_RETRIEVE_MMS_ERROR);
|
||||
|
||||
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;
|
||||
|
||||
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_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;
|
||||
}
|
||||
|
||||
x = octstr_format("X-Mbuni-Via-%d", i);
|
||||
requested_mmsc = e->hdrs ? http_header_value(e->hdrs, x) : NULL;
|
||||
octstr_destroy(x);
|
||||
|
||||
|
||||
if ((mmc = get_handler_mmc(requested_mmsc ? requested_mmsc : e->viaproxy, to->rcpt, e->from)) == NULL &&
|
||||
!is_email) {
|
||||
err = octstr_format("MMSBox error: Failed to deliver to "
|
||||
"%S. Don't know how to route!",
|
||||
to->rcpt);
|
||||
res = MMS_SEND_ERROR_TRANSIENT;
|
||||
goto done_route;
|
||||
}
|
||||
|
||||
|
||||
/* 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();
|
||||
|
||||
gwlist_append(mlist, m);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* 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"));
|
||||
gwlist_append(xto, x);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
process_send_res(e, msg, to, mmc, res, err, errl, new_msgid, j == 0);
|
||||
|
||||
}
|
||||
octstr_destroy(zto);
|
||||
gwlist_destroy(xto, (void *)octstr_destroy);
|
||||
octstr_destroy(new_msgid);
|
||||
octstr_destroy(err);
|
||||
http_destroy_headers(errl);
|
||||
|
||||
octstr_destroy(requested_mmsc);
|
||||
e->lasttry = tnow;
|
||||
if (qfs->mms_queue_update(e) == 1) {
|
||||
e = NULL;
|
||||
break; /* Queue entry gone. */
|
||||
}
|
||||
gwlist_destroy(lto, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
done2:
|
||||
mms_destroy(msg);
|
||||
octstr_destroy(otransid);
|
||||
|
||||
/* 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);
|
||||
|
||||
if (e) { /* Update the queue if it is still valid (e.g. recipients not handled)
|
||||
* XXX can this happen here??...
|
||||
*/
|
||||
|
|
|
@ -663,6 +663,10 @@ static MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, List *warnings, List
|
|||
if (mms_cfg_get_bool(cfg, x, octstr_imm("strip-domain"), &m->strip_domain) < 0)
|
||||
m->strip_domain = 1;
|
||||
|
||||
if (mms_cfg_get_int(cfg,x, octstr_imm("max-recipients"), &m->max_recipients) < 0 ||
|
||||
m->max_recipients <= 0)
|
||||
m->max_recipients = 1;
|
||||
|
||||
if (mms_cfg_get_int(cfg,x, octstr_imm("maximum-request-size"), &m->max_pkt_size) < 0 ||
|
||||
m->max_pkt_size <= 0)
|
||||
m->max_pkt_size = DEFAULT_MAX_PKT_SIZE;
|
||||
|
@ -700,9 +704,13 @@ static MmscGrp *start_mmsc_from_conf(mCfg *cfg, mCfgGrp *x, List *warnings, List
|
|||
m->settings = _mms_cfg_getx(cfg, x, octstr_imm("custom-settings"));
|
||||
/* also load the libary. */
|
||||
if ((m->fns = _mms_load_module(cfg, x, "mmsc-library", "mmsc_funcs", NULL)) == NULL) {
|
||||
mms_error(0, "mmsbox", NULL, "failed to load MMSC libary functions from module!");
|
||||
m->fns = &dummy_mmsc_funcs;
|
||||
panic(errno, "failed to load MMSC libary functions from module, mmsc id <%s>!",
|
||||
octstr_get_cstr(m->id));
|
||||
}
|
||||
m->max_recipients = 1;
|
||||
mms_info(0, "mmsbox", NULL,"Loaded MMSC[%s], max recipients per transaction forced to 1",
|
||||
octstr_get_cstr(m->id));
|
||||
} else
|
||||
WARNING("MMSBox: Unknown MMSC type [%s]!",
|
||||
octstr_get_cstr(type));
|
||||
|
@ -978,13 +986,11 @@ void mmsbox_settings_cleanup(void)
|
|||
|
||||
void return_mmsc_conn(MmscGrp *m)
|
||||
{
|
||||
|
||||
if (m)
|
||||
MMSBOX_MMSC_UNMARK_INUSE(m); /* Vital! */
|
||||
|
||||
/* now try and delete as many to-be-deleted mmc as possible */
|
||||
delete_stale_mmsc(0);
|
||||
|
||||
}
|
||||
|
||||
/* handle message routing. */
|
||||
|
|
|
@ -82,6 +82,8 @@ typedef struct MmscGrp {
|
|||
long max_pkt_size;
|
||||
|
||||
int strip_domain; /* MM4 only */
|
||||
|
||||
long max_recipients; /* Max recpients per transaction */
|
||||
} MmscGrp;
|
||||
|
||||
#define DEFAULT_MAX_PKT_SIZE 1024*1024
|
||||
|
|
|
@ -181,14 +181,17 @@ static int sendMsg(MmsEnvelope *e)
|
|||
e->msgId,
|
||||
e->hdrs,
|
||||
msg, &err);
|
||||
else
|
||||
res = mms_sendtoemail(pfrom, to->rcpt,
|
||||
else {
|
||||
List *lto = gwlist_create_ex(to->rcpt);
|
||||
res = mms_sendtoemail(pfrom, lto,
|
||||
e->subject ? e->subject : settings->mms_email_subject,
|
||||
e->msgId, msg, 0, &err, sendmail_cmd,
|
||||
settings->hostname, 1, 1,
|
||||
octstr_get_cstr(settings->mms_email_txt),
|
||||
octstr_get_cstr(settings->mms_email_html), 0, e->xqfname,
|
||||
e->hdrs, settings->smtp_relay, settings->smtp_port);
|
||||
gwlist_destroy(lto, NULL);
|
||||
}
|
||||
if (res == MMS_SEND_QUEUED)
|
||||
res = MMS_SEND_OK; /* queued to email treated same as sent.
|
||||
* XXX - this means DLR requests for emailed messages not supported!
|
||||
|
@ -575,6 +578,7 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
{
|
||||
|
||||
Octstr *pto, *pfrom;
|
||||
List *lto;
|
||||
int x = MMS_SEND_ERROR_FATAL;
|
||||
Octstr *xtransid; /* We make a fake transaction ID that includes 'to' field. */
|
||||
|
||||
|
@ -596,7 +600,8 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
pfrom = from;
|
||||
|
||||
xtransid = octstr_format("%S-%s", to,transid);
|
||||
x = mms_sendtoemail(from, pto,
|
||||
lto = gwlist_create_ex(pto);
|
||||
x = mms_sendtoemail(from, lto,
|
||||
subject ? subject : settings->mms_email_subject,
|
||||
msgid, msg, dlr,
|
||||
error, proxy_sendmail_cmd ? octstr_get_cstr(proxy_sendmail_cmd) : sendmail_cmd,
|
||||
|
@ -613,6 +618,7 @@ static int mms_sendtoproxy(Octstr *from, Octstr *to,
|
|||
octstr_destroy(pto);
|
||||
if (pfrom != from)
|
||||
octstr_destroy(pfrom);
|
||||
gwlist_destroy(lto, NULL);
|
||||
return x;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue