コード例 #1
0
ファイル: flb_network.c プロジェクト: enukane/fluent-bit
int flb_net_server(char *port, char *listen_addr)
{
    int socket_fd = -1;
    int ret;
    struct addrinfo hints;
    struct addrinfo *res, *rp;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    ret = getaddrinfo(listen_addr, port, &hints, &res);
    if (ret != 0) {
        flb_message(FLB_MSG_ERROR, "net_server: Can't get addr info");
        return -1;
    }

    for (rp = res; rp != NULL; rp = rp->ai_next) {
        socket_fd = flb_net_socket_create(rp->ai_family, 1);
        if (socket_fd == -1) {
            flb_message(FLB_MSG_ERROR, "Error creating server socket, retrying");
            continue;
        }

        flb_net_socket_tcp_nodelay(socket_fd);
        flb_net_socket_reset(socket_fd);

        ret = flb_net_bind(socket_fd, rp->ai_addr, rp->ai_addrlen, 128);
        if(ret == -1) {
            flb_message(FLB_MSG_WARN, "Cannot listen on %s port %s", listen_addr, port);
            close(socket_fd);
            continue;
        }
        break;
    }
    freeaddrinfo(res);

    if (rp == NULL) {
        return -1;
    }

    return socket_fd;
}
コード例 #2
0
ファイル: flb_network.c プロジェクト: enukane/fluent-bit
/* Connect to a TCP socket server and returns the file descriptor */
int flb_net_tcp_connect(char *host, unsigned long port)
{
    int socket_fd = -1;
    int ret;
    struct addrinfo hints;
    struct addrinfo *res, *rp;
    char _port[6];

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    snprintf(_port, sizeof(_port), "%lu", port);
    ret = getaddrinfo(host, _port, &hints, &res);
    if (ret != 0) {
        flb_message(FLB_MSG_ERROR, "net_tcp_connect: Can't get addr info");
        return -1;
    }

    for (rp = res; rp != NULL; rp = rp->ai_next) {
        socket_fd = flb_net_socket_create(rp->ai_family, 0);
        if (socket_fd == -1) {
            flb_message(FLB_MSG_ERROR, "Error creating client socket, retrying");
            continue;
        }

        if (connect(socket_fd, rp->ai_addr, rp->ai_addrlen) == -1) {
            flb_message(FLB_MSG_ERROR, "Cannot connect to %s port %s", host, _port);
            close(socket_fd);
            continue;
        }
        break;
    }

    freeaddrinfo(res);

    if (rp == NULL) {
        return -1;
    }

    return socket_fd;
}
コード例 #3
0
ファイル: flb_io.c プロジェクト: pandax381/fluent-bit
FLB_INLINE int flb_io_net_connect(struct flb_io_upstream *u,
                                  struct flb_thread *th)
{
    int fd;
    int ret;
    int error = 0;
    socklen_t len = sizeof(error);

    if (u->fd > 0) {
        close(u->fd);
    }

    /* Create the socket */
    fd = flb_net_socket_create(AF_INET, FLB_TRUE);
    if (fd == -1) {
        flb_error("[io] could not create socket");
        return -1;
    }
    u->fd = fd;

    /* Make the socket non-blocking */
    flb_net_socket_nonblocking(u->fd);

    /* Start the connection */
    ret = flb_net_tcp_fd_connect(fd, u->tcp_host, u->tcp_port);
    if (ret == -1) {
        if (errno == EINPROGRESS) {
            flb_debug("[upstream] connection in process");
        }
        else {
        }

        u->event.mask = MK_EVENT_EMPTY;
        u->event.status = MK_EVENT_NONE;
        u->thread = th;

        ret = mk_event_add(u->evl,
                           fd,
                           FLB_ENGINE_EV_THREAD,
                           MK_EVENT_WRITE, &u->event);
        if (ret == -1) {
            /*
             * If we failed here there no much that we can do, just
             * let the caller we failed
             */
            close(fd);
            return -1;
        }

        /*
         * Return the control to the parent caller, we need to wait for
         * the event loop to get back to us.
         */
        flb_thread_yield(th, FLB_FALSE);

        /* We got a notification, remove the event registered */
        ret = mk_event_del(u->evl, &u->event);
        assert(ret == 0);

        /* Check the connection status */
        if (u->event.mask & MK_EVENT_WRITE) {
            ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
            if (ret == -1) {
                flb_error("[io] could not validate socket status");
                return -1;
            }

            if (error != 0) {
                /* Connection is broken, not much to do here */
                flb_debug("[io] connection failed");
                return -1;
            }
            u->event.mask   = MK_EVENT_EMPTY;
            u->event.status = MK_EVENT_NONE;
        }
        else {
            return -1;
        }
    }

    flb_debug("[io] connection OK");
    return 0;
}
コード例 #4
0
ファイル: flb_io_tls.c プロジェクト: coxnegative/fluent-bit
/*
 * This routine perform a TCP connection and the required TLS/SSL
 * handshake,
 */
FLB_INLINE int flb_io_net_tls_connect(struct flb_io_upstream *u,
                                      struct flb_thread *th)
{
    int fd;
    int ret;
    int error = 0;
    int flag;
    socklen_t len = sizeof(error);
    struct flb_tls_session *session;

    if (u->fd > 0) {
        close(u->fd);
    }

    /* Create the socket */
    fd = flb_net_socket_create(AF_INET, FLB_TRUE);
    if (fd == -1) {
        flb_error("[io] could not create socket");
        return -1;
    }
    u->fd = fd;

    /* Make the socket non-blocking */
    flb_net_socket_nonblocking(u->fd);

    /* Start the connection */
    ret = flb_net_tcp_fd_connect(fd, u->tcp_host, u->tcp_port);
    if (ret == -1) {
        if (errno == EINPROGRESS) {
            flb_debug("[upstream] connection in process");
        }
        else {
            close(u->fd);
            if (u->tls_session) {
                tls_session_destroy(u->tls_session);
                u->tls_session = NULL;
            }
            return -1;
        }

        MK_EVENT_NEW(&u->event);
        u->thread = th;

        ret = mk_event_add(u->evl,
                           fd,
                           FLB_ENGINE_EV_THREAD,
                           MK_EVENT_WRITE, &u->event);
        if (ret == -1) {
            /*
             * If we failed here there no much that we can do, just
             * let the caller we failed
             */
            flb_error("[io_tls] connect failed registering event");
            close(fd);
            return -1;
        }

        /*
         * Return the control to the parent caller, we need to wait for
         * the event loop to get back to us.
         */
        flb_thread_yield(th, FLB_FALSE);

        /* Check the connection status */
        if (u->event.mask & MK_EVENT_WRITE) {
            ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);
            if (ret == -1) {
                flb_error("[io_tls] could not validate socket status");
                goto error;
            }

            if (error != 0) {
                /* Connection is broken, not much to do here */
                flb_error("[io_tls] connection failed");
                goto error;
            }
        }
        else {
            return -1;
        }
    }

    /* Configure TLS and prepare handshake */
    session = u->tls_session;
    mbedtls_ssl_set_bio(&session->ssl,
                        u,
                        mbedtls_net_send, mbedtls_net_recv, NULL);

 retry_handshake:
    ret = mbedtls_ssl_handshake(&session->ssl);

    if (ret != 0) {
        if (ret != MBEDTLS_ERR_SSL_WANT_READ &&
            ret !=  MBEDTLS_ERR_SSL_WANT_WRITE) {
            io_tls_error(ret);
            goto error;
        }

        if (ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
            flag = MK_EVENT_WRITE;
        }
        else if (ret == MBEDTLS_ERR_SSL_WANT_READ) {
            flag = MK_EVENT_READ;
        }
        else {

        }

        /*
         * FIXME: if we need multiple reads we are invoking the same
         * system call multiple times.
         */
        ret = mk_event_add(u->evl,
                           u->event.fd,
                           FLB_ENGINE_EV_THREAD,
                           flag, &u->event);
        if (ret == -1) {
            goto error;
        }

        flb_thread_yield(th, FLB_FALSE);
        goto retry_handshake;
    }
    else {
        flb_debug("[io_tls] Handshake OK");
    }

    if (u->event.status == MK_EVENT_REGISTERED) {
        mk_event_del(u->evl, &u->event);
    }
    flb_debug("[io_tls] connection OK");
    return 0;

 error:
    if (u->event.status == MK_EVENT_REGISTERED) {
        mk_event_del(u->evl, &u->event);
    }

    return -1;
}