]> granicus.if.org Git - pdns/commitdiff
auth: Check the connection status in addition to PQstatus()
authorRemi Gacogne <remi.gacogne@powerdns.com>
Sun, 14 May 2017 12:52:20 +0000 (14:52 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 13 Jun 2017 13:47:08 +0000 (15:47 +0200)
`PQstatus()` only checks the known state of the connection. It's
useful because if the connection is already known to be bad we don't
need to go further, but it isn't sufficient to detect whether it has
been closed since the last time we used it.

modules/gpgsqlbackend/spgsql.cc

index 78e6539a36f8515454d191c57ef9efbe0c26396e..cfb0ca27c7f95dc62b77c4e6294af90df3f8dfbc 100644 (file)
@@ -349,7 +349,29 @@ void SPgSQL::rollback() {
 
 bool SPgSQL::isConnectionUsable()
 {
-  return PQstatus(d_db) == CONNECTION_OK;
+  if (PQstatus(d_db) != CONNECTION_OK) {
+    return false;
+  }
+
+  bool usable = false;
+  int sd = PQsocket(d_db);
+  bool wasNonBlocking = isNonBlocking(sd);
+
+  if (!wasNonBlocking) {
+    if (!setNonBlocking(sd)) {
+      return usable;
+    }
+  }
+
+  usable = isTCPSocketUsable(sd);
+
+  if (!wasNonBlocking) {
+    if (!setBlocking(sd)) {
+      usable = false;
+    }
+  }
+
+  return usable;
 }
 
 void SPgSQL::reconnect()