73 #include <sys/types.h> 74 #include <sys/socket.h> 83 #define SMSBOX_MAX_PENDING 100 88 extern volatile sig_atomic_t
restart;
135 typedef struct _boxc {
147 volatile sig_atomic_t
alive;
180 info(0,
"Read error when reading from box <%s>, disconnecting",
185 info(0,
"Connection closed by the box <%s>",
192 error(0,
"Connection to box <%s> broke.",
205 error(0,
"Failed to unpack data!");
226 mack->ack.time =
msg->sms.time;
242 warning(0,
"Message rejected by bearerbox, no router!");
256 warning(0,
"Message rejected by bearerbox, %s!",
270 warning(0,
"Message rejected by bearerbox, validity expired!");
284 warning(0,
"Message rejected by bearerbox, white/black listed!");
323 mack->ack.time =
msg->sms.time;
332 debug(
"bb.boxc", 0,
"boxc_receiver: sms received");
343 debug(
"bb.boxc", 0,
"boxc_receiver: got wdp from wapbox");
350 debug(
"bb.boxc", 0,
"boxc_receiver: got sms from wapbox");
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;
377 debug(
"bb.boxc", 0,
"boxc_receiver: got ack");
386 if (
msg->admin.boxc_id != NULL) {
391 List *boxc_id_list = NULL;
405 if (boxc_id_list != NULL) {
416 if (boxc_id_list == NULL) {
432 msg->admin.boxc_id = NULL;
434 debug(
"bb.boxc", 0,
"boxc_receiver: got boxc_id <%s> from <%s>",
444 warning(0,
"boxc_receiver: unknown msg received from <%s>, " 466 debug(
"bb.boxc", 0,
"send_msg: sending msg to boxc: <%s>",
469 debug(
"bb.boxc", 0,
"send_msg: sending msg to box: <%s>",
473 error(0,
"Couldn't write Msg to box <%s>, disconnecting",
521 error(0,
"BOXC: Got ack for nonexistend message!");
559 debug(
"bb.boxc", 0,
"boxc_sender: catch an heartbeat - we are alive");
571 debug(
"bb.boxc", 0,
"boxc_sender: sent message to <%s>",
592 boxc = gw_malloc(
sizeof(
Boxc));
627 struct sockaddr_in client_addr;
630 client_addr_len =
sizeof(client_addr);
632 newfd = accept(fd, (
struct sockaddr *)&client_addr, &client_addr_len);
639 info(0,
"Box connection tried from denied host <%s>, disconnected",
652 if (
ssl && !conn_get_ssl(newconn->
conn))
684 error(0,
"Failed to start a new thread, disconnecting client <%s>",
710 if(boxc_id_list != NULL) {
777 debug(
"bb", 0,
"setting up systems for new wapbox");
789 error(0,
"Failed to start a new thread, disconnecting client <%s>",
841 if (
msg->wdp_datagram.source_port == addr->
port &&
865 debug(
"bb.boxc", 0,
"Did not find previous routing info for WDP, " 884 if (conn != NULL && best != NULL)
889 warning(0,
"wapbox_list empty!");
896 ap = gw_malloc(
sizeof(
AddrPar));
898 ap->
port =
msg->wdp_datagram.source_port;
910 debug(
"bb.boxc", 0,
"Old wapbox has disappeared, re-routing");
949 warning(0,
"Cannot route message, discard it");
955 debug(
"bb", 0,
"wdp_to_wapboxes: destroying lists");
993 if (ret == -1 || !timeout)
1005 if (newconn != NULL) {
1009 error(0,
"Failed to create new boxc connection.");
1011 }
else if (ret < 0 && errno != EINTR && errno != EAGAIN)
1012 error(errno,
"bb_boxc::wait_for_connections failed");
1083 port = (int) *((
long*)arg);
1089 panic(0,
"Could not open wapbox port %d",
port);
1118 #define RELOAD_PANIC(...) \ 1119 if (reload) { error(__VA_ARGS__); continue; } \ 1120 else panic(__VA_ARGS__); 1129 Octstr *boxc_id, *smsc_ids, *shortcuts;
1132 boxc_id = smsc_ids = shortcuts = NULL;
1141 RELOAD_PANIC(0,
"'smsbox-route' group without valid 'smsbox-id' directive!");
1157 if (smsc_ids && !shortcuts) {
1164 debug(
"bb.boxc",0,
"Adding smsbox routing to id <%s> for smsc id <%s>",
1168 RELOAD_PANIC(0,
"Routing for smsc-id <%s> already exists!",
1175 else if (!smsc_ids && shortcuts) {
1182 debug(
"bb.boxc",0,
"Adding smsbox routing to id <%s> for receiver no <%s>",
1186 RELOAD_PANIC(0,
"Routing for receiver no <%s> already exists!",
1193 else if (smsc_ids && shortcuts) {
1205 debug(
"bb.boxc",0,
"Adding smsbox routing to id <%s> " 1206 "for receiver no <%s> and smsc id <%s>",
1214 RELOAD_PANIC(0,
"Routing for receiver:smsc <%s> already exists!",
1226 debug(
"bb.boxc",0,
"Adding smsbox default routing to id <%s>",
1230 RELOAD_PANIC(0,
"Default smsbox routing to id <%s> already exists!",
1256 debug(
"bb", 0,
"starting smsbox connection module");
1260 error(0,
"Missing smsbox-port variable, cannot start smsboxes");
1268 debug(
"bb", 0,
"smsbox connection module is SSL-enabled");
1284 info(0,
"Box connection allowed IPs defined without any denied...");
1307 panic(0,
"Failed to start a new thread for smsbox routing");
1310 panic(0,
"Failed to start a new thread for smsbox connections");
1345 debug(
"bb", 0,
"starting wapbox connection module");
1350 error(0,
"Missing wapbox-port variable, cannot start WAP");
1368 info(0,
"Box connection allowed IPs defined without any denied...");
1376 panic(0,
"Failed to start a new thread for wapbox routing");
1379 panic(0,
"Failed to start a new thread for wapbox connections");
1390 int i, boxes, para = 0;
1406 ws =
" ";
1420 tmp =
octstr_format(
"%sBox connections:%s", para ?
"<p>" :
"", lb);
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,
1438 conn_get_ssl(bi->
conn) != NULL ?
"yes" :
"no" 1445 "%swapbox, IP %s (on-line %ldd %ldh %ldm %lds) %s %s",
1447 t/3600/24, t/3600%24, t/60%60, t%60,
1449 conn_get_ssl(bi->
conn) != NULL ?
"using SSL" :
"",
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>",
1474 t/3600/24, t/3600%24, t/60%60, t%60,
1476 conn_get_ssl(bi->
conn) != NULL ?
"yes" :
"no" 1482 octstr_format_append(tmp,
"%ssmsbox:%s, IP %s (%ld queued), (on-line %ldd %ldh %ldm %lds) %s %s",
1485 t/3600/24, t/3600%24, t/60%60, t%60,
1487 conn_get_ssl(bi->
conn) != NULL ?
"using SSL" :
"",
1498 tmp =
octstr_format(
"%sNo boxes connected", para ?
"<p>" :
"");
1552 Octstr *s, *r, *rs, *boxc_id = NULL;
1564 warning(0,
"smsbox_list empty!");
1577 boxc_id =
msg->sms.boxc_id;
1603 if (boxc_id != NULL) {
1611 warning(0,
"Could not route message to smsbox id <%s>, smsbox is gone!",
1629 for (i = 0; i < len; i++) {
1673 for (i = 0; i < len; i++) {
1697 if (bc == NULL && full_found == 0) {
1698 warning(0,
"smsbox_list empty!");
1705 }
else if (bc == NULL && full_found == 1) {
1715 Msg *newmsg, *startmsg, *
msg;
1722 newmsg = startmsg =
msg = NULL;
1726 if (newmsg == startmsg) {
1731 if (ret == 0 || ret == -1) {
1747 if (newmsg == startmsg) {
1763 startmsg = newmsg = NULL;
1764 else if (ret == -1) {
1771 for (i=0; i < len; i++) {
Dict * dict_create(long size_hint, void(*destroy_value)(void *))
void msg_dump(Msg *msg, int level)
static volatile sig_atomic_t smsbox_running
void error(int err, const char *fmt,...)
static void run_wapbox(void *arg)
void info(int err, const char *fmt,...)
int boxc_incoming_wdp_queue(void)
static Boxc * route_msg(List *route_info, Msg *msg)
Msg * msg_duplicate(Msg *msg)
void * gwlist_search(List *list, void *pattern, int(*cmp)(void *, void *))
static void sms_to_smsboxes(void *arg)
static Msg * read_from_box(Boxc *boxconn)
gw_assert(wtls_machine->packet_to_send !=NULL)
void dict_put(Dict *dict, Octstr *key, void *value)
void counter_destroy(Counter *counter)
void gwlist_append(List *list, void *item)
char * bb_status_linebreak(int status_type)
static int wapbox_port_ssl
static void boxc_destroy(Boxc *boxc)
static Dict * smsbox_by_smsc
void semaphore_destroy(Semaphore *semaphore)
void gwlist_produce(List *list, void *item)
void gwthread_join(long thread)
static RWLock * smsbox_list_rwlock
long gwlist_len(List *list)
int(* store_save_ack)(Msg *msg, ack_status_t status)
void gw_rwlock_destroy(RWLock *lock)
int gw_rwlock_wrlock(RWLock *lock)
volatile sig_atomic_t restart
void * gwlist_get(List *list, long pos)
static int cmp_boxc(void *bc, void *ap)
static void boxc_sent_pop(Boxc *, Msg *, Msg **)
#define cfg_get(grp, varname)
void uuid_unparse(const uuid_t uu, char *out)
static int smsbox_port_ssl
RWLock * gw_rwlock_create(void)
int gw_rwlock_rdlock(RWLock *lock)
void octstr_append_cstr(Octstr *ostr, const char *cstr)
static Octstr * box_deny_ip
int conn_eof(Connection *conn)
void octstr_strip_blanks(Octstr *text)
int gwlist_wait_until_nonempty(List *list)
#define octstr_get_cstr(ostr)
unsigned long counter_increase(Counter *counter)
static Octstr * smsbox_by_default
int is_allowed_ip(Octstr *allow_ip, Octstr *deny_ip, Octstr *ip)
static void boxc_receiver(void *arg)
static Dict * smsbox_by_receiver
volatile sig_atomic_t alive
#define RELOAD_PANIC(...)
void semaphore_down(Semaphore *semaphore)
void gwlist_unlock(List *list)
volatile sig_atomic_t bb_status
static Boxc * boxc_create(int fd, Octstr *ip, int ssl)
long max_incoming_sms_qlength
Octstr * octstr_imm(const char *cstr)
static int send_msg(Boxc *boxconn, Msg *pmsg)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
void * dict_remove(Dict *dict, Octstr *key)
Counter * counter_create(void)
void * gwlist_extract_first(List *list)
void grp_dump(CfgGroup *grp)
static void wait_for_connections(int fd, void(*function)(void *arg), List *waited, int ssl)
static void ap_destroy(AddrPar *addr)
void * dict_get(Dict *dict, Octstr *key)
void gwlist_remove_producer(List *list)
void conn_destroy(Connection *conn)
static void deliver_sms_to_queue(Msg *msg, Boxc *conn)
void octstr_insert_char(Octstr *ostr, long pos, const char c)
int route_incoming_to_boxc(Msg *msg)
#define octstr_duplicate(ostr)
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
static Dict * smsbox_by_id
int smsbox_start(Cfg *cfg)
long dict_key_count(Dict *dict)
long gwlist_delete_equal(List *list, void *item)
void uuid_copy(uuid_t dst, const uuid_t src)
void msg_destroy(Msg *msg)
int gw_rwlock_unlock(RWLock *lock)
static Octstr * smsbox_interface
static void smsboxc_run(void *arg)
static void wapboxc_run(void *arg)
static void boxc_gwlist_destroy(List *list)
int make_server_socket(int port, const char *interface_name)
void warning(int err, const char *fmt,...)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define gwthread_create(func, arg)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
static long smsbox_max_pending
void gwthread_sleep(double seconds)
static Dict * smsbox_by_smsc_receiver
Octstr * conn_read_withlen(Connection *conn)
int conn_write_withlen(Connection *conn, Octstr *data)
int smsbox_restart(Cfg *cfg)
void gwlist_insert(List *list, long pos, void *item)
int gwthread_pollfd(int fd, int events, double timeout)
void gwlist_lock(List *list)
void semaphore_up(Semaphore *semaphore)
static void init_smsbox_routes(Cfg *cfg, int reload)
long octstr_len(const Octstr *ostr)
void dict_destroy(Dict *dict)
int cfg_get_bool(int *n, CfgGroup *grp, Octstr *varname)
int conn_wait(Connection *conn, double seconds)
void * gwlist_consume(List *list)
Octstr * host_ip(struct sockaddr_in addr)
void debug(const char *place, int err, const char *fmt,...)
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
int wapbox_start(Cfg *cfg)
void gwthread_wakeup(long thread)
static Octstr * box_allow_ip
void octstr_format_append(Octstr *os, const char *fmt,...)
static List * smsbox_list
static void wdp_to_wapboxes(void *arg)
static void boxc_sent_push(Boxc *, Msg *)
Octstr * msg_pack(Msg *msg)
List * dict_keys(Dict *dict)
static Boxc * accept_boxc(int fd, int ssl)
static List * wapbox_list
Octstr * boxc_status(int status_type)
int(* store_save)(Msg *msg)
static void boxc_sender(void *arg)
static long sms_dequeue_thread
int dict_put_once(Dict *dict, Octstr *key, void *value)
int conn_error(Connection *conn)
static void run_smsbox(void *arg)
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
void gwlist_add_producer(List *list)
static volatile sig_atomic_t wapbox_running
Semaphore * semaphore_create(long n)
static int cmp_route(void *ap, void *ms)
List * octstr_split(const Octstr *os, const Octstr *sep)
static XMLRPCDocument * msg
#define SMSBOX_MAX_PENDING
int gwlist_producer_count(List *list)
Connection * conn_wrap_fd(int fd, int ssl)
int conn_flush(Connection *conn)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
long smsc2_rout(Msg *msg, int resend)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)