示例#1
0
文件: test_dict.c 项目: armic/erpts
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;
}
示例#2
0
static int store_file_dump(void)
{
    int retval;

    debug("bb.store", 0, "Dumping %ld messages to store",
	  dict_key_count(sms_dict));
    mutex_lock(file_mutex);
    if (file != NULL) {
        fclose(file);
        file = NULL;
    }
    retval = do_dump();
    mutex_unlock(file_mutex);

    return retval;
}
示例#3
0
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);
}
示例#4
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;
}
示例#5
0
static void proxy_thread(void *arg)
{
    int ss, cs; /* server and client sockets */
    int fl; /* socket flags */
    Octstr *addr = NULL;
    int forward;
    Octstr *tmp;

    run_thread = 1;
    ss = cs = -1;

    /* create client binding, only if we have a remote server
     * and make the client socet non-blocking */
    if (remote_host != NULL) {
        cs = udp_client_socket();
        fl = fcntl(cs, F_GETFL);
        fcntl(cs, F_SETFL, fl | O_NONBLOCK);
        addr = udp_create_address(remote_host, remote_port);
    }

    /* create server binding */
    ss = udp_bind(our_port, octstr_get_cstr(our_host));

    /* make the server socket non-blocking */
    fl = fcntl(ss, F_GETFL);
    fcntl(ss, F_SETFL, fl | O_NONBLOCK);

    if (ss == -1)
        panic(0, "RADIUS: Couldn't set up server socket for port %ld.", our_port);

    while (run_thread) {
        RADIUS_PDU *pdu, *r;
        Octstr *data, *rdata;
        Octstr *from_nas, *from_radius;

        pdu = r = NULL;
        data = rdata = from_nas = from_radius = NULL;
        
        if (read_available(ss, 100000) < 1)
            continue;

        /* get request from NAS */
        if (udp_recvfrom(ss, &data, &from_nas) == -1) {
            if (errno == EAGAIN)
                /* No datagram available, don't block. */
                continue;

            error(0, "RADIUS: Couldn't receive request data from NAS");
            continue;
        }

        tmp = udp_get_ip(from_nas);
        info(0, "RADIUS: Got data from NAS <%s:%d>",
             octstr_get_cstr(tmp), udp_get_port(from_nas));
        octstr_destroy(tmp);
        octstr_dump(data, 0);

        /* unpacking the RADIUS PDU */
        if ((pdu = radius_pdu_unpack(data)) == NULL) {
            warning(0, "RADIUS: Couldn't unpack PDU from NAS, ignoring.");
            goto error;
        }
        info(0, "RADIUS: from NAS: PDU type: %s", pdu->type_name);

        /* authenticate the Accounting-Request packet */
        if (radius_authenticate_pdu(pdu, &data, secret_nas) == 0) {
            warning(0, "RADIUS: Authentication failed for PDU from NAS, ignoring.");
            goto error;
        }

        /* store to hash table if not present yet */
        mutex_lock(radius_mutex);
        forward = update_tables(pdu);
        mutex_unlock(radius_mutex);

        /* create response PDU for NAS */
        r = radius_pdu_create(0x05, pdu);

        /*
         * create response authenticator 
         * code+identifier(req)+length+authenticator(req)+(attributes)+secret 
         */
        r->u.Accounting_Response.identifier = pdu->u.Accounting_Request.identifier;
        r->u.Accounting_Response.authenticator =
            octstr_duplicate(pdu->u.Accounting_Request.authenticator);

        /* pack response for NAS */
        rdata = radius_pdu_pack(r);

        /* creates response autenticator in encoded PDU */
        radius_authenticate_pdu(r, &rdata, secret_nas);

        /* 
         * forward request to remote RADIUS server only if updated
         * and if we have a configured remote RADIUS server 
         */
        if ((remote_host != NULL) && forward) {
            if (udp_sendto(cs, data, addr) == -1) {
                error(0, "RADIUS: Couldn't send to remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else 
            if (read_available(cs, remote_timeout) < 1) {
                error(0, "RADIUS: Timeout for response from remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else 
            if (udp_recvfrom(cs, &data, &from_radius) == -1) {
                error(0, "RADIUS: Couldn't receive from remote RADIUS <%s:%ld>.",
                      octstr_get_cstr(remote_host), remote_port);
            } else {
                info(0, "RADIUS: Got data from remote RADIUS <%s:%d>.",
                     octstr_get_cstr(udp_get_ip(from_radius)), udp_get_port(from_radius));
                octstr_dump(data, 0);

                /* XXX unpack the response PDU and check if the response
                 * authenticator is valid */
            }
        }

        /* send response to NAS */
        if (udp_sendto(ss, rdata, from_nas) == -1)
            error(0, "RADIUS: Couldn't send response data to NAS <%s:%d>.",
                  octstr_get_cstr(udp_get_ip(from_nas)), udp_get_port(from_nas));

error:
        radius_pdu_destroy(pdu);
        radius_pdu_destroy(r);

        octstr_destroy(rdata);
        octstr_destroy(data);
        octstr_destroy(from_nas);

        debug("radius.proxy", 0, "RADIUS: Mapping table contains %ld elements",
              dict_key_count(radius_table));
        debug("radius.proxy", 0, "RADIUS: Session table contains %ld elements",
              dict_key_count(session_table));
        debug("radius.proxy", 0, "RADIUS: Client table contains %ld elements",
              dict_key_count(client_table));

    }

    octstr_destroy(addr);
}
示例#6
0
static int store_file_load(void(*receive_msg)(Msg*))
{
    List *keys;
    Octstr *store_file, *key;
    Msg *msg;
    int retval, msgs;
    long end, pos;

    if (filename == NULL)
        return 0;

    mutex_lock(file_mutex);
    if (file != NULL) {
        fclose(file);
        file = NULL;
    }

    store_file = octstr_read_file(octstr_get_cstr(filename));
    if (store_file != NULL)
        info(0, "Loading store file `%s'", octstr_get_cstr(filename));
    else {
        store_file = octstr_read_file(octstr_get_cstr(newfile));
        if (store_file != NULL)
            info(0, "Loading store file `%s'", octstr_get_cstr(newfile));
        else {
            store_file = octstr_read_file(octstr_get_cstr(bakfile));
            if (store_file != NULL)
        	       info(0, "Loading store file `%s'", octstr_get_cstr(bakfile));
            else {
                info(0, "Cannot open any store file, starting a new one");
                retval = open_file(filename);
                goto end;
            }
        }
    }

    info(0, "Store-file size %ld, starting to unpack%s", octstr_len(store_file),
        octstr_len(store_file) > 10000 ? " (may take awhile)" : "");


    pos = 0;
    msgs = 0;
    end = octstr_len(store_file);
    
    while (pos < end) {
        if (read_msg(&msg, store_file, &pos) == -1) {
            error(0, "Garbage at store-file, skipped.");
            continue;
        }
        if (msg_type(msg) == sms) {
            store_to_dict(msg);
            msgs++;
        } else if (msg_type(msg) == ack) {
            store_to_dict(msg);
        } else {
            warning(0, "Strange message in store-file, discarded, "
                "dump follows:");
            msg_dump(msg, 0);
        }
        msg_destroy(msg);
    }
    octstr_destroy(store_file);

    info(0, "Retrieved %d messages, non-acknowledged messages: %ld",
        msgs, dict_key_count(sms_dict));

    /* now create a new sms_store out of messages left */

    keys = dict_keys(sms_dict);
    while ((key = gwlist_extract_first(keys)) != NULL) {
        msg = dict_remove(sms_dict, key);
        if (store_to_dict(msg) != -1) {
            receive_msg(msg);
        } else {
            error(0, "Found unknown message type in store file.");
            msg_dump(msg, 0);
            msg_destroy(msg);
        }
        octstr_destroy(key);
    }
    gwlist_destroy(keys, octstr_destroy_item);

    /* Finally, generate new store file out of left messages */
    retval = do_dump();

end:
    mutex_unlock(file_mutex);

    /* allow using of store */
    gwlist_remove_producer(loaded);

    /* start dumper thread */
    if ((cleanup_thread = gwthread_create(store_dumper, NULL))==-1)
        panic(0, "Failed to create a cleanup thread!");

    return retval;
}
示例#7
0
static long store_file_messages(void)
{
    return (sms_dict ? dict_key_count(sms_dict) : -1);
}