Kannel: Open Source WAP and SMS gateway  svn-r5335
bb_boxc.c File Reference
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include "gwlib/gwlib.h"
#include "msg.h"
#include "bearerbox.h"
#include "bb_smscconn_cb.h"

Go to the source code of this file.

Data Structures

struct  _boxc
 
struct  _addrpar
 

Macros

#define SMSBOX_MAX_PENDING   100
 
#define RELOAD_PANIC(...)
 

Typedefs

typedef struct _boxc Boxc
 
typedef struct _addrpar AddrPar
 

Functions

static void sms_to_smsboxes (void *arg)
 
static int send_msg (Boxc *boxconn, Msg *pmsg)
 
static void boxc_sent_push (Boxc *, Msg *)
 
static void boxc_sent_pop (Boxc *, Msg *, Msg **)
 
static void boxc_gwlist_destroy (List *list)
 
static Msgread_from_box (Boxc *boxconn)
 
static void deliver_sms_to_queue (Msg *msg, Boxc *conn)
 
static void boxc_receiver (void *arg)
 
static void boxc_sender (void *arg)
 
static Boxcboxc_create (int fd, Octstr *ip, int ssl)
 
static void boxc_destroy (Boxc *boxc)
 
static Boxcaccept_boxc (int fd, int ssl)
 
static void run_smsbox (void *arg)
 
static void run_wapbox (void *arg)
 
static void ap_destroy (AddrPar *addr)
 
static int cmp_route (void *ap, void *ms)
 
static int cmp_boxc (void *bc, void *ap)
 
static Boxcroute_msg (List *route_info, Msg *msg)
 
static void wdp_to_wapboxes (void *arg)
 
static void wait_for_connections (int fd, void(*function)(void *arg), List *waited, int ssl)
 
static void smsboxc_run (void *arg)
 
static void wapboxc_run (void *arg)
 
static void init_smsbox_routes (Cfg *cfg, int reload)
 
int smsbox_start (Cfg *cfg)
 
int smsbox_restart (Cfg *cfg)
 
int wapbox_start (Cfg *cfg)
 
Octstrboxc_status (int status_type)
 
int boxc_incoming_wdp_queue (void)
 
void boxc_cleanup (void)
 
int route_incoming_to_boxc (Msg *msg)
 

Variables

volatile sig_atomic_t bb_status
 
volatile sig_atomic_t restart
 
Listincoming_sms
 
Listoutgoing_sms
 
Listincoming_wdp
 
Listoutgoing_wdp
 
Listflow_threads
 
Listsuspended
 
long max_incoming_sms_qlength
 
static volatile sig_atomic_t smsbox_running
 
static volatile sig_atomic_t wapbox_running
 
static Listwapbox_list
 
static Listsmsbox_list
 
static RWLocksmsbox_list_rwlock
 
static Dictsmsbox_by_id
 
static Dictsmsbox_by_smsc
 
static Dictsmsbox_by_receiver
 
static Dictsmsbox_by_smsc_receiver
 
static Octstrsmsbox_by_default
 
static long smsbox_port
 
static int smsbox_port_ssl
 
static Octstrsmsbox_interface
 
static long wapbox_port
 
static int wapbox_port_ssl
 
static long smsbox_max_pending
 
static Octstrbox_allow_ip
 
static Octstrbox_deny_ip
 
static Counterboxid
 
static long sms_dequeue_thread
 

Macro Definition Documentation

◆ RELOAD_PANIC

#define RELOAD_PANIC (   ...)
Value:
if (reload) { error(__VA_ARGS__); continue; } \
else panic(__VA_ARGS__);
void error(int err, const char *fmt,...)
Definition: log.c:648
#define panic
Definition: log.h:87

Definition at line 1118 of file bb_boxc.c.

Referenced by init_smsbox_routes().

◆ SMSBOX_MAX_PENDING

#define SMSBOX_MAX_PENDING   100

Definition at line 83 of file bb_boxc.c.

Referenced by smsbox_start().

Typedef Documentation

◆ AddrPar

typedef struct _addrpar AddrPar

◆ Boxc

typedef struct _boxc Boxc

Function Documentation

◆ accept_boxc()

static Boxc* accept_boxc ( int  fd,
int  ssl 
)
static

Definition at line 621 of file bb_boxc.c.

References box_allow_ip, box_deny_ip, boxc_create(), _boxc::conn, host_ip(), info(), is_allowed_ip(), octstr_destroy(), octstr_get_cstr, and ssl.

Referenced by wait_for_connections().

622 {
623  Boxc *newconn;
624  Octstr *ip;
625 
626  int newfd;
627  struct sockaddr_in client_addr;
628  socklen_t client_addr_len;
629 
630  client_addr_len = sizeof(client_addr);
631 
632  newfd = accept(fd, (struct sockaddr *)&client_addr, &client_addr_len);
633  if (newfd < 0)
634  return NULL;
635 
636  ip = host_ip(client_addr);
637 
638  if (is_allowed_ip(box_allow_ip, box_deny_ip, ip) == 0) {
639  info(0, "Box connection tried from denied host <%s>, disconnected",
640  octstr_get_cstr(ip));
641  octstr_destroy(ip);
642  close(newfd);
643  return NULL;
644  }
645  newconn = boxc_create(newfd, ip, ssl);
646 
647  /*
648  * check if the SSL handshake was successfull, otherwise
649  * this is no valid box connection any more
650  */
651 #ifdef HAVE_LIBSSL
652  if (ssl && !conn_get_ssl(newconn->conn))
653  return NULL;
654 #endif
655 
656  info(0, "Client connected from <%s> %s", octstr_get_cstr(ip), ssl?"using SSL":"");
657 
658  /* XXX TODO: do the hand-shake, baby, yeah-yeah! */
659 
660  return newconn;
661 }
Connection * conn
Definition: bb_boxc.c:136
void info(int err, const char *fmt,...)
Definition: log.c:672
int ssl
static Octstr * box_deny_ip
Definition: bb_boxc.c:126
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
Definition: utils.c:815
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
Definition: bb_boxc.c:588
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Definition: octstr.c:118
Octstr * host_ip(struct sockaddr_in addr)
Definition: socket.c:615
int socklen_t
Definition: socket.h:73
static Octstr * box_allow_ip
Definition: bb_boxc.c:125

◆ ap_destroy()

static void ap_destroy ( AddrPar addr)
static

Definition at line 830 of file bb_boxc.c.

References _addrpar::address, and octstr_destroy().

Referenced by route_msg(), and wdp_to_wapboxes().

831 {
832  octstr_destroy(addr->address);
833  gw_free(addr);
834 }
Octstr * address
Definition: bb_boxc.c:825
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ boxc_cleanup()

void boxc_cleanup ( void  )

Definition at line 1527 of file bb_boxc.c.

References box_allow_ip, box_deny_ip, boxid, counter_destroy(), octstr_destroy(), and smsbox_interface.

Referenced by main().

1528 {
1531  box_allow_ip = NULL;
1532  box_deny_ip = NULL;
1534  boxid = NULL;
1536  smsbox_interface = NULL;
1537 }
void counter_destroy(Counter *counter)
Definition: counter.c:110
static Octstr * box_deny_ip
Definition: bb_boxc.c:126
static Octstr * smsbox_interface
Definition: bb_boxc.c:118
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Counter * boxid
Definition: bb_boxc.c:129
static Octstr * box_allow_ip
Definition: bb_boxc.c:125

◆ boxc_create()

static Boxc* boxc_create ( int  fd,
Octstr ip,
int  ssl 
)
static

Definition at line 588 of file bb_boxc.c.

References _boxc::alive, _boxc::boxc_id, boxid, _boxc::client_ip, _boxc::conn, conn_wrap_fd(), _boxc::connect_time, counter_increase(), _boxc::id, _boxc::is_wap, _boxc::load, _boxc::routable, and ssl.

Referenced by accept_boxc().

589 {
590  Boxc *boxc;
591 
592  boxc = gw_malloc(sizeof(Boxc));
593  boxc->is_wap = 0;
594  boxc->load = 0;
595  boxc->conn = conn_wrap_fd(fd, ssl);
596  boxc->id = counter_increase(boxid);
597  boxc->client_ip = ip;
598  boxc->alive = 1;
599  boxc->connect_time = time(NULL);
600  boxc->boxc_id = NULL;
601  boxc->routable = 0;
602  return boxc;
603 }
Connection * conn
Definition: bb_boxc.c:136
int ssl
Octstr * client_ip
Definition: opensmppbox.c:153
int load
Definition: opensmppbox.c:148
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
Octstr * boxc_id
Definition: opensmppbox.c:160
time_t connect_time
Definition: opensmppbox.c:151
static Counter * boxid
Definition: bb_boxc.c:129
long id
Definition: opensmppbox.c:147
int is_wap
Definition: opensmppbox.c:146
volatile int routable
Definition: opensmppbox.c:167
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ boxc_destroy()

static void boxc_destroy ( Boxc boxc)
static

Definition at line 605 of file bb_boxc.c.

References _boxc::boxc_id, _boxc::client_ip, _boxc::conn, conn_destroy(), and octstr_destroy().

Referenced by run_smsbox(), and run_wapbox().

606 {
607  if (boxc == NULL)
608  return;
609 
610  /* do nothing to the lists, as they are only references */
611 
612  if (boxc->conn)
613  conn_destroy(boxc->conn);
614  octstr_destroy(boxc->client_ip);
615  octstr_destroy(boxc->boxc_id);
616  gw_free(boxc);
617 }
Connection * conn
Definition: bb_boxc.c:136
Octstr * client_ip
Definition: opensmppbox.c:153
Octstr * boxc_id
Definition: opensmppbox.c:160
void conn_destroy(Connection *conn)
Definition: conn.c:627
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324

◆ boxc_gwlist_destroy()

static void boxc_gwlist_destroy ( List list)
static

Definition at line 1786 of file bb_boxc.c.

References gwlist_destroy().

Referenced by smsbox_start().

1787 {
1788  gwlist_destroy(list, NULL);
1789 }
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ boxc_incoming_wdp_queue()

int boxc_incoming_wdp_queue ( void  )

Definition at line 1510 of file bb_boxc.c.

References gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_unlock(), _boxc::incoming, and wapbox_list.

Referenced by bb_print_status().

1511 {
1512  int i, q = 0;
1513  Boxc *boxc;
1514 
1515  if (wapbox_list) {
1517  for(i=0; i < gwlist_len(wapbox_list); i++) {
1518  boxc = gwlist_get(wapbox_list, i);
1519  q += gwlist_len(boxc->incoming);
1520  }
1522  }
1523  return q;
1524 }
List * incoming
Definition: opensmppbox.c:154
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
void gwlist_unlock(List *list)
Definition: list.c:354
void gwlist_lock(List *list)
Definition: list.c:347
static List * wapbox_list
Definition: bb_boxc.c:105

◆ boxc_receiver()

static void boxc_receiver ( void *  arg)
static

Definition at line 302 of file bb_boxc.c.

References ack_failed_tmp, _boxc::alive, BB_DEAD, BB_SHUTDOWN, bb_status, _boxc::boxc_id, boxc_sent_pop(), _boxc::client_ip, cmd_identify, debug(), deliver_sms_to_queue(), dict_get(), dict_put_once(), gwlist_append(), gwlist_consume(), gwlist_create, gwlist_delete_equal(), gwlist_produce(), gwthread_wakeup(), _boxc::is_wap, _boxc::load, msg, msg_create, msg_destroy(), octstr_compare(), octstr_destroy(), octstr_get_cstr, _boxc::outgoing, read_from_box(), _boxc::retry, _boxc::routable, send_msg(), sms_dequeue_thread, smsbox_by_id, store_save, suspended, uuid_copy(), and warning().

Referenced by run_smsbox(), and run_wapbox().

303 {
304  Boxc *conn = arg;
305  Msg *msg, *mack;
306 
307  /* remove messages from socket until it is closed */
308  while (bb_status != BB_DEAD && conn->alive) {
309 
310  gwlist_consume(suspended); /* block here if suspended */
311 
312  msg = read_from_box(conn);
313 
314  if (msg == NULL) { /* garbage/connection lost */
315  conn->alive = 0;
316  break;
317  }
318 
319  /* we don't accept new messages in shutdown phase */
320  if ((bb_status == BB_SHUTDOWN || bb_status == BB_DEAD) && msg_type(msg) == sms) {
321  mack = msg_create(ack);
322  uuid_copy(mack->ack.id, msg->sms.id);
323  mack->ack.time = msg->sms.time;
324  mack->ack.nack = ack_failed_tmp;
325  msg_destroy(msg);
326  send_msg(conn, mack);
327  msg_destroy(mack);
328  continue;
329  }
330 
331  if (msg_type(msg) == sms && conn->is_wap == 0) {
332  debug("bb.boxc", 0, "boxc_receiver: sms received");
333 
334  /* deliver message to queue */
335  deliver_sms_to_queue(msg, conn);
336 
337  if (conn->routable == 0) {
338  conn->routable = 1;
339  /* wakeup the dequeue thread */
341  }
342  } else if (msg_type(msg) == wdp_datagram && conn->is_wap) {
343  debug("bb.boxc", 0, "boxc_receiver: got wdp from wapbox");
344 
345  /* XXX we should block these in SHUTDOWN phase too, but
346  we need ack/nack msgs implemented first. */
347  gwlist_produce(conn->outgoing, msg);
348 
349  } else if (msg_type(msg) == sms && conn->is_wap) {
350  debug("bb.boxc", 0, "boxc_receiver: got sms from wapbox");
351 
352  /* should be a WAP push message, so tried it the same way */
353  deliver_sms_to_queue(msg, conn);
354 
355  if (conn->routable == 0) {
356  conn->routable = 1;
357  /* wakeup the dequeue thread */
359  }
360  } else {
361  if (msg_type(msg) == heartbeat) {
362  if (msg->heartbeat.load != conn->load)
363  debug("bb.boxc", 0, "boxc_receiver: heartbeat with "
364  "load value %ld received", msg->heartbeat.load);
365  conn->load = msg->heartbeat.load;
366  }
367  else if (msg_type(msg) == ack) {
368  if (msg->ack.nack == ack_failed_tmp) {
369  Msg *orig;
370  boxc_sent_pop(conn, msg, &orig);
371  if (orig != NULL) /* retry this message */
372  gwlist_append(conn->retry, orig);
373  } else {
374  boxc_sent_pop(conn, msg, NULL);
375  store_save(msg);
376  }
377  debug("bb.boxc", 0, "boxc_receiver: got ack");
378  }
379  /* if this is an identification message from an smsbox instance */
380  else if (msg_type(msg) == admin && msg->admin.command == cmd_identify) {
381 
382  /*
383  * any smsbox sends this command even if boxc_id is NULL,
384  * but we will only consider real identified boxes
385  */
386  if (msg->admin.boxc_id != NULL) {
387 
388  /* Only interested if the connection is not named, or its a different name */
389  if (conn->boxc_id == NULL ||
390  octstr_compare(conn->boxc_id, msg->admin.boxc_id)) {
391  List *boxc_id_list = NULL;
392 
393  /*
394  * Different name, need to remove it from the old list.
395  *
396  * I Don't think this case should ever arise, but might as well
397  * be safe.
398  */
399  if (conn->boxc_id != NULL) {
400 
401  /* Get the list for this box id */
402  boxc_id_list = dict_get(smsbox_by_id, conn->boxc_id);
403 
404  /* Delete the connection from the list */
405  if (boxc_id_list != NULL) {
406  gwlist_delete_equal(boxc_id_list, conn);
407  }
408 
409  octstr_destroy(conn->boxc_id);
410  }
411 
412  /* Get the list for this box id */
413  boxc_id_list = dict_get(smsbox_by_id, msg->admin.boxc_id);
414 
415  /* No list yet, so create it */
416  if (boxc_id_list == NULL) {
417  boxc_id_list = gwlist_create();
418  if (!dict_put_once(smsbox_by_id, msg->admin.boxc_id, boxc_id_list))
419  /* list already added */
420  boxc_id_list = dict_get(smsbox_by_id, msg->admin.boxc_id);
421  }
422 
423  /* Add the connection into the list */
424  gwlist_append(boxc_id_list, conn);
425 
426  conn->boxc_id = msg->admin.boxc_id;
427  }
428  else {
429  octstr_destroy(msg->admin.boxc_id);
430  }
431 
432  msg->admin.boxc_id = NULL;
433 
434  debug("bb.boxc", 0, "boxc_receiver: got boxc_id <%s> from <%s>",
435  octstr_get_cstr(conn->boxc_id),
436  octstr_get_cstr(conn->client_ip));
437  }
438 
439  conn->routable = 1;
440  /* wakeup the dequeue thread */
442  }
443  else
444  warning(0, "boxc_receiver: unknown msg received from <%s>, "
445  "ignored", octstr_get_cstr(conn->client_ip));
446  msg_destroy(msg);
447  }
448  }
449 }
static Msg * read_from_box(Boxc *boxconn)
Definition: bb_boxc.c:166
void gwlist_append(List *list, void *item)
Definition: list.c:179
Octstr * client_ip
Definition: opensmppbox.c:153
void gwlist_produce(List *list, void *item)
Definition: list.c:411
List * outgoing
Definition: opensmppbox.c:156
msg_type
Definition: msg.h:73
static void boxc_sent_pop(Boxc *, Msg *, Msg **)
Definition: bb_boxc.c:504
int load
Definition: opensmppbox.c:148
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
List * retry
Definition: opensmppbox.c:155
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
static int send_msg(Boxc *boxconn, Msg *pmsg)
Definition: bb_boxc.c:456
Definition: msg.h:79
Octstr * boxc_id
Definition: opensmppbox.c:160
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
List * suspended
Definition: bearerbox.c:122
static void deliver_sms_to_queue(Msg *msg, Boxc *conn)
Definition: bb_boxc.c:214
static Dict * smsbox_by_id
Definition: bb_boxc.c:110
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
void uuid_copy(uuid_t dst, const uuid_t src)
Definition: gw_uuid.c:150
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
void gwthread_wakeup(long thread)
#define gwlist_create()
Definition: list.h:136
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
static long sms_dequeue_thread
Definition: bb_boxc.c:132
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
int is_wap
Definition: opensmppbox.c:146
volatile int routable
Definition: opensmppbox.c:167
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ boxc_sender()

static void boxc_sender ( void *  arg)
static

Definition at line 533 of file bb_boxc.c.

References _boxc::alive, BB_DEAD, bb_status, boxc_sent_pop(), boxc_sent_push(), _boxc::client_ip, cmd_restart, cmd_shutdown, _boxc::conn, conn_flush(), debug(), flow_threads, gwlist_add_producer(), gwlist_consume(), gwlist_produce(), gwlist_remove_producer(), _boxc::incoming, msg, msg_create, msg_destroy(), octstr_get_cstr, restart, _boxc::retry, _boxc::routable, send_msg(), and suspended.

Referenced by run_smsbox(), and run_wapbox().

534 {
535  Msg *msg;
536  Boxc *conn = arg;
537 
539 
540  while (bb_status != BB_DEAD && conn->alive) {
541 
542  /*
543  * Make sure there's no data left in the outgoing connection before
544  * doing the potentially blocking gwlist_consume()s
545  */
546  conn_flush(conn->conn);
547 
548  gwlist_consume(suspended); /* block here if suspended */
549 
550  if ((msg = gwlist_consume(conn->incoming)) == NULL) {
551  /* tell sms/wapbox to die */
552  msg = msg_create(admin);
553  msg->admin.command = restart ? cmd_restart : cmd_shutdown;
554  send_msg(conn, msg);
555  msg_destroy(msg);
556  break;
557  }
558  if (msg_type(msg) == heartbeat) {
559  debug("bb.boxc", 0, "boxc_sender: catch an heartbeat - we are alive");
560  msg_destroy(msg);
561  continue;
562  }
563  boxc_sent_push(conn, msg);
564  if (!conn->alive || send_msg(conn, msg) == -1) {
565  /* we got message here */
566  boxc_sent_pop(conn, msg, NULL);
567  gwlist_produce(conn->retry, msg);
568  break;
569  }
570  msg_destroy(msg);
571  debug("bb.boxc", 0, "boxc_sender: sent message to <%s>",
572  octstr_get_cstr(conn->client_ip));
573  }
574  /* the client closes the connection, after that die in receiver */
575  /* conn->alive = 0; */
576 
577  /* set conn to unroutable */
578  conn->routable = 0;
579 
581 }
Connection * conn
Definition: bb_boxc.c:136
List * incoming
Definition: opensmppbox.c:154
Octstr * client_ip
Definition: opensmppbox.c:153
void gwlist_produce(List *list, void *item)
Definition: list.c:411
volatile sig_atomic_t restart
Definition: bearerbox.c:149
msg_type
Definition: msg.h:73
static void boxc_sent_pop(Boxc *, Msg *, Msg **)
Definition: bb_boxc.c:504
#define msg_create(type)
Definition: msg.h:136
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
List * retry
Definition: opensmppbox.c:155
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
static int send_msg(Boxc *boxconn, Msg *pmsg)
Definition: bb_boxc.c:456
Definition: msg.h:79
List * suspended
Definition: bearerbox.c:122
void gwlist_remove_producer(List *list)
Definition: list.c:401
void msg_destroy(Msg *msg)
Definition: msg.c:132
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static void boxc_sent_push(Boxc *, Msg *)
Definition: bb_boxc.c:484
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
volatile int routable
Definition: opensmppbox.c:167
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int conn_flush(Connection *conn)
Definition: conn.c:995

◆ boxc_sent_pop()

static void boxc_sent_pop ( Boxc conn,
Msg m,
Msg **  orig 
)
static

Definition at line 504 of file bb_boxc.c.

References dict_remove(), error(), _boxc::is_wap, msg, msg_destroy(), msg_dump(), octstr_create, octstr_destroy(), _boxc::pending, semaphore_up(), _boxc::sent, UUID_STR_LEN, and uuid_unparse().

Referenced by boxc_receiver(), and boxc_sender().

505 {
506  Octstr *os;
507  char id[UUID_STR_LEN + 1];
508  Msg *msg;
509 
510  if (conn->is_wap || !conn->sent || !m || (msg_type(m) != ack && msg_type(m) != sms))
511  return;
512 
513  if (orig != NULL)
514  *orig = NULL;
515 
516  uuid_unparse((msg_type(m) == sms ? m->sms.id : m->ack.id), id);
517  os = octstr_create(id);
518  msg = dict_remove(conn->sent, os);
519  octstr_destroy(os);
520  if (!msg) {
521  error(0, "BOXC: Got ack for nonexistend message!");
522  msg_dump(m, 0);
523  return;
524  }
525  semaphore_up(conn->pending);
526  if (orig == NULL)
527  msg_destroy(msg);
528  else
529  *orig = msg;
530 }
void msg_dump(Msg *msg, int level)
Definition: msg.c:152
void error(int err, const char *fmt,...)
Definition: log.c:648
msg_type
Definition: msg.h:73
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
void msg_destroy(Msg *msg)
Definition: msg.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
#define UUID_STR_LEN
Definition: gw_uuid.h:19
void semaphore_up(Semaphore *semaphore)
Definition: gw-semaphore.c:118
Definition: octstr.c:118
int is_wap
Definition: opensmppbox.c:146
Dict * sent
Definition: opensmppbox.c:157
Semaphore * pending
Definition: opensmppbox.c:158
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ boxc_sent_push()

static void boxc_sent_push ( Boxc conn,
Msg m 
)
static

Definition at line 484 of file bb_boxc.c.

References dict_put(), _boxc::is_wap, msg_duplicate(), octstr_create, octstr_destroy(), _boxc::pending, semaphore_down(), _boxc::sent, UUID_STR_LEN, and uuid_unparse().

Referenced by boxc_sender().

485 {
486  Octstr *os;
487  char id[UUID_STR_LEN + 1];
488 
489  if (conn->is_wap || !conn->sent || !m || msg_type(m) != sms)
490  return;
491 
492  uuid_unparse(m->sms.id, id);
493  os = octstr_create(id);
494  dict_put(conn->sent, os, msg_duplicate(m));
495  semaphore_down(conn->pending);
496  octstr_destroy(os);
497 }
Msg * msg_duplicate(Msg *msg)
Definition: msg.c:111
void dict_put(Dict *dict, Octstr *key, void *value)
Definition: dict.c:240
msg_type
Definition: msg.h:73
void uuid_unparse(const uuid_t uu, char *out)
Definition: gw_uuid.c:562
void semaphore_down(Semaphore *semaphore)
Definition: gw-semaphore.c:132
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
#define UUID_STR_LEN
Definition: gw_uuid.h:19
Definition: octstr.c:118
int is_wap
Definition: opensmppbox.c:146
Dict * sent
Definition: opensmppbox.c:157
Semaphore * pending
Definition: opensmppbox.c:158

◆ boxc_status()

Octstr* boxc_status ( int  status_type)

Definition at line 1386 of file bb_boxc.c.

References _boxc::alive, bb_status_linebreak(), BBSTATUS_HTML, BBSTATUS_TEXT, BBSTATUS_WML, BBSTATUS_XML, _boxc::boxc_id, _boxc::client_ip, _boxc::conn, _boxc::connect_time, dict_key_count(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_unlock(), _boxc::incoming, octstr_append_cstr(), octstr_create, octstr_destroy(), octstr_format(), octstr_format_append(), octstr_get_cstr, _boxc::sent, smsbox_list, smsbox_list_rwlock, and wapbox_list.

Referenced by bb_print_status().

1387 {
1388  Octstr *tmp;
1389  char *lb, *ws;
1390  int i, boxes, para = 0;
1391  time_t orig, t;
1392  Boxc *bi;
1393 
1394  orig = time(NULL);
1395 
1396  /*
1397  * XXX: this will cause segmentation fault if this is called
1398  * between 'destroy_list and setting list to NULL calls.
1399  * Ok, this has to be fixed, but now I am too tired.
1400  */
1401 
1402  if ((lb = bb_status_linebreak(status_type))==NULL)
1403  return octstr_create("Un-supported format");
1404 
1405  if (status_type == BBSTATUS_HTML)
1406  ws = "&nbsp;&nbsp;&nbsp;&nbsp;";
1407  else if (status_type == BBSTATUS_TEXT)
1408  ws = " ";
1409  else
1410  ws = "";
1411 
1412  if (status_type == BBSTATUS_HTML || status_type == BBSTATUS_WML)
1413  para = 1;
1414 
1415  if (status_type == BBSTATUS_XML) {
1416  tmp = octstr_create ("");
1417  octstr_append_cstr(tmp, "<boxes>\n\t");
1418  }
1419  else
1420  tmp = octstr_format("%sBox connections:%s", para ? "<p>" : "", lb);
1421  boxes = 0;
1422 
1423  if (wapbox_list) {
1425  for(i=0; i < gwlist_len(wapbox_list); i++) {
1426  bi = gwlist_get(wapbox_list, i);
1427  if (bi->alive == 0)
1428  continue;
1429  t = orig - bi->connect_time;
1430  if (status_type == BBSTATUS_XML)
1432  "<box>\n\t\t<type>wapbox</type>\n\t\t<IP>%s</IP>\n"
1433  "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
1434  "\t\t<ssl>%s</ssl>\n\t</box>\n",
1436  t/3600/24, t/3600%24, t/60%60, t%60,
1437 #ifdef HAVE_LIBSSL
1438  conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
1439 #else
1440  "not installed"
1441 #endif
1442  );
1443  else
1445  "%swapbox, IP %s (on-line %ldd %ldh %ldm %lds) %s %s",
1446  ws, octstr_get_cstr(bi->client_ip),
1447  t/3600/24, t/3600%24, t/60%60, t%60,
1448 #ifdef HAVE_LIBSSL
1449  conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
1450 #else
1451  "",
1452 #endif
1453  lb);
1454  boxes++;
1455  }
1457  }
1458  if (smsbox_list) {
1460  for(i=0; i < gwlist_len(smsbox_list); i++) {
1461  bi = gwlist_get(smsbox_list, i);
1462  if (bi->alive == 0)
1463  continue;
1464  t = orig - bi->connect_time;
1465  if (status_type == BBSTATUS_XML)
1466  octstr_format_append(tmp, "<box>\n\t\t<type>smsbox</type>\n"
1467  "\t\t<id>%s</id>\n\t\t<IP>%s</IP>\n"
1468  "\t\t<queue>%ld</queue>\n"
1469  "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
1470  "\t\t<ssl>%s</ssl>\n\t</box>",
1471  (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : ""),
1473  gwlist_len(bi->incoming) + dict_key_count(bi->sent),
1474  t/3600/24, t/3600%24, t/60%60, t%60,
1475 #ifdef HAVE_LIBSSL
1476  conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
1477 #else
1478  "not installed"
1479 #endif
1480  );
1481  else
1482  octstr_format_append(tmp, "%ssmsbox:%s, IP %s (%ld queued), (on-line %ldd %ldh %ldm %lds) %s %s",
1483  ws, (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : "(none)"),
1485  t/3600/24, t/3600%24, t/60%60, t%60,
1486 #ifdef HAVE_LIBSSL
1487  conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
1488 #else
1489  "",
1490 #endif
1491  lb);
1492  boxes++;
1493  }
1495  }
1496  if (boxes == 0 && status_type != BBSTATUS_XML) {
1497  octstr_destroy(tmp);
1498  tmp = octstr_format("%sNo boxes connected", para ? "<p>" : "");
1499  }
1500  if (para)
1501  octstr_append_cstr(tmp, "</p>");
1502  if (status_type == BBSTATUS_XML)
1503  octstr_append_cstr(tmp, "</boxes>\n");
1504  else
1505  octstr_append_cstr(tmp, "\n\n");
1506  return tmp;
1507 }
Connection * conn
Definition: bb_boxc.c:136
List * incoming
Definition: opensmppbox.c:154
char * bb_status_linebreak(int status_type)
Definition: bearerbox.c:1109
Octstr * client_ip
Definition: opensmppbox.c:153
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
void octstr_append_cstr(Octstr *ostr, const char *cstr)
Definition: octstr.c:1511
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
void gwlist_unlock(List *list)
Definition: list.c:354
Octstr * boxc_id
Definition: opensmppbox.c:160
long dict_key_count(Dict *dict)
Definition: dict.c:335
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
time_t connect_time
Definition: opensmppbox.c:151
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
void gwlist_lock(List *list)
Definition: list.c:347
Definition: octstr.c:118
void octstr_format_append(Octstr *os, const char *fmt,...)
Definition: octstr.c:2507
static List * smsbox_list
Definition: bb_boxc.c:106
static List * wapbox_list
Definition: bb_boxc.c:105
Dict * sent
Definition: opensmppbox.c:157

◆ cmp_boxc()

static int cmp_boxc ( void *  bc,
void *  ap 
)
static

Definition at line 848 of file bb_boxc.c.

References _boxc::id, and _addrpar::wapboxid.

Referenced by route_msg().

849 {
850  Boxc *boxc = bc;
851  AddrPar *addr = ap;
852 
853  if (boxc->id == addr->wapboxid) return 1;
854  return 0;
855 }
long id
Definition: opensmppbox.c:147
int wapboxid
Definition: bb_boxc.c:827

◆ cmp_route()

static int cmp_route ( void *  ap,
void *  ms 
)
static

Definition at line 836 of file bb_boxc.c.

References _addrpar::address, msg, octstr_compare(), and _addrpar::port.

Referenced by route_msg().

837 {
838  AddrPar *addr = ap;
839  Msg *msg = ms;
840 
841  if (msg->wdp_datagram.source_port == addr->port &&
842  octstr_compare(msg->wdp_datagram.source_address, addr->address)==0)
843  return 1;
844 
845  return 0;
846 }
Octstr * address
Definition: bb_boxc.c:825
Definition: msg.h:79
int port
Definition: bb_boxc.c:826
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871

◆ deliver_sms_to_queue()

static void deliver_sms_to_queue ( Msg msg,
Boxc conn 
)
static

Definition at line 214 of file bb_boxc.c.

References ack_buffered, ack_failed, ack_failed_tmp, ack_success, gw_assert(), msg, msg_create, msg_destroy(), send_msg(), smsc2_rout(), SMSCCONN_FAILED_DISCARDED, SMSCCONN_FAILED_EXPIRED, SMSCCONN_FAILED_QFULL, SMSCCONN_FAILED_REJECTED, SMSCCONN_QUEUED, SMSCCONN_SUCCESS, store_save, store_save_ack, uuid_copy(), and warning().

Referenced by boxc_receiver().

215 {
216  Msg *mack;
217  int rc;
218 
219  /*
220  * save modifies ID and time, so if the smsbox uses it, save
221  * it FIRST for the reply message!!!
222  */
223  mack = msg_create(ack);
224  gw_assert(mack != NULL);
225  uuid_copy(mack->ack.id, msg->sms.id);
226  mack->ack.time = msg->sms.time;
227 
228  store_save(msg);
229 
230  rc = smsc2_rout(msg, 0);
231  switch (rc) {
232 
233  case SMSCCONN_SUCCESS:
234  mack->ack.nack = ack_success;
235  break;
236 
237  case SMSCCONN_QUEUED:
238  mack->ack.nack = ack_buffered;
239  break;
240 
241  case SMSCCONN_FAILED_DISCARDED: /* no router at all */
242  warning(0, "Message rejected by bearerbox, no router!");
243 
244  /*
245  * we don't store_save_ack() here, since the call to
246  * bb_smscconn_send_failed() within smsc2_route() did
247  * it already.
248  */
249  mack->ack.nack = ack_failed;
250 
251  /* destroy original message */
252  msg_destroy(msg);
253  break;
254 
255  case SMSCCONN_FAILED_QFULL: /* queue full */
256  warning(0, "Message rejected by bearerbox, %s!",
257  (rc == SMSCCONN_FAILED_DISCARDED) ? "no router" : "queue full");
258  /*
259  * first create nack for store-file, in order to delete
260  * message from store-file.
261  */
262  mack->ack.nack = ack_failed_tmp;
264 
265  /* destroy original message */
266  msg_destroy(msg);
267  break;
268 
269  case SMSCCONN_FAILED_EXPIRED: /* validity expired */
270  warning(0, "Message rejected by bearerbox, validity expired!");
271 
272  /*
273  * we don't store_save_ack() here, since the call to
274  * bb_smscconn_send_failed() within smsc2_route() did
275  * it already.
276  */
277  mack->ack.nack = ack_failed;
278 
279  /* destroy original message */
280  msg_destroy(msg);
281  break;
282 
283  case SMSCCONN_FAILED_REJECTED: /* white/black-list rejection */
284  warning(0, "Message rejected by bearerbox, white/black listed!");
285 
286  mack->ack.nack = ack_failed;
287 
288  /* destroy original message */
289  msg_destroy(msg);
290  break;
291 
292  default:
293  break;
294  }
295 
296  /* put ack into incoming queue of conn */
297  send_msg(conn, mack);
298  msg_destroy(mack);
299 }
gw_assert(wtls_machine->packet_to_send !=NULL)
int(* store_save_ack)(Msg *msg, ack_status_t status)
Definition: bb_store.c:73
#define msg_create(type)
Definition: msg.h:136
static int send_msg(Boxc *boxconn, Msg *pmsg)
Definition: bb_boxc.c:456
Definition: msg.h:79
void uuid_copy(uuid_t dst, const uuid_t src)
Definition: gw_uuid.c:150
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
int(* store_save)(Msg *msg)
Definition: bb_store.c:72
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
long smsc2_rout(Msg *msg, int resend)
Definition: bb_smscconn.c:1716

◆ init_smsbox_routes()

static void init_smsbox_routes ( Cfg cfg,
int  reload 
)
static

Definition at line 1125 of file bb_boxc.c.

References cfg, cfg_get, cfg_get_multi_group(), debug(), dict_put_once(), grp_dump(), gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), octstr_destroy(), octstr_destroy_item(), octstr_duplicate, octstr_get_cstr, octstr_imm(), octstr_insert(), octstr_insert_char(), octstr_len(), octstr_split(), octstr_strip_blanks(), RELOAD_PANIC, smsbox_by_default, smsbox_by_receiver, smsbox_by_smsc, and smsbox_by_smsc_receiver.

Referenced by smsbox_restart(), and smsbox_start().

1126 {
1127  CfgGroup *grp;
1128  List *list, *items;
1129  Octstr *boxc_id, *smsc_ids, *shortcuts;
1130  int i, j;
1131 
1132  boxc_id = smsc_ids = shortcuts = NULL;
1133 
1134  list = cfg_get_multi_group(cfg, octstr_imm("smsbox-route"));
1135 
1136  /* loop multi-group "smsbox-route" */
1137  while (list && (grp = gwlist_extract_first(list)) != NULL) {
1138 
1139  if ((boxc_id = cfg_get(grp, octstr_imm("smsbox-id"))) == NULL) {
1140  grp_dump(grp);
1141  RELOAD_PANIC(0,"'smsbox-route' group without valid 'smsbox-id' directive!");
1142  }
1143 
1144  /*
1145  * If smsc-id is given, then any message comming from the specified
1146  * smsc-id in the list will be routed to this smsbox instance.
1147  * If shortcode is given, then any message with receiver number
1148  * matching those will be routed to this smsbox instance.
1149  * If both are given, then only receiver within shortcode originating
1150  * from smsc-id list will be routed to this smsbox instance. So if both
1151  * are present then this is a logical AND operation.
1152  */
1153  smsc_ids = cfg_get(grp, octstr_imm("smsc-id"));
1154  shortcuts = cfg_get(grp, octstr_imm("shortcode"));
1155 
1156  /* consider now the 3 possibilities: */
1157  if (smsc_ids && !shortcuts) {
1158  /* smsc-id only, so all MO traffic */
1159  items = octstr_split(smsc_ids, octstr_imm(";"));
1160  for (i = 0; i < gwlist_len(items); i++) {
1161  Octstr *item = gwlist_get(items, i);
1162  octstr_strip_blanks(item);
1163 
1164  debug("bb.boxc",0,"Adding smsbox routing to id <%s> for smsc id <%s>",
1165  octstr_get_cstr(boxc_id), octstr_get_cstr(item));
1166 
1167  if (!dict_put_once(smsbox_by_smsc, item, octstr_duplicate(boxc_id))) {
1168  RELOAD_PANIC(0, "Routing for smsc-id <%s> already exists!",
1169  octstr_get_cstr(item));
1170  }
1171  }
1173  octstr_destroy(smsc_ids);
1174  }
1175  else if (!smsc_ids && shortcuts) {
1176  /* shortcode only, so these MOs from all smscs */
1177  items = octstr_split(shortcuts, octstr_imm(";"));
1178  for (i = 0; i < gwlist_len(items); i++) {
1179  Octstr *item = gwlist_get(items, i);
1180  octstr_strip_blanks(item);
1181 
1182  debug("bb.boxc",0,"Adding smsbox routing to id <%s> for receiver no <%s>",
1183  octstr_get_cstr(boxc_id), octstr_get_cstr(item));
1184 
1185  if (!dict_put_once(smsbox_by_receiver, item, octstr_duplicate(boxc_id))) {
1186  RELOAD_PANIC(0, "Routing for receiver no <%s> already exists!",
1187  octstr_get_cstr(item));
1188  }
1189  }
1191  octstr_destroy(shortcuts);
1192  }
1193  else if (smsc_ids && shortcuts) {
1194  /* both, so only specified MOs from specified smscs */
1195  items = octstr_split(shortcuts, octstr_imm(";"));
1196  for (i = 0; i < gwlist_len(items); i++) {
1197  List *subitems;
1198  Octstr *item = gwlist_get(items, i);
1199  octstr_strip_blanks(item);
1200  subitems = octstr_split(smsc_ids, octstr_imm(";"));
1201  for (j = 0; j < gwlist_len(subitems); j++) {
1202  Octstr *subitem = gwlist_get(subitems, j);
1203  octstr_strip_blanks(subitem);
1204 
1205  debug("bb.boxc",0,"Adding smsbox routing to id <%s> "
1206  "for receiver no <%s> and smsc id <%s>",
1207  octstr_get_cstr(boxc_id), octstr_get_cstr(item),
1208  octstr_get_cstr(subitem));
1209 
1210  /* construct the dict key '<shortcode>:<smsc-id>' */
1211  octstr_insert(subitem, item, 0);
1212  octstr_insert_char(subitem, octstr_len(item), ':');
1213  if (!dict_put_once(smsbox_by_smsc_receiver, subitem, octstr_duplicate(boxc_id))) {
1214  RELOAD_PANIC(0, "Routing for receiver:smsc <%s> already exists!",
1215  octstr_get_cstr(subitem));
1216  }
1217  }
1219  }
1221  octstr_destroy(shortcuts);
1222  octstr_destroy(smsc_ids);
1223  }
1224  else { /* !smscids && !shortcuts */
1225  if (!smsbox_by_default) {
1226  debug("bb.boxc",0,"Adding smsbox default routing to id <%s>",
1227  octstr_get_cstr(boxc_id));
1229  } else {
1230  RELOAD_PANIC(0, "Default smsbox routing to id <%s> already exists!",
1232  }
1233  }
1234 
1235  octstr_destroy(boxc_id);
1236  }
1237 
1238  gwlist_destroy(list, NULL);
1239 }
static Dict * smsbox_by_smsc
Definition: bb_boxc.c:111
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
#define cfg_get(grp, varname)
Definition: cfg.h:86
static Cfg * cfg
Definition: opensmppbox.c:95
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * smsbox_by_default
Definition: bb_boxc.c:114
static Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
#define RELOAD_PANIC(...)
Definition: bb_boxc.c:1118
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
Definition: octstr.c:1303
void * gwlist_extract_first(List *list)
Definition: list.c:305
void grp_dump(CfgGroup *grp)
Definition: cfg.c:811
void octstr_insert_char(Octstr *ostr, long pos, const char c)
Definition: octstr.c:1481
#define octstr_duplicate(ostr)
Definition: octstr.h:187
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void octstr_destroy_item(void *os)
Definition: octstr.c:336
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Definition: cfg.c:73
int dict_put_once(Dict *dict, Octstr *key, void *value)
Definition: dict.c:271
List * octstr_split(const Octstr *os, const Octstr *sep)
Definition: octstr.c:1640
Definition: list.c:102
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ read_from_box()

static Msg* read_from_box ( Boxc boxconn)
static

Definition at line 166 of file bb_boxc.c.

References _boxc::alive, BB_DEAD, bb_status, _boxc::client_ip, _boxc::conn, conn_eof(), conn_error(), conn_read_withlen(), conn_wait(), error(), info(), msg, msg_unpack, octstr_destroy(), and octstr_get_cstr.

Referenced by boxc_receiver().

167 {
168  int ret;
169  Octstr *pack;
170  Msg *msg;
171 
172  pack = NULL;
173  while (bb_status != BB_DEAD && boxconn->alive) {
174  /* XXX: if box doesn't send (just keep conn open) we block here while shutdown */
175  pack = conn_read_withlen(boxconn->conn);
176  gw_claim_area(pack);
177  if (pack != NULL)
178  break;
179  if (conn_error(boxconn->conn)) {
180  info(0, "Read error when reading from box <%s>, disconnecting",
181  octstr_get_cstr(boxconn->client_ip));
182  return NULL;
183  }
184  if (conn_eof(boxconn->conn)) {
185  info(0, "Connection closed by the box <%s>",
186  octstr_get_cstr(boxconn->client_ip));
187  return NULL;
188  }
189 
190  ret = conn_wait(boxconn->conn, -1.0);
191  if (ret < 0) {
192  error(0, "Connection to box <%s> broke.",
193  octstr_get_cstr(boxconn->client_ip));
194  return NULL;
195  }
196  }
197 
198  if (pack == NULL)
199  return NULL;
200 
201  msg = msg_unpack(pack);
202  octstr_destroy(pack);
203 
204  if (msg == NULL)
205  error(0, "Failed to unpack data!");
206  return msg;
207 }
Connection * conn
Definition: bb_boxc.c:136
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
#define msg_unpack(os)
Definition: msg.h:183
Octstr * client_ip
Definition: opensmppbox.c:153
int conn_eof(Connection *conn)
Definition: conn.c:705
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
Definition: msg.h:79
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
Octstr * conn_read_withlen(Connection *conn)
Definition: conn.c:1169
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:904
int conn_error(Connection *conn)
Definition: conn.c:716
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ route_incoming_to_boxc()

int route_incoming_to_boxc ( Msg msg)

Definition at line 1549 of file bb_boxc.c.

References _boxc::boxc_id, dict_get(), gw_assert(), gw_rand(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_get(), gwlist_len(), gwlist_produce(), _boxc::incoming, incoming_sms, _boxc::load, max_incoming_sms_qlength, msg, octstr_destroy(), octstr_format(), octstr_get_cstr, octstr_len(), _boxc::routable, smsbox_by_default, smsbox_by_id, smsbox_by_receiver, smsbox_by_smsc, smsbox_by_smsc_receiver, smsbox_list, smsbox_list_rwlock, and warning().

Referenced by bb_smscconn_receive_internal(), and sms_to_smsboxes().

1550 {
1551  Boxc *bc = NULL;
1552  Octstr *s, *r, *rs, *boxc_id = NULL;
1553  long len, b, i;
1554  int full_found = 0;
1555 
1556  gw_assert(msg_type(msg) == sms);
1557 
1558  /* msg_dump(msg, 0); */
1559 
1560  /* Check we have at least one smsbox connected! */
1562  if (gwlist_len(smsbox_list) == 0) {
1564  warning(0, "smsbox_list empty!");
1565  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1567  return 0;
1568  } else {
1569  return -1;
1570  }
1571  }
1572 
1573  /*
1574  * Do we have a specific smsbox-id route to pass this msg to?
1575  */
1576  if (octstr_len(msg->sms.boxc_id) > 0) {
1577  boxc_id = msg->sms.boxc_id;
1578  } else {
1579  /*
1580  * Check if we have a "smsbox-route" for this msg.
1581  * Where the shortcode route has a higher priority then the smsc-id rule.
1582  * Highest priority has the combined <shortcode>:<smsc-id> route.
1583  */
1584  Octstr *os = octstr_format("%s:%s",
1585  octstr_get_cstr(msg->sms.receiver),
1586  octstr_get_cstr(msg->sms.smsc_id));
1587  s = (msg->sms.smsc_id ? dict_get(smsbox_by_smsc, msg->sms.smsc_id) : NULL);
1588  r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, msg->sms.receiver) : NULL);
1589  rs = (os ? dict_get(smsbox_by_smsc_receiver, os) : NULL);
1590  octstr_destroy(os);
1591 
1592  if (rs)
1593  boxc_id = rs;
1594  else if (r)
1595  boxc_id = r;
1596  else if (s)
1597  boxc_id = s;
1598  else if (smsbox_by_default)
1599  boxc_id = smsbox_by_default;
1600  }
1601 
1602  /* We have a specific smsbox-id to use */
1603  if (boxc_id != NULL) {
1604 
1605  List *boxc_id_list = dict_get(smsbox_by_id, boxc_id);
1606  if (gwlist_len(boxc_id_list) == 0) {
1607  /*
1608  * something is wrong, this was the smsbox connection we used
1609  * for sending, so it seems this smsbox is gone
1610  */
1611  warning(0, "Could not route message to smsbox id <%s>, smsbox is gone!",
1612  octstr_get_cstr(boxc_id));
1614  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1616  return 0;
1617  } else {
1618  return -1;
1619  }
1620  }
1621 
1622  /*
1623  * Take random smsbox from list, as long as it has space we will use it,
1624  * otherwise check the next one.
1625  */
1626  len = gwlist_len(boxc_id_list);
1627  b = gw_rand() % len;
1628 
1629  for (i = 0; i < len; i++) {
1630  bc = gwlist_get(boxc_id_list, (i+b) % len);
1631 
1632  if (bc != NULL && max_incoming_sms_qlength > 0 &&
1634  bc = NULL;
1635  }
1636 
1637  if (bc != NULL) {
1638  break;
1639  }
1640  }
1641 
1642  if (bc != NULL) {
1643  bc->load++;
1644  gwlist_produce(bc->incoming, msg);
1646  return 1; /* we are done */
1647  }
1648  else {
1649  /*
1650  * we have routing defined, but no smsbox connected at the moment.
1651  * put msg into global incoming queue and wait until smsbox with
1652  * such boxc_id connected.
1653  */
1655  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1657  return 0;
1658  } else {
1659  return -1;
1660  }
1661  }
1662  }
1663 
1664  /*
1665  * Ok, none of the specific routing things applied previously,
1666  * so route it to a random smsbox.
1667  * Take random smsbox from list, as long as it has space we will
1668  * use it, therwise check the next one.
1669  */
1670  len = gwlist_len(smsbox_list);
1671  b = gw_rand() % len;
1672 
1673  for (i = 0; i < len; i++) {
1674  bc = gwlist_get(smsbox_list, (i+b) % len);
1675 
1676  if (bc->boxc_id != NULL || bc->routable == 0)
1677  bc = NULL;
1678 
1679  if (bc != NULL && max_incoming_sms_qlength > 0 &&
1681  full_found = 1;
1682  bc = NULL;
1683  }
1684 
1685  if (bc != NULL) {
1686  break;
1687  }
1688  }
1689 
1690  if (bc != NULL) {
1691  bc->load++;
1692  gwlist_produce(bc->incoming, msg);
1693  }
1694 
1696 
1697  if (bc == NULL && full_found == 0) {
1698  warning(0, "smsbox_list empty!");
1699  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1701  return 0;
1702  } else {
1703  return -1;
1704  }
1705  } else if (bc == NULL && full_found == 1) {
1706  return -1;
1707  }
1708 
1709  return 1;
1710 }
List * incoming
Definition: opensmppbox.c:154
gw_assert(wtls_machine->packet_to_send !=NULL)
static Dict * smsbox_by_smsc
Definition: bb_boxc.c:111
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
msg_type
Definition: msg.h:73
int load
Definition: opensmppbox.c:148
List * incoming_sms
Definition: bearerbox.c:84
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * smsbox_by_default
Definition: bb_boxc.c:114
static Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
long max_incoming_sms_qlength
Definition: bearerbox.c:98
Octstr * boxc_id
Definition: opensmppbox.c:160
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
static Dict * smsbox_by_id
Definition: bb_boxc.c:110
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void warning(int err, const char *fmt,...)
Definition: log.c:660
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static List * smsbox_list
Definition: bb_boxc.c:106
volatile int routable
Definition: opensmppbox.c:167
int gw_rand(void)
Definition: protected.c:174
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ route_msg()

static Boxc* route_msg ( List route_info,
Msg msg 
)
static

Definition at line 857 of file bb_boxc.c.

References _addrpar::address, ap_destroy(), cmp_boxc(), cmp_route(), debug(), gw_rand(), gwlist_delete_equal(), gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_produce(), gwlist_search(), gwlist_unlock(), _boxc::id, _boxc::load, msg, octstr_duplicate, _addrpar::port, wapbox_list, _addrpar::wapboxid, and warning().

Referenced by wdp_to_wapboxes().

858 {
859  AddrPar *ap;
860  Boxc *conn, *best;
861  int i, b, len;
862 
863  ap = gwlist_search(route_info, msg, cmp_route);
864  if (ap == NULL) {
865  debug("bb.boxc", 0, "Did not find previous routing info for WDP, "
866  "generating new");
867 route:
868 
869  if (gwlist_len(wapbox_list) == 0)
870  return NULL;
871 
873 
874  /* take random wapbox from list, and then check all wapboxes
875  * and select the one with lowest load level - if tied, the first
876  * one
877  */
878  len = gwlist_len(wapbox_list);
879  b = gw_rand() % len;
880  best = gwlist_get(wapbox_list, b);
881 
882  for(i = 0; i < gwlist_len(wapbox_list); i++) {
883  conn = gwlist_get(wapbox_list, (i+b) % len);
884  if (conn != NULL && best != NULL)
885  if (conn->load < best->load)
886  best = conn;
887  }
888  if (best == NULL) {
889  warning(0, "wapbox_list empty!");
891  return NULL;
892  }
893  conn = best;
894  conn->load++; /* simulate new client until we get new values */
895 
896  ap = gw_malloc(sizeof(AddrPar));
897  ap->address = octstr_duplicate(msg->wdp_datagram.source_address);
898  ap->port = msg->wdp_datagram.source_port;
899  ap->wapboxid = conn->id;
900  gwlist_produce(route_info, ap);
901 
903  } else
904  conn = gwlist_search(wapbox_list, ap, cmp_boxc);
905 
906  if (conn == NULL) {
907  /* routing failed; wapbox has disappeared!
908  * ..remove routing info and re-route */
909 
910  debug("bb.boxc", 0, "Old wapbox has disappeared, re-routing");
911 
912  gwlist_delete_equal(route_info, ap);
913  ap_destroy(ap);
914  goto route;
915  }
916  return conn;
917 }
Octstr * address
Definition: bb_boxc.c:825
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
Definition: list.c:486
void gwlist_produce(List *list, void *item)
Definition: list.c:411
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
static int cmp_boxc(void *bc, void *ap)
Definition: bb_boxc.c:848
int load
Definition: opensmppbox.c:148
void gwlist_unlock(List *list)
Definition: list.c:354
static void ap_destroy(AddrPar *addr)
Definition: bb_boxc.c:830
int port
Definition: bb_boxc.c:826
#define octstr_duplicate(ostr)
Definition: octstr.h:187
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
void warning(int err, const char *fmt,...)
Definition: log.c:660
void gwlist_lock(List *list)
Definition: list.c:347
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
static List * wapbox_list
Definition: bb_boxc.c:105
long id
Definition: opensmppbox.c:147
int wapboxid
Definition: bb_boxc.c:827
int gw_rand(void)
Definition: protected.c:174
static int cmp_route(void *ap, void *ms)
Definition: bb_boxc.c:836
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ run_smsbox()

static void run_smsbox ( void *  arg)
static

Definition at line 665 of file bb_boxc.c.

References boxc_destroy(), _boxc::boxc_id, boxc_receiver(), boxc_sender(), _boxc::client_ip, dict_create(), dict_destroy(), dict_get(), dict_key_count(), dict_keys(), dict_remove(), error(), flow_threads, gw_assert(), gw_rwlock_unlock(), gw_rwlock_wrlock(), gwlist_add_producer(), gwlist_append(), gwlist_create, gwlist_delete_equal(), gwlist_destroy(), gwlist_extract_first(), gwlist_len(), gwlist_produce(), gwlist_producer_count(), gwlist_remove_producer(), gwthread_create, gwthread_join(), gwthread_wakeup(), _boxc::incoming, incoming_sms, msg, octstr_destroy(), octstr_destroy_item(), octstr_get_cstr, _boxc::outgoing, outgoing_sms, _boxc::pending, _boxc::retry, semaphore_create(), semaphore_destroy(), semaphore_up(), _boxc::sent, sms_dequeue_thread, smsbox_by_id, smsbox_list, smsbox_list_rwlock, and smsbox_max_pending.

Referenced by smsboxc_run().

666 {
667  Boxc *newconn;
668  long sender;
669  Msg *msg;
670  List *keys;
671  Octstr *key;
672 
674  newconn = arg;
675  newconn->incoming = gwlist_create();
676  gwlist_add_producer(newconn->incoming);
677  newconn->retry = incoming_sms;
678  newconn->outgoing = outgoing_sms;
679  newconn->sent = dict_create(smsbox_max_pending, NULL);
681 
682  sender = gwthread_create(boxc_sender, newconn);
683  if (sender == -1) {
684  error(0, "Failed to start a new thread, disconnecting client <%s>",
685  octstr_get_cstr(newconn->client_ip));
686  goto cleanup;
687  }
688  /*
689  * We register newconn in the smsbox_list here but mark newconn as routable
690  * after identification or first message received from smsbox. So we can avoid
691  * a race condition for routable smsboxes (otherwise between startup and
692  * registration we will forward some messages to smsbox).
693  */
695  gwlist_append(smsbox_list, newconn);
697 
698  gwlist_add_producer(newconn->outgoing);
699  boxc_receiver(newconn);
701 
702  /* remove us from smsbox routing list */
705  if (newconn->boxc_id) {
706 
707  /* Get the list, and remove the connection from it */
708  List *boxc_id_list = dict_get(smsbox_by_id, newconn->boxc_id);
709 
710  if(boxc_id_list != NULL) {
711  gwlist_delete_equal(boxc_id_list, newconn);
712  }
713  }
714 
716 
717  /*
718  * check if we in the shutdown phase and sms dequeueing thread
719  * has removed the producer already
720  */
721  if (gwlist_producer_count(newconn->incoming) > 0)
723 
724  /* check if we are still waiting for ack's and semaphore locked */
725  if (dict_key_count(newconn->sent) >= smsbox_max_pending)
726  semaphore_up(newconn->pending); /* allow sender to go down */
727 
728  gwthread_join(sender);
729 
730  /* put not acked msgs into incoming queue */
731  keys = dict_keys(newconn->sent);
732  while((key = gwlist_extract_first(keys)) != NULL) {
733  msg = dict_remove(newconn->sent, key);
735  octstr_destroy(key);
736  }
737  gw_assert(gwlist_len(keys) == 0);
739 
740  /* clear our send queue */
741  while((msg = gwlist_extract_first(newconn->incoming)) != NULL) {
743  }
744 
745 cleanup:
746  gw_assert(gwlist_len(newconn->incoming) == 0);
747  gwlist_destroy(newconn->incoming, NULL);
748  gw_assert(dict_key_count(newconn->sent) == 0);
749  dict_destroy(newconn->sent);
750  semaphore_destroy(newconn->pending);
751  boxc_destroy(newconn);
752 
753  /* wakeup the dequeueing thread */
755 
757 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
void error(int err, const char *fmt,...)
Definition: log.c:648
List * incoming
Definition: opensmppbox.c:154
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
Definition: list.c:179
static void boxc_destroy(Boxc *boxc)
Definition: bb_boxc.c:605
Octstr * client_ip
Definition: opensmppbox.c:153
void semaphore_destroy(Semaphore *semaphore)
Definition: gw-semaphore.c:104
void gwlist_produce(List *list, void *item)
Definition: list.c:411
List * outgoing
Definition: opensmppbox.c:156
void gwthread_join(long thread)
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
long gwlist_len(List *list)
Definition: list.c:166
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
List * incoming_sms
Definition: bearerbox.c:84
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void boxc_receiver(void *arg)
Definition: bb_boxc.c:302
List * retry
Definition: opensmppbox.c:155
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
Octstr * boxc_id
Definition: opensmppbox.c:160
void * gwlist_extract_first(List *list)
Definition: list.c:305
List * outgoing_sms
Definition: bearerbox.c:85
void * dict_get(Dict *dict, Octstr *key)
Definition: dict.c:286
void gwlist_remove_producer(List *list)
Definition: list.c:401
static Dict * smsbox_by_id
Definition: bb_boxc.c:110
long dict_key_count(Dict *dict)
Definition: dict.c:335
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void octstr_destroy_item(void *os)
Definition: octstr.c:336
static long smsbox_max_pending
Definition: bb_boxc.c:123
void semaphore_up(Semaphore *semaphore)
Definition: gw-semaphore.c:118
void dict_destroy(Dict *dict)
Definition: dict.c:215
Definition: octstr.c:118
void gwthread_wakeup(long thread)
static List * smsbox_list
Definition: bb_boxc.c:106
List * dict_keys(Dict *dict)
Definition: dict.c:347
#define gwlist_create()
Definition: list.h:136
static void boxc_sender(void *arg)
Definition: bb_boxc.c:533
static long sms_dequeue_thread
Definition: bb_boxc.c:132
List * flow_threads
Definition: bearerbox.c:116
Dict * sent
Definition: opensmppbox.c:157
void gwlist_add_producer(List *list)
Definition: list.c:383
Semaphore * pending
Definition: opensmppbox.c:158
Semaphore * semaphore_create(long n)
Definition: gw-semaphore.c:81
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int gwlist_producer_count(List *list)
Definition: list.c:391
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ run_wapbox()

static void run_wapbox ( void *  arg)
static

Definition at line 761 of file bb_boxc.c.

References _boxc::alive, boxc_destroy(), boxc_receiver(), boxc_sender(), _boxc::client_ip, debug(), error(), flow_threads, gw_assert(), gwlist_add_producer(), gwlist_append(), gwlist_create, gwlist_delete_equal(), gwlist_destroy(), gwlist_len(), gwlist_lock(), gwlist_producer_count(), gwlist_remove_producer(), gwlist_unlock(), gwthread_create, gwthread_join(), _boxc::incoming, incoming_wdp, _boxc::is_wap, octstr_get_cstr, _boxc::outgoing, outgoing_wdp, _boxc::retry, and wapbox_list.

Referenced by wapboxc_run().

762 {
763  Boxc *newconn;
764  List *newlist;
765  long sender;
766 
768  newconn = arg;
769  newconn->is_wap = 1;
770 
771  /*
772  * create a new incoming list for just that box,
773  * and add it to list of list pointers, so we can start
774  * to route messages to it.
775  */
776 
777  debug("bb", 0, "setting up systems for new wapbox");
778 
779  newlist = gwlist_create();
780  /* this is released by the sender/receiver if it exits */
781  gwlist_add_producer(newlist);
782 
783  newconn->incoming = newlist;
784  newconn->retry = incoming_wdp;
785  newconn->outgoing = outgoing_wdp;
786 
787  sender = gwthread_create(boxc_sender, newconn);
788  if (sender == -1) {
789  error(0, "Failed to start a new thread, disconnecting client <%s>",
790  octstr_get_cstr(newconn->client_ip));
791  goto cleanup;
792  }
793  gwlist_append(wapbox_list, newconn);
794  gwlist_add_producer(newconn->outgoing);
795  boxc_receiver(newconn);
796 
797  /* cleanup after receiver has exited */
798 
803 
804  while (gwlist_producer_count(newlist) > 0)
805  gwlist_remove_producer(newlist);
806 
807  newconn->alive = 0;
808 
809  gwthread_join(sender);
810 
811 cleanup:
812  gw_assert(gwlist_len(newlist) == 0);
813  gwlist_destroy(newlist, NULL);
814  boxc_destroy(newconn);
815 
817 }
void error(int err, const char *fmt,...)
Definition: log.c:648
List * incoming
Definition: opensmppbox.c:154
List * outgoing_wdp
Definition: bearerbox.c:88
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
Definition: list.c:179
static void boxc_destroy(Boxc *boxc)
Definition: bb_boxc.c:605
Octstr * client_ip
Definition: opensmppbox.c:153
List * outgoing
Definition: opensmppbox.c:156
void gwthread_join(long thread)
long gwlist_len(List *list)
Definition: list.c:166
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static void boxc_receiver(void *arg)
Definition: bb_boxc.c:302
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
void gwlist_unlock(List *list)
Definition: list.c:354
List * retry
Definition: opensmppbox.c:155
void gwlist_remove_producer(List *list)
Definition: list.c:401
List * incoming_wdp
Definition: bearerbox.c:87
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void gwlist_lock(List *list)
Definition: list.c:347
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define gwlist_create()
Definition: list.h:136
static List * wapbox_list
Definition: bb_boxc.c:105
static void boxc_sender(void *arg)
Definition: bb_boxc.c:533
int is_wap
Definition: opensmppbox.c:146
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102
int gwlist_producer_count(List *list)
Definition: list.c:391
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ send_msg()

static int send_msg ( Boxc boxconn,
Msg pmsg 
)
static

Definition at line 456 of file bb_boxc.c.

References _boxc::boxc_id, _boxc::client_ip, _boxc::conn, conn_write_withlen(), debug(), error(), msg_pack(), octstr_destroy(), and octstr_get_cstr.

Referenced by boxc_receiver(), boxc_sender(), and deliver_sms_to_queue().

457 {
458  Octstr *pack;
459 
460  pack = msg_pack(pmsg);
461 
462  if (pack == NULL)
463  return -1;
464 
465  if (boxconn->boxc_id != NULL)
466  debug("bb.boxc", 0, "send_msg: sending msg to boxc: <%s>",
467  octstr_get_cstr(boxconn->boxc_id));
468  else
469  debug("bb.boxc", 0, "send_msg: sending msg to box: <%s>",
470  octstr_get_cstr(boxconn->client_ip));
471 
472  if (conn_write_withlen(boxconn->conn, pack) == -1) {
473  error(0, "Couldn't write Msg to box <%s>, disconnecting",
474  octstr_get_cstr(boxconn->client_ip));
475  octstr_destroy(pack);
476  return -1;
477  }
478 
479  octstr_destroy(pack);
480  return 0;
481 }
Connection * conn
Definition: bb_boxc.c:136
void error(int err, const char *fmt,...)
Definition: log.c:648
Octstr * client_ip
Definition: opensmppbox.c:153
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
Octstr * boxc_id
Definition: opensmppbox.c:160
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
int conn_write_withlen(Connection *conn, Octstr *data)
Definition: conn.c:1075
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
Octstr * msg_pack(Msg *msg)
Definition: msg.c:181

◆ sms_to_smsboxes()

static void sms_to_smsboxes ( void *  arg)
static

Definition at line 1713 of file bb_boxc.c.

References BB_DEAD, BB_SHUTDOWN, bb_status, flow_threads, gw_assert(), gw_rwlock_rdlock(), gw_rwlock_unlock(), gwlist_add_producer(), gwlist_consume(), gwlist_get(), gwlist_insert(), gwlist_len(), gwlist_produce(), gwlist_producer_count(), gwlist_remove_producer(), gwthread_sleep(), _boxc::incoming, incoming_sms, msg, route_incoming_to_boxc(), smsbox_list, and smsbox_list_rwlock.

Referenced by smsbox_start().

1714 {
1715  Msg *newmsg, *startmsg, *msg;
1716  long i, len;
1717  int ret = -1;
1718  Boxc *boxc;
1719 
1721 
1722  newmsg = startmsg = msg = NULL;
1723 
1724  while (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
1725 
1726  if (newmsg == startmsg) {
1727  /* check if we are in shutdown phase */
1729  break;
1730 
1731  if (ret == 0 || ret == -1) {
1732  /* debug("", 0, "time to sleep"); */
1733  gwthread_sleep(60.0);
1734  /* debug("", 0, "wake up list len %ld", gwlist_len(incoming_sms)); */
1735  /* shutdown ? */
1737  break;
1738  }
1739  startmsg = msg = gwlist_consume(incoming_sms);
1740  /* debug("", 0, "gwlist_consume done 1"); */
1741  newmsg = NULL;
1742  }
1743  else {
1744  newmsg = msg = gwlist_consume(incoming_sms);
1745 
1746  /* Back at the first message? */
1747  if (newmsg == startmsg) {
1749  continue;
1750  }
1751  }
1752 
1753  if (msg == NULL)
1754  break;
1755 
1756  gw_assert(msg_type(msg) == sms);
1757 
1758  /* debug("bb.sms", 0, "sms_boxc_router: handling message (%p vs %p)",
1759  msg, startmsg); */
1760 
1761  ret = route_incoming_to_boxc(msg);
1762  if (ret == 1)
1763  startmsg = newmsg = NULL;
1764  else if (ret == -1) {
1766  }
1767  }
1768 
1770  len = gwlist_len(smsbox_list);
1771  for (i=0; i < len; i++) {
1772  boxc = gwlist_get(smsbox_list, i);
1774  }
1776 
1778 }
List * incoming
Definition: opensmppbox.c:154
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_produce(List *list, void *item)
Definition: list.c:411
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
msg_type
Definition: msg.h:73
List * incoming_sms
Definition: bearerbox.c:84
int gw_rwlock_rdlock(RWLock *lock)
Definition: gw-rwlock.c:134
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
Definition: msg.h:79
void gwlist_remove_producer(List *list)
Definition: list.c:401
int route_incoming_to_boxc(Msg *msg)
Definition: bb_boxc.c:1549
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void gwthread_sleep(double seconds)
void gwlist_insert(List *list, long pos, void *item)
Definition: list.c:214
void * gwlist_consume(List *list)
Definition: list.c:427
static List * smsbox_list
Definition: bb_boxc.c:106
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int gwlist_producer_count(List *list)
Definition: list.c:391

◆ smsbox_restart()

int smsbox_restart ( Cfg cfg)

Definition at line 1316 of file bb_boxc.c.

References cfg, dict_create(), dict_destroy(), gw_rwlock_unlock(), gw_rwlock_wrlock(), init_smsbox_routes(), octstr_destroy(), smsbox_by_default, smsbox_by_receiver, smsbox_by_smsc, smsbox_by_smsc_receiver, smsbox_list_rwlock, and smsbox_running.

Referenced by bb_graceful_restart().

1317 {
1318  if (!smsbox_running) return -1;
1319 
1324  smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
1325  smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1326  smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1328  smsbox_by_default = NULL;
1329  init_smsbox_routes(cfg, 1);
1331 
1332  return 0;
1333 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static volatile sig_atomic_t smsbox_running
Definition: bb_boxc.c:103
static Dict * smsbox_by_smsc
Definition: bb_boxc.c:111
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
int gw_rwlock_wrlock(RWLock *lock)
Definition: gw-rwlock.c:177
static Cfg * cfg
Definition: opensmppbox.c:95
static Octstr * smsbox_by_default
Definition: bb_boxc.c:114
static Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
int gw_rwlock_unlock(RWLock *lock)
Definition: gw-rwlock.c:155
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
static void init_smsbox_routes(Cfg *cfg, int reload)
Definition: bb_boxc.c:1125
void dict_destroy(Dict *dict)
Definition: dict.c:215

◆ smsbox_start()

int smsbox_start ( Cfg cfg)

Definition at line 1250 of file bb_boxc.c.

References box_allow_ip, box_deny_ip, boxc_gwlist_destroy(), boxid, cfg, cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_single_group(), counter_create(), debug(), dict_create(), error(), gw_rwlock_create(), gwlist_add_producer(), gwlist_create, gwthread_create, info(), init_smsbox_routes(), octstr_create, octstr_destroy(), octstr_imm(), outgoing_sms, panic, sms_dequeue_thread, sms_to_smsboxes(), smsbox_by_default, smsbox_by_id, smsbox_by_receiver, smsbox_by_smsc, smsbox_by_smsc_receiver, smsbox_interface, smsbox_list, smsbox_list_rwlock, SMSBOX_MAX_PENDING, smsbox_max_pending, smsbox_port, smsbox_port_ssl, smsbox_running, and smsboxc_run().

Referenced by start_smsc().

1251 {
1252  CfgGroup *grp;
1253 
1254  if (smsbox_running) return -1;
1255 
1256  debug("bb", 0, "starting smsbox connection module");
1257 
1258  grp = cfg_get_single_group(cfg, octstr_imm("core"));
1259  if (cfg_get_integer(&smsbox_port, grp, octstr_imm("smsbox-port")) == -1) {
1260  error(0, "Missing smsbox-port variable, cannot start smsboxes");
1261  return -1;
1262  }
1263 #ifdef HAVE_LIBSSL
1264  cfg_get_bool(&smsbox_port_ssl, grp, octstr_imm("smsbox-port-ssl"));
1265 #endif /* HAVE_LIBSSL */
1266 
1267  if (smsbox_port_ssl)
1268  debug("bb", 0, "smsbox connection module is SSL-enabled");
1269 
1270  smsbox_interface = cfg_get(grp, octstr_imm("smsbox-interface"));
1271 
1272  if (cfg_get_integer(&smsbox_max_pending, grp, octstr_imm("smsbox-max-pending")) == -1) {
1274  info(0, "BOXC: 'smsbox-max-pending' not set, using default (%ld).", smsbox_max_pending);
1275  }
1276 
1277  box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip"));
1278  if (box_allow_ip == NULL)
1280  box_deny_ip = cfg_get(grp, octstr_imm("box-deny-ip"));
1281  if (box_deny_ip == NULL)
1282  box_deny_ip = octstr_create("");
1283  if (box_allow_ip != NULL && box_deny_ip == NULL)
1284  info(0, "Box connection allowed IPs defined without any denied...");
1285 
1286  smsbox_list = gwlist_create(); /* have a list of connections */
1288  if (!boxid)
1289  boxid = counter_create();
1290 
1291  /* the smsbox routing specific inits */
1292  smsbox_by_id = dict_create(10, (void(*)(void *)) boxc_gwlist_destroy);
1293  smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
1294  smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1295  smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1296  smsbox_by_default = NULL;
1297 
1298  /* load the defined smsbox routing rules */
1299  init_smsbox_routes(cfg, 0);
1300 
1303 
1304  smsbox_running = 1;
1305 
1306  if ((sms_dequeue_thread = gwthread_create(sms_to_smsboxes, NULL)) == -1)
1307  panic(0, "Failed to start a new thread for smsbox routing");
1308 
1309  if (gwthread_create(smsboxc_run, NULL) == -1)
1310  panic(0, "Failed to start a new thread for smsbox connections");
1311 
1312  return 0;
1313 }
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
Definition: dict.c:192
static volatile sig_atomic_t smsbox_running
Definition: bb_boxc.c:103
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
static void sms_to_smsboxes(void *arg)
Definition: bb_boxc.c:1713
static Dict * smsbox_by_smsc
Definition: bb_boxc.c:111
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
#define cfg_get(grp, varname)
Definition: cfg.h:86
static int smsbox_port_ssl
Definition: bb_boxc.c:117
RWLock * gw_rwlock_create(void)
Definition: gw-rwlock.c:77
static Cfg * cfg
Definition: opensmppbox.c:95
static Octstr * box_deny_ip
Definition: bb_boxc.c:126
static Octstr * smsbox_by_default
Definition: bb_boxc.c:114
static Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Counter * counter_create(void)
Definition: counter.c:94
List * outgoing_sms
Definition: bearerbox.c:85
static Dict * smsbox_by_id
Definition: bb_boxc.c:110
static Octstr * smsbox_interface
Definition: bb_boxc.c:118
static void smsboxc_run(void *arg)
Definition: bb_boxc.c:1018
static void boxc_gwlist_destroy(List *list)
Definition: bb_boxc.c:1786
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
static long smsbox_max_pending
Definition: bb_boxc.c:123
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
static Counter * boxid
Definition: bb_boxc.c:129
static void init_smsbox_routes(Cfg *cfg, int reload)
Definition: bb_boxc.c:1125
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:759
static long smsbox_port
Definition: bb_boxc.c:116
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Octstr * box_allow_ip
Definition: bb_boxc.c:125
static List * smsbox_list
Definition: bb_boxc.c:106
#define gwlist_create()
Definition: list.h:136
static long sms_dequeue_thread
Definition: bb_boxc.c:132
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:639
void gwlist_add_producer(List *list)
Definition: list.c:383
#define SMSBOX_MAX_PENDING
Definition: bb_boxc.c:83

◆ smsboxc_run()

static void smsboxc_run ( void *  arg)
static

Definition at line 1018 of file bb_boxc.c.

References dict_destroy(), flow_threads, gw_rwlock_destroy(), gwlist_add_producer(), gwlist_destroy(), gwlist_remove_producer(), gwlist_wait_until_nonempty(), gwthread_join(), gwthread_sleep(), gwthread_wakeup(), incoming_sms, MAIN_THREAD_ID, make_server_socket(), octstr_destroy(), octstr_get_cstr, outgoing_sms, panic, run_smsbox(), sms_dequeue_thread, smsbox_by_default, smsbox_by_id, smsbox_by_receiver, smsbox_by_smsc, smsbox_by_smsc_receiver, smsbox_interface, smsbox_list, smsbox_list_rwlock, smsbox_port, smsbox_port_ssl, and wait_for_connections().

Referenced by smsbox_start().

1019 {
1020  int fd;
1021 
1024 
1026  /* XXX add interface_name if required */
1027 
1028  if (fd < 0) {
1029  panic(0, "Could not open smsbox port %ld", smsbox_port);
1030  }
1031 
1032  /*
1033  * infinitely wait for new connections;
1034  * to shut down the system, SIGTERM is send and then
1035  * select drops with error, so we can check the status
1036  */
1038 
1040 
1041  /* continue avalanche */
1043 
1044  /* all connections do the same, so that all must remove() before it
1045  * is completely over
1046  */
1048  gwthread_sleep(1.0);
1049 
1050  /* close listen socket */
1051  close(fd);
1052 
1055 
1056  gwlist_destroy(smsbox_list, NULL);
1057  smsbox_list = NULL;
1059  smsbox_list_rwlock = NULL;
1060 
1061  /* destroy things related to smsbox routing */
1063  smsbox_by_id = NULL;
1065  smsbox_by_smsc = NULL;
1067  smsbox_by_receiver = NULL;
1069  smsbox_by_smsc_receiver = NULL;
1071  smsbox_by_default = NULL;
1072 
1074 }
static Dict * smsbox_by_smsc
Definition: bb_boxc.c:111
void gwthread_join(long thread)
static RWLock * smsbox_list_rwlock
Definition: bb_boxc.c:107
void gw_rwlock_destroy(RWLock *lock)
Definition: gw-rwlock.c:112
List * incoming_sms
Definition: bearerbox.c:84
static int smsbox_port_ssl
Definition: bb_boxc.c:117
int gwlist_wait_until_nonempty(List *list)
Definition: list.c:361
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * smsbox_by_default
Definition: bb_boxc.c:114
static Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
List * outgoing_sms
Definition: bearerbox.c:85
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited, int ssl)
Definition: bb_boxc.c:975
void gwlist_remove_producer(List *list)
Definition: list.c:401
static Dict * smsbox_by_id
Definition: bb_boxc.c:110
static Octstr * smsbox_interface
Definition: bb_boxc.c:118
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void gwthread_sleep(double seconds)
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
void dict_destroy(Dict *dict)
Definition: dict.c:215
static long smsbox_port
Definition: bb_boxc.c:116
#define panic
Definition: log.h:87
void gwthread_wakeup(long thread)
static List * smsbox_list
Definition: bb_boxc.c:106
static long sms_dequeue_thread
Definition: bb_boxc.c:132
#define MAIN_THREAD_ID
Definition: gwthread.h:77
List * flow_threads
Definition: bearerbox.c:116
static void run_smsbox(void *arg)
Definition: bb_boxc.c:665
void gwlist_add_producer(List *list)
Definition: list.c:383
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wait_for_connections()

static void wait_for_connections ( int  fd,
void(*)(void *arg)  function,
List waited,
int  ssl 
)
static

Definition at line 975 of file bb_boxc.c.

References accept_boxc(), BB_DEAD, BB_SHUTDOWN, bb_status, error(), gw_assert(), gwlist_consume(), gwlist_wait_until_nonempty(), gwthread_create, gwthread_pollfd(), gwthread_sleep(), POLLIN, ssl, and suspended.

Referenced by smsboxc_run(), and wapboxc_run().

977 {
978  int ret;
979  int timeout = 10; /* 10 sec. */
980 
981  gw_assert(function != NULL);
982 
983  while(bb_status != BB_DEAD) {
984 
985  /* if we are being shutdowned, as long as there is
986  * messages in incoming list allow new connections, but when
987  * list is empty, exit.
988  * Note: We have timeout (defined above) for which we allow new connections.
989  * Otherwise we wait here for ever!
990  */
991  if (bb_status == BB_SHUTDOWN) {
992  ret = gwlist_wait_until_nonempty(waited);
993  if (ret == -1 || !timeout)
994  break;
995  else
996  timeout--;
997  }
998 
999  /* block here if suspended */
1001 
1002  ret = gwthread_pollfd(fd, POLLIN, 1.0);
1003  if (ret > 0) {
1004  Boxc *newconn = accept_boxc(fd, ssl);
1005  if (newconn != NULL) {
1006  gwthread_create(function, newconn);
1007  gwthread_sleep(1.0);
1008  } else {
1009  error(0, "Failed to create new boxc connection.");
1010  }
1011  } else if (ret < 0 && errno != EINTR && errno != EAGAIN)
1012  error(errno, "bb_boxc::wait_for_connections failed");
1013  }
1014 }
void error(int err, const char *fmt,...)
Definition: log.c:648
gw_assert(wtls_machine->packet_to_send !=NULL)
int ssl
int gwlist_wait_until_nonempty(List *list)
Definition: list.c:361
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
#define POLLIN
Definition: gwpoll.h:91
List * suspended
Definition: bearerbox.c:122
#define gwthread_create(func, arg)
Definition: gwthread.h:90
void gwthread_sleep(double seconds)
int gwthread_pollfd(int fd, int events, double timeout)
void * gwlist_consume(List *list)
Definition: list.c:427
static Boxc * accept_boxc(int fd, int ssl)
Definition: bb_boxc.c:621

◆ wapbox_start()

int wapbox_start ( Cfg cfg)

Definition at line 1339 of file bb_boxc.c.

References box_allow_ip, box_deny_ip, boxid, cfg, cfg_get, cfg_get_bool(), cfg_get_integer(), cfg_get_single_group(), counter_create(), debug(), error(), gwlist_add_producer(), gwlist_create, gwthread_create, info(), octstr_create, octstr_imm(), outgoing_wdp, panic, wapbox_list, wapbox_port, wapbox_port_ssl, wapbox_running, wapboxc_run(), and wdp_to_wapboxes().

Referenced by start_wap().

1340 {
1341  CfgGroup *grp;
1342 
1343  if (wapbox_running) return -1;
1344 
1345  debug("bb", 0, "starting wapbox connection module");
1346 
1347  grp = cfg_get_single_group(cfg, octstr_imm("core"));
1348 
1349  if (cfg_get_integer(&wapbox_port, grp, octstr_imm("wapbox-port")) == -1) {
1350  error(0, "Missing wapbox-port variable, cannot start WAP");
1351  return -1;
1352  }
1353 #ifdef HAVE_LIBSSL
1354  cfg_get_bool(&wapbox_port_ssl, grp, octstr_imm("wapbox-port-ssl"));
1355 #endif /* HAVE_LIBSSL */
1356 
1357  if (box_allow_ip == NULL) {
1358  box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip"));
1359  if (box_allow_ip == NULL)
1361  }
1362  if (box_deny_ip == NULL) {
1363  box_deny_ip = cfg_get(grp, octstr_imm("box-deny-ip"));
1364  if (box_deny_ip == NULL)
1365  box_deny_ip = octstr_create("");
1366  }
1367  if (box_allow_ip != NULL && box_deny_ip == NULL)
1368  info(0, "Box connection allowed IPs defined without any denied...");
1369 
1370  wapbox_list = gwlist_create(); /* have a list of connections */
1372  if (!boxid)
1373  boxid = counter_create();
1374 
1375  if (gwthread_create(wdp_to_wapboxes, NULL) == -1)
1376  panic(0, "Failed to start a new thread for wapbox routing");
1377 
1379  panic(0, "Failed to start a new thread for wapbox connections");
1380 
1381  wapbox_running = 1;
1382  return 0;
1383 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void info(int err, const char *fmt,...)
Definition: log.c:672
List * outgoing_wdp
Definition: bearerbox.c:88
static int wapbox_port_ssl
Definition: bb_boxc.c:120
#define cfg_get(grp, varname)
Definition: cfg.h:86
static Cfg * cfg
Definition: opensmppbox.c:95
static Octstr * box_deny_ip
Definition: bb_boxc.c:126
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Counter * counter_create(void)
Definition: counter.c:94
static void wapboxc_run(void *arg)
Definition: bb_boxc.c:1077
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
static Counter * boxid
Definition: bb_boxc.c:129
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:759
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Octstr * box_allow_ip
Definition: bb_boxc.c:125
static void wdp_to_wapboxes(void *arg)
Definition: bb_boxc.c:924
#define gwlist_create()
Definition: list.h:136
static List * wapbox_list
Definition: bb_boxc.c:105
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:639
void gwlist_add_producer(List *list)
Definition: list.c:383
static volatile sig_atomic_t wapbox_running
Definition: bb_boxc.c:104
static long wapbox_port
Definition: bb_boxc.c:119

◆ wapboxc_run()

static void wapboxc_run ( void *  arg)
static

Definition at line 1077 of file bb_boxc.c.

References flow_threads, gwlist_add_producer(), gwlist_consume(), gwlist_destroy(), gwlist_remove_producer(), gwlist_wait_until_nonempty(), gwthread_sleep(), gwthread_wakeup(), incoming_wdp, MAIN_THREAD_ID, make_server_socket(), outgoing_wdp, panic, port, run_wapbox(), wait_for_connections(), wapbox_list, and wapbox_port_ssl.

Referenced by wapbox_start().

1078 {
1079  int fd, port;
1080 
1083  port = (int) *((long*)arg);
1084 
1085  fd = make_server_socket(port, NULL);
1086  /* XXX add interface_name if required */
1087 
1088  if (fd < 0) {
1089  panic(0, "Could not open wapbox port %d", port);
1090  }
1091 
1093 
1094  /* continue avalanche */
1095 
1097 
1098 
1099  /* wait for all connections to die and then remove list
1100  */
1101 
1103  gwthread_sleep(1.0);
1104 
1105  /* wait for wdp_to_wapboxes to exit */
1106  while(gwlist_consume(wapbox_list)!=NULL)
1107  ;
1108 
1109  /* close listen socket */
1110  close(fd);
1111 
1112  gwlist_destroy(wapbox_list, NULL);
1113  wapbox_list = NULL;
1114 
1116 }
static void run_wapbox(void *arg)
Definition: bb_boxc.c:761
Definition: http.c:2014
List * outgoing_wdp
Definition: bearerbox.c:88
static int wapbox_port_ssl
Definition: bb_boxc.c:120
int gwlist_wait_until_nonempty(List *list)
Definition: list.c:361
static int port
Definition: fakesmsc.c:121
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited, int ssl)
Definition: bb_boxc.c:975
void gwlist_remove_producer(List *list)
Definition: list.c:401
List * incoming_wdp
Definition: bearerbox.c:87
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
void gwthread_sleep(double seconds)
void * gwlist_consume(List *list)
Definition: list.c:427
#define panic
Definition: log.h:87
void gwthread_wakeup(long thread)
static List * wapbox_list
Definition: bb_boxc.c:105
#define MAIN_THREAD_ID
Definition: gwthread.h:77
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

◆ wdp_to_wapboxes()

static void wdp_to_wapboxes ( void *  arg)
static

Definition at line 924 of file bb_boxc.c.

References _boxc::alive, ap_destroy(), BB_DEAD, bb_status, debug(), flow_threads, gw_assert(), gwlist_add_producer(), gwlist_consume(), gwlist_create, gwlist_destroy(), gwlist_extract_first(), gwlist_get(), gwlist_len(), gwlist_lock(), gwlist_produce(), gwlist_remove_producer(), gwlist_unlock(), _boxc::incoming, incoming_wdp, msg, msg_destroy(), route_msg(), suspended, wapbox_list, and warning().

Referenced by wapbox_start().

925 {
926  List *route_info;
927  AddrPar *ap;
928  Boxc *conn;
929  Msg *msg;
930  int i;
931 
934 
935  route_info = gwlist_create();
936 
937 
938  while(bb_status != BB_DEAD) {
939 
940  gwlist_consume(suspended); /* block here if suspended */
941 
942  if ((msg = gwlist_consume(incoming_wdp)) == NULL)
943  break;
944 
945  gw_assert(msg_type(msg) == wdp_datagram);
946 
947  conn = route_msg(route_info, msg);
948  if (conn == NULL) {
949  warning(0, "Cannot route message, discard it");
950  msg_destroy(msg);
951  continue;
952  }
953  gwlist_produce(conn->incoming, msg);
954  }
955  debug("bb", 0, "wdp_to_wapboxes: destroying lists");
956  while((ap = gwlist_extract_first(route_info)) != NULL)
957  ap_destroy(ap);
958 
959  gw_assert(gwlist_len(route_info) == 0);
960  gwlist_destroy(route_info, NULL);
961 
963  for(i=0; i < gwlist_len(wapbox_list); i++) {
964  conn = gwlist_get(wapbox_list, i);
966  conn->alive = 0;
967  }
969 
972 }
List * incoming
Definition: opensmppbox.c:154
static Boxc * route_msg(List *route_info, Msg *msg)
Definition: bb_boxc.c:857
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_produce(List *list, void *item)
Definition: list.c:411
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
msg_type
Definition: msg.h:73
volatile sig_atomic_t alive
Definition: opensmppbox.c:159
void gwlist_unlock(List *list)
Definition: list.c:354
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
Definition: msg.h:79
void * gwlist_extract_first(List *list)
Definition: list.c:305
static void ap_destroy(AddrPar *addr)
Definition: bb_boxc.c:830
List * suspended
Definition: bearerbox.c:122
void gwlist_remove_producer(List *list)
Definition: list.c:401
List * incoming_wdp
Definition: bearerbox.c:87
void msg_destroy(Msg *msg)
Definition: msg.c:132
void warning(int err, const char *fmt,...)
Definition: log.c:660
void gwlist_lock(List *list)
Definition: list.c:347
void * gwlist_consume(List *list)
Definition: list.c:427
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
#define gwlist_create()
Definition: list.h:136
static List * wapbox_list
Definition: bb_boxc.c:105
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145

Variable Documentation

◆ bb_status

volatile sig_atomic_t bb_status

◆ box_allow_ip

Octstr* box_allow_ip
static

Definition at line 125 of file bb_boxc.c.

Referenced by accept_boxc(), boxc_cleanup(), smsbox_start(), and wapbox_start().

◆ box_deny_ip

Octstr* box_deny_ip
static

Definition at line 126 of file bb_boxc.c.

Referenced by accept_boxc(), boxc_cleanup(), smsbox_start(), and wapbox_start().

◆ boxid

Counter* boxid
static

Definition at line 129 of file bb_boxc.c.

Referenced by boxc_cleanup(), boxc_create(), smsbox_start(), and wapbox_start().

◆ flow_threads

List* flow_threads

◆ incoming_sms

List* incoming_sms

Definition at line 84 of file bearerbox.c.

Referenced by route_incoming_to_boxc(), run_smsbox(), sms_to_smsboxes(), and smsboxc_run().

◆ incoming_wdp

List* incoming_wdp

Definition at line 87 of file bearerbox.c.

Referenced by run_wapbox(), wapboxc_run(), and wdp_to_wapboxes().

◆ max_incoming_sms_qlength

long max_incoming_sms_qlength

Definition at line 98 of file bearerbox.c.

Referenced by route_incoming_to_boxc().

◆ outgoing_sms

List* outgoing_sms

Definition at line 85 of file bearerbox.c.

Referenced by run_smsbox(), smsbox_start(), and smsboxc_run().

◆ outgoing_wdp

◆ restart

volatile sig_atomic_t restart

Definition at line 149 of file bearerbox.c.

Referenced by bb_restart(), boxc_sender(), main(), and read_messages_from_bearerbox().

◆ sms_dequeue_thread

long sms_dequeue_thread
static

Definition at line 132 of file bb_boxc.c.

Referenced by boxc_receiver(), run_smsbox(), smsbox_start(), and smsboxc_run().

◆ smsbox_by_default

Octstr* smsbox_by_default
static

◆ smsbox_by_id

Dict* smsbox_by_id
static

◆ smsbox_by_receiver

Dict* smsbox_by_receiver
static

◆ smsbox_by_smsc

Dict* smsbox_by_smsc
static

◆ smsbox_by_smsc_receiver

Dict* smsbox_by_smsc_receiver
static

◆ smsbox_interface

Octstr* smsbox_interface
static

Definition at line 118 of file bb_boxc.c.

Referenced by boxc_cleanup(), smsbox_start(), and smsboxc_run().

◆ smsbox_list

List* smsbox_list
static

◆ smsbox_list_rwlock

RWLock* smsbox_list_rwlock
static

◆ smsbox_max_pending

long smsbox_max_pending
static

Definition at line 123 of file bb_boxc.c.

Referenced by run_smsbox(), and smsbox_start().

◆ smsbox_port

long smsbox_port
static

Definition at line 116 of file bb_boxc.c.

Referenced by smsbox_start(), and smsboxc_run().

◆ smsbox_port_ssl

int smsbox_port_ssl
static

Definition at line 117 of file bb_boxc.c.

Referenced by smsbox_start(), and smsboxc_run().

◆ smsbox_running

volatile sig_atomic_t smsbox_running
static

Definition at line 103 of file bb_boxc.c.

Referenced by smsbox_restart(), and smsbox_start().

◆ suspended

List* suspended

Definition at line 122 of file bearerbox.c.

Referenced by boxc_receiver(), boxc_sender(), wait_for_connections(), and wdp_to_wapboxes().

◆ wapbox_list

List* wapbox_list
static

◆ wapbox_port

long wapbox_port
static

Definition at line 119 of file bb_boxc.c.

Referenced by wapbox_start().

◆ wapbox_port_ssl

int wapbox_port_ssl
static

Definition at line 120 of file bb_boxc.c.

Referenced by wapbox_start(), and wapboxc_run().

◆ wapbox_running

volatile sig_atomic_t wapbox_running
static

Definition at line 104 of file bb_boxc.c.

Referenced by wapbox_start().

See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.