Kannel: Open Source WAP and SMS gateway  svn-r5285
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 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 1115 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 620 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().

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

◆ ap_destroy()

static void ap_destroy ( AddrPar addr)
static

Definition at line 829 of file bb_boxc.c.

References _addrpar::address, and octstr_destroy().

Referenced by route_msg(), and wdp_to_wapboxes().

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

◆ boxc_cleanup()

void boxc_cleanup ( void  )

Definition at line 1510 of file bb_boxc.c.

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

Referenced by main().

1511 {
1514  box_allow_ip = NULL;
1515  box_deny_ip = NULL;
1517  boxid = NULL;
1519  smsbox_interface = NULL;
1520 }
void counter_destroy(Counter *counter)
Definition: counter.c:110
static Octstr * box_deny_ip
Definition: bb_boxc.c:125
static Octstr * smsbox_interface
Definition: bb_boxc.c:117
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
static Counter * boxid
Definition: bb_boxc.c:128
static Octstr * box_allow_ip
Definition: bb_boxc.c:124

◆ boxc_create()

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

Definition at line 587 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().

588 {
589  Boxc *boxc;
590 
591  boxc = gw_malloc(sizeof(Boxc));
592  boxc->is_wap = 0;
593  boxc->load = 0;
594  boxc->conn = conn_wrap_fd(fd, ssl);
595  boxc->id = counter_increase(boxid);
596  boxc->client_ip = ip;
597  boxc->alive = 1;
598  boxc->connect_time = time(NULL);
599  boxc->boxc_id = NULL;
600  boxc->routable = 0;
601  return boxc;
602 }
Connection * conn
Definition: bb_boxc.c:135
int ssl
Octstr * client_ip
Definition: opensmppbox.c:152
int load
Definition: opensmppbox.c:147
unsigned long counter_increase(Counter *counter)
Definition: counter.c:123
volatile sig_atomic_t alive
Definition: opensmppbox.c:158
Octstr * boxc_id
Definition: opensmppbox.c:159
time_t connect_time
Definition: opensmppbox.c:150
static Counter * boxid
Definition: bb_boxc.c:128
long id
Definition: opensmppbox.c:146
int is_wap
Definition: opensmppbox.c:145
volatile int routable
Definition: opensmppbox.c:166
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:560

◆ boxc_destroy()

static void boxc_destroy ( Boxc boxc)
static

Definition at line 604 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().

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

◆ boxc_gwlist_destroy()

static void boxc_gwlist_destroy ( List list)
static

Definition at line 1767 of file bb_boxc.c.

References gwlist_destroy().

Referenced by smsbox_start().

1768 {
1769  gwlist_destroy(list, NULL);
1770 }
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 1493 of file bb_boxc.c.

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

Referenced by bb_print_status().

1494 {
1495  int i, q = 0;
1496  Boxc *boxc;
1497 
1498  if (wapbox_list) {
1500  for(i=0; i < gwlist_len(wapbox_list); i++) {
1501  boxc = gwlist_get(wapbox_list, i);
1502  q += gwlist_len(boxc->incoming);
1503  }
1505  }
1506  return q;
1507 }
List * incoming
Definition: opensmppbox.c:153
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 301 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().

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

533 {
534  Msg *msg;
535  Boxc *conn = arg;
536 
538 
539  while (bb_status != BB_DEAD && conn->alive) {
540 
541  /*
542  * Make sure there's no data left in the outgoing connection before
543  * doing the potentially blocking gwlist_consume()s
544  */
545  conn_flush(conn->conn);
546 
547  gwlist_consume(suspended); /* block here if suspended */
548 
549  if ((msg = gwlist_consume(conn->incoming)) == NULL) {
550  /* tell sms/wapbox to die */
551  msg = msg_create(admin);
552  msg->admin.command = restart ? cmd_restart : cmd_shutdown;
553  send_msg(conn, msg);
554  msg_destroy(msg);
555  break;
556  }
557  if (msg_type(msg) == heartbeat) {
558  debug("bb.boxc", 0, "boxc_sender: catch an heartbeat - we are alive");
559  msg_destroy(msg);
560  continue;
561  }
562  boxc_sent_push(conn, msg);
563  if (!conn->alive || send_msg(conn, msg) == -1) {
564  /* we got message here */
565  boxc_sent_pop(conn, msg, NULL);
566  gwlist_produce(conn->retry, msg);
567  break;
568  }
569  msg_destroy(msg);
570  debug("bb.boxc", 0, "boxc_sender: sent message to <%s>",
571  octstr_get_cstr(conn->client_ip));
572  }
573  /* the client closes the connection, after that die in receiver */
574  /* conn->alive = 0; */
575 
576  /* set conn to unroutable */
577  conn->routable = 0;
578 
580 }
Connection * conn
Definition: bb_boxc.c:135
List * incoming
Definition: opensmppbox.c:153
Octstr * client_ip
Definition: opensmppbox.c:152
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:503
#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:158
List * retry
Definition: opensmppbox.c:154
volatile sig_atomic_t bb_status
Definition: bearerbox.c:132
static int send_msg(Boxc *boxconn, Msg *pmsg)
Definition: bb_boxc.c:455
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:483
List * flow_threads
Definition: bearerbox.c:116
void gwlist_add_producer(List *list)
Definition: list.c:383
volatile int routable
Definition: opensmppbox.c:166
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
int conn_flush(Connection *conn)
Definition: conn.c:989

◆ boxc_sent_pop()

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

Definition at line 503 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().

504 {
505  Octstr *os;
506  char id[UUID_STR_LEN + 1];
507  Msg *msg;
508 
509  if (conn->is_wap || !conn->sent || !m || (msg_type(m) != ack && msg_type(m) != sms))
510  return;
511 
512  if (orig != NULL)
513  *orig = NULL;
514 
515  uuid_unparse((msg_type(m) == sms ? m->sms.id : m->ack.id), id);
516  os = octstr_create(id);
517  msg = dict_remove(conn->sent, os);
518  octstr_destroy(os);
519  if (!msg) {
520  error(0, "BOXC: Got ack for nonexistend message!");
521  msg_dump(m, 0);
522  return;
523  }
524  semaphore_up(conn->pending);
525  if (orig == NULL)
526  msg_destroy(msg);
527  else
528  *orig = msg;
529 }
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:145
Dict * sent
Definition: opensmppbox.c:156
Semaphore * pending
Definition: opensmppbox.c:157
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ boxc_sent_push()

static void boxc_sent_push ( Boxc conn,
Msg m 
)
static

Definition at line 483 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().

484 {
485  Octstr *os;
486  char id[UUID_STR_LEN + 1];
487 
488  if (conn->is_wap || !conn->sent || !m || msg_type(m) != sms)
489  return;
490 
491  uuid_unparse(m->sms.id, id);
492  os = octstr_create(id);
493  dict_put(conn->sent, os, msg_duplicate(m));
494  semaphore_down(conn->pending);
495  octstr_destroy(os);
496 }
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:145
Dict * sent
Definition: opensmppbox.c:156
Semaphore * pending
Definition: opensmppbox.c:157

◆ boxc_status()

Octstr* boxc_status ( int  status_type)

Definition at line 1369 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().

1370 {
1371  Octstr *tmp;
1372  char *lb, *ws;
1373  int i, boxes, para = 0;
1374  time_t orig, t;
1375  Boxc *bi;
1376 
1377  orig = time(NULL);
1378 
1379  /*
1380  * XXX: this will cause segmentation fault if this is called
1381  * between 'destroy_list and setting list to NULL calls.
1382  * Ok, this has to be fixed, but now I am too tired.
1383  */
1384 
1385  if ((lb = bb_status_linebreak(status_type))==NULL)
1386  return octstr_create("Un-supported format");
1387 
1388  if (status_type == BBSTATUS_HTML)
1389  ws = "&nbsp;&nbsp;&nbsp;&nbsp;";
1390  else if (status_type == BBSTATUS_TEXT)
1391  ws = " ";
1392  else
1393  ws = "";
1394 
1395  if (status_type == BBSTATUS_HTML || status_type == BBSTATUS_WML)
1396  para = 1;
1397 
1398  if (status_type == BBSTATUS_XML) {
1399  tmp = octstr_create ("");
1400  octstr_append_cstr(tmp, "<boxes>\n\t");
1401  }
1402  else
1403  tmp = octstr_format("%sBox connections:%s", para ? "<p>" : "", lb);
1404  boxes = 0;
1405 
1406  if (wapbox_list) {
1408  for(i=0; i < gwlist_len(wapbox_list); i++) {
1409  bi = gwlist_get(wapbox_list, i);
1410  if (bi->alive == 0)
1411  continue;
1412  t = orig - bi->connect_time;
1413  if (status_type == BBSTATUS_XML)
1415  "<box>\n\t\t<type>wapbox</type>\n\t\t<IP>%s</IP>\n"
1416  "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
1417  "\t\t<ssl>%s</ssl>\n\t</box>\n",
1419  t/3600/24, t/3600%24, t/60%60, t%60,
1420 #ifdef HAVE_LIBSSL
1421  conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
1422 #else
1423  "not installed"
1424 #endif
1425  );
1426  else
1428  "%swapbox, IP %s (on-line %ldd %ldh %ldm %lds) %s %s",
1429  ws, octstr_get_cstr(bi->client_ip),
1430  t/3600/24, t/3600%24, t/60%60, t%60,
1431 #ifdef HAVE_LIBSSL
1432  conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
1433 #else
1434  "",
1435 #endif
1436  lb);
1437  boxes++;
1438  }
1440  }
1441  if (smsbox_list) {
1443  for(i=0; i < gwlist_len(smsbox_list); i++) {
1444  bi = gwlist_get(smsbox_list, i);
1445  if (bi->alive == 0)
1446  continue;
1447  t = orig - bi->connect_time;
1448  if (status_type == BBSTATUS_XML)
1449  octstr_format_append(tmp, "<box>\n\t\t<type>smsbox</type>\n"
1450  "\t\t<id>%s</id>\n\t\t<IP>%s</IP>\n"
1451  "\t\t<queue>%ld</queue>\n"
1452  "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
1453  "\t\t<ssl>%s</ssl>\n\t</box>",
1454  (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : ""),
1456  gwlist_len(bi->incoming) + dict_key_count(bi->sent),
1457  t/3600/24, t/3600%24, t/60%60, t%60,
1458 #ifdef HAVE_LIBSSL
1459  conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
1460 #else
1461  "not installed"
1462 #endif
1463  );
1464  else
1465  octstr_format_append(tmp, "%ssmsbox:%s, IP %s (%ld queued), (on-line %ldd %ldh %ldm %lds) %s %s",
1466  ws, (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : "(none)"),
1468  t/3600/24, t/3600%24, t/60%60, t%60,
1469 #ifdef HAVE_LIBSSL
1470  conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
1471 #else
1472  "",
1473 #endif
1474  lb);
1475  boxes++;
1476  }
1478  }
1479  if (boxes == 0 && status_type != BBSTATUS_XML) {
1480  octstr_destroy(tmp);
1481  tmp = octstr_format("%sNo boxes connected", para ? "<p>" : "");
1482  }
1483  if (para)
1484  octstr_append_cstr(tmp, "</p>");
1485  if (status_type == BBSTATUS_XML)
1486  octstr_append_cstr(tmp, "</boxes>\n");
1487  else
1488  octstr_append_cstr(tmp, "\n\n");
1489  return tmp;
1490 }
Connection * conn
Definition: bb_boxc.c:135
List * incoming
Definition: opensmppbox.c:153
char * bb_status_linebreak(int status_type)
Definition: bearerbox.c:1109
Octstr * client_ip
Definition: opensmppbox.c:152
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:158
void gwlist_unlock(List *list)
Definition: list.c:354
Octstr * boxc_id
Definition: opensmppbox.c:159
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:150
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:156

◆ cmp_boxc()

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

Definition at line 847 of file bb_boxc.c.

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

Referenced by route_msg().

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

◆ cmp_route()

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

Definition at line 835 of file bb_boxc.c.

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

Referenced by route_msg().

836 {
837  AddrPar *addr = ap;
838  Msg *msg = ms;
839 
840  if (msg->wdp_datagram.source_port == addr->port &&
841  octstr_compare(msg->wdp_datagram.source_address, addr->address)==0)
842  return 1;
843 
844  return 0;
845 }
Octstr * address
Definition: bb_boxc.c:824
Definition: msg.h:79
int port
Definition: bb_boxc.c:825
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 213 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().

214 {
215  Msg *mack;
216  int rc;
217 
218  /*
219  * save modifies ID and time, so if the smsbox uses it, save
220  * it FIRST for the reply message!!!
221  */
222  mack = msg_create(ack);
223  gw_assert(mack != NULL);
224  uuid_copy(mack->ack.id, msg->sms.id);
225  mack->ack.time = msg->sms.time;
226 
227  store_save(msg);
228 
229  rc = smsc2_rout(msg, 0);
230  switch (rc) {
231 
232  case SMSCCONN_SUCCESS:
233  mack->ack.nack = ack_success;
234  break;
235 
236  case SMSCCONN_QUEUED:
237  mack->ack.nack = ack_buffered;
238  break;
239 
240  case SMSCCONN_FAILED_DISCARDED: /* no router at all */
241  warning(0, "Message rejected by bearerbox, no router!");
242 
243  /*
244  * we don't store_save_ack() here, since the call to
245  * bb_smscconn_send_failed() within smsc2_route() did
246  * it already.
247  */
248  mack->ack.nack = ack_failed;
249 
250  /* destroy original message */
251  msg_destroy(msg);
252  break;
253 
254  case SMSCCONN_FAILED_QFULL: /* queue full */
255  warning(0, "Message rejected by bearerbox, %s!",
256  (rc == SMSCCONN_FAILED_DISCARDED) ? "no router" : "queue full");
257  /*
258  * first create nack for store-file, in order to delete
259  * message from store-file.
260  */
261  mack->ack.nack = ack_failed_tmp;
263 
264  /* destroy original message */
265  msg_destroy(msg);
266  break;
267 
268  case SMSCCONN_FAILED_EXPIRED: /* validity expired */
269  warning(0, "Message rejected by bearerbox, validity expired!");
270 
271  /*
272  * we don't store_save_ack() here, since the call to
273  * bb_smscconn_send_failed() within smsc2_route() did
274  * it already.
275  */
276  mack->ack.nack = ack_failed;
277 
278  /* destroy original message */
279  msg_destroy(msg);
280  break;
281 
282  case SMSCCONN_FAILED_REJECTED: /* white/black-list rejection */
283  warning(0, "Message rejected by bearerbox, white/black listed!");
284 
285  mack->ack.nack = ack_failed;
286 
287  /* destroy original message */
288  msg_destroy(msg);
289  break;
290 
291  default:
292  break;
293  }
294 
295  /* put ack into incoming queue of conn */
296  send_msg(conn, mack);
297  msg_destroy(mack);
298 }
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:455
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:1708

◆ init_smsbox_routes()

static void init_smsbox_routes ( Cfg cfg,
int  reload 
)
static

Definition at line 1122 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_receiver, smsbox_by_smsc, and smsbox_by_smsc_receiver.

Referenced by smsbox_restart(), and smsbox_start().

1123 {
1124  CfgGroup *grp;
1125  List *list, *items;
1126  Octstr *boxc_id, *smsc_ids, *shortcuts;
1127  int i, j;
1128 
1129  boxc_id = smsc_ids = shortcuts = NULL;
1130 
1131  list = cfg_get_multi_group(cfg, octstr_imm("smsbox-route"));
1132 
1133  /* loop multi-group "smsbox-route" */
1134  while (list && (grp = gwlist_extract_first(list)) != NULL) {
1135 
1136  if ((boxc_id = cfg_get(grp, octstr_imm("smsbox-id"))) == NULL) {
1137  grp_dump(grp);
1138  RELOAD_PANIC(0,"'smsbox-route' group without valid 'smsbox-id' directive!");
1139  }
1140 
1141  /*
1142  * If smsc-id is given, then any message comming from the specified
1143  * smsc-id in the list will be routed to this smsbox instance.
1144  * If shortcode is given, then any message with receiver number
1145  * matching those will be routed to this smsbox instance.
1146  * If both are given, then only receiver within shortcode originating
1147  * from smsc-id list will be routed to this smsbox instance. So if both
1148  * are present then this is a logical AND operation.
1149  */
1150  smsc_ids = cfg_get(grp, octstr_imm("smsc-id"));
1151  shortcuts = cfg_get(grp, octstr_imm("shortcode"));
1152 
1153  /* consider now the 3 possibilities: */
1154  if (smsc_ids && !shortcuts) {
1155  /* smsc-id only, so all MO traffic */
1156  items = octstr_split(smsc_ids, octstr_imm(";"));
1157  for (i = 0; i < gwlist_len(items); i++) {
1158  Octstr *item = gwlist_get(items, i);
1159  octstr_strip_blanks(item);
1160 
1161  debug("bb.boxc",0,"Adding smsbox routing to id <%s> for smsc id <%s>",
1162  octstr_get_cstr(boxc_id), octstr_get_cstr(item));
1163 
1164  if (!dict_put_once(smsbox_by_smsc, item, octstr_duplicate(boxc_id))) {
1165  RELOAD_PANIC(0, "Routing for smsc-id <%s> already exists!",
1166  octstr_get_cstr(item));
1167  }
1168  }
1170  octstr_destroy(smsc_ids);
1171  }
1172  else if (!smsc_ids && shortcuts) {
1173  /* shortcode only, so these MOs from all smscs */
1174  items = octstr_split(shortcuts, octstr_imm(";"));
1175  for (i = 0; i < gwlist_len(items); i++) {
1176  Octstr *item = gwlist_get(items, i);
1177  octstr_strip_blanks(item);
1178 
1179  debug("bb.boxc",0,"Adding smsbox routing to id <%s> for receiver no <%s>",
1180  octstr_get_cstr(boxc_id), octstr_get_cstr(item));
1181 
1182  if (!dict_put_once(smsbox_by_receiver, item, octstr_duplicate(boxc_id))) {
1183  RELOAD_PANIC(0, "Routing for receiver no <%s> already exists!",
1184  octstr_get_cstr(item));
1185  }
1186  }
1188  octstr_destroy(shortcuts);
1189  }
1190  else if (smsc_ids && shortcuts) {
1191  /* both, so only specified MOs from specified smscs */
1192  items = octstr_split(shortcuts, octstr_imm(";"));
1193  for (i = 0; i < gwlist_len(items); i++) {
1194  List *subitems;
1195  Octstr *item = gwlist_get(items, i);
1196  octstr_strip_blanks(item);
1197  subitems = octstr_split(smsc_ids, octstr_imm(";"));
1198  for (j = 0; j < gwlist_len(subitems); j++) {
1199  Octstr *subitem = gwlist_get(subitems, j);
1200  octstr_strip_blanks(subitem);
1201 
1202  debug("bb.boxc",0,"Adding smsbox routing to id <%s> "
1203  "for receiver no <%s> and smsc id <%s>",
1204  octstr_get_cstr(boxc_id), octstr_get_cstr(item),
1205  octstr_get_cstr(subitem));
1206 
1207  /* construct the dict key '<shortcode>:<smsc-id>' */
1208  octstr_insert(subitem, item, 0);
1209  octstr_insert_char(subitem, octstr_len(item), ':');
1210  if (!dict_put_once(smsbox_by_smsc_receiver, subitem, octstr_duplicate(boxc_id))) {
1211  RELOAD_PANIC(0, "Routing for receiver:smsc <%s> already exists!",
1212  octstr_get_cstr(subitem));
1213  }
1214  }
1216  }
1218  octstr_destroy(shortcuts);
1219  octstr_destroy(smsc_ids);
1220  }
1221  octstr_destroy(boxc_id);
1222  }
1223 
1224  gwlist_destroy(list, NULL);
1225 }
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 Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
#define RELOAD_PANIC(...)
Definition: bb_boxc.c:1115
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:809
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:643
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 165 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().

166 {
167  int ret;
168  Octstr *pack;
169  Msg *msg;
170 
171  pack = NULL;
172  while (bb_status != BB_DEAD && boxconn->alive) {
173  /* XXX: if box doesn't send (just keep conn open) we block here while shutdown */
174  pack = conn_read_withlen(boxconn->conn);
175  gw_claim_area(pack);
176  if (pack != NULL)
177  break;
178  if (conn_error(boxconn->conn)) {
179  info(0, "Read error when reading from box <%s>, disconnecting",
180  octstr_get_cstr(boxconn->client_ip));
181  return NULL;
182  }
183  if (conn_eof(boxconn->conn)) {
184  info(0, "Connection closed by the box <%s>",
185  octstr_get_cstr(boxconn->client_ip));
186  return NULL;
187  }
188 
189  ret = conn_wait(boxconn->conn, -1.0);
190  if (ret < 0) {
191  error(0, "Connection to box <%s> broke.",
192  octstr_get_cstr(boxconn->client_ip));
193  return NULL;
194  }
195  }
196 
197  if (pack == NULL)
198  return NULL;
199 
200  msg = msg_unpack(pack);
201  octstr_destroy(pack);
202 
203  if (msg == NULL)
204  error(0, "Failed to unpack data!");
205  return msg;
206 }
Connection * conn
Definition: bb_boxc.c:135
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:152
int conn_eof(Connection *conn)
Definition: conn.c:699
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
volatile sig_atomic_t alive
Definition: opensmppbox.c:158
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:1163
Definition: octstr.c:118
int conn_wait(Connection *conn, double seconds)
Definition: conn.c:898
int conn_error(Connection *conn)
Definition: conn.c:710
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ route_incoming_to_boxc()

int route_incoming_to_boxc ( Msg msg)

Definition at line 1532 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_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().

1533 {
1534  Boxc *bc = NULL;
1535  Octstr *s, *r, *rs, *boxc_id = NULL;
1536  long len, b, i;
1537  int full_found = 0;
1538 
1539  gw_assert(msg_type(msg) == sms);
1540 
1541  /* msg_dump(msg, 0); */
1542 
1543  /* Check we have at least one smsbox connected! */
1545  if (gwlist_len(smsbox_list) == 0) {
1547  warning(0, "smsbox_list empty!");
1548  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1550  return 0;
1551  } else {
1552  return -1;
1553  }
1554  }
1555 
1556  /*
1557  * Do we have a specific smsbox-id route to pass this msg to?
1558  */
1559  if (octstr_len(msg->sms.boxc_id) > 0) {
1560  boxc_id = msg->sms.boxc_id;
1561  } else {
1562  /*
1563  * Check if we have a "smsbox-route" for this msg.
1564  * Where the shortcode route has a higher priority then the smsc-id rule.
1565  * Highest priority has the combined <shortcode>:<smsc-id> route.
1566  */
1567  Octstr *os = octstr_format("%s:%s",
1568  octstr_get_cstr(msg->sms.receiver),
1569  octstr_get_cstr(msg->sms.smsc_id));
1570  s = (msg->sms.smsc_id ? dict_get(smsbox_by_smsc, msg->sms.smsc_id) : NULL);
1571  r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, msg->sms.receiver) : NULL);
1572  rs = (os ? dict_get(smsbox_by_smsc_receiver, os) : NULL);
1573  octstr_destroy(os);
1574 
1575  if (rs)
1576  boxc_id = rs;
1577  else if (r)
1578  boxc_id = r;
1579  else if (s)
1580  boxc_id = s;
1581  }
1582 
1583  /* We have a specific smsbox-id to use */
1584  if (boxc_id != NULL) {
1585 
1586  List *boxc_id_list = dict_get(smsbox_by_id, boxc_id);
1587  if (gwlist_len(boxc_id_list) == 0) {
1588  /*
1589  * something is wrong, this was the smsbox connection we used
1590  * for sending, so it seems this smsbox is gone
1591  */
1592  warning(0, "Could not route message to smsbox id <%s>, smsbox is gone!",
1593  octstr_get_cstr(boxc_id));
1595  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1597  return 0;
1598  } else {
1599  return -1;
1600  }
1601  }
1602 
1603  /*
1604  * Take random smsbox from list, as long as it has space we will use it,
1605  * otherwise check the next one.
1606  */
1607  len = gwlist_len(boxc_id_list);
1608  b = gw_rand() % len;
1609 
1610  for (i = 0; i < len; i++) {
1611  bc = gwlist_get(boxc_id_list, (i+b) % len);
1612 
1613  if (bc != NULL && max_incoming_sms_qlength > 0 &&
1615  bc = NULL;
1616  }
1617 
1618  if (bc != NULL) {
1619  break;
1620  }
1621  }
1622 
1623  if (bc != NULL) {
1624  bc->load++;
1625  gwlist_produce(bc->incoming, msg);
1627  return 1; /* we are done */
1628  }
1629  else {
1630  /*
1631  * we have routing defined, but no smsbox connected at the moment.
1632  * put msg into global incoming queue and wait until smsbox with
1633  * such boxc_id connected.
1634  */
1636  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1638  return 0;
1639  } else {
1640  return -1;
1641  }
1642  }
1643  }
1644 
1645  /*
1646  * Ok, none of the specific routing things applied previously,
1647  * so route it to a random smsbox.
1648  * Take random smsbox from list, as long as it has space we will
1649  * use it, therwise check the next one.
1650  */
1651  len = gwlist_len(smsbox_list);
1652  b = gw_rand() % len;
1653 
1654  for (i = 0; i < len; i++) {
1655  bc = gwlist_get(smsbox_list, (i+b) % len);
1656 
1657  if (bc->boxc_id != NULL || bc->routable == 0)
1658  bc = NULL;
1659 
1660  if (bc != NULL && max_incoming_sms_qlength > 0 &&
1662  full_found = 1;
1663  bc = NULL;
1664  }
1665 
1666  if (bc != NULL) {
1667  break;
1668  }
1669  }
1670 
1671  if (bc != NULL) {
1672  bc->load++;
1673  gwlist_produce(bc->incoming, msg);
1674  }
1675 
1677 
1678  if (bc == NULL && full_found == 0) {
1679  warning(0, "smsbox_list empty!");
1680  if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
1682  return 0;
1683  } else {
1684  return -1;
1685  }
1686  } else if (bc == NULL && full_found == 1) {
1687  return -1;
1688  }
1689 
1690  return 1;
1691 }
List * incoming
Definition: opensmppbox.c:153
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:147
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 Dict * smsbox_by_receiver
Definition: bb_boxc.c:112
long max_incoming_sms_qlength
Definition: bearerbox.c:98
Octstr * boxc_id
Definition: opensmppbox.c:159
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:166
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 856 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().

857 {
858  AddrPar *ap;
859  Boxc *conn, *best;
860  int i, b, len;
861 
862  ap = gwlist_search(route_info, msg, cmp_route);
863  if (ap == NULL) {
864  debug("bb.boxc", 0, "Did not find previous routing info for WDP, "
865  "generating new");
866 route:
867 
868  if (gwlist_len(wapbox_list) == 0)
869  return NULL;
870 
872 
873  /* take random wapbox from list, and then check all wapboxes
874  * and select the one with lowest load level - if tied, the first
875  * one
876  */
877  len = gwlist_len(wapbox_list);
878  b = gw_rand() % len;
879  best = gwlist_get(wapbox_list, b);
880 
881  for(i = 0; i < gwlist_len(wapbox_list); i++) {
882  conn = gwlist_get(wapbox_list, (i+b) % len);
883  if (conn != NULL && best != NULL)
884  if (conn->load < best->load)
885  best = conn;
886  }
887  if (best == NULL) {
888  warning(0, "wapbox_list empty!");
890  return NULL;
891  }
892  conn = best;
893  conn->load++; /* simulate new client until we get new values */
894 
895  ap = gw_malloc(sizeof(AddrPar));
896  ap->address = octstr_duplicate(msg->wdp_datagram.source_address);
897  ap->port = msg->wdp_datagram.source_port;
898  ap->wapboxid = conn->id;
899  gwlist_produce(route_info, ap);
900 
902  } else
903  conn = gwlist_search(wapbox_list, ap, cmp_boxc);
904 
905  if (conn == NULL) {
906  /* routing failed; wapbox has disappeared!
907  * ..remove routing info and re-route */
908 
909  debug("bb.boxc", 0, "Old wapbox has disappeared, re-routing");
910 
911  gwlist_delete_equal(route_info, ap);
912  ap_destroy(ap);
913  goto route;
914  }
915  return conn;
916 }
Octstr * address
Definition: bb_boxc.c:824
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:847
int load
Definition: opensmppbox.c:147
void gwlist_unlock(List *list)
Definition: list.c:354
static void ap_destroy(AddrPar *addr)
Definition: bb_boxc.c:829
int port
Definition: bb_boxc.c:825
#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:146
int wapboxid
Definition: bb_boxc.c:826
int gw_rand(void)
Definition: protected.c:174
static int cmp_route(void *ap, void *ms)
Definition: bb_boxc.c:835
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86

◆ run_smsbox()

static void run_smsbox ( void *  arg)
static

Definition at line 664 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().

665 {
666  Boxc *newconn;
667  long sender;
668  Msg *msg;
669  List *keys;
670  Octstr *key;
671 
673  newconn = arg;
674  newconn->incoming = gwlist_create();
675  gwlist_add_producer(newconn->incoming);
676  newconn->retry = incoming_sms;
677  newconn->outgoing = outgoing_sms;
678  newconn->sent = dict_create(smsbox_max_pending, NULL);
680 
681  sender = gwthread_create(boxc_sender, newconn);
682  if (sender == -1) {
683  error(0, "Failed to start a new thread, disconnecting client <%s>",
684  octstr_get_cstr(newconn->client_ip));
685  goto cleanup;
686  }
687  /*
688  * We register newconn in the smsbox_list here but mark newconn as routable
689  * after identification or first message received from smsbox. So we can avoid
690  * a race condition for routable smsboxes (otherwise between startup and
691  * registration we will forward some messages to smsbox).
692  */
694  gwlist_append(smsbox_list, newconn);
696 
697  gwlist_add_producer(newconn->outgoing);
698  boxc_receiver(newconn);
700 
701  /* remove us from smsbox routing list */
704  if (newconn->boxc_id) {
705 
706  /* Get the list, and remove the connection from it */
707  List *boxc_id_list = dict_get(smsbox_by_id, newconn->boxc_id);
708 
709  if(boxc_id_list != NULL) {
710  gwlist_delete_equal(boxc_id_list, newconn);
711  }
712  }
713 
715 
716  /*
717  * check if we in the shutdown phase and sms dequeueing thread
718  * has removed the producer already
719  */
720  if (gwlist_producer_count(newconn->incoming) > 0)
722 
723  /* check if we are still waiting for ack's and semaphore locked */
724  if (dict_key_count(newconn->sent) >= smsbox_max_pending)
725  semaphore_up(newconn->pending); /* allow sender to go down */
726 
727  gwthread_join(sender);
728 
729  /* put not acked msgs into incoming queue */
730  keys = dict_keys(newconn->sent);
731  while((key = gwlist_extract_first(keys)) != NULL) {
732  msg = dict_remove(newconn->sent, key);
734  octstr_destroy(key);
735  }
736  gw_assert(gwlist_len(keys) == 0);
738 
739  /* clear our send queue */
740  while((msg = gwlist_extract_first(newconn->incoming)) != NULL) {
742  }
743 
744 cleanup:
745  gw_assert(gwlist_len(newconn->incoming) == 0);
746  gwlist_destroy(newconn->incoming, NULL);
747  gw_assert(dict_key_count(newconn->sent) == 0);
748  dict_destroy(newconn->sent);
749  semaphore_destroy(newconn->pending);
750  boxc_destroy(newconn);
751 
752  /* wakeup the dequeueing thread */
754 
756 }
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:153
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:604
Octstr * client_ip
Definition: opensmppbox.c:152
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:155
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:301
List * retry
Definition: opensmppbox.c:154
Definition: msg.h:79
void * dict_remove(Dict *dict, Octstr *key)
Definition: dict.c:307
Octstr * boxc_id
Definition: opensmppbox.c:159
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:122
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:532
static long sms_dequeue_thread
Definition: bb_boxc.c:131
List * flow_threads
Definition: bearerbox.c:116
Dict * sent
Definition: opensmppbox.c:156
void gwlist_add_producer(List *list)
Definition: list.c:383
Semaphore * pending
Definition: opensmppbox.c:157
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 760 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().

761 {
762  Boxc *newconn;
763  List *newlist;
764  long sender;
765 
767  newconn = arg;
768  newconn->is_wap = 1;
769 
770  /*
771  * create a new incoming list for just that box,
772  * and add it to list of list pointers, so we can start
773  * to route messages to it.
774  */
775 
776  debug("bb", 0, "setting up systems for new wapbox");
777 
778  newlist = gwlist_create();
779  /* this is released by the sender/receiver if it exits */
780  gwlist_add_producer(newlist);
781 
782  newconn->incoming = newlist;
783  newconn->retry = incoming_wdp;
784  newconn->outgoing = outgoing_wdp;
785 
786  sender = gwthread_create(boxc_sender, newconn);
787  if (sender == -1) {
788  error(0, "Failed to start a new thread, disconnecting client <%s>",
789  octstr_get_cstr(newconn->client_ip));
790  goto cleanup;
791  }
792  gwlist_append(wapbox_list, newconn);
793  gwlist_add_producer(newconn->outgoing);
794  boxc_receiver(newconn);
795 
796  /* cleanup after receiver has exited */
797 
802 
803  while (gwlist_producer_count(newlist) > 0)
804  gwlist_remove_producer(newlist);
805 
806  newconn->alive = 0;
807 
808  gwthread_join(sender);
809 
810 cleanup:
811  gw_assert(gwlist_len(newlist) == 0);
812  gwlist_destroy(newlist, NULL);
813  boxc_destroy(newconn);
814 
816 }
void error(int err, const char *fmt,...)
Definition: log.c:648
List * incoming
Definition: opensmppbox.c:153
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:604
Octstr * client_ip
Definition: opensmppbox.c:152
List * outgoing
Definition: opensmppbox.c:155
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:301
volatile sig_atomic_t alive
Definition: opensmppbox.c:158
void gwlist_unlock(List *list)
Definition: list.c:354
List * retry
Definition: opensmppbox.c:154
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:532
int is_wap
Definition: opensmppbox.c:145
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 455 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().

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

1695 {
1696  Msg *newmsg, *startmsg, *msg;
1697  long i, len;
1698  int ret = -1;
1699  Boxc *boxc;
1700 
1702 
1703  newmsg = startmsg = msg = NULL;
1704 
1705  while (bb_status != BB_SHUTDOWN && bb_status != BB_DEAD) {
1706 
1707  if (newmsg == startmsg) {
1708  /* check if we are in shutdown phase */
1710  break;
1711 
1712  if (ret == 0 || ret == -1) {
1713  /* debug("", 0, "time to sleep"); */
1714  gwthread_sleep(60.0);
1715  /* debug("", 0, "wake up list len %ld", gwlist_len(incoming_sms)); */
1716  /* shutdown ? */
1718  break;
1719  }
1720  startmsg = msg = gwlist_consume(incoming_sms);
1721  /* debug("", 0, "gwlist_consume done 1"); */
1722  newmsg = NULL;
1723  }
1724  else {
1725  newmsg = msg = gwlist_consume(incoming_sms);
1726 
1727  /* Back at the first message? */
1728  if (newmsg == startmsg) {
1730  continue;
1731  }
1732  }
1733 
1734  if (msg == NULL)
1735  break;
1736 
1737  gw_assert(msg_type(msg) == sms);
1738 
1739  /* debug("bb.sms", 0, "sms_boxc_router: handling message (%p vs %p)",
1740  msg, startmsg); */
1741 
1742  ret = route_incoming_to_boxc(msg);
1743  if (ret == 1)
1744  startmsg = newmsg = NULL;
1745  else if (ret == -1) {
1747  }
1748  }
1749 
1751  len = gwlist_len(smsbox_list);
1752  for (i=0; i < len; i++) {
1753  boxc = gwlist_get(smsbox_list, i);
1755  }
1757 
1759 }
List * incoming
Definition: opensmppbox.c:153
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:1532
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 1301 of file bb_boxc.c.

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

Referenced by bb_graceful_restart().

1302 {
1303  if (!smsbox_running) return -1;
1304 
1309  smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
1310  smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1311  smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1312  init_smsbox_routes(cfg, 1);
1314 
1315  return 0;
1316 }
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 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:1122
void dict_destroy(Dict *dict)
Definition: dict.c:215

◆ smsbox_start()

int smsbox_start ( Cfg cfg)

Definition at line 1236 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_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().

1237 {
1238  CfgGroup *grp;
1239 
1240  if (smsbox_running) return -1;
1241 
1242  debug("bb", 0, "starting smsbox connection module");
1243 
1244  grp = cfg_get_single_group(cfg, octstr_imm("core"));
1245  if (cfg_get_integer(&smsbox_port, grp, octstr_imm("smsbox-port")) == -1) {
1246  error(0, "Missing smsbox-port variable, cannot start smsboxes");
1247  return -1;
1248  }
1249 #ifdef HAVE_LIBSSL
1250  cfg_get_bool(&smsbox_port_ssl, grp, octstr_imm("smsbox-port-ssl"));
1251 #endif /* HAVE_LIBSSL */
1252 
1253  if (smsbox_port_ssl)
1254  debug("bb", 0, "smsbox connection module is SSL-enabled");
1255 
1256  smsbox_interface = cfg_get(grp, octstr_imm("smsbox-interface"));
1257 
1258  if (cfg_get_integer(&smsbox_max_pending, grp, octstr_imm("smsbox-max-pending")) == -1) {
1260  info(0, "BOXC: 'smsbox-max-pending' not set, using default (%ld).", smsbox_max_pending);
1261  }
1262 
1263  box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip"));
1264  if (box_allow_ip == NULL)
1266  box_deny_ip = cfg_get(grp, octstr_imm("box-deny-ip"));
1267  if (box_deny_ip == NULL)
1268  box_deny_ip = octstr_create("");
1269  if (box_allow_ip != NULL && box_deny_ip == NULL)
1270  info(0, "Box connection allowed IPs defined without any denied...");
1271 
1272  smsbox_list = gwlist_create(); /* have a list of connections */
1274  if (!boxid)
1275  boxid = counter_create();
1276 
1277  /* the smsbox routing specific inits */
1278  smsbox_by_id = dict_create(10, (void(*)(void *)) boxc_gwlist_destroy);
1279  smsbox_by_smsc = dict_create(30, (void(*)(void *)) octstr_destroy);
1280  smsbox_by_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1281  smsbox_by_smsc_receiver = dict_create(50, (void(*)(void *)) octstr_destroy);
1282 
1283  /* load the defined smsbox routing rules */
1284  init_smsbox_routes(cfg, 0);
1285 
1288 
1289  smsbox_running = 1;
1290 
1291  if ((sms_dequeue_thread = gwthread_create(sms_to_smsboxes, NULL)) == -1)
1292  panic(0, "Failed to start a new thread for smsbox routing");
1293 
1294  if (gwthread_create(smsboxc_run, NULL) == -1)
1295  panic(0, "Failed to start a new thread for smsbox connections");
1296 
1297  return 0;
1298 }
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:1694
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:116
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:125
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:117
static void smsboxc_run(void *arg)
Definition: bb_boxc.c:1017
static void boxc_gwlist_destroy(List *list)
Definition: bb_boxc.c:1767
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:122
static Dict * smsbox_by_smsc_receiver
Definition: bb_boxc.c:113
static Counter * boxid
Definition: bb_boxc.c:128
static void init_smsbox_routes(Cfg *cfg, int reload)
Definition: bb_boxc.c:1122
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:757
static long smsbox_port
Definition: bb_boxc.c:115
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:740
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Octstr * box_allow_ip
Definition: bb_boxc.c:124
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:131
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:637
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 1017 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_get_cstr, outgoing_sms, panic, run_smsbox(), sms_dequeue_thread, 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().

1018 {
1019  int fd;
1020 
1023 
1025  /* XXX add interface_name if required */
1026 
1027  if (fd < 0) {
1028  panic(0, "Could not open smsbox port %ld", smsbox_port);
1029  }
1030 
1031  /*
1032  * infinitely wait for new connections;
1033  * to shut down the system, SIGTERM is send and then
1034  * select drops with error, so we can check the status
1035  */
1037 
1039 
1040  /* continue avalanche */
1042 
1043  /* all connections do the same, so that all must remove() before it
1044  * is completely over
1045  */
1047  gwthread_sleep(1.0);
1048 
1049  /* close listen socket */
1050  close(fd);
1051 
1054 
1055  gwlist_destroy(smsbox_list, NULL);
1056  smsbox_list = NULL;
1058  smsbox_list_rwlock = NULL;
1059 
1060  /* destroy things related to smsbox routing */
1062  smsbox_by_id = NULL;
1064  smsbox_by_smsc = NULL;
1066  smsbox_by_receiver = NULL;
1068  smsbox_by_smsc_receiver = NULL;
1069 
1071 }
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:116
int gwlist_wait_until_nonempty(List *list)
Definition: list.c:361
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
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:974
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:117
int make_server_socket(int port, const char *interface_name)
Definition: socket.c:93
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:115
#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:131
#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:664
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 974 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().

976 {
977  int ret;
978  int timeout = 10; /* 10 sec. */
979 
980  gw_assert(function != NULL);
981 
982  while(bb_status != BB_DEAD) {
983 
984  /* if we are being shutdowned, as long as there is
985  * messages in incoming list allow new connections, but when
986  * list is empty, exit.
987  * Note: We have timeout (defined above) for which we allow new connections.
988  * Otherwise we wait here for ever!
989  */
990  if (bb_status == BB_SHUTDOWN) {
991  ret = gwlist_wait_until_nonempty(waited);
992  if (ret == -1 || !timeout)
993  break;
994  else
995  timeout--;
996  }
997 
998  /* block here if suspended */
1000 
1001  ret = gwthread_pollfd(fd, POLLIN, 1.0);
1002  if (ret > 0) {
1003  Boxc *newconn = accept_boxc(fd, ssl);
1004  if (newconn != NULL) {
1005  gwthread_create(function, newconn);
1006  gwthread_sleep(1.0);
1007  } else {
1008  error(0, "Failed to create new boxc connection.");
1009  }
1010  } else if (ret < 0 && errno != EINTR && errno != EAGAIN)
1011  error(errno, "bb_boxc::wait_for_connections failed");
1012  }
1013 }
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:620

◆ wapbox_start()

int wapbox_start ( Cfg cfg)

Definition at line 1322 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().

1323 {
1324  CfgGroup *grp;
1325 
1326  if (wapbox_running) return -1;
1327 
1328  debug("bb", 0, "starting wapbox connection module");
1329 
1330  grp = cfg_get_single_group(cfg, octstr_imm("core"));
1331 
1332  if (cfg_get_integer(&wapbox_port, grp, octstr_imm("wapbox-port")) == -1) {
1333  error(0, "Missing wapbox-port variable, cannot start WAP");
1334  return -1;
1335  }
1336 #ifdef HAVE_LIBSSL
1337  cfg_get_bool(&wapbox_port_ssl, grp, octstr_imm("wapbox-port-ssl"));
1338 #endif /* HAVE_LIBSSL */
1339 
1340  if (box_allow_ip == NULL) {
1341  box_allow_ip = cfg_get(grp, octstr_imm("box-allow-ip"));
1342  if (box_allow_ip == NULL)
1344  }
1345  if (box_deny_ip == NULL) {
1346  box_deny_ip = cfg_get(grp, octstr_imm("box-deny-ip"));
1347  if (box_deny_ip == NULL)
1348  box_deny_ip = octstr_create("");
1349  }
1350  if (box_allow_ip != NULL && box_deny_ip == NULL)
1351  info(0, "Box connection allowed IPs defined without any denied...");
1352 
1353  wapbox_list = gwlist_create(); /* have a list of connections */
1355  if (!boxid)
1356  boxid = counter_create();
1357 
1358  if (gwthread_create(wdp_to_wapboxes, NULL) == -1)
1359  panic(0, "Failed to start a new thread for wapbox routing");
1360 
1362  panic(0, "Failed to start a new thread for wapbox connections");
1363 
1364  wapbox_running = 1;
1365  return 0;
1366 }
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:119
#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:125
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:1074
#define gwthread_create(func, arg)
Definition: gwthread.h:90
#define octstr_create(cstr)
Definition: octstr.h:125
static Counter * boxid
Definition: bb_boxc.c:128
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:757
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:740
#define panic
Definition: log.h:87
Definition: cfg.c:73
static Octstr * box_allow_ip
Definition: bb_boxc.c:124
static void wdp_to_wapboxes(void *arg)
Definition: bb_boxc.c:923
#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:637
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:118

◆ wapboxc_run()

static void wapboxc_run ( void *  arg)
static

Definition at line 1074 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().

1075 {
1076  int fd, port;
1077 
1080  port = (int) *((long*)arg);
1081 
1082  fd = make_server_socket(port, NULL);
1083  /* XXX add interface_name if required */
1084 
1085  if (fd < 0) {
1086  panic(0, "Could not open wapbox port %d", port);
1087  }
1088 
1090 
1091  /* continue avalanche */
1092 
1094 
1095 
1096  /* wait for all connections to die and then remove list
1097  */
1098 
1100  gwthread_sleep(1.0);
1101 
1102  /* wait for wdp_to_wapboxes to exit */
1103  while(gwlist_consume(wapbox_list)!=NULL)
1104  ;
1105 
1106  /* close listen socket */
1107  close(fd);
1108 
1109  gwlist_destroy(wapbox_list, NULL);
1110  wapbox_list = NULL;
1111 
1113 }
static void run_wapbox(void *arg)
Definition: bb_boxc.c:760
Definition: http.c:2004
List * outgoing_wdp
Definition: bearerbox.c:88
static int wapbox_port_ssl
Definition: bb_boxc.c:119
int gwlist_wait_until_nonempty(List *list)
Definition: list.c:361
static int port
Definition: fakesmsc.c:120
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited, int ssl)
Definition: bb_boxc.c:974
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 923 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().

924 {
925  List *route_info;
926  AddrPar *ap;
927  Boxc *conn;
928  Msg *msg;
929  int i;
930 
933 
934  route_info = gwlist_create();
935 
936 
937  while(bb_status != BB_DEAD) {
938 
939  gwlist_consume(suspended); /* block here if suspended */
940 
941  if ((msg = gwlist_consume(incoming_wdp)) == NULL)
942  break;
943 
944  gw_assert(msg_type(msg) == wdp_datagram);
945 
946  conn = route_msg(route_info, msg);
947  if (conn == NULL) {
948  warning(0, "Cannot route message, discard it");
949  msg_destroy(msg);
950  continue;
951  }
952  gwlist_produce(conn->incoming, msg);
953  }
954  debug("bb", 0, "wdp_to_wapboxes: destroying lists");
955  while((ap = gwlist_extract_first(route_info)) != NULL)
956  ap_destroy(ap);
957 
958  gw_assert(gwlist_len(route_info) == 0);
959  gwlist_destroy(route_info, NULL);
960 
962  for(i=0; i < gwlist_len(wapbox_list); i++) {
963  conn = gwlist_get(wapbox_list, i);
965  conn->alive = 0;
966  }
968 
971 }
List * incoming
Definition: opensmppbox.c:153
static Boxc * route_msg(List *route_info, Msg *msg)
Definition: bb_boxc.c:856
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:158
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:829
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 124 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 125 of file bb_boxc.c.

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

◆ boxid

Counter* boxid
static

Definition at line 128 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 131 of file bb_boxc.c.

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

◆ 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 117 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 122 of file bb_boxc.c.

Referenced by run_smsbox(), and smsbox_start().

◆ smsbox_port

long smsbox_port
static

Definition at line 115 of file bb_boxc.c.

Referenced by smsbox_start(), and smsboxc_run().

◆ smsbox_port_ssl

int smsbox_port_ssl
static

Definition at line 116 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 118 of file bb_boxc.c.

Referenced by wapbox_start().

◆ wapbox_port_ssl

int wapbox_port_ssl
static

Definition at line 119 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.