Exemple #1
0
static int sendNotify(MmsEnvelope *e)
{
     Octstr *to;
     MmsMsg *msg, *smsg = NULL;
     MmsEnvelopeTo *xto = gwlist_get(e->to, 0);
     Octstr *err = NULL;
     time_t tnow = time(NULL);
     int j, k, len;
     Octstr *phonenum = NULL, *rcpt_ip = NULL, *msgId, *from, *fromproxy;
     int mtype, msize;
     int res = MMS_SEND_OK, dlr;
     time_t expiryt;
     char *prov_notify_event = NULL;
     char *rtype = NULL;

          
     if (e->lastaccess != 0) { /* This message has been fetched at least once, no more signals. */	  
	  e->sendt = e->expiryt + 3600*24*30*12;
	  info(0, "MM1: Message [ID: %s] fetched/touched at least once. Skipping",
	       e->xqfname);
	  return settings->qfs->mms_queue_update(e);
     }

     if (!xto) {
	  error(0, "mobilesender: Queue entry %s with no recipients!", 
		e->xqfname);
	  return 0;
     }

     msg = settings->qfs->mms_queue_getdata(e);
     to = octstr_duplicate(xto->rcpt);
     expiryt = e->expiryt;
     msgId = e->msgId ? octstr_duplicate(e->msgId) : NULL;
     from = octstr_duplicate(e->from);
     fromproxy = e->fromproxy ? octstr_duplicate(e->fromproxy) : NULL;
     msize = e->msize;
     dlr = e->dlr;

     if (e->expiryt != 0 &&  /* Handle message expiry. */
	 e->expiryt < tnow) {
	  err = octstr_format("MMSC error: Message expired while sending to %S!", to);
	  res = MMS_SEND_ERROR_FATAL;
	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     } else if (e->attempts >= settings->maxsendattempts) {
	  err = octstr_format("MMSC error: Failed to deliver to %S after %ld attempts!", 
			      to, e->attempts);
	  res = MMS_SEND_ERROR_FATAL;

	  prov_notify_event = "failedfetch";
	  rtype = "Expired";	  
	  goto done;
     }
     
     j = octstr_case_search(to, octstr_imm("/TYPE=PLMN"), 0);
     k = octstr_case_search(to, octstr_imm("/TYPE=IPv"), 0);
     len = octstr_len(to);
     
     if (j > 0 && j - 1 +  sizeof "/TYPE=PLMN" == len) { /* A proper number. */
	  phonenum = octstr_copy(to, 0, j);
#if 0
	  normalize_number(octstr_get_cstr(settings->unified_prefix), &phonenum);
#else
	  mms_normalize_phonenum(&phonenum, 
				 octstr_get_cstr(settings->unified_prefix), 
				 settings->strip_prefixes);	  
#endif
     }     else if (k > 0 && k + sizeof "/TYPE=IPv" == len) 
	  rcpt_ip = octstr_copy(to, 0, k);
     else {
	  /* We only handle phone numbers here. */
	  err = octstr_format("Unexpected recipient %s in MT queue!", octstr_get_cstr(to));	  
	  res = MMS_SEND_ERROR_FATAL;	  
	  goto done;
     }
     
     mtype = mms_messagetype(msg);     
     
     /* For phone, getting here means the message can be delivered. So: 
      * - Check whether the recipient is provisioned, if not, wait (script called will queue creation req)
      * - If the recipient can't take MMS, then send SMS.
      */
     
     /* We handle two types of requests: send and delivery/read notifications. 
      * other types of messages cannot possibly be in this queue!
      */
     
     if (mtype == MMS_MSGTYPE_SEND_REQ ||
	 mtype == MMS_MSGTYPE_RETRIEVE_CONF) {
	  Octstr *url, *transid;
	  
	  if (phonenum) {
	       int send_ind = mms_ind_send(settings->prov_getstatus, phonenum);
	       
	       if (send_ind < 0 && 
		   settings->notify_unprovisioned)
		    send_ind = 0;

	       if (send_ind < 0) { /* That is, recipient is not (yet) provisioned. */
		    res = MMS_SEND_ERROR_TRANSIENT;
		    err = octstr_format("%S is not provisioned for MMS reception, delivery deferred!", 
					phonenum);
		    
		    /* Do not increase delivery attempts counter. */
		    e->lasttry = tnow;		    
		    e->sendt = e->lasttry + settings->send_back_off * (1 + e->attempts);
		    
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; /* Queue entry gone. */	
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    		    
		    goto done;
	       } else if (send_ind == 0) { /*  provisioned but does not support */		    
		    Octstr *s = octstr_format(octstr_get_cstr(settings->mms_notify_txt),
					      from);
		    if (settings->notify_unprovisioned && s && octstr_len(s) > 0) { /* Only send if the string was set. */
			 List *pheaders;					    
			 Octstr *sto = octstr_duplicate(phonenum);
			 
			 octstr_url_encode(s);
			 octstr_url_encode(sto);
			 
			 url = octstr_format("%S&text=%S&to=%S",settings->sendsms_url,s, sto);
			 pheaders = http_create_empty_headers();
			 http_header_add(pheaders, "Connection", "close");
			 http_header_add(pheaders, "User-Agent", MM_NAME "/" VERSION);      
			 
			 http_start_request(httpcaller, HTTP_METHOD_GET, url, 
					    pheaders, NULL, 0, &edummy, NULL);			 			 
			 http_destroy_headers(pheaders);
			 octstr_destroy(url);
			 octstr_destroy(sto);		   		 
		    } else if (s)
			 octstr_destroy(s);	
		    res = MMS_SEND_OK;
		    err = octstr_imm("No MMS Ind support, sent SMS instead");
		    
		    xto->process = 0; /* No more processing. */
		    if (settings->qfs->mms_queue_update(e) == 1) 
			 e = NULL; 
		    else 	  
			 settings->qfs->mms_queue_free_env(e);		    
		    goto done;

	       }	       
	  }
	  
	  /* To get here means we can send Ind. */
	  url = mms_makefetchurl(e->xqfname, e->token, MMS_LOC_MQUEUE,
				 phonenum ? phonenum : to,
				 settings);
	  info(0, "Preparing to notify client to fetch message at URL: %s",
	       octstr_get_cstr(url));
	  transid = mms_maketransid(e->xqfname, settings->host_alias);	  
	  
	  smsg = mms_notification(msg, e->msize, url, transid, 
				  e->expiryt ? e->expiryt :
				  tnow + settings->default_msgexpiry,
				  settings->optimize_notification_size);
	  octstr_destroy(transid);
	  octstr_destroy(url);
     } else if (mtype == MMS_MSGTYPE_DELIVERY_IND ||
		mtype == MMS_MSGTYPE_READ_ORIG_IND) 
	  smsg = msg;
     else {
	  error(0, "Unexpected message type %s for %s found in MT queue!", 
		mms_message_type_to_cstr(mtype), octstr_get_cstr(to));
	  res = MMS_SEND_ERROR_FATAL;
	  goto done;
     }
     
     if (smsg)
	  start_push(phonenum ? phonenum : rcpt_ip, 
		     phonenum ? 1 : 0, 
		     e, smsg); /* Send the message. 
				* Don't touch 'e' after this point!
				* It may be freed by receive thread. 
				*/
     
     if (smsg != msg && smsg)
	  mms_destroy(smsg);
    
 done:
     if (err != NULL && 
	 res != MMS_SEND_ERROR_TRANSIENT) { /* If there was a report request and this is a legit error
					     *  queue it. 
					     */
	  
	  if (dlr) {	       
	       MmsMsg *m = mms_deliveryreport(msgId, to, tnow, 
					      rtype ? octstr_imm(rtype) : 
					      octstr_imm("Indeterminate"));
	       
	       List *l = gwlist_create();
	       Octstr *res;
	       gwlist_append(l, from);
	       
	       /* Add to queue, switch via proxy to be from proxy. */
	       res = settings->qfs->mms_queue_add(to ? to : settings->system_user, l,  err, 
						  NULL, fromproxy,  
						  tnow, tnow+settings->default_msgexpiry, m, NULL, 
						  NULL, NULL,
						  NULL, NULL,
						  NULL,
						  0,
						  octstr_get_cstr(settings->mm1_queuedir), 
						  "MM2",
						  settings->host_alias);
	       gwlist_destroy(l, NULL);
	       mms_destroy(m);
	       octstr_destroy(res);
	  }
	  
     }
     
     /* Write to log */
     info(0, "%s Mobile Queue MMS Send Notify: From=%s, to=%s, msgsize=%d, reason=%s", 
	  SEND_ERROR_STR(res),
	  octstr_get_cstr(from), octstr_get_cstr(to), msize,
	  err ? octstr_get_cstr(err) : "");
     
     
     if (res == MMS_SEND_ERROR_FATAL) {
	  xto->process = 0;  /* No more attempts to deliver, delete this. */	       
	  if (settings->qfs->mms_queue_update(e) == 1) 
	       e = NULL; /* Queue entry gone. */	
	  else 	  
	       settings->qfs->mms_queue_free_env(e);
     }    /* Else queue will be updated/freed elsewhere. */
     
     
     if (prov_notify_event)
	  notify_prov_server(octstr_get_cstr(settings->prov_notify), 
			     to ? octstr_get_cstr(to) : "unknown", 
			     prov_notify_event, 
			     rtype ? rtype : "",
			     e ? e->msgId : NULL, NULL, NULL);

     if (msg) mms_destroy(msg);       

     octstr_destroy(phonenum);
     
     octstr_destroy(rcpt_ip);
     octstr_destroy(to);
     octstr_destroy(msgId);
     octstr_destroy(fromproxy);
     octstr_destroy(from);
     octstr_destroy(err);

     return 1;
}
Exemple #2
0
static int mm7http_receive(MmsBoxHTTPClientInfo *h)
{
     MmsMsg *m = NULL;
     List *mh = NULL;
     int hstatus = HTTP_OK;
     List *rh = http_create_empty_headers();
     Octstr *reply_body = NULL;
     
     List *to = NULL;
     Octstr *hto = NULL, *subject = NULL,  *msgid = NULL;
     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, rr;
     int mtype;
     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, 
	   " --> 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");
	  
	  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");
	  
	  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?");
	  
	  goto done;
     }      


     to = octstr_split_words(hto);

     mtype = mms_messagetype(m);
     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) {
	  Octstr *value, *value2;
     case MMS_MSGTYPE_SEND_REQ:
     case MMS_MSGTYPE_RETRIEVE_CONF:
       
	  /* 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);
	  
	  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);
	  

	  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,
				  dlr_uri, rr_uri,
				  rqh,
				  dlr,
				  octstr_get_cstr(qdir),
				  "MM7/HTTP-IN",
				  NULL);
	  
	  if (qf) {
	       /* Log to access log */
	       mms_log("Received", hfrom, to, msize, msgid, NULL, h->m->id, "MMSBox", h->ua, NULL);
	       
	       hstatus = HTTP_OK;
	  } else 
	       hstatus = HTTP_INTERNAL_SERVER_ERROR;
	  break;
     case MMS_MSGTYPE_DELIVERY_IND:
	  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")); 
	  
	  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));		    

	  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;
	  }  else 
	       hstatus = HTTP_INTERNAL_SERVER_ERROR;
	  octstr_destroy(value);
	  octstr_destroy(value2);
	  break;
	  
     case MMS_MSGTYPE_READ_ORIG_IND:
	  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")); 

	  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));		    

	  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;
	  }  else 
	       hstatus = HTTP_INTERNAL_SERVER_ERROR;
	  octstr_destroy(value);
	  octstr_destroy(value2);
	  break;
     }
     
 done:
     
     http_header_add(rh, "X-Mbuni-Version", VERSION);
     
     http_send_reply(h->client, hstatus, rh, msgid ? msgid : (qf ? qf : octstr_imm("")));

     gwlist_destroy(to, (gwlist_item_destructor_t *)octstr_destroy);

     octstr_destroy(subject);

     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);      
     
     http_destroy_cgiargs(cgivars_ctypes);
     
     return http_status_class(hstatus) == HTTP_STATUS_SUCCESSFUL ? 0 : -1;
}