コード例 #1
0
ファイル: circqueue.c プロジェクト: anatolijd/statsite
/**
 * Writes the data from a given input buffer
 * into the circular buffer.
 * @return 0 on success.
 */
int circbuf_write(circular_buffer *buf, char *in, uint64_t bytes) {
    // Check for available space
    uint64_t avail = circbuf_avail_buf(buf);
    while (avail < bytes) {
        circbuf_grow_buf(buf);
        avail = circbuf_avail_buf(buf);
    }

    if (buf->write_cursor < buf->read_cursor) {
        memcpy(buf->buffer+buf->write_cursor, in, bytes);
        buf->write_cursor += bytes;

    } else {
        uint64_t end_size = buf->buf_size - buf->write_cursor;
        if (end_size >= bytes) {
            memcpy(buf->buffer+buf->write_cursor, in, bytes);
            buf->write_cursor += bytes;

        } else {
            // Copy the first end_size bytes
            memcpy(buf->buffer+buf->write_cursor, in, end_size);

            // Copy the remaining data
            memcpy(buf->buffer, in+end_size, (bytes - end_size));
            buf->write_cursor = (bytes - end_size);
        }
    }

    return 0;
}
コード例 #2
0
ファイル: networking.c プロジェクト: SponsorPay/bloomd
/**
 * Invoked when a client connection has data ready to be read.
 * We need to take care to add the data to our buffers, and then
 * invoke the connection handlers who have the business logic
 * of what to do.
 */
static int read_client_data(conn_info *conn) {
    /**
     * Figure out how much space we have to write.
     * If we have < 50% free, we resize the buffer using
     * a multiplier.
     */
    int avail_buf = circbuf_avail_buf(&conn->input);
    if (avail_buf < conn->input.buf_size / 2) {
        circbuf_grow_buf(&conn->input);
    }

    // Build the IO vectors to perform the read
    struct iovec vectors[2];
    int num_vectors;
    circbuf_setup_readv_iovec(&conn->input, (struct iovec*)&vectors, &num_vectors);

    // Issue the read
    ssize_t read_bytes = readv(conn->client.fd, (struct iovec*)&vectors, num_vectors);

    // Make sure we actually read something
    if (read_bytes == 0) {
        syslog(LOG_DEBUG, "Closed client connection. [%d]\n", conn->client.fd);
        return 1;
    } else if (read_bytes == -1) {
        if (errno != EAGAIN && errno != EINTR) {
            syslog(LOG_ERR, "Failed to read() from connection [%d]! %s.",
                    conn->client.fd, strerror(errno));
        }
        return 1;
    }

    // Update the write cursor
    circbuf_advance_write(&conn->input, read_bytes);
    return 0;
}
コード例 #3
0
ファイル: networking.c プロジェクト: Instagram/statsite
/**
 * Initializes the UDP Listener.
 * @arg netconf The network configuration
 * @return 0 on success.
 */
static int setup_udp_listener(statsite_networking *netconf) {
    if (netconf->config->udp_port == 0) {
        syslog(LOG_INFO, "UDP port is disabled");
        return 0;
    }
    struct sockaddr_in addr;
    struct in_addr bind_addr;
    bzero(&addr, sizeof(addr));
    bzero(&bind_addr, sizeof(bind_addr));
    addr.sin_family = PF_INET;
    addr.sin_port = htons(netconf->config->udp_port);

    int ret = inet_pton(AF_INET, netconf->config->bind_address, &bind_addr);
    if (ret != 1) {
        syslog(LOG_ERR, "Invalid IPv4 address '%s'!", netconf->config->bind_address);
        return 1;
    }
    addr.sin_addr = bind_addr;

    // Make the socket, bind and listen
    int udp_listener_fd = socket(PF_INET, SOCK_DGRAM, 0);
    int optval = 1;
    if (setsockopt(udp_listener_fd, SOL_SOCKET,
                SO_REUSEADDR, &optval, sizeof(optval))) {
        syslog(LOG_ERR, "Failed to set SO_REUSEADDR! Err: %s", strerror(errno));
        close(udp_listener_fd);
        return 1;
    }
    if (bind(udp_listener_fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        syslog(LOG_ERR, "Failed to bind on UDP socket! Err: %s", strerror(errno));
        close(udp_listener_fd);
        return 1;
    }

    // Put the socket in non-blocking mode
    int flags = fcntl(udp_listener_fd, F_GETFL, 0);
    fcntl(udp_listener_fd, F_SETFL, flags | O_NONBLOCK);

    // Allocate a connection object for the UDP socket,
    // ensure a min-buffer size of 64K
    conn_info *conn = get_conn();
    while (circbuf_avail_buf(&conn->input) < 65536) {
        circbuf_grow_buf(&conn->input);
    }
    netconf->udp_client.data = conn;

    syslog(LOG_INFO, "Listening on udp '%s:%d'.",
           netconf->config->bind_address, netconf->config->udp_port);

    // Create the libev objects
    ev_io_init(&netconf->udp_client, handle_udp_message,
                udp_listener_fd, EV_READ);
    ev_io_start(&netconf->udp_client);
    return 0;
}
コード例 #4
0
/**
 * Initializes the UDP Listener.
 * @arg netconf The network configuration
 * @return 0 on success.
 */
static int setup_udp_listener(statsite_proxy_networking *netconf) {
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = PF_INET;
    addr.sin_port = htons(netconf->config->udp_port);
    addr.sin_addr.s_addr = INADDR_ANY;



    // Make the socket, bind and listen
    int udp_listener_fd = socket(PF_INET, SOCK_DGRAM, 0);
    int optval = 1;
    if (setsockopt(udp_listener_fd, SOL_SOCKET,
                SO_REUSEADDR, &optval, sizeof(optval))) {
        syslog(LOG_ERR, "Failed to set SO_REUSEADDR! Err: %s", strerror(errno));
        close(udp_listener_fd);
        return 1;
    }
    if (bind(udp_listener_fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
        syslog(LOG_ERR, "Failed to bind on UDP socket! Err: %s", strerror(errno));
        close(udp_listener_fd);
        return 1;
    }

    // Allocate a connection object for the UDP socket,
    // ensure a min-buffer size of 64K
    conn_info *conn = get_conn(netconf);
    while (circbuf_avail_buf(&conn->input) < 65536) {
        circbuf_grow_buf(&conn->input);
    }
    netconf->udp_client.data = conn;

    // Create the libev objects
    ev_io_init(&netconf->udp_client, prepare_event,
                udp_listener_fd, EV_READ);
    ev_io_start(&netconf->udp_client);
    return 0;
}
コード例 #5
0
ファイル: networking.c プロジェクト: choplin/statsite
/**
 * Initializes the UDP Listener.
 * @arg netconf The network configuration
 * @return 0 on success.
 */
static int setup_udp_listener(statsite_networking *netconf) {
    if (netconf->config->udp_port == 0) {
        syslog(LOG_INFO, "UDP port is disabled");
        return 0;
    }
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int s;
    int udp_listener_fd;
    int optval = 1;
    char udp_port[MAX_PORT_LEN];

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = AI_PASSIVE;
    hints.ai_protocol = 0;          /* Any protocol */
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

    snprintf(udp_port, MAX_PORT_LEN, "%d", netconf->config->udp_port);

    s = getaddrinfo(netconf->config->bind_address, udp_port, &hints, &result);
    if (s != 0) {
        syslog(LOG_ERR, "getaddrinfo: %s\n", gai_strerror(s));
        return 1;
    }
    for (rp = result; rp != NULL; rp = rp->ai_next) {
        udp_listener_fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (udp_listener_fd == -1)
            continue;
        if (setsockopt(udp_listener_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
            syslog(LOG_ERR, "Failed to set SO_REUSEADDR! Err: %s", strerror(errno));
            close(udp_listener_fd);
            continue;
        }
        if (bind(udp_listener_fd, rp->ai_addr, rp->ai_addrlen) == 0)
            break;
        syslog(LOG_ERR, "Failed to bind on UDP socket! Err: %s", strerror(errno));
        close(udp_listener_fd);
    }
    if (rp == NULL) {               /* No address succeeded */
        syslog(LOG_ERR, "Failed to bind on any UDP socket!\n");
        return 1;
    }

    // Put the socket in non-blocking mode
    int flags = fcntl(udp_listener_fd, F_GETFL, 0);
    fcntl(udp_listener_fd, F_SETFL, flags | O_NONBLOCK);

    // Allocate a connection object for the UDP socket,
    // ensure a min-buffer size of 64K
    conn_info *conn = get_conn();
    while (circbuf_avail_buf(&conn->input) < 65536) {
        circbuf_grow_buf(&conn->input);
    }
    netconf->udp_client.data = conn;

    syslog(LOG_INFO, "Listening on udp '%s:%d'.",
           netconf->config->bind_address, netconf->config->udp_port);

    // Create the libev objects
    ev_io_init(&netconf->udp_client, handle_udp_message,
                udp_listener_fd, EV_READ);
    ev_io_start(&netconf->udp_client);
    return 0;
}