Example #1
0
void
readcb(int fd, int id, void* data) {
    struct client* c = data;
    if (c == NULL) {
        printf("id %d, NULL client read\n", id);
        return;
    }

    int error = NETEV_OK;
    for (;;) {
        struct msg_header* h = netev_read(s->ne, id, sizeof(struct msg_header));
        if (h == NULL) {
            error = netev_error(s->ne);
            if (error == NETEV_OK) {
                goto out;
            } else {
                goto err_out;
            }
        }
        assert(h->size == package_size);
        
        uint32_t* msg = netev_read(s->ne, id, h->size);
        if (msg == NULL) {
            error = netev_error(s->ne);
            if (error == NETEV_OK) {
                goto out;
            } else {
                goto err_out;
            }
        }
        int i;
        for (i=0; i<h->size/sizeof(msg[0]); ++i) {
            assert(msg[i] == id);
        }
        //printf("from client %d, read msg size=%d\n", id, h->size);

        //_handle_msg(c, (void*)h, sizeof(*h) + h->size);

        netev_dropread(s->ne, id);

        s->rstat += 1;
    }
out:
    return;
err_out:
    printf("client %d read occur error %d\n", id, error);
    _free_client(s, c);
    s->nclosedread +=1;
    return;
}
Example #2
0
// Handshake with client and attach to PSL
static struct client *_client_connect(int *fd, char *ip)
{
    struct client *client;
    uint8_t buffer[MAX_LINE_CHARS];
    uint8_t ack[3];
    uint16_t map;
    int rc;

    // Parse client handshake data
    ack[0] = PSLSE_DETACH;
    memset(buffer, '\0', MAX_LINE_CHARS);
    rc = get_bytes(*fd, 5, buffer, timeout, 0, fp, -1, -1);
    if ((rc < 0) || (strcmp((char *)buffer, "PSLSE"))) {
        info_msg("Connecting application is not PSLSE client\n");
        info_msg("Expected: \"PSLSE\" Got: \"%s\"", buffer);
        put_bytes(*fd, 1, ack, fp, -1, -1);
        close_socket(fd);
        return NULL;
    }
    rc = get_bytes_silent(*fd, 2, buffer, timeout, 0);
    if ((rc < 0) || ((uint8_t) buffer[0] != PSLSE_VERSION_MAJOR) ||
            ((uint8_t) buffer[1] != PSLSE_VERSION_MINOR)) {
        info_msg("Client is wrong version\n");
        put_bytes(*fd, 1, ack, fp, -1, -1);
        close_socket(fd);
        return NULL;
    }
    // Initialize client struct
    client = (struct client *)calloc(1, sizeof(struct client));
    client->fd = *fd;
    client->ip = ip;
    client->pending = 1;
    client->timeout = timeout;
    client->flushing = FLUSH_NONE;
    client->state = CLIENT_INIT;

    // Return acknowledge to client
    ack[0] = PSLSE_CONNECT;
    map = htons(afu_map);
    memcpy(&(ack[1]), &map, sizeof(map));
    if (put_bytes(client->fd, 3, ack, fp, -1, -1) < 0) {
        _free_client(client);
        return NULL;
    }

    info_msg("%s connected", client->ip);
    return client;
}
Example #3
0
void
_start_write(struct server* s) {
    int i;
    int j;
    int size = package_size + sizeof(struct msg_header);
    char data[size];
    struct msg_header* m = (struct msg_header*)data;
    m->size = package_size;

    for (i=0; i<s->max; ++i) {
        struct client* c = &s->clients[i];
        if (_is_client_closed(c)) 
            continue;
        for (j=0; j<m->size/sizeof(m->text[0]); ++j) {
            m->text[j] = c->conn_id;
        }
        if (_start_write_client(c, m, size) != 0) {
            netev_close_socket(s->ne, c->conn_id);
            _free_client(s, c); 
            s->nclosedwrite +=1;
        } 
    }
}
Example #4
0
static void *fserv_thread_function(void *arg)
{
    fserve_t *fclient, **trail;
    int sbytes, bytes;

    INFO0("file serving thread started");
    while (run_fserv) {
        wait_for_fds();

        fclient = active_list;
        trail = &active_list;

        while (fclient)
        {
            /* process this client, if it is ready */
            if (fclient->ready)
            {
                fclient->ready = 0;
                if(fclient->offset >= fclient->datasize) {
                    /* Grab a new chunk */
                    bytes = fread(fclient->buf, 1, BUFSIZE, fclient->file);
                    if (bytes == 0)
                    {
                        fserve_t *to_go = fclient;
                        fclient = fclient->next;
                        *trail = fclient;
                        _free_client (to_go);
                        fserve_clients--;
                        client_tree_changed = 1;
                        continue;
                    }
                    fclient->offset = 0;
                    fclient->datasize = bytes;
                }

                /* Now try and send current chunk. */
                sbytes = client_send_bytes (fclient->client, 
                        &fclient->buf[fclient->offset], 
                        fclient->datasize - fclient->offset);

                /* TODO: remove clients if they take too long. */
                if(sbytes > 0) {
                    fclient->offset += sbytes;
                }

                if (fclient->client->con->error)
                {
                    fserve_t *to_go = fclient;
                    fclient = fclient->next;
                    *trail = fclient;
                    fserve_clients--;
                    _free_client (to_go);
                    client_tree_changed = 1;
                    continue;
                }
            }
            trail = &fclient->next;
            fclient = fclient->next;
        }
    }

    /* Shutdown path */
    thread_mutex_lock (&pending_lock);
    while (pending_list)
    {
        fserve_t *to_go = (fserve_t *)pending_list;
        pending_list = to_go->next;
        _free_client (to_go);
    }
    thread_mutex_unlock (&pending_lock);

    while (active_list)
    {
        fserve_t *to_go = active_list;
        active_list = to_go->next;
        _free_client (to_go);
    }

    return NULL;
}
Example #5
0
void
writecb(int fd, int id, void* data) {
    struct client* c = data;
    if (c == NULL) {
        printf("id %d, NULL client write\n", id);
        return;
    }

    struct netbuf_block* wbuf_b = c->wbuf_b;
    if (wbuf_b->roffset == wbuf_b->woffset) {
        return; // empty
    }
    int error;
    if (wbuf_b->roffset < wbuf_b->woffset) {
        void* buf = (void*)wbuf_b + sizeof(*wbuf_b) + wbuf_b->roffset;
        int nbyte = netev_write(s->ne, id, buf, wbuf_b->woffset - wbuf_b->roffset);
        if (nbyte == -1) {
            goto err_out;
        }
        if (nbyte > 0) {
            wbuf_b->roffset += nbyte;
            c->stat_write += nbyte;
            goto out;
        }
    } else {
        void* begin = (void*)wbuf_b + sizeof(*wbuf_b);
        void* buf = begin + wbuf_b->roffset;
        int wsize = wbuf_b->size - wbuf_b->roffset;
        int nbyte = netev_write(s->ne, id, buf, wsize);
        if (nbyte == -1) {
            goto err_out;
        }
        if (nbyte == 0) {
            goto out;
        }
        c->stat_write += nbyte;
        if (nbyte < wsize) {
            wbuf_b->roffset += nbyte;
            goto out;
        }
        wbuf_b->roffset = 0;
        wsize = wbuf_b->woffset;
        if (wsize == 0) { 
            goto out;
        }
        nbyte = netev_write(s->ne, id, begin, wsize);
        if (nbyte == -1) {
            goto err_out;
        }
        if (nbyte > 0) {
            wbuf_b->roffset += nbyte;
            c->stat_write += nbyte;
            goto out;
        } 
    }
out:
    //printf("write size=%d, woffset=%d roffset=%d\n", 
            //c->stat_write - oldstat, wbuf_b->woffset, wbuf_b->roffset);
    return;
err_out:
    error = netev_error(s->ne);
    printf("client %d, write occur error %d\n", id, error);
    _free_client(s, c);
    s->nclosedwrite +=1;
}
Example #6
0
int main(int argc, char **argv)
{
    struct sockaddr_in client_addr;
    struct client *client;
    struct client **client_ptr;
    int listen_fd, connect_fd;
    socklen_t client_len;
    sigset_t set;
    struct sigaction action;
    char *shim_host_path;
    char *parms_path;
    char *debug_log_path;
    struct parms *parms;
    char *ip;

    // Open debug.log file
    debug_log_path = getenv("DEBUG_LOG_PATH");
    if (!debug_log_path) debug_log_path = "debug.log";
    fp = fopen(debug_log_path, "w");
    if (!fp) {
        error_msg("Could not open debug.log");
        return -1;
    }

    // Mask SIGPIPE signal for all threads
    sigemptyset(&set);
    sigaddset(&set, SIGPIPE);
    if (pthread_sigmask(SIG_BLOCK, &set, NULL)) {
        perror("pthread_sigmask");
        return -1;
    }
    // Catch SIGINT for graceful termination
    action.sa_handler = _INThandler;
    sigemptyset(&(action.sa_mask));
    action.sa_flags = 0;
    sigaction(SIGINT, &action, NULL);

    // Report version
    info_msg("PSLSE version %d.%03d compiled @ %s %s", PSLSE_VERSION_MAJOR,
             PSLSE_VERSION_MINOR, __DATE__, __TIME__);
    debug_send_version(fp, PSLSE_VERSION_MAJOR, PSLSE_VERSION_MINOR);

    // Parse parameters file
    parms_path = getenv("PSLSE_PARMS");
    if (!parms_path) parms_path = "pslse.parms";
    parms = parse_parms(parms_path, fp);
    if (parms == NULL) {
        error_msg("Unable to parse params file \"%s\"", parms_path);
        return -1;
    }
    timeout = parms->timeout;

    // Connect to simulator(s) and start psl thread(s)
    pthread_mutex_init(&lock, NULL);
    pthread_mutex_lock(&lock);
    shim_host_path = getenv("SHIM_HOST_DAT");
    if (!shim_host_path) shim_host_path = "shim_host.dat";
    afu_map = parse_host_data(&psl_list, parms, shim_host_path, &lock, fp);
    if (psl_list == NULL) {
        free(parms);
        fclose(fp);
        warn_msg("Unable to connect to any simulators");
        return -1;
    }
    // Start server
    if ((listen_fd = _start_server()) < 0) {
        free(parms);
        fclose(fp);
        return -1;
    }
    // Watch for client connections
    while (psl_list != NULL) {
        // Wait for next client to connect
        client_len = sizeof(client_addr);
        pthread_mutex_unlock(&lock);
        connect_fd = accept(listen_fd, (struct sockaddr *)&client_addr,
                            &client_len);
        pthread_mutex_lock(&lock);
        if (connect_fd < 0) {
            lock_delay(&lock);
            continue;
        }
        ip = (char *)malloc(INET_ADDRSTRLEN + 1);
        inet_ntop(AF_INET, &(client_addr.sin_addr.s_addr), ip,
                  INET_ADDRSTRLEN);
        // Clean up disconnected clients
        client_ptr = &client_list;
        while (*client_ptr != NULL) {
            client = *client_ptr;
            if ((client->pending == 0)
                    && (client->state == CLIENT_NONE)) {
                *client_ptr = client->_next;
                if (client->_next != NULL)
                    client->_next->_prev = client->_prev;
                _free_client(client);
                lock_delay(&lock);
                continue;
            }
            client_ptr = &((*client_ptr)->_next);
        }
        // Add new client
        info_msg("Connection from %s", ip);
        client = _client_connect(&connect_fd, ip);
        if (client != NULL) {
            if (client_list != NULL)
                client_list->_prev = client;
            client->_next = client_list;
            client_list = client;
            if (pthread_create(&(client->thread), NULL,
                               _client_loop, client)) {
                perror("pthread_create");
                break;
            }
        }
        lock_delay(&lock);
    }
    info_msg("No AFUs connected, Shutting down PSLSE\n");
    close_socket(&listen_fd);

    // Shutdown unassociated client connections
    while (client_list != NULL) {
        client = client_list;
        client_list = client->_next;
        if (client->pending)
            client->pending = 0;
        pthread_mutex_unlock(&lock);
        pthread_join(client->thread, NULL);
        pthread_mutex_lock(&lock);
        close_socket(&(client->fd));
        _free_client(client);
    }
    pthread_mutex_unlock(&lock);

    free(parms);
    fclose(fp);
    pthread_mutex_destroy(&lock);

    return 0;
}