Esempio n. 1
0
/*
 * Main function for timer thread.
 */
static void watch_timers(void *arg)
{
    Timerset *set;
    long top_time;
    long now;

    set = arg;

    while (!set->stopping) {
        lock(set);

	now = time(NULL);

	while (set->heap->len > 0 && set->heap->tab[0]->elapses <= now) {
	    elapse_timer(set->heap->tab[0]);
	    heap_delete(set->heap, 0);
	}

	/*
	 * Now sleep until the next timer elapses.  If there isn't one,
	 * then just sleep very long.  We will get woken up if the
	 * top of the heap changes before we wake.
	 */

        if (set->heap->len == 0) {
            unlock(set);
            gwthread_sleep(1000000.0);
        } else {
	    top_time = set->heap->tab[0]->elapses;
	    unlock(set);
	    gwthread_sleep(top_time - now);
	}
    }
}
Esempio n. 2
0
static void smsbox_thread(void *arg)
{
    Connection *conn;
    Msg *msg;
    Octstr *os;
    Octstr *reply_msg;
    unsigned long count;
    
    msg = msg_create(sms);
    msg->sms.sender = octstr_create("123");
    msg->sms.receiver = octstr_create("456");
    msg->sms.msgdata = octstr_create("hello world");
    reply_msg = msg_pack(msg);
    msg_destroy(msg);

    gwthread_sleep(1.0);
    conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
    if (conn == NULL) {
	gwthread_sleep(2.0);
	conn = conn_open_tcp(bearerbox_host, port_for_smsbox, NULL);
    	if (conn == NULL)
	    panic(0, "Couldn't connect to bearerbox as smsbox");
    }

    while (!quitting && conn_wait(conn, -1.0) != -1) {
    	for (;;) {
	    os = conn_read_withlen(conn);
	    if (os == NULL) {
		if (conn_eof(conn) || conn_error(conn))
		    goto error;
		break;
	    }
	    
	    msg = msg_unpack(os);
	    if (msg == NULL || msg->type == wdp_datagram)
		error(0, "Bearerbox sent garbage to smsbox");

	    if (msg->type == sms) {
		if (first_from_bb == (time_t) -1)
		    time(&first_from_bb);
		count = counter_increase(num_from_bearerbox) + 1;
		debug("test.smpp", 0, 
		      "Bearerbox sent sms #%ld <%s> to smsbox, sending reply.",
		      count, octstr_get_cstr(msg->sms.msgdata));
		if (count == max_to_esme)
		    info(0, "Bearerbox has sent all messages to smsbox.");
		conn_write_withlen(conn, reply_msg);
		counter_increase(num_to_bearerbox);
	    }
	    msg_destroy(msg);
	    octstr_destroy(os);
	    time(&last_to_bb);
	}
    }
    
error:
    conn_destroy(conn);
    octstr_destroy(reply_msg);
    debug("test.smpp", 0, "%s terminates.", __func__);
}
Esempio n. 3
0
DBPoolConn *dbpool_conn_consume(DBPool *p)
{
    DBPoolConn *pc;

    gw_assert(p != NULL && p->pool != NULL);
    
    /* check for max connections and if 0 return NULL */
    if (p->max_size < 1)
        return NULL;

    /* check if we have any connection */
    while (p->curr_size < 1) {
        debug("dbpool", 0, "DBPool has no connections, reconnecting up to maximum...");
        /* dbpool_increase ensure max_size is not exceeded so don't lock */
        dbpool_increase(p, p->max_size - p->curr_size);
        if (p->curr_size < 1)
            gwthread_sleep(0.1);
    }

    /* garantee that you deliver a valid connection to the caller */
    while ((pc = gwlist_consume(p->pool)) != NULL) {

        /* 
         * XXX check that the connection is still existing.
         * Is this a performance bottle-neck?!
         */
        if (!pc->conn || (p->db_ops->check && p->db_ops->check(pc->conn) != 0)) {
            /* something was wrong, reinitialize the connection */
            /* lock dbpool for update */
            gwlist_lock(p->pool);
            dbpool_conn_destroy(pc);
            p->curr_size--;
            /* unlock dbpool for update */
            gwlist_unlock(p->pool);
            /*
             * maybe not needed, just try to get next connection, but it
             * can be dangeros if all connections where broken, then we will
             * block here for ever.
             */
            while (p->curr_size < 1) {
                debug("dbpool", 0, "DBPool has too few connections, reconnecting up to maximum...");
                /* dbpool_increase ensure max_size is not exceeded so don't lock */
                dbpool_increase(p, p->max_size - p->curr_size);
                if (p->curr_size < 1)
                    gwthread_sleep(0.1);
            }

        } else {
            break;
        }
    }

    return (pc->conn != NULL ? pc : NULL);
}
Esempio n. 4
0
static void main_thread() {
	while (httpbox_status == SMPP_RUNNING) {
		readQueueMessages();
		gwthread_sleep(1.0);

	}
}
Esempio n. 5
0
/*
 * Send a message to the bearerbox for delivery to a phone.
 * Return >= 0 for success & count of splitted sms messages, 
 * -1 for failure.  Does not destroy the msg.
 */
static int send_message(Msg *msg)
{
    unsigned long msg_count;
    List *list;
    
    gw_assert(msg != NULL);
    gw_assert(msg_type(msg) == sms);
    
    /* 
     * Encode our smsbox-id to the msg structure.
     * This will allow bearerbox to return specific answers to the
     * same smsbox, mainly for DLRs and SMS proxy modes.
     */
    if (smsbox_id != NULL) {
        msg->sms.boxc_id = octstr_duplicate(smsbox_id);
    }
    
    list = sms_split(msg, NULL, NULL, NULL, NULL, 1, 0, 100, MAX_SMS_OCTETS);
    msg_count = gwlist_len(list);
    gwlist_destroy(list, msg_destroy_item);

    debug("sms", 0, "message length %ld, sending %ld messages", 
          octstr_len(msg->sms.msgdata), msg_count);

    if (delay > 0)
        gwthread_sleep(delay);

    /* pass message to bearerbox */
    if (deliver_to_bearerbox(msg) != 0)
        return -1;
    
    return msg_count;
}
Esempio n. 6
0
void mbuni_mm1_queue_runner(volatile sig_atomic_t  *rstop)
{
     settings->qfs->mms_queue_run(octstr_get_cstr(settings->mm1_queuedir), 
		   sendNotify, settings->mm1_queue_interval, settings->maxthreads, rstop);
     gwthread_sleep(2); /* Wait for it to die. */
     return;     
}
Esempio n. 7
0
static void wait_for_connections(int fd, void (*function) (void *arg),
                                 List *waited)
{
    int ret;
    int timeout = 10; /* 10 sec. */

    gw_assert(function != NULL);

    while(sqlbox_status == SQL_RUNNING) {

        ret = gwthread_pollfd(fd, POLLIN, 1.0);
        if (sqlbox_status == SQL_SHUTDOWN) {
            if (ret == -1 || !timeout)
                    break;
                else
                    timeout--;
        }

        if (ret > 0) {
            gwthread_create(function, (void *)fd);
            gwthread_sleep(1.0);
        } else if (ret < 0) {
            if(errno==EINTR) continue;
            if(errno==EAGAIN) continue;
            error(errno, "wait_for_connections failed");
        }
    }
}
Esempio n. 8
0
/*
 * check if the password matches. Return NULL if
 * it does (or is not required)
 */
static Octstr *httpd_check_authorization(List *cgivars, int status)
{
    Octstr *password;
    static double sleep = 0.01;

    password = http_cgi_variable(cgivars, "password");

    if (status) {
	if (ha_status_pw == NULL)
	    return NULL;

	if (password == NULL)
	    goto denied;

	if (octstr_compare(password, ha_password)!=0
	    && octstr_compare(password, ha_status_pw)!=0)
	    goto denied;
    }
    else {
	if (password == NULL || octstr_compare(password, ha_password)!=0)
	    goto denied;
    }
    sleep = 0.0;
    return NULL;	/* allowed */
denied:
    gwthread_sleep(sleep);
    sleep += 1.0;		/* little protection against brute force
				 * password cracking */
    return octstr_create("Denied");
}
Esempio n. 9
0
int main(int argc, char **argv)
{
    Connection *conn;
    Octstr *host = NULL;
    int port, i;
    
    gwlib_init();

    get_and_set_debugs(argc, argv, NULL);

    host = octstr_create(argv[1]);    
    port = atoi(argv[2]);
    i = 50;
    
    debug("",0,"Connecting to host '%s', port %d, looping %i times.", 
          octstr_get_cstr(host), port, i);
    
    for (i = 0; i <= 50; i++) {
        conn = conn_open_tcp(host, port, NULL);
        if (conn == NULL) {
            panic(0, "Couldn't connect.");
        }
        debug("",0,"%d: connected.", i);
        gwthread_sleep(0.2);
        debug("",0,"%d: closing.", i);
        conn_destroy(conn);
    }

    octstr_destroy(host);
    gwlib_shutdown();
    return 0;
}
Esempio n. 10
0
static void smsboxc_run(void *arg)
{
    int fd;
    int port;

    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    port = (int) *((long *)arg);
    
    fd = make_server_socket(port, NULL); 
    /* XXX add interface_name if required */

    if (fd < 0) {
        panic(0, "Could not open smsbox port %d", port);
    }

    /*
     * infinitely wait for new connections;
     * to shut down the system, SIGTERM is send and then
     * select drops with error, so we can check the status
     */
    wait_for_connections(fd, run_smsbox, incoming_sms, smsbox_port_ssl);

    gwlist_remove_producer(smsbox_list);

    /* continue avalanche */
    gwlist_remove_producer(outgoing_sms);

    /* all connections do the same, so that all must remove() before it
     * is completely over
     */
    while(gwlist_wait_until_nonempty(smsbox_list) == 1)
        gwthread_sleep(1.0);

    /* close listen socket */
    close(fd);

    gwthread_wakeup(sms_dequeue_thread);
    gwthread_join(sms_dequeue_thread);

    gwlist_destroy(smsbox_list, NULL);
    smsbox_list = NULL;
    gw_rwlock_destroy(smsbox_list_rwlock);
    smsbox_list_rwlock = NULL;

    /* destroy things related to smsbox routing */
    dict_destroy(smsbox_by_id);
    smsbox_by_id = NULL;
    dict_destroy(smsbox_by_smsc);
    smsbox_by_smsc = NULL;
    dict_destroy(smsbox_by_receiver);
    smsbox_by_receiver = NULL;
    dict_destroy(smsbox_by_smsc_receiver);
    smsbox_by_smsc_receiver = NULL;
    
    gwlist_remove_producer(flow_threads);
}
Esempio n. 11
0
int main(int argc, char **argv) {
	int cf_index;
	Octstr *filename, *version;

	gwlib_init();
	list_dict = dict_create(32, msg_list_destroy_item);

	cf_index = get_and_set_debugs(argc, argv, check_args);
	setup_signal_handlers();

	if (argv[cf_index] == NULL)
		filename = octstr_create("httpClient.conf");
	else
		filename = octstr_create(argv[cf_index]);

	cfg = cfg_create(filename);

	/* Adding cfg-checks to core */
	cfg_add_hooks(smppbox_is_allowed_in_group, smppbox_is_single_group);

	if (cfg_read(cfg) == -1)
		panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));

	octstr_destroy(filename);

	version = octstr_format("httpClient version %s gwlib", GW_VERSION);
	report_versions(octstr_get_cstr(version));
	octstr_destroy(version);

	struct server_type *res = NULL;
	res = sqlbox_init_mysql(cfg);
	sqlbox_configure_mysql(cfg);

	init_smpp_server_box(cfg);
	http_client_box_run();

	//gwthread_join_every(sql_to_smpp);
	//gwthread_join_every(smpp_to_sql);
	smpp_server_box_shutdown();

	dict_destroy(list_dict);
	list_dict = NULL;

	cfg_destroy(cfg);

	if (restart_httpbox) {
		gwthread_sleep(1.0);
	}

	gw_smpp_leave();
	gwlib_shutdown();

	if (restart_httpbox)
		execvp(argv[0], argv);
	return 0;
}
Esempio n. 12
0
static Connection *cgw_open_send_connection(SMSCConn *conn)
{
    PrivData *privdata = conn->data;
    int wait;
    Connection *server;
    Msg *msg;

    wait = 0;
    while (!privdata->shutdown) {

        /* Change status only if the first attempt to form a
	 * connection fails, as it's possible that the SMSC closed the
	 * connection because of idle timeout and a new one will be
	 * created quickly. */
        if (wait) {
            if (conn->status == SMSCCONN_ACTIVE) {
                mutex_lock(conn->flow_mutex);
                conn->status = SMSCCONN_RECONNECTING;
                mutex_unlock(conn->flow_mutex);
            }
            while ((msg = gwlist_extract_first(privdata->outgoing_queue)))
                bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
            info(0, "smsc_cgw: waiting for %d minutes before trying to connect again", wait);
            gwthread_sleep(wait * 60);
            wait = wait > 5 ? 10 : wait * 2;
        } else
            wait = 1;

        server = conn_open_tcp_with_port(privdata->host, privdata->port,
                                         privdata->our_port, conn->our_host);

        if (privdata->shutdown) {
            conn_destroy(server);
            return NULL;
        }

        if (server == NULL) {
            error(0, "smsc_cgw: opening TCP connection to %s failed", octstr_get_cstr(privdata->host));
            continue;
        }

        if (conn->status != SMSCCONN_ACTIVE) {
            mutex_lock(conn->flow_mutex);
            conn->status = SMSCCONN_ACTIVE;
            conn->connect_time = time(NULL);
            mutex_unlock(conn->flow_mutex);
            bb_smscconn_connected(conn);
        }
        return server;
    }
    return NULL;
}
Esempio n. 13
0
static void client_thread(void *arg) 
{
    List *reqh;
    unsigned long i;
    long succeeded, failed;
    HTTPCaller *caller;
    char buf[1024];
    long in_queue;
    Counter *counter = NULL;

    caller = arg;
    succeeded = 0;
    failed = 0;
    reqh = gwlist_create();
    sprintf(buf, "%ld", (long) gwthread_self());
    http_header_add(reqh, "X-Thread", buf);
    if (auth_username != NULL && auth_password != NULL)
	http_add_basic_auth(reqh, auth_username, auth_password);

    in_queue = 0;
    counter = counter_create();
    
    for (;;) {
	    i = counter_increase(counter);
	    if (i >= max_requests)
	    	goto receive_rest;
	    start_request(caller, reqh, i);
	    if (interval > 0)
            gwthread_sleep(interval);
        ++in_queue;
	    if (receive_reply(caller) == -1)
	       ++failed;
    	else
	    	++succeeded;
	    --in_queue;
    }

receive_rest:
    while (in_queue > 0) {
	if (receive_reply(caller) == -1)
	    ++failed;
	else
	    ++succeeded;
    	--in_queue;
    }

    counter_destroy(counter);
    http_destroy_headers(reqh);
    http_caller_destroy(caller);
    info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed);
}
Esempio n. 14
0
static void sql_list(Boxc *boxc)
{
    Msg *msg;
    List *qlist, *save_list;

    qlist = gwlist_create();
    gwlist_add_producer(qlist);
    save_list = gwlist_create();
    gwlist_add_producer(save_list);

    while (sqlbox_status == SQL_RUNNING && boxc->alive) {
	if ( gw_sql_fetch_msg_list(qlist, limit_per_cycle) > 0 ) {
	    while((gwlist_len(qlist)>0) && ((msg = gwlist_consume(qlist)) != NULL )) {
                if (charset_processing(msg) == -1) {
                    error(0, "Could not charset process message, dropping it!");
                    msg_destroy(msg);
                    continue;
                }
                if (global_sender != NULL && (msg->sms.sender == NULL || octstr_len(msg->sms.sender) == 0)) {
                    msg->sms.sender = octstr_duplicate(global_sender);
                }
                /* convert validity and deferred to unix timestamp */
                if (msg->sms.validity != SMS_PARAM_UNDEFINED)
                    msg->sms.validity = time(NULL) + msg->sms.validity * 60;
                if (msg->sms.deferred != SMS_PARAM_UNDEFINED)
                    msg->sms.deferred = time(NULL) + msg->sms.deferred * 60;
                send_msg(boxc->bearerbox_connection, boxc, msg);
    
                /* convert validity & deferred back to minutes */
                if (save_mt && msg->sms.validity != SMS_PARAM_UNDEFINED)
                    msg->sms.validity = (msg->sms.validity - time(NULL))/60;
                if (save_mt && msg->sms.deferred != SMS_PARAM_UNDEFINED)
                    msg->sms.deferred = (msg->sms.deferred - time(NULL))/60;
		gwlist_produce(save_list, msg);
            }
            /* save_list also deletes and destroys messages */
	    gw_sql_save_list(save_list, octstr_imm("MT"), save_mt);
        }
        else {
            gwthread_sleep(SLEEP_BETWEEN_EMPTY_SELECTS);
        }
    }

    gwlist_remove_producer(qlist);
    gwlist_remove_producer(save_list);
    gwlist_destroy(qlist, msg_destroy_item);
    gwlist_destroy(save_list, msg_destroy_item);
}
Esempio n. 15
0
int restart_box(char **argv)
{
    int rc;

    if (!(rc = fork())) {
        /*
         * Sleep a while in order to get father
         * process time to cleanup things
         */
        gwthread_sleep(1.0);
        if (execvp(argv[0],argv) == -1)
            error(errno, "Unable to start new process.");
    } else if (rc == -1)
        error(errno, "Could not restart, exiting...");

    return rc == -1 ? -1 : 0;
}
Esempio n. 16
0
static void push_thread(void *arg)
{
    HTTPCaller *caller;
    long succeeded, failed, in_queue;
    unsigned long i;

    caller = arg;
    succeeded = 0;
    failed = 0;   
    in_queue = 0;
    i = 0;

    for (;;) {
        while (in_queue < MAX_IN_QUEUE) {
	        i = counter_increase(counter);
            if (i >= max_pushes)
	            goto receive_rest;
            start_push(caller, i);
            if (wait_seconds > 0)
                gwthread_sleep(wait_seconds);
            ++in_queue;
        }

        while (in_queue >= MAX_IN_QUEUE) {
	        if (receive_push_reply(caller) == -1)
	            ++failed;
            else
	            ++succeeded;
            --in_queue;
        }
    }

receive_rest:
    while (in_queue > 0) {
        if (receive_push_reply(caller) == -1)
	        ++failed;
        else
	        ++succeeded;
        --in_queue;
    }

    http_caller_destroy(caller);
    info(0, "TEST_PPG: In thread %ld %ld succeeded, %ld failed", 
         (long) gwthread_self(), succeeded, failed);
}
Esempio n. 17
0
int main(int argc, char **argv)
{
    int cf_index;
    Octstr *filename;

    gwlib_init();

    cf_index = get_and_set_debugs(argc, argv, check_args);
    setup_signal_handlers();

    if (argv[cf_index] == NULL) {
        filename = octstr_create("sqlbox.conf");
    } else {
        filename = octstr_create(argv[cf_index]);
    }

    cfg = cfg_create(filename);

    /* Adding cfg-checks to core */

    cfg_add_hooks(sqlbox_is_allowed_in_group, sqlbox_is_single_group);

    if (cfg_read(cfg) == -1)
        panic(0, "Couldn't read configuration from `%s'.", octstr_get_cstr(filename));

    octstr_destroy(filename);

    report_versions("sqlbox");

    init_sqlbox(cfg);

    sqlboxc_run((void *)sqlbox_port);

    cfg_destroy(cfg);
    if (restart_sqlbox) {
        gwthread_sleep(1.0);
    }

    gw_sql_leave();
    gwlib_shutdown();

    if (restart_sqlbox)
        execvp(argv[0], argv);
    return 0;
}
Esempio n. 18
0
int main(void)
{
    Dict *dict;
    Octstr *foo, *bar;
    unsigned long i;

    gwlib_init();

    foo = octstr_imm("foo");
    bar = octstr_imm("bar");

    debug("",0,"Dict simple test.");
    dict = dict_create(10, NULL);
    dict_put(dict, foo, bar);
    info(0, "foo gives %s", octstr_get_cstr(dict_get(dict, foo)));
    if (dict_key_count(dict) == 1)
        info(0, "there is but one foo.");
    else
        error(0, "key count is %ld, should be 1.", dict_key_count(dict));
    dict_destroy(dict);

    debug("",0,"Dict extended/huge test.");
    dict = dict_create(HUGE_SIZE, (void (*)(void *))octstr_destroy);
    for (i = 1; i <= HUGE_SIZE; i++) {
        unsigned long val;
        Octstr *okey, *oval;
        uuid_t id;
        char key[UUID_STR_LEN + 1];
        uuid_generate(id);
        uuid_unparse(id, key);
        val = gw_rand();
        okey = octstr_create(key);
        oval = octstr_format("%ld", val);
        dict_put(dict, okey, oval);
    }
    gwthread_sleep(5); /* give hash table some time */
    if (dict_key_count(dict) == HUGE_SIZE)
        info(0, "ok, got %d entries in the dictionary.", HUGE_SIZE);
    else
        error(0, "key count is %ld, should be %d.", dict_key_count(dict), HUGE_SIZE);
    dict_destroy(dict);

    gwlib_shutdown();
    return 0;
}
Esempio n. 19
0
static void send_smpp_thread(void *arg)
{
    ESME *esme;
    Octstr *os;
    SMPP_PDU *pdu;
    unsigned long id;

    esme = arg;
    
    id = 0;
    while (!quitting && counter_value(num_to_esme) < max_to_esme) {
        id = counter_increase(num_to_esme) + 1;
        while (!quitting && counter_value(num_from_esme) + 500 < id)
            gwthread_sleep(1.0);
        if (quitting)
            break;
        pdu = smpp_pdu_create(deliver_sm, counter_increase(message_id_counter));
        pdu->u.deliver_sm.source_addr = octstr_create("456");
        pdu->u.deliver_sm.destination_addr = octstr_create("123");
        pdu->u.deliver_sm.short_message = octstr_format("%ld", id);
        if (esme->version > 0x33)
            pdu->u.deliver_sm.receipted_message_id = octstr_create("receipted_message_id\0");
        os = smpp_pdu_pack(NULL, pdu);
        conn_write(esme->conn, os);
        octstr_destroy(os);
        smpp_pdu_destroy(pdu);
        if (first_to_esme == (time_t) -1)
            time(&first_to_esme);
        debug("test.smpp", 0, "Delivered SMS %ld of %ld to bearerbox via SMPP.",
              id, max_to_esme);

        if ((id % enquire_interval) == 0) {
            pdu = smpp_pdu_create(enquire_link, counter_increase(message_id_counter));
            os = smpp_pdu_pack(NULL, pdu);
            conn_write(esme->conn, os);
            octstr_destroy(os);
            smpp_pdu_destroy(pdu);
            debug("test.smpp", 0, "Sent enquire_link to bearerbox.");
        }
    }
    time(&last_to_esme);
    if (id == max_to_esme)
	info(0, "All messages sent to ESME.");
    debug("test.smpp", 0, "%s terminates.", __func__);
}
Esempio n. 20
0
/*
 * thread to write current store to file now and then, to prevent
 * it from becoming far too big (slows startup)
 */
static void store_dumper(void *arg)
{
    time_t now;
    int busy = 0;

    while (active) {
        now = time(NULL);
        /*
         * write store to file up to each N. second, providing
         * that something happened or if we are constantly busy.
         */
        if (now - last_dict_mod > dump_frequency || busy) {
            store_dump();
            /* 
             * make sure that no new dump is done for a while unless
             * something happens. This moves the trigger in the future
             * and allows the if statement to pass if nothing happened
             * in the mean time while sleeping. The busy flag is needed
             * to garantee we do dump in case we are constantly busy
             * and hence the difference between now and last dict
             * operation is less then dump frequency, otherwise we
             * would never dump. This is for constant high load.
             */
            last_dict_mod = time(NULL) + 3600*24;
            busy = 0;
        } else {
            busy = (now - last_dict_mod) > 0;
        }
        gwthread_sleep(dump_frequency);
    }
    store_dump();
    if (file != NULL)
       fclose(file);
    octstr_destroy(filename);
    octstr_destroy(newfile);
    octstr_destroy(bakfile);
    mutex_destroy(file_mutex);

    dict_destroy(sms_dict);
    /* set all vars to NULL */
    filename = newfile = bakfile = NULL;
    file_mutex = NULL;
    sms_dict = NULL;
}
Esempio n. 21
0
static void wrapper_receiver(void *arg)
{
    Msg 	*msg;
    SMSCConn 	*conn = arg;
    SmscWrapper *wrap = conn->data;
    /* SmscWrapper *wrap = conn->data; ** non-used */
    double 	sleep = 0.0001;
    
    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);
    
    /* remove messages from SMSC until we are killed */
    while(conn->why_killed == SMSCCONN_ALIVE) {

        gwlist_consume(wrap->stopped); /* block here if suspended/isolated */

	msg = sms_receive(conn);
	if (msg) {
            debug("bb.sms", 0, "smscconn (%s): new message received",
		  octstr_get_cstr(conn->name));
            sleep = 0.0001;
	    bb_smscconn_receive(conn, msg);
        }
        else {
	    /* note that this implementations means that we sleep even
	     * when we fail connection.. but time is very short, anyway
	     */
            gwthread_sleep(sleep);
            /* gradually sleep longer and longer times until something starts to
             * happen - this of course reduces response time, but that's better than
             * extensive CPU usage when it is not used
             */
            sleep *= 2;
            if (sleep >= 2.0)
                sleep = 1.999999;
        }
    }
    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;

    /* this thread is joined at sender */
}
Esempio n. 22
0
static void wait_for_connections(int fd, void (*function) (void *arg), 
    	    	    	    	 List *waited, int ssl)
{
    int ret;
    int timeout = 10; /* 10 sec. */

    gw_assert(function != NULL);
    
    while(bb_status != BB_DEAD) {

        /* if we are being shutdowned, as long as there is
         * messages in incoming list allow new connections, but when
         * list is empty, exit.
         * Note: We have timeout (defined above) for which we allow new connections.
         *           Otherwise we wait here for ever!
         */
        if (bb_status == BB_SHUTDOWN) {
            ret = gwlist_wait_until_nonempty(waited);
            if (ret == -1 || !timeout)
                break;
            else
                timeout--;
        }

        /* block here if suspended */
        gwlist_consume(suspended);

        ret = gwthread_pollfd(fd, POLLIN, 1.0);
        if (ret > 0) {
            Boxc *newconn = accept_boxc(fd, ssl);
            if (newconn != NULL) {
                gwthread_create(function, newconn);
                gwthread_sleep(1.0);
            } else {
                error(0, "Failed to create new boxc connection.");
            }
        } else if (ret < 0 && errno != EINTR && errno != EAGAIN)
            error(errno, "bb_boxc::wait_for_connections failed");
    }
}
Esempio n. 23
0
static void wapboxc_run(void *arg)
{
    int fd, port;

    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    port = (int) *((long*)arg);
    
    fd = make_server_socket(port, NULL);
    	/* XXX add interface_name if required */

    if (fd < 0) {
	    panic(0, "Could not open wapbox port %d", port);
    }

    wait_for_connections(fd, run_wapbox, incoming_wdp, wapbox_port_ssl);

    /* continue avalanche */

    gwlist_remove_producer(outgoing_wdp);


    /* wait for all connections to die and then remove list
     */
    
    while(gwlist_wait_until_nonempty(wapbox_list) == 1)
        gwthread_sleep(1.0);

    /* wait for wdp_to_wapboxes to exit */
    while(gwlist_consume(wapbox_list)!=NULL)
	;
    
    /* close listen socket */
    close(fd);   
 
    gwlist_destroy(wapbox_list, NULL);
    wapbox_list = NULL;
    
    gwlist_remove_producer(flow_threads);
}
Esempio n. 24
0
/*
 * Send a message to the bearerbox for delivery to a phone.
 * Return >= 0 for success & count of splitted sms messages, 
 * -1 for failure.  Does not destroy the msg.
 */
static int send_message(Msg *msg)
{
    unsigned long msg_count;
    List *list;
    
    gw_assert(msg != NULL);
    gw_assert(msg_type(msg) == sms);
    
    /* 
     * Encode our smsbox-id to the msg structure.
     * This will allow bearerbox to return specific answers to the
     * same smsbox, mainly for DLRs and SMS proxy modes.
     *
     * In addition the -x flag can be used to identify the mtbatch
     * instance with an own smsbox-id, but let the normal smsbox
     * daemons handle the DLRs coming back, as the mtbatch shuts down
     * after all MTs have been injected. It's not meant to process
     * the DLR messages.
     */
    if (no_smsbox_id == 0 && smsbox_id != NULL) {
        msg->sms.boxc_id = octstr_duplicate(smsbox_id);
    }
    
    list = sms_split(msg, NULL, NULL, NULL, NULL, 1, 0, 100, MAX_SMS_OCTETS);
    msg_count = gwlist_len(list);
    gwlist_destroy(list, msg_destroy_item);

    debug("sms", 0, "message length %ld, sending %ld messages", 
          octstr_len(msg->sms.msgdata), msg_count);

    if (delay > 0)
        gwthread_sleep(delay);

    /* pass message to bearerbox */
    if (deliver_to_bearerbox(msg) != 0)
        return -1;
    
    return msg_count;
}
Esempio n. 25
0
static void sql_single(Boxc *boxc)
{
    Msg *msg;

    while (sqlbox_status == SQL_RUNNING && boxc->alive) {
        if ((msg = gw_sql_fetch_msg()) != NULL) {
            if (charset_processing(msg) == -1) {
                error(0, "Could not charset process message, dropping it!");
                msg_destroy(msg);
                continue;
            }
            if (global_sender != NULL && (msg->sms.sender == NULL || octstr_len(msg->sms.sender) == 0)) {
                msg->sms.sender = octstr_duplicate(global_sender);
            }
            /* convert validity and deferred to unix timestamp */
            if (msg->sms.validity != SMS_PARAM_UNDEFINED)
                msg->sms.validity = time(NULL) + msg->sms.validity * 60;
            if (msg->sms.deferred != SMS_PARAM_UNDEFINED)
                msg->sms.deferred = time(NULL) + msg->sms.deferred * 60;
            send_msg(boxc->bearerbox_connection, boxc, msg);

            if (save_mt) {
                /* convert validity & deferred back to minutes
                 * TODO clarify why we fetched message from DB and then insert it back here???
                 */
                if (msg->sms.validity != SMS_PARAM_UNDEFINED)
                    msg->sms.validity = (msg->sms.validity - time(NULL))/60;
                if (msg->sms.deferred != SMS_PARAM_UNDEFINED)
                    msg->sms.deferred = (msg->sms.deferred - time(NULL))/60;
                gw_sql_save_msg(msg, octstr_imm("MT"));
            }
        }
        else {
            gwthread_sleep(SLEEP_BETWEEN_EMPTY_SELECTS);
        }
        msg_destroy(msg);
    }
}
Esempio n. 26
0
int main(int argc, char **argv)
{
    int opt;
    unsigned long sended = 0;
    Octstr *cf, *rf;

    gwlib_init();

    bb_host = octstr_create("localhost");
    bb_port = 13001;
    bb_ssl = 0;
        
    while ((opt = getopt(argc, argv, "hv:b:p:si:n:a:f:D:u:d:r:")) != EOF) {
        switch (opt) {
            case 'v':
                log_set_output_level(atoi(optarg));
                break;
            case 'b':
                octstr_destroy(bb_host);
                bb_host = octstr_create(optarg);
                break;
            case 'p':
                bb_port = atoi(optarg);
                break;
            case 's':
                bb_ssl = 1;
                break;
            case 'i':
                smsbox_id = octstr_create(optarg);
                break;
            case 'n':
                service = octstr_create(optarg);
                break;
            case 'a':
                account = octstr_create(optarg);
                break;
            case 'f':
                from = octstr_create(optarg);
                break;
            case 'D':
                dlr_mask = atoi(optarg);
                break;
            case 'u':
                dlr_url = octstr_create(optarg);
                break;
            case 'd':
                delay = atof(optarg);
                break;
            case 'r':
                smsc_id = octstr_create(optarg);
                break;
            case '?':
            default:
                error(0, "Invalid option %c", opt);
                help();
                panic(0, "Stopping.");
        }
    }
    
    if (optind == argc || argc-optind < 2) {
        help();
        exit(1);
    }

    /* check some mandatory elements */
    if (from == NULL)
        panic(0,"Sender address not specified. Use option -f to specify sender address.");

    if ((DLR_IS_ENABLED(dlr_mask) && dlr_url == NULL) || (!DLR_IS_ENABLED(dlr_mask) && dlr_url != NULL))
        panic(0,"dlr-url address OR dlr-mask not specified. Use option -D or -u to specify dlr values");

    rf = octstr_create(argv[argc-1]);
    cf = octstr_create(argv[argc-2]);

    report_versions("mtbatch");
    write_pid_file();
 
    init_batch(cf, rf);

    connect_to_bearerbox(bb_host, bb_port, bb_ssl, NULL /* bb_our_host */);
    identify_to_bearerbox();
    gwthread_create(read_messages_from_bearerbox, NULL);

    sended = run_batch();

    /* avoid exiting before sending all msgs */
    while(sended > counter_value(counter)) {
         gwthread_sleep(0.1);
    }

    program_status = shutting_down;
    gwthread_join_all();

    octstr_destroy(bb_host);
    octstr_destroy(smsbox_id);
    octstr_destroy(content);
    octstr_destroy(service);
    octstr_destroy(account);
    octstr_destroy(dlr_url);
    octstr_destroy(smsc_id);
    counter_destroy(counter);
    gwlist_destroy(lines, octstr_destroy_item); 
   
    gwlib_shutdown();

    return 0;
}
Esempio n. 27
0
static int reconnect(SMSCConn *conn)
{
    SmscWrapper *wrap = conn->data;
    Msg *msg;
    int ret;
    int wait = 1;

    /* disable double-reconnect
     * NOTE: it is still possible that we do double-connect if
     *   first thread gets through this if-statement and then
     *   execution switches to another thread.. this can be avoided
     *   via double-mutex system, but I do not feel it is worth it,
     *   maybe later --rpr
     */
    if (conn->status == SMSCCONN_RECONNECTING) {
	mutex_lock(wrap->reconnect_mutex);	/* wait here */
	mutex_unlock(wrap->reconnect_mutex);
	return 0;
    }
    mutex_lock(wrap->reconnect_mutex);

    debug("bb.sms", 0, "smsc_wrapper <%s>: reconnect started",
	  octstr_get_cstr(conn->name));

    while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
	bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
    }
    conn->status = SMSCCONN_RECONNECTING;
    

    while(conn->why_killed == SMSCCONN_ALIVE) {
	ret = smsc_reopen(wrap->smsc);
	if (ret == 0) {
	    info(0, "Re-open of %s succeeded.", octstr_get_cstr(conn->name));
	    mutex_lock(conn->flow_mutex);
	    conn->status = SMSCCONN_ACTIVE;
	    conn->connect_time = time(NULL);
	    mutex_unlock(conn->flow_mutex);
	    bb_smscconn_connected(conn);
	    break;
	}
	else if (ret == -2) {
	    error(0, "Re-open of %s failed permanently",
		  octstr_get_cstr(conn->name));
	    mutex_lock(conn->flow_mutex);
	    conn->status = SMSCCONN_DISCONNECTED;
	    mutex_unlock(wrap->reconnect_mutex);
	    mutex_unlock(conn->flow_mutex);
	    return -1;	/* permanent failure */
	}
	else {
	    error(0, "Re-open to <%s> failed, retrying after %d minutes...",
		  octstr_get_cstr(conn->name), wait);
	    gwthread_sleep(wait*60.0);

	    wait = wait > 10 ? 10 : wait * 2 + 1;
	}
    }
    mutex_unlock(wrap->reconnect_mutex);
    return 0;
}
Esempio n. 28
0
/*
 * Thread to handle finished sendings
 */
static void httpsmsc_send_cb(void *arg)
{
    SMSCConn *conn = arg;
    ConnData *conndata = conn->data;
    Msg *msg;
    int status;
    List *headers;
    Octstr *final_url, *body;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    while(conndata->shutdown == 0 || counter_value(conndata->open_sends)) {

        msg = http_receive_result(conndata->http_ref, &status,
                                  &final_url, &headers, &body);

        if (msg == NULL)
            break;  /* they told us to die, by unlocking */

        counter_decrease(conndata->open_sends);
        if (conndata->max_pending_sends)
            semaphore_up(conndata->max_pending_sends);

        /* Handle various states here. */

        /* request failed and we are not in shutdown mode */
        if (status == -1 && conndata->shutdown == 0) {
            error(0, "HTTP[%s]: Couldn't connect to SMS center."
                     "(retrying in %ld seconds) %ld.",
                     octstr_get_cstr(conn->id), conn->reconnect_delay, counter_value(conndata->open_sends));
            mutex_lock(conn->flow_mutex);
            conn->status = SMSCCONN_RECONNECTING;
            mutex_unlock(conn->flow_mutex);
            /* XXX how should we know whether it's temp. error ?? */
            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL);
            /*
             * Just sleep reconnect delay and set conn to ACTIVE again;
             * otherwise if no pending request are here, we leave conn in
             * RECONNECTING state for ever and no routing (trials) take place.
             */
            if (counter_value(conndata->open_sends) == 0) {
                gwthread_sleep(conn->reconnect_delay);
                /* and now enable routing again */
                mutex_lock(conn->flow_mutex);
                conn->status = SMSCCONN_ACTIVE;
                time(&conn->connect_time);
                mutex_unlock(conn->flow_mutex);
                /* tell bearerbox core that we are connected again */
                bb_smscconn_connected(conn);
            }
            continue;
        }
        /* request failed and we *are* in shutdown mode, drop the message */
        else if (status == -1 && conndata->shutdown == 1) {
            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
        }
        /* request succeeded */
        else {
            /* we received a response, so this link is considered online again */
            if (conn->status != SMSCCONN_ACTIVE) {
                mutex_lock(conn->flow_mutex);
                conn->status = SMSCCONN_ACTIVE;
                time(&conn->connect_time);
                mutex_unlock(conn->flow_mutex);
                /* tell bearerbox core that we are connected again */
                bb_smscconn_connected(conn);
            }
            conndata->callbacks->parse_reply(conn, msg, status, headers, body);
        }

        http_destroy_headers(headers);
        octstr_destroy(final_url);
        octstr_destroy(body);
    }
    debug("smsc.http", 0, "HTTP[%s]: httpsmsc_send_cb dying",
          octstr_get_cstr(conn->id));
    conndata->shutdown = 1;

    if (counter_value(conndata->open_sends)) {
        warning(0, "HTTP[%s]: Shutdown while <%ld> requests are pending.",
                octstr_get_cstr(conn->id), counter_value(conndata->open_sends));
    }
}
Esempio n. 29
0
/*
 * Thread to send queued messages
 */
static void httpsmsc_sender(void *arg)
{
    SMSCConn *conn = arg;
    ConnData *conndata = conn->data;
    Msg *msg;
    double delay = 0;

    /* Make sure we log into our own log-file if defined */
    log_thread_to(conn->log_idx);

    if (conn->throughput) {
        delay = 1.0 / conn->throughput;
    }

    while (conndata->shutdown == 0) {
        /* check if we can send ; otherwise block on semaphore */
        if (conndata->max_pending_sends)
            semaphore_down(conndata->max_pending_sends);

        if (conndata->shutdown) {
            if (conndata->max_pending_sends)
                semaphore_up(conndata->max_pending_sends);
            break;
        }

        msg = gwlist_consume(conndata->msg_to_send);
        if (msg == NULL)
            break;

        /* obey throughput speed limit, if any */
        if (conn->throughput > 0) {
            gwthread_sleep(delay);
        }
        counter_increase(conndata->open_sends);
        if (conndata->callbacks->send_sms(conn, msg) == -1) {
            counter_decrease(conndata->open_sends);
            if (conndata->max_pending_sends)
                semaphore_up(conndata->max_pending_sends);
        }
    }

    /* put outstanding sends back into global queue */
    while((msg = gwlist_extract_first(conndata->msg_to_send)))
        bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);

    /* if there no receiver shutdown */
    if (conndata->port <= 0) {
        /* unblock http_receive_result() if there are no open sends */
        if (counter_value(conndata->open_sends) == 0)
            http_caller_signal_shutdown(conndata->http_ref);

        if (conndata->send_cb_thread != -1) {
            gwthread_wakeup(conndata->send_cb_thread);
            gwthread_join(conndata->send_cb_thread);
        }
        mutex_lock(conn->flow_mutex);
        conn->status = SMSCCONN_DEAD;
        mutex_unlock(conn->flow_mutex);

        if (conndata->callbacks != NULL && conndata->callbacks->destroy != NULL)
            conndata->callbacks->destroy(conn);
        conn->data = NULL;
        conndata_destroy(conndata);
        bb_smscconn_killed();
    }
}
Esempio n. 30
0
static void parachute_start(const char *myname, const char *panic_script) {
    time_t last_start = 0, last_panic = 0;
    long respawn_count = 0;
    int status;


    if (panic_script && !is_executable(panic_script))
        panic(0, "Panic script `%s' is not executable for us.", panic_script);

    /* setup sighandler */
    parachute_init_signals(0);

    for (;;) {
        if (respawn_count > 0 && difftime(time(NULL), last_start) < 10) {
            error(0, "Child process died too fast, disabling for 30 sec.");
            gwthread_sleep(30.0);
        }
        if (!(child_pid = fork())) { /* child process */
            parachute_init_signals(1); /* reset sighandlers */
	    return;
        }
	else if (child_pid < 0) {
	    error(errno, "Could not start child process! Will retry in 5 sec.");
	    gwthread_sleep(5.0);
            continue;
	}
	else { /* father process */
	    time(&last_start);
            info(0, "Child process with PID (%ld) started.", (long) child_pid);
            do {
                if (waitpid(child_pid, &status, 0) == child_pid) {
                    /* check here why child terminated */
                   if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
                       info(0, "Child process exited gracefully, exit...");
                       gwlib_shutdown();
                       exit(0);
                   }
                   else if (WIFEXITED(status)) {
                       error(0, "Caught child PID (%ld) which died with return code %d",
                           (long) child_pid, WEXITSTATUS(status));
                       child_pid = -1;
                   }
                   else if (WIFSIGNALED(status)) {
                       error(0, "Caught child PID (%ld) which died due to signal %d",
                           (long) child_pid, WTERMSIG(status));
                       child_pid = -1;
                   }
                }
                else if (errno != EINTR) {
                    error(errno, "Error while waiting of child process.");
                }
            } while(child_pid > 0);

            if (parachute_shutdown) {
                /* may only happens if child process crashed while shutdown */
                info(0, "Child process crashed while shutdown. Exiting due to signal...");
                info(0, "Going into gwlib_shutdown...");
                gwlib_shutdown();
                info(0, "gwlib_shutdown done... Bye bye...");
                exit(WIFEXITED(status) ? WEXITSTATUS(status) : 0);
            }

            /* check whether it's panic while start */
            if (respawn_count == 0 && difftime(time(NULL), last_start) < 2) {
                info(0, "Child process crashed while starting. Exiting...");
                info(0, "Going into gwlib_shutdown...");
                gwlib_shutdown();
                info(0, "gwlib_shutdown done... Bye bye...");
                exit(WIFEXITED(status) ? WEXITSTATUS(status) : 1);
            }

            respawn_count++;
            if (panic_script && myname && difftime(time(NULL), last_panic) > 300) {
                time(&last_panic);
                debug("kannel", 0, "Executing panic script: %s %s %ld", panic_script, myname, respawn_count);
                execute_panic_script(panic_script, "%s %ld", myname, respawn_count);
            }
            /* sleep a while to get e.g. sockets released */
            gwthread_sleep(5.0);
	}
    }
}