thanks Stipe ;) Valter
----- Original Message ----- From: "Stipe Tolj" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Wednesday, January 16, 2002 9:55 PM Subject: [PATCH] multi-cast support for sendsms > Hi all, > > today I have implemented the multi-cast support within > gw/smsbox.c:smsbox_req_handle(). > > This allows to pass a 'to' element containing a list of receiver > numbers seperated by a blank. The octstr gets split into a list and > further processing is done. > > Main problem is how to deal with a list of receivers where: > > a) some receivers may be allowed (white-list), some may be dis-allowed > (black-list) > b) how to report failed messages, even if there have been successfull > c) do we break the list iteration if a failed sending happen, or do we > (as it is now) go on with all receiver numbers and report at the end > which ones have failed. > > Attached is the corresponding patch for this change. I would like to > ask the core developers to have a look on this and test the > functionality before commiting to cvs. > > BTW, I did some testing on this and it worked for me. But maybe I > missed the obvious -- as this happens from time to time I would like > to have a couple of other pairs of eyes on this :) > > Again, I would appritiate a simple voting for commiting. > > > Stipe > > [EMAIL PROTECTED] > ------------------------------------------------------------------- > Wapme Systems AG > > Münsterstr. 248 > 40470 Düsseldorf > > Tel: +49-211-74845-0 > Fax: +49-211-74845-299 > > E-Mail: [EMAIL PROTECTED] > Internet: http://www.wapme-systems.de > ------------------------------------------------------------------- > wapme.net - wherever you are ---------------------------------------------------------------------------- ---- > =================================================================== > RCS file: RCS/smsbox.c,v > retrieving revision 1.1 > diff -u -r1.1 smsbox.c > --- smsbox.c 2002/01/16 21:47:22 1.1 > +++ smsbox.c 2002/01/16 21:47:30 > @@ -1001,8 +1001,18 @@ > int *status, int dlr_mask, Octstr *dlr_url, Octstr *account) > { > Msg *msg = NULL; > - Octstr *newfrom, *returnerror; > - int ret; > + Octstr *newfrom, *returnerror, *receiv; > + List *receiver, *failed_id, *allowed, *denied; > + int no_recv, ret, i; > + long del; > + > + /* > + * Multi-cast messages with several receivers in 'to' are handled > + * in a loop. We only change sms.time and sms.receiver within the > + * loop below, because everything else is identical for all receivers. > + */ > + receiver = octstr_split_words(to); > + no_recv = list_len(receiver); > > /* > * check if UDH length is legal, or otherwise discard the > @@ -1013,42 +1023,79 @@ > goto fielderror2; > } > > + /* > + * Check if there are any illegal characters in the 'to' scheme > + */ > if (strspn(octstr_get_cstr(to), sendsms_number_chars) < octstr_len(to)) { > info(0,"Illegal characters in 'to' string ('%s') vs '%s'", > octstr_get_cstr(to), sendsms_number_chars); > returnerror = octstr_create("Garbage 'to' field, rejected."); > goto fielderror2; > } > - if (urltrans_white_list(t) && > - numhash_find_number(urltrans_white_list(t), to) < 1) { > - info(0, "Number <%s> is not in white-list, message discarded", > - octstr_get_cstr(to)); > - returnerror = octstr_create("Number is not in white-list."); > - goto fielderror2; > - } > - if (urltrans_black_list(t) && > - numhash_find_number(urltrans_black_list(t), to) == 1) { > - info(0, "Number <%s> is in black-list, message discarded", > - octstr_get_cstr(to)); > - returnerror = octstr_create("Number is in black-list."); > - goto fielderror2; > + > + /* > + * Check for white and black lists, first for the URLTranlation > + * lists and then for the global lists. > + * > + * Set the 'allowed' and 'denied' lists accordingly to process at > + * least all allowed receiver messages. This is a constrain > + * walk through all disallowing rules within the lists. > + */ > + allowed = list_create(); > + denied = list_create(); > + > + for (i = 0; i < no_recv; i++) { > + receiv = list_get(receiver, i); > + > + /* > + * First of all fill the two lists systematicaly by the rules, > + * then we will revice the lists. > + */ > + if (urltrans_white_list(t) && > + numhash_find_number(urltrans_white_list(t), receiv) < 1) { > + info(0, "Number <%s> is not in white-list, message discarded", > + octstr_get_cstr(receiv)); > + list_append_unique(denied, receiv, octstr_item_match); > + } else { > + list_append_unique(allowed, receiv, octstr_item_match); > + } > + if (urltrans_black_list(t) && > + numhash_find_number(urltrans_black_list(t), receiv) == 1) { > + info(0, "Number <%s> is in black-list, message discarded", > + octstr_get_cstr(receiv)); > + list_append_unique(denied, receiv, octstr_item_match); > + } else { > + list_append_unique(allowed, receiv, octstr_item_match); > + } > + if (white_list && > + numhash_find_number(white_list, receiv) < 1) { > + info(0, "Number <%s> is not in global white-list, message discarded", > + octstr_get_cstr(receiv)); > + list_append_unique(denied, receiv, octstr_item_match); > + } else { > + list_append_unique(allowed, receiv, octstr_item_match); > + } > + if (black_list && > + numhash_find_number(black_list, receiv) == 1) { > + info(0, "Number <%s> is in global black-list, message discarded", > + octstr_get_cstr(receiv)); > + list_append_unique(denied, receiv, octstr_item_match); > + } else { > + list_append_unique(allowed, receiv, octstr_item_match); > + } > } > + > > - if (white_list && > - numhash_find_number(white_list, to) < 1) { > - info(0, "Number <%s> is not in global white-list, message discarded", > - octstr_get_cstr(to)); > - returnerror = octstr_create("Number is not in global white-list."); > - goto fielderror2; > - } > - if (black_list && > - numhash_find_number(black_list, to) == 1) { > - info(0, "Number <%s> is in global black-list, message discarded", > - octstr_get_cstr(to)); > - returnerror = octstr_create("Number is in global black-list."); > - goto fielderror2; > + /* > + * Now we have to revise the 'allowed' and 'denied' lists by walking > + * the 'denied' list and check if items are also present in 'allowed', > + * then we will discard them from 'allowed'. > + */ > + for (i = 0; i < list_len(denied); i++) { > + receiv = list_get(denied, i); > + del = list_delete_matching(allowed, receiv, octstr_item_match); > } > - > + > if (urltrans_faked_sender(t) != NULL) { > /* discard previous from */ > newfrom = octstr_duplicate(urltrans_faked_sender(t)); > @@ -1062,21 +1109,20 @@ > } > > info(0, "sendsms sender:<%s:%s> (%s) to:<%s> msg:<%s>", > - octstr_get_cstr(urltrans_username(t)), > - octstr_get_cstr(newfrom), > - octstr_get_cstr(client_ip), > - octstr_get_cstr(to), > - udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>"); > - > + octstr_get_cstr(urltrans_username(t)), > + octstr_get_cstr(newfrom), > + octstr_get_cstr(client_ip), > + octstr_get_cstr(to), > + udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>"); > + > /* > - * XXX here we should validate and split the 'to' field > - * to allow multi-cast. Waiting for octstr_split... > + * Create the msg structure and fill the types. Note that sms.receiver > + * and sms.time are set in the multi-cast support loop below. > */ > msg = msg_create(sms); > > msg->sms.service = octstr_duplicate(urltrans_name(t)); > msg->sms.sms_type = mt_push; > - msg->sms.receiver = octstr_duplicate(to); > msg->sms.sender = octstr_duplicate(newfrom); > msg->sms.account = account ? octstr_duplicate(account) : NULL; > msg->sms.msgdata = text ? octstr_duplicate(text) : octstr_create(""); > @@ -1150,22 +1196,62 @@ > goto fielderror; > } > > - msg->sms.time = time(NULL); > - ret = send_message(t, msg); > + /* > + * All checks are done, now add multi-cast request support by > + * looping through 'allowed'. This should work for any > + * number of receivers within 'to'. If the message fails append > + * it to 'failed_id'. > + */ > + failed_id = list_create(); > + > + while ((receiv = list_extract_first(allowed)) != NULL) { > + > + msg->sms.receiver = octstr_duplicate(receiv); > + msg->sms.time = time(NULL); > + ret = send_message(t, msg); > + > + if (ret == -1) { > + /* add the receiver to the failed list */ > + list_append(failed_id, receiv); > + } else { > + /* log the sending as successfull for this particular message */ > + alog("send-SMS request added - sender:%s:%s %s target:%s request: '%s'", > + octstr_get_cstr(urltrans_username(t)), > + octstr_get_cstr(newfrom), octstr_get_cstr(client_ip), > + octstr_get_cstr(receiv), > + udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>"); > + } > + } > msg_destroy(msg); > - > - if (ret == -1) > + list_destroy(receiver, NULL); > + list_destroy(allowed, NULL); > + > + /* have all receivers been denied by list rules?! */ > + if (no_recv == list_len(denied)) { > + returnerror = octstr_create("Number(s) has/have been denied by white- and/or black-lists."); > + goto fielderror2; > + } > + > + if (list_len(failed_id) > 0) > goto error; > > - alog("send-SMS request added - sender:%s:%s %s target:%s request: '%s'", > - octstr_get_cstr(urltrans_username(t)), > - octstr_get_cstr(newfrom), octstr_get_cstr(client_ip), > - octstr_get_cstr(to), > - udh == NULL ? ( text == NULL ? "" : octstr_get_cstr(text) ) : "<< UDH >>"); > - > + list_destroy(failed_id, NULL); > octstr_destroy(newfrom); > *status = HTTP_ACCEPTED; > - return octstr_create("Sent."); > + returnerror = octstr_create("Sent."); > + > + /* > + * Append all denied receivers to the returned body in case this is > + * a multi-cast send request > + */ > + if (list_len(denied) > 0) { > + octstr_format_append(returnerror, " Denied receivers are:"); > + while ((receiv = list_extract_first(denied)) != NULL) { > + octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv)); > + } > + } > + list_destroy(denied, NULL); > + return returnerror; > > > fielderror: > @@ -1174,7 +1260,7 @@ > > fielderror2: > alog("send-SMS request failed - %s", > - octstr_get_cstr(returnerror)); > + octstr_get_cstr(returnerror)); > > *status = HTTP_BAD_REQUEST; > return returnerror; > @@ -1183,7 +1269,23 @@ > error(0, "sendsms_request: failed"); > octstr_destroy(from); > *status = HTTP_INTERNAL_SERVER_ERROR; > - return octstr_create("Sending failed."); > + returnerror = octstr_create("Sending failed."); > + > + /* > + * Append all receivers to the returned body in case this is > + * a multi-cast send request > + */ > + if (no_recv > 1) { > + octstr_format_append(returnerror, " Failed receivers are:"); > + while ((receiv = list_extract_first(failed_id)) != NULL) { > + octstr_format_append(returnerror, " %s", octstr_get_cstr(receiv)); > + } > + } > + > + octstr_destroy(receiv); > + list_destroy(failed_id, NULL); > + list_destroy(denied, NULL); > + return returnerror; > } > > >