diff --git a/include/fluent-bit/flb_network.h b/include/fluent-bit/flb_network.h index 6437d318014..18f9aad37f0 100644 --- a/include/fluent-bit/flb_network.h +++ b/include/fluent-bit/flb_network.h @@ -33,7 +33,7 @@ int flb_net_socket_nonblocking(int sockfd); int flb_net_socket_tcp_fastopen(int sockfd); /* Socket handling */ -int flb_net_socket_create(); +int flb_net_socket_create(int family, int nonblock); int flb_net_tcp_connect(char *host, unsigned long port); int flb_net_server(char *port, char *listen_addr); int flb_net_bind(int socket_fd, const struct sockaddr *addr, diff --git a/src/flb_network.c b/src/flb_network.c index d127a24baa5..1de428dcd99 100644 --- a/src/flb_network.c +++ b/src/flb_network.c @@ -75,17 +75,19 @@ int flb_net_socket_tcp_fastopen(int sockfd) return setsockopt(sockfd, SOL_TCP, TCP_FASTOPEN, &qlen, sizeof(qlen)); } -int flb_net_socket_create() +int flb_net_socket_create(int family, int nonblock) { int fd; /* create the socket and set the nonblocking flag status */ - fd = socket(AF_INET, SOCK_STREAM, 0); + fd = socket(family, SOCK_STREAM, 0); if (fd <= 0) { perror("socket"); return -1; } - flb_net_socket_tcp_nodelay(fd); + if (nonblock) { + flb_net_socket_tcp_nodelay(fd); + } return fd; } @@ -93,35 +95,45 @@ int flb_net_socket_create() /* Connect to a TCP socket server and returns the file descriptor */ int flb_net_tcp_connect(char *host, unsigned long port) { - int sock_fd; - struct sockaddr_in *remote; - struct hostent *hostp; + 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; - sock_fd = socket(AF_INET, SOCK_STREAM, 0); - if (sock_fd <= 0) { - printf("Error: could not create socket\n"); + 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; } - remote = (struct sockaddr_in *) malloc(sizeof(struct sockaddr_in)); - remote->sin_family = AF_INET; + 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; + } - hostp = gethostbyname(host); - if (hostp == NULL) { - close(sock_fd); - return -1; + 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; } - memcpy(&remote->sin_addr, hostp->h_addr, sizeof(remote->sin_addr)); - remote->sin_port = htons(port); - if (connect(sock_fd, - (struct sockaddr *) remote, sizeof(struct sockaddr)) == -1) { - close(sock_fd); - free(remote); + + freeaddrinfo(res); + + if (rp == NULL) { return -1; } - free(remote); - return sock_fd; + return socket_fd; } int flb_net_server(char *port, char *listen_addr) @@ -143,7 +155,7 @@ int flb_net_server(char *port, char *listen_addr) } for (rp = res; rp != NULL; rp = rp->ai_next) { - socket_fd = flb_net_socket_create(); + 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; @@ -154,7 +166,8 @@ int flb_net_server(char *port, char *listen_addr) 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:%s\n", listen_addr, port); + flb_message(FLB_MSG_WARN, "Cannot listen on %s port %s", listen_addr, port); + close(socket_fd); continue; } break; diff --git a/src/flb_output.c b/src/flb_output.c index d719d15d358..886368ca37e 100644 --- a/src/flb_output.c +++ b/src/flb_output.c @@ -47,42 +47,40 @@ static char *copy_substr(char *str, int s) static int split_address(struct flb_output_plugin *plugin, char *output) { int len; - char *sep; - char *tmp; - char *buf; - + char *s, *e; len = strlen(plugin->name) + 3; if (strlen(output) <= len) { return -1; } - tmp = output + len; - sep = strchr(output + len, ':'); - if (sep) { - len = (sep - tmp); - plugin->host = copy_substr(tmp, sep - tmp); - - tmp += len + 1; - len = strlen(tmp); - if (len == 0) { - plugin->port = atoi(FLB_OUTPUT_FLUENT_PORT); - return 0; + s = output + len; + if (*s == '[') { + /* IPv6 address (RFC 3986) */ + e = strchr(++s, ']'); + if (!e) { + return -1; } - buf = copy_substr(tmp, len); - plugin->port = atoi(buf); - free(buf); - return 0; - } - else { - if (strlen(tmp) == 0) { + plugin->host = copy_substr(s, e - s); + s = e + 1; + } else { + e = s; + while (!(*e == '\0' || *e == ':')) { + ++e; + } + if (e == s) { return -1; } - - plugin->host = strdup(tmp); + plugin->host = copy_substr(s, e - s); + s = e; + } + if (*s == ':') { + plugin->port = atoi(++s); + } + else { plugin->port = atoi(FLB_OUTPUT_FLUENT_PORT); - return 0; } + return 0; } /* Validate the the output address protocol */