]> granicus.if.org Git - pgbouncer/blobdiff - src/pooler.c
Fix some scan-build warnings
[pgbouncer] / src / pooler.c
index 42902dfec7910a7ed3eb4d28588477c0529ec7a2..9dd9a3bd9ce6956696c0ba4f6ec561227cc0bcb7 100644 (file)
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -85,7 +85,7 @@ static void cleanup_sockets(void)
 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;
 
@@ -101,7 +101,7 @@ static bool add_listen(int af, const struct sockaddr *sa, int salen)
 #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)
@@ -112,7 +112,7 @@ static bool add_listen(int af, const struct sockaddr *sa, int salen)
 #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)
@@ -120,6 +120,30 @@ static bool add_listen(int af, const struct sockaddr *sa, int salen)
        }
 #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);
@@ -162,7 +186,7 @@ static bool add_listen(int af, const struct sockaddr *sa, int 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)
@@ -244,7 +268,7 @@ void pooler_tune_accept(bool on)
        }
 }
 
-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();
@@ -267,14 +291,15 @@ static const char *addrpair(const PgAddr *src, const PgAddr *dst)
 
 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;
@@ -289,7 +314,7 @@ static void pool_accept(int sock, short flags, void *arg)
        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:
@@ -477,4 +502,3 @@ bool for_each_pooler_fd(pooler_cb cbfunc, void *arg)
        }
        return true;
 }
-