Пример #1
0
float load_get(Load *load, int pos)
{
    float ret;
    time_t now;
    struct load_entry *entry;

    if (load == NULL || pos >= load->len) {
        return -1.0;
    }

    /* first maybe rotate load */
    load_increase_with(load, 0);
    
    time(&now);
    gw_rwlock_rdlock(load->lock);
    entry = load->entries[pos];
    if (load->heuristic && !entry->dirty) {
        ret = entry->prev;
    } else {
        time_t diff = (now - entry->last);
        if (diff == 0) diff = 1;
        ret = entry->curr/diff;
    }
    gw_rwlock_unlock(load->lock);

    return ret;
}
Пример #2
0
int load_len(Load *load)
{
    int ret;
    if (load == NULL)
        return 0;
    gw_rwlock_rdlock(load->lock);
    ret = load->len;
    gw_rwlock_unlock(load->lock);
    return ret;
}
Пример #3
0
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);
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
Octstr *boxc_status(int status_type)
{
    Octstr *tmp;
    char *lb, *ws;
    int i, boxes, para = 0;
    time_t orig, t;
    Boxc *bi;

    orig = time(NULL);

    /*
     * XXX: this will cause segmentation fault if this is called
     *    between 'destroy_list and setting list to NULL calls.
     *    Ok, this has to be fixed, but now I am too tired.
     */
    
    if ((lb = bb_status_linebreak(status_type))==NULL)
	    return octstr_create("Un-supported format");

    if (status_type == BBSTATUS_HTML)
	    ws = "&nbsp;&nbsp;&nbsp;&nbsp;";
    else if (status_type == BBSTATUS_TEXT)
	    ws = "    ";
    else
	    ws = "";

    if (status_type == BBSTATUS_HTML || status_type == BBSTATUS_WML)
	    para = 1;
    
    if (status_type == BBSTATUS_XML) {
        tmp = octstr_create ("");
        octstr_append_cstr(tmp, "<boxes>\n\t");
    }
    else
        tmp = octstr_format("%sBox connections:%s", para ? "<p>" : "", lb);
    boxes = 0;
    
    if (wapbox_list) {
	    gwlist_lock(wapbox_list);
	    for(i=0; i < gwlist_len(wapbox_list); i++) {
	        bi = gwlist_get(wapbox_list, i);
	        if (bi->alive == 0)
		        continue;
	        t = orig - bi->connect_time;
            if (status_type == BBSTATUS_XML)
	            octstr_format_append(tmp,
		        "<box>\n\t\t<type>wapbox</type>\n\t\t<IP>%s</IP>\n"
                "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
                "\t\t<ssl>%s</ssl>\n\t</box>\n",
				octstr_get_cstr(bi->client_ip),
				t/3600/24, t/3600%24, t/60%60, t%60,
#ifdef HAVE_LIBSSL
                conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
#else 
                "not installed"
#endif
                );
            else
	            octstr_format_append(tmp,
		        "%swapbox, IP %s (on-line %ldd %ldh %ldm %lds) %s %s",
				ws, octstr_get_cstr(bi->client_ip),
				t/3600/24, t/3600%24, t/60%60, t%60, 
#ifdef HAVE_LIBSSL
                conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
#else
                "",
#endif 
                lb);
	            boxes++;
	       }
	       gwlist_unlock(wapbox_list);
        }
        if (smsbox_list) {
            gw_rwlock_rdlock(smsbox_list_rwlock);
	    for(i=0; i < gwlist_len(smsbox_list); i++) {
	        bi = gwlist_get(smsbox_list, i);
	        if (bi->alive == 0)
		        continue;
	        t = orig - bi->connect_time;
            if (status_type == BBSTATUS_XML)
	            octstr_format_append(tmp, "<box>\n\t\t<type>smsbox</type>\n"
                    "\t\t<id>%s</id>\n\t\t<IP>%s</IP>\n"
                    "\t\t<queue>%ld</queue>\n"
                    "\t\t<status>on-line %ldd %ldh %ldm %lds</status>\n"
                    "\t\t<ssl>%s</ssl>\n\t</box>",
                    (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : ""),
		            octstr_get_cstr(bi->client_ip),
		            gwlist_len(bi->incoming) + dict_key_count(bi->sent),
		            t/3600/24, t/3600%24, t/60%60, t%60,
#ifdef HAVE_LIBSSL
                    conn_get_ssl(bi->conn) != NULL ? "yes" : "no"
#else 
                    "not installed"
#endif
                    );
            else
                octstr_format_append(tmp, "%ssmsbox:%s, IP %s (%ld queued), (on-line %ldd %ldh %ldm %lds) %s %s",
                    ws, (bi->boxc_id ? octstr_get_cstr(bi->boxc_id) : "(none)"), 
                    octstr_get_cstr(bi->client_ip), gwlist_len(bi->incoming) + dict_key_count(bi->sent),
		            t/3600/24, t/3600%24, t/60%60, t%60, 
#ifdef HAVE_LIBSSL
                    conn_get_ssl(bi->conn) != NULL ? "using SSL" : "",
#else
                    "",
#endif 
                    lb);
	       boxes++;
	    }
	    gw_rwlock_unlock(smsbox_list_rwlock);
    }
    if (boxes == 0 && status_type != BBSTATUS_XML) {
	    octstr_destroy(tmp);
	    tmp = octstr_format("%sNo boxes connected", para ? "<p>" : "");
    }
    if (para)
	    octstr_append_cstr(tmp, "</p>");
    if (status_type == BBSTATUS_XML)
        octstr_append_cstr(tmp, "</boxes>\n");
    else
        octstr_append_cstr(tmp, "\n\n");
    return tmp;
}
Пример #6
0
void smpp_route_message_database(SMPPServer *smpp_server, int direction, Octstr *smsc_id, Octstr *system_id, Msg *msg, void(*callback)(void *context, int result, double cost), void *context) {
    SMPPRouting *smpp_routing = smpp_server->routing;
    List *routes;
    
    long i, num_routes;
    
    int found = 0;
    SMPPRoute *route;
    
    gw_rwlock_rdlock(smpp_routing->lock);
    if(msg_type(msg) == sms) { /* we can only route sms's */
        if((direction == SMPP_ROUTE_DIRECTION_OUTBOUND) && octstr_len(system_id)) {
            /* Look for our ESME routes */
            gw_rwlock_wrlock(smpp_routing->outbound_lock);
            routes = dict_get(smpp_routing->outbound_routes, system_id);
            if(!routes) {
                routes = smpp_database_get_routes(smpp_server, direction, system_id);
                dict_put(smpp_routing->outbound_routes, system_id, routes);
            }
            gw_rwlock_unlock(smpp_routing->outbound_lock);

            num_routes = gwlist_len(routes);
            for(i=0;i<num_routes;i++) {
                route = gwlist_get(routes, i);
                found = gw_regex_match_pre(route->regex, msg->sms.receiver);
                
                if(found) {
                    break;
                }
            }
            
            if(found) {
                octstr_destroy(msg->sms.smsc_id);
                msg->sms.smsc_id = octstr_duplicate(route->smsc_id);
                debug("smpp.route.message.database", 0, "SMPP[%s] Found outbound route for %s towards %s", octstr_get_cstr(system_id), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.smsc_id));
                callback(context, 1, route->cost);
            } else {
                callback(context, 0, 0);
            }
        } else if((direction == SMPP_ROUTE_DIRECTION_INBOUND) && octstr_len(smsc_id)) {
            routes = smpp_routing->inbound_routes;
            num_routes = gwlist_len(routes);
            for(i=0;i<num_routes;i++) {
                route = gwlist_get(routes, i);
                found = gw_regex_match_pre(route->regex, msg->sms.receiver);
                
                if(found) {
                    break;
                }
            }
            
            if(found) {
                octstr_destroy(msg->sms.service);
                msg->sms.service = octstr_duplicate(route->system_id);
                debug("smpp.route.message.database", 0, "SMPP[%s] Found inbound route for %s from %s", octstr_get_cstr(route->system_id), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(smsc_id));
                callback(context, 1, route->cost);
            } else {
                callback(context, 0, 0);
            }
        } else {
            callback(context, 0, 0);
        }
    } else {
        callback(context, 0, 0);
    }
    
    gw_rwlock_unlock(smpp_routing->lock);
}