atexit(cleanup_unix_socket);
/* set common options */
- tune_socket(sock, true);
+ if (!tune_socket(sock, true))
+ fatal_perror("tune_socket");
/* finally, accept connections */
res = listen(sock, cf_listen_backlog);
fatal_perror("bind");
/* set common options */
- tune_socket(sock, false);
+ if (!tune_socket(sock, false))
+ fatal_perror("tune_socket");
/* make it accept connections */
res = listen(sock, cf_listen_backlog);
bool use_pooler_socket(int sock, bool is_unix)
{
- tune_socket(sock, is_unix);
+ if (!tune_socket(sock, is_unix))
+ return false;
if (is_unix)
fd_unix = sock;
Assert(iobuf_empty(sbuf->io) && sbuf->sock == 0);
AssertSanity(sbuf);
- tune_socket(sock, is_unix);
sbuf->sock = sock;
+ if (!tune_socket(sock, is_unix))
+ goto failed;
if (!cf_reboot) {
res = sbuf_wait_for_data(sbuf);
- if (!res) {
- sbuf_call_proto(sbuf, SBUF_EV_RECV_FAILED);
- return false;
- }
+ if (!res)
+ goto failed;
/* socket should already have some data (linux only) */
if (cf_tcp_defer_accept && !is_unix) {
sbuf_main_loop(sbuf, DO_RECV);
}
}
return true;
+failed:
+ sbuf_call_proto(sbuf, SBUF_EV_RECV_FAILED);
+ return false;
}
/* need to connect() to get a socket */
/* probably fd limit */
goto failed;
- tune_socket(sock, is_unix);
+ if (!tune_socket(sock, is_unix))
+ goto failed;
sbuf->sock = sock;
}
/* set needed socket options */
-void tune_socket(int sock, bool is_unix)
+bool tune_socket(int sock, bool is_unix)
{
int res;
int val;
/* close fd on exec */
res = fcntl(sock, F_SETFD, FD_CLOEXEC);
if (res < 0)
- fatal_perror("fcntl FD_CLOEXEC");
+ goto fail;
/* when no data available, return EAGAIN instead blocking */
socket_set_nonblocking(sock, 1);
val = 1;
res = setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt SO_NOSIGPIPE");
+ goto fail;
#endif
/*
* Following options are for network sockets
*/
if (is_unix)
- return;
+ return true;
/* the keepalive stuff needs some poking before enbling */
if (cf_tcp_keepalive) {
val = 1;
res = setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt SO_KEEPALIVE");
+ goto fail;
#ifdef __linux__
/* set count of keepalive packets */
if (cf_tcp_keepcnt > 0) {
val = cf_tcp_keepcnt;
res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt TCP_KEEPCNT");
+ goto fail;
}
/* how long the connection can stay idle before sending keepalive pkts */
if (cf_tcp_keepidle) {
val = cf_tcp_keepidle;
res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt TCP_KEEPIDLE");
+ goto fail;
}
/* time between packets */
if (cf_tcp_keepintvl) {
val = cf_tcp_keepintvl;
res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt TCP_KEEPINTVL");
+ goto fail;
}
#else
#ifdef TCP_KEEPALIVE
val = cf_tcp_keepidle;
res = setsockopt(sock, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt TCP_KEEPALIVE");
+ goto fail;
}
#endif
#endif
val = cf_tcp_socket_buffer;
res = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt SO_SNDBUF");
+ goto fail;
val = cf_tcp_socket_buffer;
res = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt SO_RCVBUF");
+ goto fail;
}
/*
val = 1;
res = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
if (res < 0)
- fatal_perror("setsockopt TCP_NODELAY");
+ goto fail;
+ return true;
+fail:
+ log_warning("tune_socket(%d) failed: %s", sock, strerror(errno));
+ return false;
}
/*