예제 #1
0
/*
 * this function receives an WDP message and checks if a UDP
 * service for this client has to be created
 */
static int udp_addwdp_from_client(Msg *msg)
{
    Udpc *udpc;
    Octstr *map_addr;
    Octstr *os;
    Octstr *source;
    
    if (!udp_running) return -1;
    assert(msg != NULL);
    assert(msg_type(msg) == wdp_datagram);
    
    /* 
     * Check if there is allready a bound UDP port for this mapping.
     * If not create a mapping and bind the mapped UDP port
     * The mapped port is simply 2x of the client port. 
     */
    if ((udpc = udpc_find_mapping(msg, 1)) == NULL) {
        info(0, "Creating UDP mapping <%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.source_port*2);

        map_addr = udp_create_address(msg->wdp_datagram.source_address, 
                                      msg->wdp_datagram.source_port);
        add_service(msg->wdp_datagram.source_port * 2, 
                    octstr_get_cstr(interface_name), map_addr);
        /* now we should find it in the udpc_list */
        if ((udpc = udpc_find_mapping(msg, 1)) == NULL)
            panic(0,"Could not find UDP mapping, internal error");
    }

    /* now swap the message addressing */
    octstr_destroy(msg->wdp_datagram.source_address);
    octstr_destroy(msg->wdp_datagram.destination_address);

    os = octstr_duplicate(interface_name);
    source = udp_create_address(os, msg->wdp_datagram.source_port * 2);
    msg->wdp_datagram.source_address = udp_get_ip(source);
    msg->wdp_datagram.source_port = udp_get_port(source);
    msg->wdp_datagram.destination_address = octstr_duplicate(wapgw);
    msg->wdp_datagram.destination_port = CONNECTION_ORIENTED_PORT;

    octstr_destroy(os);

    gwlist_produce(udpc->outgoing_list, msg);
    
    return -1;
}
예제 #2
0
파일: gw-timer.c 프로젝트: dimimpou/gwlib
/*
 * This timer has elapsed.  Do the housekeeping.  We have its set locked.
 */
static void elapse_timer(Timer *timer)
{
    gw_assert(timer != NULL);
    gw_assert(timer->timerset != NULL);
    /* This must be true because abort_elapsed is always called
     * before a timer is activated. */
    gw_assert(timer->elapsed_data == NULL);

    timer->elapsed_data = timer->data;
    timer->elapses = -1;
    if (timer->output != NULL)
        gwlist_produce(timer->output, timer->elapsed_data);
    if (timer->callback != NULL)
        timer->callback(timer->elapsed_data);
}
예제 #3
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);
}
예제 #4
0
/*
 * this function receives an WDP message and adds it to
 * corresponding outgoing_list.
 */
static int udp_addwdp_from_server(Msg *msg)
{
    Udpc *udpc;
    Octstr *os;
    Octstr *source;

    if (!udp_running) return -1;
    assert(msg != NULL);
    assert(msg_type(msg) == wdp_datagram);

    octstr_destroy(msg->wdp_datagram.source_address);
    msg->wdp_datagram.source_address = 
        octstr_create(octstr_get_cstr(msg->wdp_datagram.destination_address));
    msg->wdp_datagram.source_port = msg->wdp_datagram.destination_port;

    if ((udpc = udpc_find_mapping(msg, 0)) == NULL) 
        /* there should have been one */
        panic(0,"Could not find UDP mapping, internal error");

    /* insert the found mapped destination */
    octstr_destroy(msg->wdp_datagram.source_address);
    octstr_destroy(msg->wdp_datagram.destination_address);
    
    msg->wdp_datagram.destination_address = udp_get_ip(udpc->map_addr);
    msg->wdp_datagram.destination_port = udp_get_port(udpc->map_addr);

    /* now search for our inbound UDP socket */
    os = octstr_duplicate(interface_name);
    source = udp_create_address(os, server_port);

    msg->wdp_datagram.source_address = udp_get_ip(source);
    msg->wdp_datagram.source_port = udp_get_port(source);
    if ((udpc = udpc_find_mapping(msg, 0)) == NULL) 
        panic(0,"Could not find main inbound UDP socket, internal error");

    /* 
     * ok, got the destination, got the socket, 
     * now put it on the outbound queue
     */
    gwlist_produce(udpc->outgoing_list, msg);

    octstr_destroy(os);

    return 0;
}
예제 #5
0
파일: smsc_cgw.c 프로젝트: frese/mbuni
void cgw_check_acks(PrivData *privdata)
{
    time_t	current_time;
    int i;

    current_time = time(NULL);
    if (privdata->unacked && (current_time > privdata->check_time + 30)) {
        privdata->check_time = current_time;
        for (i = 0; i < CGW_TRN_MAX; i++)
            if (privdata->sendtime[i] && privdata->sendtime[i] < (current_time - privdata->waitack)) {
                privdata->sendtime[i] = 0;
                privdata->unacked--;
                warning(0, "smsc_cgw: received neither OK nor ERR for message %d "
                        "in %d seconds, resending message", i, privdata->waitack);
                gwlist_produce(privdata->outgoing_queue, privdata->sendmsg[i]);
            }
    }
}
예제 #6
0
파일: smsc_cgw.c 프로젝트: frese/mbuni
static int cgw_send_loop(SMSCConn *conn, Connection *server)
{
    PrivData *privdata = conn->data;
    struct cgwop *cgwop;
    Msg	*msg;
    int firsttrn;

    /* Send messages in queue */
    while ((msg = gwlist_extract_first(privdata->outgoing_queue)) != NULL) {
        firsttrn = privdata->nexttrn;
        while (privdata->sendtime[privdata->nexttrn] != 0) { 
            if (++privdata->nexttrn >= CGW_TRN_MAX) privdata->nexttrn = 0;    
            if (privdata->nexttrn == firsttrn) { /* no available trn */
	        /* this happens too many messages are sent, and old messages
		 * haven't been acked. In this case, increase size of 
                 * CGW_TRN_MAX */
                info(0, "cgw: Saturated, increase size of CGW_TRN_MAX!");
                gwlist_produce(privdata->outgoing_queue, msg);
                return 1;     /* re-insert, and go check for acks */
            }
        }

        cgwop = msg_to_cgwop(privdata, msg, privdata->nexttrn);

        if (cgwop == NULL) {
            info(0, "cgw: cgwop == NULL");
            return 0;
        }

        privdata->sendmsg[privdata->nexttrn] = msg;
        privdata->sendtime[privdata->nexttrn] = time(NULL);

        if (cgwop_send(server, cgwop) == -1) {
            cgwop_destroy(cgwop);
            info(0, "cgw: Unable to send (cgwop_send() == -1)");
            return -1;
        }

        privdata->unacked++;

        cgwop_destroy(cgwop);
    }
    return 0;
}
예제 #7
0
파일: semaphore.c 프로젝트: dimimpou/gwlib
Semaphore *semaphore_create(long n)
{
    Semaphore *semaphore;
#ifndef HAVE_SEMAPHORE
    static char item;
#endif
    
    semaphore = gw_malloc(sizeof(*semaphore));

#ifdef HAVE_SEMAPHORE
    if (sem_init(&semaphore->sem, 0, (unsigned int) n) != 0)
        panic(errno, "Could not initialize semaphore.");
#else
    semaphore->list = gwlist_create();
    gwlist_add_producer(semaphore->list);
    while (n-- > 0)
	gwlist_produce(semaphore->list, &item);
#endif

    return semaphore;
}
예제 #8
0
static int httpsmsc_send(SMSCConn *conn, Msg *msg)
{
    ConnData *conndata = conn->data;
    Msg *sms;


    /* don't crash if no send_sms handle defined */
    if (!conndata || !conndata->callbacks->send_sms)
        return -1;

    sms = msg_duplicate(msg);
    /* convert character encoding if required */
    if (msg->sms.coding == DC_7BIT && conndata->alt_charset &&
        charset_convert(sms->sms.msgdata, DEFAULT_CHARSET,
                        octstr_get_cstr(conndata->alt_charset)) != 0) {
        error(0, "Failed to convert msgdata from charset <%s> to <%s>, will send as is.",
              DEFAULT_CHARSET, octstr_get_cstr(conndata->alt_charset));
    }

    gwlist_produce(conndata->msg_to_send, sms);

    return 0;
}
예제 #9
0
파일: bb_boxc.c 프로젝트: Phonebooth/kannel
static void boxc_receiver(void *arg)
{
    Boxc *conn = arg;
    Msg *msg, *mack;

    /* remove messages from socket until it is closed */
    while (bb_status != BB_DEAD && conn->alive) {

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

        msg = read_from_box(conn);

        if (msg == NULL) {	/* garbage/connection lost */
            conn->alive = 0;
            break;
        }

        /* we don't accept new messages in shutdown phase */
        if ((bb_status == BB_SHUTDOWN || bb_status == BB_DEAD) && msg_type(msg) == sms) {
            mack = msg_create(ack);
            uuid_copy(mack->ack.id, msg->sms.id);
            mack->ack.time = msg->sms.time;
            mack->ack.nack = ack_failed_tmp;
            msg_destroy(msg);
            send_msg(conn, mack);
            msg_destroy(mack);
            continue;
        }

        if (msg_type(msg) == sms && conn->is_wap == 0) {
            debug("bb.boxc", 0, "boxc_receiver: sms received");

            /* deliver message to queue */
            deliver_sms_to_queue(msg, conn);

            if (conn->routable == 0) {
                conn->routable = 1;
                /* wakeup the dequeue thread */
                gwthread_wakeup(sms_dequeue_thread);
            }
        } else if (msg_type(msg) == wdp_datagram && conn->is_wap) {
            debug("bb.boxc", 0, "boxc_receiver: got wdp from wapbox");

            /* XXX we should block these in SHUTDOWN phase too, but
               we need ack/nack msgs implemented first. */
            gwlist_produce(conn->outgoing, msg);

        } else if (msg_type(msg) == sms && conn->is_wap) {
            debug("bb.boxc", 0, "boxc_receiver: got sms from wapbox");

            /* should be a WAP push message, so tried it the same way */
            deliver_sms_to_queue(msg, conn);

            if (conn->routable == 0) {
                conn->routable = 1;
                /* wakeup the dequeue thread */
                gwthread_wakeup(sms_dequeue_thread);
            }
        } else {
            if (msg_type(msg) == heartbeat) {
                if (msg->heartbeat.load != conn->load)
                    debug("bb.boxc", 0, "boxc_receiver: heartbeat with "
                          "load value %ld received", msg->heartbeat.load);
                conn->load = msg->heartbeat.load;
            }
            else if (msg_type(msg) == ack) {
                if (msg->ack.nack == ack_failed_tmp) {
                    Msg *orig;
                    boxc_sent_pop(conn, msg, &orig);
                    if (orig != NULL) /* retry this message */
                        gwlist_append(conn->retry, orig);
                } else {
                    boxc_sent_pop(conn, msg, NULL);
                    store_save(msg);
                }
                debug("bb.boxc", 0, "boxc_receiver: got ack");
            }
            /* if this is an identification message from an smsbox instance */
            else if (msg_type(msg) == admin && msg->admin.command == cmd_identify) {

                /*
                 * any smsbox sends this command even if boxc_id is NULL,
                 * but we will only consider real identified boxes
                 */
                if (msg->admin.boxc_id != NULL) {

                    /* and add the boxc_id into conn for boxc_status() output */
                    if (conn->boxc_id != NULL) {
                        dict_remove(smsbox_by_id, msg->admin.boxc_id);
                        octstr_destroy(conn->boxc_id);
                    }

                    conn->boxc_id = msg->admin.boxc_id;
                    msg->admin.boxc_id = NULL;

                    /* add this identified smsbox to the dictionary */
                    /* XXX check for equal boxc_id in Dict, otherwise we overwrite it */
                    dict_put(smsbox_by_id, conn->boxc_id, conn);
                    debug("bb.boxc", 0, "boxc_receiver: got boxc_id <%s> from <%s>",
                          octstr_get_cstr(conn->boxc_id),
                          octstr_get_cstr(conn->client_ip));
                }

                conn->routable = 1;
                /* wakeup the dequeue thread */
                gwthread_wakeup(sms_dequeue_thread);
            }
            else
                warning(0, "boxc_receiver: unknown msg received from <%s>, "
                           "ignored", octstr_get_cstr(conn->client_ip));
            msg_destroy(msg);
        }
    }
}
예제 #10
0
파일: bb_boxc.c 프로젝트: Phonebooth/kannel
/*
 * Route the incoming message to one of the following input queues:
 *   a specific smsbox conn
 *   a random smsbox conn if no shortcut routing and msg->sms.boxc_id match
 *
 * BEWARE: All logic inside here should be fast, hence speed processing
 * optimized, because every single MO message passes this function and we 
 * have to ensure that no unncessary overhead is done.
 */
int route_incoming_to_boxc(Msg *msg)
{
    Boxc *bc = NULL, *best = NULL;
    Octstr *s, *r, *rs;
    long len, b, i;
    int full_found = 0;

    s = r = NULL;
    gw_assert(msg_type(msg) == sms);

    /* msg_dump(msg, 0); */

    /* 
     * We have a specific route to pass this msg to smsbox-id 
     * Lookup the connection in the dictionary.
     */
    gw_rwlock_rdlock(smsbox_list_rwlock);
    if (gwlist_len(smsbox_list) == 0) {
        gw_rwlock_unlock(smsbox_list_rwlock);
    	warning(0, "smsbox_list empty!");
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
	    return 0;
         }
         else
             return -1;
    }

    if (octstr_len(msg->sms.boxc_id) > 0) {
        
        bc = dict_get(smsbox_by_id, msg->sms.boxc_id);
        if (bc == NULL) {
            /*
             * something is wrong, this was the smsbox connection we used
             * for sending, so it seems this smsbox is gone
             */
            warning(0,"Could not route message to smsbox id <%s>, smsbox is gone!",
                    octstr_get_cstr(msg->sms.boxc_id));
        }
    }
    else {
        /*
         * Check if we have a "smsbox-route" for this msg.
         * Where the shortcode route has a higher priority then the smsc-id rule.
         * Highest priority has the combined <shortcode>:<smsc-id> route.
         */
        Octstr *os = octstr_format("%s:%s", 
                                   octstr_get_cstr(msg->sms.receiver),
                                   octstr_get_cstr(msg->sms.smsc_id));
        s = (msg->sms.smsc_id ? dict_get(smsbox_by_smsc, msg->sms.smsc_id) : NULL);
        r = (msg->sms.receiver ? dict_get(smsbox_by_receiver, msg->sms.receiver) : NULL);
        rs = (os ? dict_get(smsbox_by_smsc_receiver, os) : NULL);
        octstr_destroy(os); 
        bc = rs ? dict_get(smsbox_by_id, rs) : 
            (r ? dict_get(smsbox_by_id, r) : (s ? dict_get(smsbox_by_id, s) : NULL));
    }

    /* check if we found our routing */
    if (bc != NULL) {
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(bc->incoming)) {
            gwlist_produce(bc->incoming, msg);
            gw_rwlock_unlock(smsbox_list_rwlock);
            return 1; /* we are done */
        }
        else {
            gw_rwlock_unlock(smsbox_list_rwlock);
            return -1;
        }
    }
    else if (s != NULL || r != NULL || octstr_len(msg->sms.boxc_id) > 0) {
        gw_rwlock_unlock(smsbox_list_rwlock);
        /*
         * we have routing defined, but no smsbox connected at the moment.
         * put msg into global incoming queue and wait until smsbox with
         * such boxc_id connected.
         */
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
            return 0;
        }
        else
            return -1;
    }

    /*
     * ok, none of the routing things applied previously, so route it to
     * a random smsbox.
     */

    /* take random smsbox from list, and then check all smsboxes
     * and select the one with lowest load level - if tied, the first
     * one
     */
    len = gwlist_len(smsbox_list);
    b = gw_rand() % len;

    for(i = 0; i < gwlist_len(smsbox_list); i++) {
	bc = gwlist_get(smsbox_list, (i+b) % len);

        if (bc->boxc_id != NULL || bc->routable == 0)
            bc = NULL;

        if (bc != NULL && max_incoming_sms_qlength > 0 &&
            gwlist_len(bc->incoming) > max_incoming_sms_qlength) {
            full_found = 1;
            bc = NULL;
        }

        if ((bc != NULL && best != NULL && bc->load < best->load) ||
             (bc != NULL && best == NULL)) {
	    best = bc;
        }
    }

    if (best != NULL) {
        best->load++;
        gwlist_produce(best->incoming, msg);
    }

    gw_rwlock_unlock(smsbox_list_rwlock);

    if (best == NULL && full_found == 0) {
	warning(0, "smsbox_list empty!");
        if (max_incoming_sms_qlength < 0 || max_incoming_sms_qlength > gwlist_len(incoming_sms)) {
            gwlist_produce(incoming_sms, msg);
	    return 0;
         }
         else
             return -1;
    }
    else if (best == NULL && full_found == 1)
        return -1;

    return 1;
}
예제 #11
0
파일: bb_boxc.c 프로젝트: Phonebooth/kannel
static void sms_to_smsboxes(void *arg)
{
    Msg *newmsg, *startmsg, *msg;
    long i, len;
    int ret = -1;
    Boxc *boxc;

    gwlist_add_producer(flow_threads);

    newmsg = startmsg = msg = NULL;

    while(bb_status != BB_DEAD) {

        if (newmsg == startmsg) {
            /* check if we are in shutdown phase */
            if (gwlist_producer_count(smsbox_list) == 0)
                break;

            if (ret == 0 || ret == -1) {
                /* debug("", 0, "time to sleep"); */
                gwthread_sleep(60.0);
                /* debug("", 0, "wake up list len %ld", gwlist_len(incoming_sms)); */
                /* shutdown ? */
                if (gwlist_producer_count(smsbox_list) == 0 && gwlist_len(smsbox_list) == 0)
                    break;
            }
            startmsg = msg = gwlist_consume(incoming_sms);
            /* debug("", 0, "gwlist_consume done 1"); */
            newmsg = NULL;
        }
        else {
            newmsg = msg = gwlist_consume(incoming_sms);
            
            /* Back at the first message? */
            if (newmsg == startmsg) {
                gwlist_insert(incoming_sms, 0, msg);
                continue;
            }
        }

        if (msg == NULL)
            break;

        gw_assert(msg_type(msg) == sms);

        /* debug("bb.sms", 0, "sms_boxc_router: handling message (%p vs %p)",
	          msg, startmsg); */

        ret = route_incoming_to_boxc(msg);
        if (ret == 1)
            startmsg = newmsg = NULL;
        else if (ret == -1) {
            gwlist_produce(incoming_sms, msg);
        }
    }

    gw_rwlock_rdlock(smsbox_list_rwlock);
    len = gwlist_len(smsbox_list);
    for (i=0; i < len; i++) {
        boxc = gwlist_get(smsbox_list, i);
        gwlist_remove_producer(boxc->incoming);
    }
    gw_rwlock_unlock(smsbox_list_rwlock);

    gwlist_remove_producer(flow_threads);
}
예제 #12
0
파일: dbpool.c 프로젝트: Phonebooth/kannel
void dbpool_conn_produce(DBPoolConn *pc)
{
    gw_assert(pc != NULL && pc->conn != NULL && pc->pool != NULL && pc->pool->pool != NULL);

    gwlist_produce(pc->pool->pool, pc);
}
예제 #13
0
파일: smpp_pdu.c 프로젝트: pwhelan/kannel
int smpp_pdu_init(Cfg *cfg)
{
    CfgGroup *grp;
    List *l;

    if (initialized)
        return 0;

    l = cfg_get_multi_group(cfg, octstr_imm("smpp-tlv"));
    tlvs = gwlist_create();
    tlvs_by_tag = dict_create(1024, (void(*)(void*))dict_destroy);
    tlvs_by_name = dict_create(1024, (void(*)(void*))dict_destroy);
    while (l != NULL && (grp = gwlist_extract_first(l)) != NULL) {
        struct smpp_tlv *tlv;
        Octstr *tmp, *smsc_id;
        List *l2;

        tlv = gw_malloc(sizeof(*tlv));
        if ((tlv->name = cfg_get(grp, octstr_imm("name"))) == NULL) {
            error(0, "SMPP: Unable to get name for smpp-tlv.");
            smpp_tlv_destroy(tlv);
            goto failed;
        }
        if (cfg_get_integer(&tlv->tag, grp, octstr_imm("tag")) == -1) {
            error(0, "SMPP: Unable to get tag for smpp-tlv.");
            smpp_tlv_destroy(tlv);
            goto failed;
        }
        if (cfg_get_integer(&tlv->length, grp, octstr_imm("length")) == -1) {
            error(0, "SMPP: Unable to get length for smpp-tlv.");
            smpp_tlv_destroy(tlv);
            goto failed;
        }
        if ((tmp = cfg_get(grp, octstr_imm("type"))) == NULL) {
            error(0, "SMPP: Unable to get type for smpp-tlv.");
            smpp_tlv_destroy(tlv);
            goto failed;
        }
        if (octstr_str_case_compare(tmp, "octetstring") == 0)
            tlv->type = SMPP_TLV_OCTETS;
        else if (octstr_str_case_compare(tmp, "nulterminated") == 0)
            tlv->type = SMPP_TLV_NULTERMINATED;
        else if (octstr_str_case_compare(tmp, "integer") == 0)
            tlv->type = SMPP_TLV_INTEGER;
        else {
            error(0, "SMPP: Unknown type for smpp-tlv: `%s'", octstr_get_cstr(tmp));
            octstr_destroy(tmp);
            smpp_tlv_destroy(tlv);
            goto failed;
        }
        octstr_destroy(tmp);

        /* put to all TLVs */
        gwlist_produce(tlvs, tlv);

        smsc_id = cfg_get(grp, octstr_imm("smsc-id"));
        if (smsc_id != NULL) {
            l2 = octstr_split(smsc_id, octstr_imm(";"));
            octstr_destroy(smsc_id);
        } else {
            l2 = gwlist_create();
            gwlist_produce(l2, octstr_create(DEFAULT_SMSC_ID));
        }
        while(l2 != NULL && (smsc_id = gwlist_extract_first(l2)) != NULL) {
            Dict *tmp_dict;

            debug("sms.smpp", 0, "adding smpp-tlv for smsc-id=%s", octstr_get_cstr(smsc_id));

            tmp_dict = dict_get(tlvs_by_name, smsc_id);
            if (tmp_dict == NULL) {
                tmp_dict = dict_create(1024, NULL);
                dict_put(tlvs_by_name, smsc_id, tmp_dict);
            }
            /* put into dict */
            if (!dict_put_once(tmp_dict, tlv->name, tlv)) {
                error(0, "SMPP: Double TLV name %s found.", octstr_get_cstr(tlv->name));
                octstr_destroy(smsc_id);
                goto failed;
            }

            tmp_dict = dict_get(tlvs_by_tag, smsc_id);
            if (tmp_dict == NULL) {
                tmp_dict = dict_create(1024, NULL);
                dict_put(tlvs_by_tag, smsc_id, tmp_dict);
            }
            tmp = octstr_format("%ld", tlv->tag);
            if (!dict_put_once(tmp_dict, tmp, tlv)) {
                error(0, "SMPP: Double TLV tag %s found.", octstr_get_cstr(tmp));
                gwlist_destroy(l2, octstr_destroy_item);
                octstr_destroy(tmp);
                octstr_destroy(smsc_id);
                goto failed;
            }
            octstr_destroy(tmp);
            octstr_destroy(smsc_id);
        }
        gwlist_destroy(l2, octstr_destroy_item);
    }
    gwlist_destroy(l, NULL);

    initialized = 1;
    return 0;

failed:
    gwlist_destroy(tlvs, (void(*)(void*))smpp_tlv_destroy);
    dict_destroy(tlvs_by_tag);
    dict_destroy(tlvs_by_name);
    return -1;
}
예제 #14
0
static void udp_receiver(void *arg)
{
    Octstr *datagram, *cliaddr;
    int ret;
    Msg *msg;
    Udpc *conn = arg;
    Octstr *ip;

    gwlist_add_producer(incoming_wdp);
    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    
    /* remove messages from socket until it is closed */
    while (1) {

        if (read_available(conn->fd, 100000) < 1)
            continue;

        ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);
        if (ret == -1) {
            if (errno == EAGAIN)
                /* No datagram available, don't block. */
                continue;

            error(errno, "Failed to receive an UDP");
            continue;
        }

    	ip = udp_get_ip(cliaddr);
        msg = msg_create(wdp_datagram);
    
        msg->wdp_datagram.source_address = udp_get_ip(cliaddr);
        msg->wdp_datagram.source_port = udp_get_port(cliaddr);
        msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);
        msg->wdp_datagram.destination_port = udp_get_port(conn->addr);
        msg->wdp_datagram.user_data = datagram;

        info(0, "datagram received <%s:%d> -> <%s:%d>",
             octstr_get_cstr(udp_get_ip(cliaddr)), udp_get_port(cliaddr),
             octstr_get_cstr(udp_get_ip(conn->addr)), udp_get_port(conn->addr));

        dump(msg);

        /* 
         * Descide if this is (a) or (b) UDP packet and add them to the
         * corresponding queues
         */
        if (octstr_compare(conn->addr, conn->map_addr) == 0) {
            gwlist_produce(incoming_wdp, msg);
            counter_increase(incoming_wdp_counter);
        } else {
            gwlist_produce(outgoing_wdp, msg);
	        counter_increase(outgoing_wdp_counter);
        }        

        octstr_destroy(cliaddr);
        octstr_destroy(ip);
    }    
    gwlist_remove_producer(incoming_wdp);
    gwlist_remove_producer(flow_threads);
}
예제 #15
0
void wsp_push_client_dispatch_event(WAPEvent *e)
{
    gwlist_produce(push_client_queue, e);
}
예제 #16
0
void wtls_dispatch_event(WAPEvent * event)
{
        /* Stick the event on the incoming events queue */
        gwlist_produce(wtls_queue, event);
}
예제 #17
0
파일: bb_boxc.c 프로젝트: Phonebooth/kannel
static void run_smsbox(void *arg)
{
    Boxc *newconn;
    long sender;
    Msg *msg;
    List *keys;
    Octstr *key;

    gwlist_add_producer(flow_threads);
    newconn = arg;
    newconn->incoming = gwlist_create();
    gwlist_add_producer(newconn->incoming);
    newconn->retry = incoming_sms;
    newconn->outgoing = outgoing_sms;
    newconn->sent = dict_create(smsbox_max_pending, NULL);
    newconn->pending = semaphore_create(smsbox_max_pending);

    sender = gwthread_create(boxc_sender, newconn);
    if (sender == -1) {
        error(0, "Failed to start a new thread, disconnecting client <%s>",
              octstr_get_cstr(newconn->client_ip));
        goto cleanup;
    }
    /*
     * We register newconn in the smsbox_list here but mark newconn as routable
     * after identification or first message received from smsbox. So we can avoid
     * a race condition for routable smsboxes (otherwise between startup and
     * registration we will forward some messages to smsbox).
     */
    gw_rwlock_wrlock(smsbox_list_rwlock);
    gwlist_append(smsbox_list, newconn);
    gw_rwlock_unlock(smsbox_list_rwlock);

    gwlist_add_producer(newconn->outgoing);
    boxc_receiver(newconn);
    gwlist_remove_producer(newconn->outgoing);

    /* remove us from smsbox routing list */
    gw_rwlock_wrlock(smsbox_list_rwlock);
    gwlist_delete_equal(smsbox_list, newconn);
    if (newconn->boxc_id) {
        dict_remove(smsbox_by_id, newconn->boxc_id);
    }
    gw_rwlock_unlock(smsbox_list_rwlock);

    /*
     * check if we in the shutdown phase and sms dequeueing thread
     *   has removed the producer already
     */
    if (gwlist_producer_count(newconn->incoming) > 0)
        gwlist_remove_producer(newconn->incoming);

    /* check if we are still waiting for ack's and semaphore locked */
    if (dict_key_count(newconn->sent) >= smsbox_max_pending)
        semaphore_up(newconn->pending); /* allow sender to go down */
        
    gwthread_join(sender);

    /* put not acked msgs into incoming queue */    
    keys = dict_keys(newconn->sent);
    while((key = gwlist_extract_first(keys)) != NULL) {
        msg = dict_remove(newconn->sent, key);
        gwlist_produce(incoming_sms, msg);
        octstr_destroy(key);
    }
    gw_assert(gwlist_len(keys) == 0);
    gwlist_destroy(keys, octstr_destroy_item);

    /* clear our send queue */
    while((msg = gwlist_extract_first(newconn->incoming)) != NULL) {
        gwlist_produce(incoming_sms, msg);
    }

cleanup:
    gw_assert(gwlist_len(newconn->incoming) == 0);
    gwlist_destroy(newconn->incoming, NULL);
    gw_assert(dict_key_count(newconn->sent) == 0);
    dict_destroy(newconn->sent);
    semaphore_destroy(newconn->pending);
    boxc_destroy(newconn);

    /* wakeup the dequeueing thread */
    gwthread_wakeup(sms_dequeue_thread);

    gwlist_remove_producer(flow_threads);
}
예제 #18
0
파일: wtp_init.c 프로젝트: markjeee/kannel
void wtp_initiator_dispatch_event(WAPEvent *event) 
{
    gwlist_produce(queue, event);
}
예제 #19
0
파일: bb_boxc.c 프로젝트: Phonebooth/kannel
static Boxc *route_msg(List *route_info, Msg *msg)
{
    AddrPar *ap;
    Boxc *conn, *best;
    int i, b, len;
    
    ap = gwlist_search(route_info, msg, cmp_route);
    if (ap == NULL) {
	    debug("bb.boxc", 0, "Did not find previous routing info for WDP, "
	    	  "generating new");
route:

	    if (gwlist_len(wapbox_list) == 0)
	        return NULL;

	    gwlist_lock(wapbox_list);

	/* take random wapbox from list, and then check all wapboxes
	 * and select the one with lowest load level - if tied, the first
	 * one
	 */
	    len = gwlist_len(wapbox_list);
	    b = gw_rand() % len;
	    best = gwlist_get(wapbox_list, b);

	    for(i = 0; i < gwlist_len(wapbox_list); i++) {
	        conn = gwlist_get(wapbox_list, (i+b) % len);
	        if (conn != NULL && best != NULL)
		        if (conn->load < best->load)
		            best = conn;
	    }
	    if (best == NULL) {
	        warning(0, "wapbox_list empty!");
	        gwlist_unlock(wapbox_list);
	        return NULL;
	    }
	    conn = best;
	    conn->load++;	/* simulate new client until we get new values */
	
	    ap = gw_malloc(sizeof(AddrPar));
	    ap->address = octstr_duplicate(msg->wdp_datagram.source_address);
	    ap->port = msg->wdp_datagram.source_port;
	    ap->wapboxid = conn->id;
	    gwlist_produce(route_info, ap);

	    gwlist_unlock(wapbox_list);
    } else
	    conn = gwlist_search(wapbox_list, ap, cmp_boxc);

    if (conn == NULL) {
	/* routing failed; wapbox has disappeared!
	 * ..remove routing info and re-route   */

	    debug("bb.boxc", 0, "Old wapbox has disappeared, re-routing");

	    gwlist_delete_equal(route_info, ap);
	    ap_destroy(ap);
	    goto route;
    }
    return conn;
}
예제 #20
0
파일: mms_queue.c 프로젝트: frese/mbuni
/* runs over a single directory, running queue items. return -1 if failed to run some item.
 * each directory found is pushed onto stack for future processing. 
 * dir must have trailing slash
 * return value of -2 means quit. 
 */
static int run_dir(char *topdir, char *dir, struct Qthread_t *tlist, int num_threads, int *i, List *stack)
{
	DIR *dirp;
	struct dirent *dp;

	Octstr *tdir = octstr_format("%s/%s", topdir, dir);
	char *xdir = octstr_get_cstr(tdir);
	int ret = 0;

	dirp = opendir(xdir);

	//debug("",0,"run_dir[%s] tlist=%p",octstr_get_cstr(tdir), tlist);
	  
	if (!dirp) {
		error(0, "mms_queue_run: Failed to read queue directory %s, error=%s", xdir, strerror(errno));
		ret = -1;
		goto done;
	}
	
	while ((dp = readdir(dirp)) != NULL) {
		struct stat st;
		Octstr *xfname = octstr_format("%s%s", xdir, dp->d_name);
		int sres = stat(octstr_get_cstr(xfname), &st);
		time_t tnow = time(NULL);

		octstr_destroy(xfname);

		if (sres == 0 && S_ISREG(st.st_mode) && dp->d_name[0] == MQF && dp->d_name[1] == 'f') {
			if (mms_queue_live_count() > max_live_queued) {
				if (!max_live_exceeded_warning_issued)
					warning(0, "Exceeded limit for new live requests while processing %s Currently I got %d queued in memory.", topdir, mms_queue_live_count());
				max_live_exceeded_warning_issued = 1;
				break;
			} 
			max_live_exceeded_warning_issued = 0;
	
			Octstr *xqf = xmake_qf(dp->d_name, dir);

			MmsEnvelope *e = mms_queue_readenvelope(octstr_get_cstr(xqf),topdir, 0);
       
			octstr_destroy(xqf);
       
			if (!e) 
				continue;
	       
			if (e->sendt <= tnow) {
				int queued = 0;
				int j = *i; /* This is the next thread to use. Checking for cycles. */
				do {
					if (tlist[*i].l) {
						debug("queuerun", 0, "Queued to thread %d for %s%s, sendt=%d, tnow=%d", 
							*i, xdir, dp->d_name, (int)e->sendt, (int)tnow);
						debug("queuerun", 0, "tlist[%d] = %p", *i, &tlist[*i]);
						gwlist_produce(tlist[*i].l, e);
						queued = 1;
					}
					*i = (*i+1)%num_threads;
				}  while (!queued && *i != j);
	    
				if (!queued) { /* A problem. There are no sender threads! */
					free_envelope(e, 0);
					error(0, "mms_queue_run: No active sender queues for directory %s. Quiting.",xdir);
					ret = -2;
					break;
				}
			} else
	    		free_envelope(e,0); /* Let go of it. */
		} else if (sres == 0 && S_ISDIR(st.st_mode) &&	strcmp(dp->d_name, ".") != 0 &&	strcmp(dp->d_name, "..") != 0) {
			Octstr *newdir = octstr_format("%s%s/", dir, dp->d_name); 
			gwlist_append(stack, newdir); /* push it... */
		}
	}
	if (dirp) 
		closedir(dirp);
done:
     octstr_destroy(tdir);
     return ret;
}
예제 #21
0
파일: bearerbox.c 프로젝트: markjeee/mbuni
void mmsc_receive_func(MmscGrp *m)
{
     int i;
     MmsBoxHTTPClientInfo h = {NULL};
     List *mmsc_incoming_reqs = gwlist_create();
     long *thids = gw_malloc((maxthreads + 1)*sizeof thids[0]);

     gwlist_add_producer(mmsc_incoming_reqs);
     
     for (i = 0; i<maxthreads; i++)
	  thids[i] = gwthread_create((gwthread_func_t *)dispatch_mm7_recv, mmsc_incoming_reqs);
     
     h.m = m;
     while(rstop == 0 &&
	   (h.client = http_accept_request(m->incoming.port, 
					   &h.ip, &h.url, &h.headers, 
					   &h.body, &h.cgivars)) != NULL) 
	  if (is_allowed_ip(m->incoming.allow_ip, m->incoming.deny_ip, h.ip)) {
	       MmsBoxHTTPClientInfo *hx = gw_malloc(sizeof hx[0]); 

	       h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));	       

	       *hx = h;		    

	       debug("mmsbox", 0, 
		     " MM7 Incoming, IP=[%s], MMSC=[%s], dest_port=[%ld] ", 
		     h.ip ? octstr_get_cstr(h.ip) : "", 
		     octstr_get_cstr(m->id),
		     m->incoming.port);  
	      	       
	       /* Dump headers, url etc. */
#if 0
	       http_header_dump(h.headers);
	       if (h.body) octstr_dump(h.body, 0);
	       if (h.ip) octstr_dump(h.ip, 0);
#endif

	       gwlist_produce(mmsc_incoming_reqs, hx);	      
	  } else {
	       h.ua = http_header_value(h.headers, octstr_imm("User-Agent"));
	       
	       mms_error_ex("auth",0,  "MM7", m->id, "HTTP: Incoming IP denied MMSC[%s] ip=[%s], ua=[%s], disconnected",
		     m->id ? octstr_get_cstr(m->id) : "(none)", 
		     h.ip ? octstr_get_cstr(h.ip) : "(none)",
		     h.ua ? octstr_get_cstr(h.ua) : "(none)");
               
               http_send_reply(h.client, HTTP_FORBIDDEN, NULL,
                               octstr_imm("Access denied."));
	       free_mmsbox_http_clientInfo(&h, 0);
	  }
     
     debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down...", octstr_get_cstr(m->id));          
     gwlist_remove_producer(mmsc_incoming_reqs);

     for (i = 0; i<maxthreads; i++)
	  if (thids[i] >= 0)
	       gwthread_join(thids[i]);
     
     gwlist_destroy(mmsc_incoming_reqs, NULL);
     gw_free(thids);
     
     debug("proxy", 0, "MMSBox: MM7 receiver [mmc=%s] Shutting down complete.", octstr_get_cstr(m->id));
}
예제 #22
0
파일: bb_udp.c 프로젝트: Phonebooth/kannel
static void udp_receiver(void *arg)
{
    Octstr *datagram, *cliaddr;
    int ret;
    Msg *msg;
    Udpc *conn = arg;
    Octstr *ip;

    gwlist_add_producer(incoming_wdp);
    gwlist_add_producer(flow_threads);
    gwthread_wakeup(MAIN_THREAD_ID);
    
    /* remove messages from socket until it is closed */
    while (bb_status != BB_DEAD && bb_status != BB_SHUTDOWN) {

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

	if (read_available(conn->fd, 100000) < 1)
	    continue;

	ret = udp_recvfrom(conn->fd, &datagram, &cliaddr);
	if (ret == -1) {
	    if (errno == EAGAIN)
		/* No datagram available, don't block. */
		continue;

	    error(errno, "Failed to receive an UDP");
	    /*
	     * just continue, or is there ANY error that would result
	     * in situation where it would be better to break; or even
	     * die off?     - Kalle 28.2
	     */
	    continue;
	}

	/* discard the message if the client is not allowed */
    	ip = udp_get_ip(cliaddr);
	if (!is_allowed_ip(allow_ip, deny_ip, ip)) {
    	    warning(0, "UDP: Discarding packet from %s, IP is denied.",
		       octstr_get_cstr(ip));
    	    octstr_destroy(datagram);
	} else {
	    debug("bb.udp", 0, "datagram received");
	    msg = msg_create(wdp_datagram);
    
	    msg->wdp_datagram.source_address = udp_get_ip(cliaddr);
	    msg->wdp_datagram.source_port    = udp_get_port(cliaddr);
	    msg->wdp_datagram.destination_address = udp_get_ip(conn->addr);
	    msg->wdp_datagram.destination_port    = udp_get_port(conn->addr);
	    msg->wdp_datagram.user_data = datagram;
    
	    gwlist_produce(incoming_wdp, msg);
	    counter_increase(incoming_wdp_counter);
	}

	octstr_destroy(cliaddr);
	octstr_destroy(ip);
    }    
    gwlist_remove_producer(incoming_wdp);
    gwlist_remove_producer(flow_threads);
}
예제 #23
0
void wsp_session_dispatch_event(WAPEvent *event) {
	wap_event_assert(event);
	gwlist_produce(queue, event);
}
예제 #24
0
void wap_push_ota_dispatch_event(WAPEvent *e)
{
    gw_assert(run_status == running); 
    gwlist_produce(ota_queue, e);
}