Improve error message when a connection is rejected by postmaster with
authorTatsuo Ishii <ishii at sraoss.co.jp>
Wed, 30 Aug 2006 01:11:48 +0000 (01:11 +0000)
committerTatsuo Ishii <ishii at sraoss.co.jp>
Wed, 30 Aug 2006 01:11:48 +0000 (01:11 +0000)
no pg_hba.conf entries. Patches contributed by Kenji Kikuchi.
See [Pgpool-general] Small change for v3 formatted ErrorResponce
handling. on 2006/8/26 for more details.

pool.h
pool_auth.c
pool_process_query.c

diff --git a/pool.h b/pool.h
index 542bb31360bd4ed527567dae59369e71bcf7da34..09b023aced5d9526357e67019e0eb9a4b6f0f468 100644 (file)
--- a/pool.h
+++ b/pool.h
@@ -290,6 +290,8 @@ extern void pool_discard_cp(char *user, char *database, int protoMajor);
 
 extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, 
                                                                  POOL_CONNECTION_POOL *backend);
+extern POOL_STATUS ErrorResponse2(POOL_CONNECTION *frontend, 
+                                                                 POOL_CONNECTION_POOL *backend);
 
 extern POOL_STATUS NoticeResponse(POOL_CONNECTION *frontend, 
                                                                  POOL_CONNECTION_POOL *backend);
@@ -311,6 +313,7 @@ extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend);
 extern int pool_read_message_length(POOL_CONNECTION_POOL *cp);
 extern int *pool_read_message_length2(POOL_CONNECTION_POOL *cp);
 extern signed char pool_read_kind(POOL_CONNECTION_POOL *cp);
+extern signed char pool_read_kind2(POOL_CONNECTION_POOL *cp);
 
 extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
 extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
index f9a68af340811584cc194441b07384cbb8368899..ceb43c641dfef336b2f11d0f1791845f6890a185 100644 (file)
@@ -55,7 +55,15 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
 
        protoMajor = MAJOR(cp);
 
-       kind = pool_read_kind(cp);
+        if (protoMajor == PROTO_MAJOR_V3)
+        {
+                kind = pool_read_kind2(cp);
+        }
+        else
+        {
+                kind = pool_read_kind(cp);
+        }
+
        if (kind < 0)
        {
                return -1;
@@ -70,7 +78,14 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp)
                 * will negotiate again using v2 protocol.
                 */
                pool_log("pool_do_auth: maybe protocol version mismatch (current version %d)", protoMajor);
-               ErrorResponse(frontend, cp);
+               if (protoMajor == PROTO_MAJOR_V3)
+               {
+                       ErrorResponse2(frontend, cp);
+               }
+               else
+               {
+                       ErrorResponse(frontend, cp);
+               }
                return -1;
        }
        else if (kind != 'R')
@@ -1035,3 +1050,38 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp)
 
        return kind;
 }
+
+signed char pool_read_kind2(POOL_CONNECTION_POOL *cp)
+{
+       int status;
+       char kind, kind1;
+       char *buf;
+
+       buf = pool_read2(MASTER(cp), sizeof(kind));
+       if (buf == NULL)
+       {
+               pool_error("read_kind2: error while reading message kind");
+               return -1;
+       }
+
+       kind = *buf;
+
+       if (DUAL_MODE)
+       {
+               status = pool_read(SECONDARY(cp), &kind1, sizeof(kind1));
+               if (status < 0)
+               {
+                       pool_error("read_kind2: error while reading message kind from secondary backend");
+                       return -1;
+               }
+
+               if (kind != kind1)
+               {
+                       pool_error("read_kind2: kind does not match between backends master(%d) secondary(%d)",
+                                          kind, kind1);
+                       return -1;
+               }
+       }
+
+       return kind;
+}
index 2ff4d2d0b0ce76d7afe812d0d28d0f045727543b..edaed2792fa8dd78a41e30fe7d61e0fcbb376285 100644 (file)
@@ -1366,6 +1366,49 @@ POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend,
        return POOL_CONTINUE;
 }
 
+POOL_STATUS ErrorResponse2(POOL_CONNECTION *frontend,
+                                                  POOL_CONNECTION_POOL *backend)
+{
+       char *buf;
+       int len;
+
+       /* forward to the frontend */
+       pool_write(frontend, "E", 1);
+
+       /* read error message length */
+       if ((buf = pool_read2(MASTER(backend), sizeof(len))) == NULL)
+               return POOL_END;
+
+       /* forward to the frontend */
+       if (pool_write_and_flush(frontend, buf, sizeof(len)) < 0)
+               return POOL_END;
+
+       len = ntohl(*(int *)buf) - sizeof(len);
+       if(len < 8 || len > 30000)
+       {
+               /* Handle error from a pre-3.0 server */
+               /* read error message */
+               if ((buf = pool_read_string(MASTER(backend), &len, 0)) == NULL)
+                       return POOL_END;
+
+               /* forward to the frontend */
+               if (pool_write_and_flush(frontend, buf, len) < 0)
+                       return POOL_END;
+       }
+       else
+       {
+               /* read rest of error message */
+               if ((buf = pool_read2(MASTER(backend), len)) == NULL)
+                       return POOL_END;
+
+               /* forward to the frontend */
+               if (pool_write_and_flush(frontend, buf, len) < 0)
+                       return POOL_END;
+       }
+
+       return POOL_CONTINUE;
+}
+
 POOL_STATUS NoticeResponse(POOL_CONNECTION *frontend, 
                                                                  POOL_CONNECTION_POOL *backend)
 {