/*
* PgBouncer - Lightweight connection pooler for PostgreSQL.
- *
+ *
* Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
- *
+ *
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
static bool add_listen(int af, const struct sockaddr *sa, int salen)
{
struct ListenSocket *ls;
- int sock, res, val;
+ int sock, res;
char buf[128];
const char *errpos;
#ifndef WIN32
/* relaxed binding */
if (af != AF_UNIX) {
- val = 1;
+ int val = 1;
errpos = "setsockopt";
res = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if (res < 0)
#ifdef IPV6_V6ONLY
/* avoid ipv6 socket's attempt to takeover ipv4 port */
if (af == AF_INET6) {
- val = 1;
+ int val = 1;
errpos = "setsockopt/IPV6_V6ONLY";
res = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val));
if (res < 0)
}
#endif
+ /*
+ * If configured, set SO_REUSEPORT or equivalent. If it's not
+ * enabled, just leave the socket alone. (We could also unset
+ * the socket option in that case, but this area is fairly
+ * unportable, so perhaps better to avoid it.)
+ */
+ if (af != AF_UNIX && cf_so_reuseport) {
+#if defined(SO_REUSEPORT)
+ int val = 1;
+ errpos = "setsockopt/SO_REUSEPORT";
+ res = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
+ if (res < 0)
+ goto failed;
+#elif defined(SO_REUSEPORT_LB)
+ int val = 1;
+ errpos = "setsockopt/SO_REUSEPORT_LB";
+ res = setsockopt(sock, SOL_SOCKET, SO_REUSEPORT_LB, &val, sizeof(val));
+ if (res < 0)
+ goto failed;
+#else
+ fatal("so_reuseport not supported on this platform");
+#endif
+ }
+
/* bind it */
errpos = "bind";
res = bind(sock, sa, salen);
return true;
failed:
- log_warning("Cannot listen on %s: %s(): %s",
+ log_warning("cannot listen on %s: %s(): %s",
sa2str(sa, buf, sizeof(buf)),
errpos, strerror(errno));
if (sock >= 0)
}
}
-static void err_wait_func(int sock, short flags, void *arg)
+static void err_wait_func(evutil_socket_t sock, short flags, void *arg)
{
if (cf_pause_mode != P_SUSPEND)
resume_pooler();
static const char *conninfo(const PgSocket *sk)
{
- if (is_server_socket(sk))
+ if (is_server_socket(sk)) {
return addrpair(&sk->local_addr, &sk->remote_addr);
- else
+ } else {
return addrpair(&sk->remote_addr, &sk->local_addr);
+ }
}
/* got new connection, associate it with client struct */
-static void pool_accept(int sock, short flags, void *arg)
+static void pool_accept(evutil_socket_t sock, short flags, void *arg)
{
struct ListenSocket *ls = arg;
int fd;
bool is_unix = pga_is_unix(&ls->addr);
if(!(flags & EV_READ)) {
- log_warning("No EV_READ in pool_accept");
+ log_warning("no EV_READ in pool_accept");
return;
}
loop:
}
return true;
}
-