Example #1
0
/*
 * Copy contents of new_listener into existing listener
 */
static void
listener_update(struct Listener *existing_listener, struct Listener *new_listener, const struct Table_head *tables) {
    assert(existing_listener != NULL);
    assert(new_listener != NULL);
    assert(address_compare(existing_listener->address, new_listener->address) == 0);

    free(existing_listener->fallback_address);
    existing_listener->fallback_address = new_listener->fallback_address;
    new_listener->fallback_address = NULL;

    free(existing_listener->source_address);
    existing_listener->source_address = new_listener->source_address;
    new_listener->source_address = NULL;

    existing_listener->protocol = new_listener->protocol;

    free(existing_listener->table_name);
    existing_listener->table_name = new_listener->table_name;
    new_listener->table_name = NULL;

    logger_ref_put(existing_listener->access_log);
    existing_listener->access_log = logger_ref_get(new_listener->access_log);

    existing_listener->log_bad_requests = new_listener->log_bad_requests;

    struct Table *new_table =
            table_lookup(tables, existing_listener->table_name);

    if (new_table != NULL) {
        init_table(new_table);

        table_ref_put(existing_listener->table);
        existing_listener->table = table_ref_get(new_table);

        table_ref_put(new_listener->table);
        new_listener->table = NULL;
    }
}
Example #2
0
void
add_table(struct Table_head *tables, struct Table *table) {
    table_ref_get(table);
    SLIST_INSERT_HEAD(tables, table, entries);
}
Example #3
0
static int
init_listener(struct Listener *listener, const struct Table_head *tables, struct ev_loop *loop) {
    struct Table *table = table_lookup(tables, listener->table_name);
    if (table == NULL) {
        err("Table \"%s\" not defined", listener->table_name);
        return -1;
    }
    init_table(table);
    listener->table = table_ref_get(table);

    /* If no port was specified on the fallback address, inherit the address
     * from the listening address */
    if (listener->fallback_address &&
            address_port(listener->fallback_address) == 0)
        address_set_port(listener->fallback_address,
                address_port(listener->address));

    int sockfd = socket(address_sa(listener->address)->sa_family, SOCK_STREAM, 0);
    if (sockfd < 0) {
        err("socket failed: %s", strerror(errno));
        return -2;
    }

    /* set SO_REUSEADDR on server socket to facilitate restart */
    int on = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    int result = bind(sockfd, address_sa(listener->address),
            address_sa_len(listener->address));
    if (result < 0 && errno == EACCES) {
        /* Retry using binder module */
        close(sockfd);
        sockfd = bind_socket(address_sa(listener->address),
                address_sa_len(listener->address));
        if (sockfd < 0) {
            char address[128];
            err("binder failed to bind to %s",
                display_address(listener->address, address, sizeof(address)));
            close(sockfd);
            return -3;
        }
    } else if (result < 0) {
        char address[128];
        err("bind %s failed: %s",
            display_address(listener->address, address, sizeof(address)),
            strerror(errno));
        close(sockfd);
        return -3;
    }

    if (listen(sockfd, SOMAXCONN) < 0) {
        err("listen failed: %s", strerror(errno));
        close(sockfd);
        return -4;
    }


    int flags = fcntl(sockfd, F_GETFL, 0);
    fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

    listener_ref_get(listener);
    ev_io_init(&listener->watcher, accept_cb, sockfd, EV_READ);
    listener->watcher.data = listener;
    listener->backoff_timer.data = listener;

    ev_io_start(loop, &listener->watcher);

    return sockfd;
}