libpq: Trace StartupMessage/SSLRequest/GSSENCRequest correctly
authorAlvaro Herrera <[email protected]>
Fri, 9 Aug 2024 21:55:01 +0000 (17:55 -0400)
committerAlvaro Herrera <[email protected]>
Fri, 9 Aug 2024 21:55:01 +0000 (17:55 -0400)
libpq tracing via PQtrace would uselessly print the wrong thing for
these types of messages.  With this commit, their type and contents
would be correctly listed.  (This can be verified with PQconnectStart(),
but we don't use that in libpq_pipeline, so I (Álvaro) haven't bothered
to add any tests.)

Author: Jelte Fennema-Nio <[email protected]>
Discussion: https://postgr.es/m/CAGECzQSoPHtZ4xe0raJ6FYSEiPPS+YWXBhOGo+Y1YecLgknF3g@mail.gmail.com

src/interfaces/libpq/fe-trace.c

index c479ea19c442b16d02ff1cecd40c4005b8f6d4fe..c34047a6e46245aae7ae31deba86940d83d9d184 100644 (file)
@@ -707,8 +707,12 @@ void
 pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
 {
        int                     length;
+       int                     version;
+       bool            regress;
        int                     logCursor = 0;
 
+       regress = (conn->traceFlags & PQTRACE_REGRESS_MODE) != 0;
+
        if ((conn->traceFlags & PQTRACE_SUPPRESS_TIMESTAMPS) == 0)
        {
                char            timestr[128];
@@ -723,19 +727,46 @@ pqTraceOutputNoTypeByteMessage(PGconn *conn, const char *message)
 
        fprintf(conn->Pfdebug, "F\t%d\t", length);
 
-       switch (length)
+       if (length < 8)
        {
-               case 16:                                /* CancelRequest */
-                       fprintf(conn->Pfdebug, "CancelRequest\t");
-                       pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
-                       pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
-                       pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, false);
-                       break;
-               case 8:                                 /* GSSENCRequest or SSLRequest */
-                       /* These messages do not reach here. */
-               default:
-                       fprintf(conn->Pfdebug, "Unknown message: length is %d", length);
-                       break;
+               fprintf(conn->Pfdebug, "Unknown message\n");
+               return;
+       }
+
+       memcpy(&version, message + logCursor, 4);
+       version = (int) pg_ntoh32(version);
+
+       if (version == CANCEL_REQUEST_CODE && length >= 16)
+       {
+               fprintf(conn->Pfdebug, "CancelRequest\t");
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
+               pqTraceOutputInt32(conn->Pfdebug, message, &logCursor, regress);
+       }
+       else if (version == NEGOTIATE_SSL_CODE)
+       {
+               fprintf(conn->Pfdebug, "SSLRequest\t");
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+       }
+       else if (version == NEGOTIATE_GSS_CODE)
+       {
+               fprintf(conn->Pfdebug, "GSSENCRequest\t");
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+       }
+       else
+       {
+               fprintf(conn->Pfdebug, "StartupMessage\t");
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               pqTraceOutputInt16(conn->Pfdebug, message, &logCursor);
+               while (message[logCursor] != '\0')
+               {
+                       /* XXX should we suppress anything in regress mode? */
+                       pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
+                       pqTraceOutputString(conn->Pfdebug, message, &logCursor, false);
+               }
        }
 
        fputc('\n', conn->Pfdebug);