Example #1
0
static void udp_sender(void *arg)
{
    Msg *msg;
    Udpc *conn = arg;

    gwlist_add_producer(flow_threads);
    while(bb_status != BB_DEAD) {

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

	if ((msg = gwlist_consume(conn->outgoing_list)) == NULL)
	    break;

	debug("bb.udp", 0, "udp: sending message");
	
        if (send_udp(conn->fd, msg) == -1)
	    /* ok, we failed... tough
	     * XXX log the message or something like that... but this
	     * is not as fatal as it is with SMS-messages...
	     */ {
	    msg_destroy(msg);
	    continue;
	}
	counter_increase(outgoing_wdp_counter);
	msg_destroy(msg);
    }
    gwthread_join(conn->receiver);

    udpc_destroy(conn);
    gwlist_remove_producer(flow_threads);
}
Example #2
0
static void boxc_sender(void *arg)
{
    Msg *msg;
    Boxc *conn = arg;

    gwlist_add_producer(flow_threads);

    while (bb_status != BB_DEAD && conn->alive) {

        /*
         * Make sure there's no data left in the outgoing connection before
         * doing the potentially blocking gwlist_consume()s
         */
        conn_flush(conn->conn);

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

        if ((msg = gwlist_consume(conn->incoming)) == NULL) {
            /* tell sms/wapbox to die */
            msg = msg_create(admin);
            msg->admin.command = restart ? cmd_restart : cmd_shutdown;
            send_msg(conn, msg);
            msg_destroy(msg);
            break;
        }
        if (msg_type(msg) == heartbeat) {
            debug("bb.boxc", 0, "boxc_sender: catch an heartbeat - we are alive");
            msg_destroy(msg);
            continue;
        }
        boxc_sent_push(conn, msg);
        if (!conn->alive || send_msg(conn, msg) == -1) {
            /* we got message here */
            boxc_sent_pop(conn, msg, NULL);
            gwlist_produce(conn->retry, msg);
            break;
        }
        msg_destroy(msg);
        debug("bb.boxc", 0, "boxc_sender: sent message to <%s>",
               octstr_get_cstr(conn->client_ip));
    }
    /* the client closes the connection, after that die in receiver */
    /* conn->alive = 0; */

    /* set conn to unroutable */
    conn->routable = 0;

    gwlist_remove_producer(flow_threads);
}
Example #3
0
/*
 * this thread listens to incoming_wdp list
 * and then routs messages to proper wapbox
 */
static void wdp_to_wapboxes(void *arg)
{
    List *route_info;
    AddrPar *ap;
    Boxc *conn;
    Msg *msg;
    int i;

    gwlist_add_producer(flow_threads);
    gwlist_add_producer(wapbox_list);

    route_info = gwlist_create();

    
    while(bb_status != BB_DEAD) {

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

	    if ((msg = gwlist_consume(incoming_wdp)) == NULL)
	         break;

	    gw_assert(msg_type(msg) == wdp_datagram);

	    conn = route_msg(route_info, msg);
	    if (conn == NULL) {
	        warning(0, "Cannot route message, discard it");
	        msg_destroy(msg);
	        continue;
	    }
	    gwlist_produce(conn->incoming, msg);
    }
    debug("bb", 0, "wdp_to_wapboxes: destroying lists");
    while((ap = gwlist_extract_first(route_info)) != NULL)
	ap_destroy(ap);

    gw_assert(gwlist_len(route_info) == 0);
    gwlist_destroy(route_info, NULL);

    gwlist_lock(wapbox_list);
    for(i=0; i < gwlist_len(wapbox_list); i++) {
	    conn = gwlist_get(wapbox_list, i);
	    gwlist_remove_producer(conn->incoming);
	    conn->alive = 0;
    }
    gwlist_unlock(wapbox_list);

    gwlist_remove_producer(wapbox_list);
    gwlist_remove_producer(flow_threads);
}
Example #4
0
static void wtls_application(WAPEvent * event, WTLSMachine * wtls_machine)
{
   int listLen, i = 0;
   WAPEvent *dgram;
   wtls_Payload *payLoad;

   /* Apply the negotiated decryption/decoding/MAC check to the received data */
   /* Take the userdata and pass it on up to the WTP/WSP, depending on the destination port */

   listLen = gwlist_len(event->u.T_Unitdata_Ind.pdu_list);
   for (; i < listLen; i++) {
      payLoad = gwlist_consume(event->u.T_Unitdata_Ind.pdu_list);
      dgram = wap_event_create(T_DUnitdata_Ind);
      dgram->u.T_DUnitdata_Ind.addr_tuple =
          wap_addr_tuple_create(event->u.T_Unitdata_Ind.addr_tuple->
                 remote->address,
                 event->u.T_Unitdata_Ind.addr_tuple->
                 remote->port,
                 event->u.T_Unitdata_Ind.addr_tuple->
                 local->address,
                 event->u.T_Unitdata_Ind.addr_tuple->
                 local->port);
      dgram->u.T_DUnitdata_Ind.user_data = payLoad->data;
      wap_dispatch_datagram(dgram);
      payLoad->data = NULL;
      wtls_payload_destroy(payLoad);
   }
}
Example #5
0
static void wdp_router(void *arg)
{
    Msg *msg;

    gwlist_add_producer(flow_threads);
    
    while (bb_status != BB_DEAD) {

        if ((msg = gwlist_consume(outgoing_wdp)) == NULL)
            break;

        gw_assert(msg_type(msg) == wdp_datagram);
	
        /*
        if (msg->list == sms)
            smsc_addwdp(msg);
        else
        */

        udp_addwdp(msg);
    }
    udp_die();
    /* smsc_endwdp(); */

    gwlist_remove_producer(flow_threads);
}
Example #6
0
static void udp_sender(void *arg)
{
    Msg *msg;
    Udpc *conn = arg;

    gwlist_add_producer(flow_threads);    
    while (1) {

        if ((msg = gwlist_consume(conn->outgoing_list)) == NULL)
            break;

        info(0, "sending datagram <%s:%ld> -> <%s:%ld>",
              octstr_get_cstr(msg->wdp_datagram.source_address),
              msg->wdp_datagram.source_port,
              octstr_get_cstr(msg->wdp_datagram.destination_address),
              msg->wdp_datagram.destination_port);

        dump(msg);

        if (send_udp(conn->fd, msg) == -1) {
            msg_destroy(msg);
            continue;
        }
        counter_increase(outgoing_wdp_counter);
        msg_destroy(msg);
    }
    gwthread_join(conn->receiver);

    udpc_destroy(conn);
    gwlist_remove_producer(flow_threads);
}
Example #7
0
static void main_thread(void *arg) {
	WAPEvent *e;
	WSPMachine *sm;
	WSP_PDU *pdu;
	
	while (run_status == running && (e = gwlist_consume(queue)) != NULL) {
		wap_event_assert(e);
		switch (e->type) {
		case TR_Invoke_Ind:
			pdu = wsp_pdu_unpack(e->u.TR_Invoke_Ind.user_data);
			if (pdu == NULL) {
				warning(0, "WSP: Broken PDU ignored.");
				wap_event_destroy(e);
				continue;
			}
			break;
	
		default:
			pdu = NULL;
			break;
		}
	
		sm = find_session_machine(e, pdu);
		if (sm == NULL) {
			wap_event_destroy(e);
		} else {
			handle_session_event(sm, e, pdu);
		}
		
		wsp_pdu_destroy(pdu);
	}
}
Example #8
0
static void main_thread(void *arg)
{
    WAPEvent *e;

    while (run_status == running && (e = gwlist_consume(ota_queue)) != NULL) {
        handle_ota_event(e);
    } 

}
Example #9
0
void semaphore_down(Semaphore *semaphore)
{
    gw_assert(semaphore != NULL);
#ifdef HAVE_SEMAPHORE
    sem_wait(&semaphore->sem);
#else
    gwlist_consume(semaphore->list);
#endif
}
Example #10
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);
}
Example #11
0
static void consumer(void *arg) {
	List *list;
	Item *item;
	
	list = arg;
	for (;;) {
		item = gwlist_consume(list);
		if (item == NULL)
			break;
		received[item->index] = 1;
		gw_free(item);
	}
}
Example #12
0
static void main_thread(void *arg)
{
	WTLSMachine *sm;
	WAPEvent *e;
        
   while (wtls_run_status == running && (e = gwlist_consume(wtls_queue))) {
		sm = wtls_machine_find_or_create(e);
		if (sm == NULL)
			wap_event_destroy(e);
		else
			wtls_event_handle(sm, e);
                }
}
Example #13
0
static void main_thread(void *arg) 
{
    WTPInitMachine *sm;
    WAPEvent *e;

    while (initiator_run_status == running && 
          (e = gwlist_consume(queue)) != NULL) {
        sm = init_machine_find_or_create(e);
	if (sm == NULL)
	    wap_event_destroy(e);
	else
	    handle_init_event(sm, e);
    }
}
Example #14
0
static void main_thread(void *arg)
{
    WSPPushClientMachine *cpm;
    WAPEvent *e;

    while (push_client_run_status == running &&
            (e = gwlist_consume(push_client_queue)) != NULL) {
         cpm = push_client_machine_find_or_create(e);
         if (cpm == NULL)
	     wap_event_destroy(e);
         else
	     push_client_event_handle(cpm, e);
    }
}
Example #15
0
static void tdeliver(struct Qthread_t *qt)
{
	MmsEnvelope *e;
	struct qfile_t *qfs;

	while ((e = gwlist_consume(qt->l)) != NULL) {
		int res;
	
		/* qt->deliver(e) will attempt to deliver the message, but it may not be delivered
		 * to all recipients (because of errors). If it is delivered or a fatal error
		 * occurs, then the queue is deleted by qt->deliver (and e is deallocated)
		 */
		res = qt->deliver(e);
		debug("", 0, "qt->deliver terminates: %d", res);
		
		switch(res) {
			case -1: // FATAL ERROR
				if (e == NULL) {
					error(0, "tdeliver: An non-recoverable error occured - but the envelope was deallocated so I cannot give you any details.");
				} else {
					qfs = e->qfs_data;
					char fname[2*QFNAMEMAX];
					snprintf(fname, -1 + sizeof fname, "%s/%s%s", qfs->dir, qfs->subdir,  qfs->name);
					error(0, "tdeliver: An non-recoverable error occured - Check (and delete) queue file %s", fname);
					free_envelope(e, 0); // Should we automatically delete file??
				}
				break;
			case 0: // Delete queue entry from memory only
				free_envelope(e, 0);
				break;
			case 1: // Queue entry gone anywhow..
				break;
			default: /* Never happens, but log an error if it does */
				error(0, "qt->deliver returned a strange value (%d) that I can't handle!", res);
				break;
		}
		
		debug("",0,"free envelope stuff cleared here.");
		
		// Are we absolutely sure the file has been closed here???
		// Yes!
	}
	
	/* Consume failed, time to go away. */
	if (qt->l)
		gwlist_destroy(qt->l, NULL);

	qt->l = NULL; /* Signal that we are gone. */
}
Example #16
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);
}
Example #17
0
void alog_close(void)
{

    if (file != NULL) {
        if (markers)
            alog("Log ends");
        gwlist_lock(writers);
        /* wait for writers to complete */
        gwlist_consume(writers);
        fclose(file);
        file = NULL;
        gwlist_unlock(writers);
        gwlist_destroy(writers, NULL);
        writers = NULL;
    }
}
Example #18
0
static unsigned long run_batch(void)
{
    Octstr *no;
    unsigned long linerr = 0;
    unsigned long lineno = 0;

    while ((no = gwlist_consume(lines)) != NULL) {
        if (octstr_check_range(no, 0, 256, gw_isdigit)) {
            Msg *msg;
        
            lineno++;

            msg = msg_create(sms);

            msg->sms.smsc_id = smsc_id ? octstr_duplicate(smsc_id) : NULL;
            msg->sms.service = service ? octstr_duplicate(service) : NULL;
            msg->sms.sms_type = mt_push;
            msg->sms.sender = octstr_duplicate(from);
            msg->sms.receiver = octstr_duplicate(no);
            msg->sms.account = account ? octstr_duplicate(account) : NULL;
            msg->sms.msgdata = content ? octstr_duplicate(content) : octstr_create("");
            msg->sms.dlr_mask = dlr_mask;
            msg->sms.dlr_url = octstr_duplicate(dlr_url);
            msg->sms.udhdata = octstr_create("");
            msg->sms.coding = DC_7BIT;

            if (send_message(msg) < 0) {
                linerr++;
                info(0,"Failed to send message at line <%ld> for receiver `%s' to bearerbox.",
                      lineno, octstr_get_cstr(no));
                msg_destroy(msg);
            }
        }
        else {
            linerr++;
            error(0, "Receiver `%s' at line <%ld> contains non-digit characters, discarded!",
                  octstr_get_cstr(no), lineno);
        }
        octstr_destroy(no);
    }
    info(0,"mtbatch has processed %ld messages with %ld errors.", lineno, linerr);
    return lineno;
} 
Example #19
0
static void service_router(void *arg)
{
    Msg *msg;

    gwlist_add_producer(flow_threads);
    
    while (1) {

        if ((msg = gwlist_consume(incoming_wdp)) == NULL)
            break;

        gw_assert(msg_type(msg) == wdp_datagram);
	
        udp_addwdp_from_client(msg);
    }
    udp_die();

    gwlist_remove_producer(flow_threads);
}
Example #20
0
static int udp_die(void)
{
    Udpc *udpc;

    if (!udp_running) return -1;
    
    /*
     * remove producers from all outgoing lists.
     */
    debug("bb.udp", 0, "udp_die: removing producers from udp-lists");

    while ((udpc = gwlist_consume(udpc_list)) != NULL) {
        gwlist_remove_producer(udpc->outgoing_list);
    }
    gwlist_destroy(udpc_list, NULL);
    udp_running = 0;
    
    return 0;
}
Example #21
0
int gw_rwlock_wrlock(RWLock *lock)
{
    int ret = 0;
    gw_assert(lock != NULL);

#ifdef HAVE_PTHREAD_RWLOCK
    ret = pthread_rwlock_wrlock(&lock->rwlock);
    if (ret != 0)
        panic(ret, "Error while pthread_rwlock_wrlock.");
#else
    RWDEBUG("", 0, "------------ gw_rwlock_wrlock(%p) ----------", lock);
    gwlist_lock(lock->rwlock);
    RWDEBUG("", 0, "------------ gw_rwlock_wrlock(%p) producers=%d", lock, gwlist_producer_count(lock->rwlock));
    /* wait for reader */
    gwlist_consume(lock->rwlock);
    lock->writer = gwthread_self();
#endif

    return ret;
}
Example #22
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 */
}
Example #23
0
void wtp_pdu_destroy(WTP_PDU *pdu) {
	if (pdu == NULL)
		return;

	switch (pdu->type) {
#define PDU(name, docstring, fields, is_valid) \
	case name: {\
	struct name *p; p = &pdu->u.name; \
	fields \
	} break;
#define UINT(field, docstring, bits)
#define UINTVAR(field, docstring)
#define OCTSTR(field, docstring, lengthfield) octstr_destroy(p->field);
#define REST(field, docstring) octstr_destroy(p->field);
#define TYPE(bits, value)
#define RESERVED(bits)
#define TPI(confield)
#include "wtp_pdu.def"
#undef TPI
#undef RESERVED
#undef TYPE
#undef REST
#undef OCTSTR
#undef UINTVAR
#undef UINT
#undef PDU
	default:
		warning(0, "Cannot destroy unknown WTP PDU type %d", pdu->type);
		break;
	}

	if (pdu->options) {
		while (gwlist_len(pdu->options)) {
			wtp_tpi_destroy(gwlist_consume(pdu->options));
		}
		gwlist_destroy(pdu->options, NULL);
	}

	gw_free(pdu);
}
Example #24
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);
}
Example #25
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");
    }
}
Example #26
0
static void dispatch_mm7_recv(List *rl) 
{

     MmsBoxHTTPClientInfo *h;
     
     while ((h = gwlist_consume(rl)) != NULL) {
	  int ret = -1, has_auth = 0;
	  MmscGrp *m = h->m;
	  if (auth_check(m->incoming.user, 
			 m->incoming.pass, 
			 h->headers, &has_auth) != 0) { /* Ask it to authenticate... */
	       List *hh = http_create_empty_headers();
	       http_header_add(hh, "WWW-Authenticate", 
			       "Basic realm=\"" MM_NAME "\"");
	       http_send_reply(h->client, HTTP_UNAUTHORIZED, hh, 
			       octstr_imm("Authentication failed"));			   
	       http_destroy_headers(hh);
	       if (!has_auth)
		    mms_info_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]",
				m->id ? octstr_get_cstr(m->id) : "(none)");
	       else 
		    mms_error_ex("auth",0, "MM7", m->id, "Auth failed, incoming connection, MMC group=[%s]",
				 m->id ? octstr_get_cstr(m->id) : "(none)");	       
	  } else if (h->m->type == SOAP_MMSC)
	       ret = mm7soap_receive(h);
	  else if (h->m->type == EAIF_MMSC)
	       ret = mm7eaif_receive(h);
	  else 
	       ret = mm7http_receive(h);

	  h->m->last_pdu = time(NULL);

	  if (ret == 0)
	       h->m->mo_pdus++;
	  else 
	       h->m->mo_errors++;
	  free_mmsbox_http_clientInfo(h, 1);
     }
}
Example #27
0
static int store_file_save(Msg *msg)
{
    if (filename == NULL)
        return 0;

    /* block here until store not loaded */
    gwlist_consume(loaded);

    /* lock file_mutex in order to have dict and file in sync */
    mutex_lock(file_mutex);
    if (store_to_dict(msg) == -1) {
        mutex_unlock(file_mutex);
        return -1;
    }
    
    /* write to file, too */
    write_msg(msg);
    fflush(file);
    mutex_unlock(file_mutex);

    return 0;
}
Example #28
0
void alog_reopen(void)
{
    if (file == NULL)
	return;

    if (markers)
        alog("Log ends");

    gwlist_lock(writers);
    /* wait for writers to complete */
    gwlist_consume(writers);

    fclose(file);
    file = fopen(filename, "a");

    gwlist_unlock(writers);

    if (file == NULL) {
        error(errno, "Couldn't re-open access logfile `%s'.", filename);
    } 
    else if (markers) {
        alog("Log begins");
    }
}
Example #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();
    }
}
Example #30
0
static void wrapper_sender(void *arg)
{
    Msg 	*msg;
    SMSCConn 	*conn = arg;
    SmscWrapper *wrap = conn->data;

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

    /* send messages to SMSC until our outgoing_list is empty and
     * no producer anymore (we are set to shutdown) */
    while(conn->status != SMSCCONN_DEAD) {

	if ((msg = gwlist_consume(wrap->outgoing_queue)) == NULL)
            break;

        if (octstr_search_char(msg->sms.receiver, ' ', 0) != -1) {
            /*
             * multi-send: this should be implemented in corresponding
             *  SMSC protocol, but while we are waiting for that...
             */
            int i;
	    Msg *newmsg;
            /* split from spaces: in future, split with something more sensible,
             * this is dangerous... (as space is url-encoded as '+')
             */
            List *nlist = octstr_split_words(msg->sms.receiver);

	    debug("bb.sms", 0, "Handling multi-receiver message");

            for(i=0; i < gwlist_len(nlist); i++) {

		newmsg = msg_duplicate(msg);
                octstr_destroy(newmsg->sms.receiver);

                newmsg->sms.receiver = gwlist_get(nlist, i);
                sms_send(conn, newmsg);
            }
            gwlist_destroy(nlist, NULL);
            msg_destroy(msg);
        }
        else
	    sms_send(conn,msg);

    }
    /* cleanup, we are now dying */

    debug("bb.sms", 0, "SMSCConn %s sender died, waiting for receiver",
	  octstr_get_cstr(conn->name));
    
    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;

    if (conn->is_stopped) {
	gwlist_remove_producer(wrap->stopped);
	conn->is_stopped = 0;
    }

    gwthread_wakeup(wrap->receiver_thread);
    gwthread_join(wrap->receiver_thread);

    /* call 'failed' to all messages still in queue */
    
    mutex_lock(conn->flow_mutex);

    conn->status = SMSCCONN_DEAD;

    while((msg = gwlist_extract_first(wrap->outgoing_queue))!=NULL) {
	bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);
    }
    smscwrapper_destroy(wrap);
    conn->data = NULL;
    
    mutex_unlock(conn->flow_mutex);

    bb_smscconn_killed();
}