21 #include <drizzled/gettext.h>
22 #include <drizzled/error.h>
23 #include <drizzled/plugin/listen_tcp.h>
24 #include <drizzled/errmsg_print.h>
25 #include <drizzled/constrained_value.h>
29 #include <sys/socket.h>
32 #include <netinet/tcp.h>
37 extern back_log_constraints back_log;
38 extern uint32_t drizzled_bind_timeout;
42 for (
int retry= 0; retry < 10; retry++)
44 int new_fd= accept(fd, NULL, 0);
47 if (errno != EINTR && errno != EAGAIN)
52 sql_perror(_(
"accept() failed with errno %d"));
54 if (errno == ENFILE || errno == EMFILE)
62 char host_buf[NI_MAXHOST];
63 char port_buf[NI_MAXSERV];
69 memset(&hints, 0,
sizeof(
struct addrinfo));
70 hints.ai_flags= AI_PASSIVE;
71 hints.ai_socktype= SOCK_STREAM;
73 snprintf(port_buf, NI_MAXSERV,
"%d", getPort());
74 ret= getaddrinfo(getHost().empty() ? NULL : getHost().c_str(), port_buf, &hints, &ai_list);
77 errmsg_printf(error::ERROR, _(
"getaddrinfo() failed with error %s"),
82 for (addrinfo* ai= ai_list; ai != NULL; ai= ai->ai_next)
84 ret= getnameinfo(ai->ai_addr, ai->ai_addrlen, host_buf, NI_MAXHOST,
85 port_buf, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
88 strcpy(host_buf,
"-");
89 strcpy(port_buf,
"-");
92 int fd= socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
102 if (ai->ai_family == AF_INET6)
105 ret= setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flags,
sizeof(flags));
108 sql_perror(_(
"setsockopt(IPV6_V6ONLY)"));
114 ret= fcntl(fd, F_SETFD, FD_CLOEXEC);
115 if (ret != 0 || !(fcntl(fd, F_GETFD, 0) & FD_CLOEXEC))
117 sql_perror(_(
"fcntl(FD_CLOEXEC)"));
121 ret= setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flags,
sizeof(flags));
124 sql_perror(_(
"setsockopt(SO_REUSEADDR)"));
128 ret= setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &flags,
sizeof(flags));
131 sql_perror(_(
"setsockopt(SO_KEEPALIVE)"));
136 ret= setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling,
sizeof(ling));
139 sql_perror(_(
"setsockopt(SO_LINGER)"));
143 ret= setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flags,
sizeof(flags));
146 sql_perror(_(
"setsockopt(TCP_NODELAY)"));
158 for (uint32_t waited= 0, retry= 1; ; retry++, waited+= this_wait)
160 if (((ret= ::bind(fd, ai->ai_addr, ai->ai_addrlen)) == 0) ||
161 (errno != EADDRINUSE) || (waited >= drizzled_bind_timeout))
166 errmsg_printf(error::INFO, _(
"Retrying bind() on %u"), getPort());
167 this_wait= retry * retry / 3 + 1;
173 std::string error_message;
175 error_message+= host_buf;
177 error_message+= port_buf;
178 error_message+= _(
" failed to bind");
179 sql_perror(error_message);
184 if (listen(fd, (
int) back_log) < 0)
186 sql_perror(
"listen()");
192 errmsg_printf(error::INFO, _(
"Listening on %s:%s"), host_buf, port_buf);
195 freeaddrinfo(ai_list);