Пример #1
0
int tbx_ns_chksum_write_flush(tbx_ns_t *ns)
{
    char chksum_value[CHKSUM_MAX_SIZE];
    int err, n;
    tbx_tbuf_t buf;

    log_printf(15, "ns_write_chksum_flush: injecting chksum!  ns=%d type=%d bytesleft=" I64T " bsize=" I64T "\n",
               tbx_ns_getid(ns), tbx_chksum_type(&(ns->write_chksum.chksum)), ns->write_chksum.bytesleft, ns->write_chksum.blocksize);
    tbx_log_flush();

    if (ns_write_chksum_state(ns) == 0) return(0);
    if (ns->write_chksum.bytesleft == ns->write_chksum.blocksize) return(0);  //** Nothing to do

    n = tbx_chksum_size(&(ns->write_chksum.chksum), CHKSUM_DIGEST_HEX);
    tbx_chksum_get(&(ns->write_chksum.chksum), CHKSUM_DIGEST_HEX, chksum_value);

    ns->write_chksum.is_running = 0;  //** Don't want to get in an endless loop
    tbx_tbuf_single(&buf, n, chksum_value);
    err = _write_netstream_block(ns, apr_time_now() + apr_time_make(5,0), &buf, 0, n, 0);
    ns->write_chksum.is_running = 1;

    if (err != 0) {
        log_printf(10, "ns_write_chksum_flush: ns=%d Error writing chksum! error=%d\n", tbx_ns_getid(ns), err);
        return(err);
    }

    chksum_value[n] = '\0';
    log_printf(15, "ns_write_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value);
    log_printf(15, "ns_write_chksum_flush: end of routine!  ns=%d\n err=%d", tbx_ns_getid(ns), err);
    tbx_log_flush();

    return(err);
}
Пример #2
0
int _read_netstream_block(tbx_ns_t *ns, apr_time_t end_time, tbx_tbuf_t *buffer, int pos, int size, int dolock)
{
    int nleft, nbytes, err;

    tbx_ns_timeout_t dt;

    tbx_ns_timeout_set(&dt, 1, 0);
    nleft = size;
    nbytes = -100;
    err = NS_OK;
    while ((nleft > 0) && (err == NS_OK)) {
        nbytes = _tbx_ns_read(ns, buffer, pos, nleft, dt, dolock);
        log_printf(15, "read_netstream_block: ns=%d size=%d nleft=%d nbytes=%d pos=%d time=" TT "\n",
                   tbx_ns_getid(ns), size, nleft, nbytes, pos, apr_time_now());

        if (apr_time_now() > end_time) {
            log_printf(15, "read_netstream_block: ns=%d Command timed out! to=" TT " ct=" TT " \n", tbx_ns_getid(ns), end_time, apr_time_now());
            err = NS_TIMEOUT;
        }

        if (nbytes < 0) {
            err = nbytes;   //** Error with write
        } else if (nbytes > 0) {   //** Normal write
            pos = pos + nbytes;
            nleft = nleft - nbytes;
            err = NS_OK;
        }
    }

    log_printf(15, "read_netstream_block: END ns=%d size=%d nleft=%d nbytes=%d pos=%d\n", tbx_ns_getid(ns), size, nleft, nbytes, pos);

    return(err);
}
Пример #3
0
void _reap_hportal(host_portal_t *hp, int quick)
{
    host_connection_t *hc;
    apr_status_t value;
    int count;

    tbx_stack_move_to_top(hp->closed_que);
    while ((hc = (host_connection_t *)tbx_stack_get_current_data(hp->closed_que)) != NULL) {
        apr_thread_join(&value, hc->recv_thread);
        log_printf(5, "hp=%s ns=%d\n", hp->skey, tbx_ns_getid(hc->ns));
        for (count=0; ((quick == 0) || (count < 2)); count++) {
            lock_hc(hc);  //** Make sure that no one is running close_hc() while we're trying to close it
            if (hc->closing != 1) {  //** Ok to to remove it
                unlock_hc(hc);

                tbx_stack_delete_current(hp->closed_que, 0, 0);
                destroy_host_connection(hc);

                break;
            } else {  //** Got somone trying ot close it so wait a little bit
                unlock_hc(hc);
                apr_sleep(apr_time_from_msec(10));
            }
        }

        tbx_stack_move_down(hp->closed_que);
        if (tbx_stack_get_current_data(hp->closed_que) == NULL) tbx_stack_move_to_top(hp->closed_que);  //** Restart it needed
    }
}
Пример #4
0
int tbx_ns_chksum_read_flush(tbx_ns_t *ns)
{
    char ns_value[CHKSUM_MAX_SIZE], chksum_value[CHKSUM_MAX_SIZE];
    int err, n;
    tbx_tbuf_t buf;

    log_printf(15, "ns_read_chksum_flush: Reading chksum!  ns=%d type=%d bleft=" I64T " bsize=" I64T " state=%d\n",
               tbx_ns_getid(ns), tbx_chksum_type(&(ns->read_chksum.chksum)), ns->read_chksum.bytesleft, ns->read_chksum.blocksize, ns_read_chksum_state(ns));
    tbx_log_flush();

    if (ns_read_chksum_state(ns) == 0) return(0);
    if (ns->read_chksum.bytesleft == ns->read_chksum.blocksize) return(0);  //** Nothing to do

    n = tbx_chksum_size(&(ns->read_chksum.chksum), CHKSUM_DIGEST_HEX);


    ns->read_chksum.is_running = 0;  //** Don't want to get in an endless loop
    tbx_tbuf_single(&buf, n, ns_value);
    err = _read_netstream_block(ns, apr_time_now() + apr_time_make(5,0), &buf, 0, n, 0);
    ns_value[n] = '\0';
    ns->read_chksum.is_running = 1;

    log_printf(15, "ns_read_chksum_flush: Finished reading chksum!  ns=%d\n", tbx_ns_getid(ns));
    tbx_log_flush();

    if (err != 0) {
        log_printf(10, "ns_read_chksum_flush: ns=%d Error reading chksum! error=%d\n", tbx_ns_getid(ns), err);
        return(err);
    }

    tbx_chksum_get(&(ns->read_chksum.chksum), CHKSUM_DIGEST_HEX, chksum_value);
    log_printf(15, "ns_read_chksum_flush: after tbx_chksum_get!  ns=%d\n", tbx_ns_getid(ns));
    tbx_log_flush();
    err = (strncmp(chksum_value, ns_value, n) == 0) ? 0 : 1;

    log_printf(15, "ns_read_chksum_flush: ns=%d     ns_value=%s  cmp=%d\n", tbx_ns_getid(ns), ns_value, err);
    log_printf(15, "ns_read_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value);
    if (err != 0) {
        log_printf(1, "ns_read_chksum_flush: ns=%d chksum error!\n", tbx_ns_getid(ns));
        log_printf(1, "ns_read_chksum_flush: ns=%d     ns_value=%s  cmp=%d\n", tbx_ns_getid(ns), ns_value, err);
        log_printf(1, "ns_read_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value);
    }

    log_printf(15, "ns_read_chksum_flush: end of routine!  ns=%d\n err=%d", tbx_ns_getid(ns), err);
    tbx_log_flush();

    return(err);
}
Пример #5
0
int _tbx_ns_read(tbx_ns_t *ns, tbx_tbuf_t *buffer, unsigned int boff, int size, tbx_ns_timeout_t timeout, int dolock)
{
    int total_bytes, i;
    tbx_tbuf_t ns_tb;

    if (size == 0) return(0);

    if (dolock == 1) lock_read_ns(ns);

    if (ns->sock_status(ns->sock) != 1) {
        log_printf(15, "read_netstream: Dead connection!  ns=%d\n", ns->id);
        if (dolock == 1) unlock_read_ns(ns);
        return(-1);
    }

    if (ns_read_chksum_state(ns) == 1) {  //** We have chksumming enabled
        if (size > ns->read_chksum.bytesleft) {
            size = ns->read_chksum.bytesleft;  //** Truncate at the block
        }
    }

    //*** 1st grab anything currently in the network buffer ***
    if (ns->end >= ns->start) {
        i = ns->end - ns->start + 1;
        if (i>size) {
            total_bytes = size;
            tbx_tbuf_single(&ns_tb, size, &(ns->buffer[ns->start]));
            tbx_tbuf_copy(&ns_tb, 0, buffer, boff, size, 1);
            ns->start = ns->start + total_bytes;
        } else {
            total_bytes = i;
            tbx_tbuf_single(&ns_tb, i, &(ns->buffer[ns->start]));
            tbx_tbuf_copy(&ns_tb, 0, buffer, boff, i, 1);
            ns->start = 0;
            ns->end = -1;
        }
    } else {  //*** Now grab some data off the network port ****
        total_bytes = ns->read(ns->sock, buffer, boff, size, timeout);
    }

    debug_code(
    if (total_bytes > 0) {
//        debug_printf(10, "read_netstream: Command : !");
//        for (i=0; i< total_bytes; i++) debug_printf(10, "%c", buffer[i]);
//        debug_printf(10, "! * nbytes =%d\n", total_bytes); flush_debug();
} else if (total_bytes == 0) {
    debug_printf(10, "read_netstream: No data!\n");
    } else {
        log_printf(10, "read_netstream:  Dead connection! ns=%d\n", tbx_ns_getid(ns));
    }
    )
Пример #6
0
int _tbx_ns_write(tbx_ns_t *ns, tbx_tbuf_t *buffer, unsigned int boff, int bsize, tbx_ns_timeout_t timeout, int dolock)
{
    int total_bytes, i;

    if (dolock == 1) lock_write_ns(ns);


    if (ns->sock_status(ns->sock) != 1) {
        log_printf(15, "write_netstream: connection closed!  ns=%d\n", ns->id);
        if (dolock == 1) unlock_write_ns(ns);
        return(-1);
    }

    if (bsize == 0) {
        if (dolock == 1) unlock_write_ns(ns);
        return(0);
    }

    if (ns_write_chksum_state(ns) == 1) {  //** We have chksumming enabled
        if (bsize > ns->write_chksum.bytesleft) {
            bsize = ns->write_chksum.bytesleft;  //** Truncate at the block
        }
    }

    total_bytes = ns->write(ns->sock, buffer, boff, bsize, timeout);

    if (total_bytes == -1) {
        log_printf(10, "write_netstream:  Dead connection! ns=%d\n", tbx_ns_getid(ns));
    }

    ns->last_write = apr_time_now();

    if ((ns_write_chksum_state(ns) == 1) && (total_bytes > 0)) {  //** We have chksumming enabled
        tbx_chksum_add(&(ns->write_chksum.chksum), total_bytes, buffer, boff);  //** Chksum it
        ns->write_chksum.bytesleft -= total_bytes;
        if (ns->write_chksum.bytesleft <= 0) { //** Reached the block size so inject the chksum
            i = tbx_ns_chksum_write_flush(ns);
            if (i != 0) total_bytes = NS_CHKSUM;

            //** Reset the chksum
            ns->write_chksum.bytesleft = ns->write_chksum.blocksize;
            tbx_chksum_reset(&(ns->write_chksum.chksum));
        }
    }

    if (dolock == 1) unlock_write_ns(ns);

    return(total_bytes);
}
Пример #7
0
void *monitor_thread(apr_thread_t *th, void *data)
{
    tbx_ns_monitor_t *nm = (tbx_ns_monitor_t *)data;
    tbx_ns_t *ns = nm->ns;
    int i;

    log_printf(15, "monitor_thread: Monitoring port %d\n", nm->port);

    apr_thread_mutex_lock(nm->lock);
    while (nm->shutdown_request == 0) {
        apr_thread_mutex_unlock(nm->lock);

        i = ns->connection_request(ns->sock, 1);

        if (i == 1) {  //** Got a request
            log_printf(15, "monitor_thread: port=%d ns=%d Got a connection request time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now());

            //** Mark that I have a connection pending
            apr_thread_mutex_lock(nm->lock);
            nm->is_pending = 1;
            apr_thread_mutex_unlock(nm->lock);

            //** Wake up the calling thread
            apr_thread_mutex_lock(nm->trigger_lock);
            (*(nm->trigger_count))++;
            apr_thread_cond_signal(nm->trigger_cond);
            apr_thread_mutex_unlock(nm->trigger_lock);

            log_printf(15, "monitor_thread: port=%d ns=%d waiting for accept\n", nm->port, tbx_ns_getid(ns));

            //** Sleep until my connection is accepted
            apr_thread_mutex_lock(nm->lock);
            while ((nm->is_pending == 1) && (nm->shutdown_request == 0)) {
                apr_thread_cond_wait(nm->cond, nm->lock);
                log_printf(15, "monitor_thread: port=%d ns=%d Cond triggered=" TT " trigger_count=%d\n", nm->port, tbx_ns_getid(ns), apr_time_now(), *(nm->trigger_count));
            }
            apr_thread_mutex_unlock(nm->lock);
            log_printf(15, "monitor_thread: port=%d ns=%d Connection accepted time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now());

            //** Update pending count
//         apr_thread_mutex_lock(nm->trigger_lock);
//         *(nm->trigger_count)--;
//         apr_thread_mutex_unlock(nm->trigger_lock);
        }

        apr_thread_mutex_lock(nm->lock);
    }

    apr_thread_mutex_unlock(nm->lock);

    //** Lastly shutdown my socket
    tbx_ns_close(ns);

    log_printf(15, "monitor_thread: Closing port %d\n", nm->port);

    apr_thread_exit(th, 0);

    return(NULL);
}
Пример #8
0
int submit_hp_direct_op(portal_context_t *hpc, op_generic_t *op)
{
    int status;
    host_portal_t *hp, *shp;
    host_connection_t *hc;
    command_op_t *hop = &(op->op->cmd);

    apr_thread_mutex_lock(hpc->lock);

    //** Check if we should do a garbage run **
    if (hpc->next_check < time(NULL)) {
        hpc->next_check = time(NULL) + hpc->compact_interval;

        apr_thread_mutex_unlock(hpc->lock);
        compact_hportals(hpc);
        apr_thread_mutex_lock(hpc->lock);
    }

    //** Find it in the list or make a new one
    hp = _lookup_hportal(hpc, hop->hostport);
    if (hp == NULL) {
        log_printf(15, "submit_hp_direct_op: New host: %s\n", hop->hostport);
        hp = create_hportal(hpc, hop->connect_context, hop->hostport, 1, 1, apr_time_from_sec(1));
        if (hp == NULL) {
            log_printf(15, "submit_hp_direct_op: create_hportal failed!\n");
            apr_thread_mutex_unlock(hpc->lock);
            return(-1);
        }
        apr_hash_set(hpc->table, hp->skey, APR_HASH_KEY_STRING, (const void *)hp);
    }

    apr_thread_mutex_unlock(hpc->lock);

    log_printf(15, "submit_hp_direct_op: start opid=%d\n", op->base.id);

    //** Scan the direct list for a free connection
    hportal_lock(hp);
    tbx_stack_move_to_top(hp->direct_list);
    while ((shp = (host_portal_t *)tbx_stack_get_current_data(hp->direct_list)) != NULL)  {
        if (hportal_trylock(shp) == 0) {
            log_printf(15, "submit_hp_direct_op: opid=%d shp->wl=" I64T " stack_size=%d\n", op->base.id, shp->workload, tbx_stack_count(shp->que));

            if (tbx_stack_count(shp->que) == 0) {
                if (tbx_stack_count(shp->conn_list) > 0) {
                    tbx_stack_move_to_top(shp->conn_list);
                    hc = (host_connection_t *)tbx_stack_get_current_data(shp->conn_list);
                    if (trylock_hc(hc) == 0) {
                        if ((tbx_stack_count(hc->pending_stack) == 0) && (hc->curr_workload == 0)) {
                            log_printf(15, "submit_hp_direct_op(A): before submit ns=%d opid=%d wl=%d\n",tbx_ns_getid(hc->ns), op->base.id, hc->curr_workload);
                            unlock_hc(hc);
                            hportal_unlock(shp);
                            status = submit_hportal(shp, op, 1, 0);
                            log_printf(15, "submit_hp_direct_op(A): after submit ns=%d opid=%d\n",tbx_ns_getid(hc->ns), op->base.id);
                            hportal_unlock(hp);
                            return(status);
                        }
                        unlock_hc(hc);
                    }
                } else {
                    hportal_unlock(shp);
                    log_printf(15, "submit_hp_direct_op(B): opid=%d\n", op->base.id);
                    status = submit_hportal(shp, op, 1, 0);
                    hportal_unlock(hp);
                    return(status);
                }
            }

            hportal_unlock(shp);
        }

        tbx_stack_move_down(hp->direct_list);  //** Move to the next hp in the list
    }

    //** If I made it here I have to add a new hportal
    shp = create_hportal(hpc, hop->connect_context, hop->hostport, 1, 1, apr_time_from_sec(1));
    if (shp == NULL) {
        log_printf(15, "submit_hp_direct_op: create_hportal failed!\n");
        hportal_unlock(hp);
        return(-1);
    }
    tbx_stack_push(hp->direct_list, (void *)shp);
    status = submit_hportal(shp, op, 1, 0);

    hportal_unlock(hp);

    return(status);
}