Tom Lane wrote:

Andrew Dunstan <[EMAIL PROTECTED]> writes:


A small problem with it was reported to me a couple of days ago - user had firewalled off all IP6 traffic. The stats collector happily bound and connected to the socket, but all the packets fell in the bit bucket. They found it quite hard to diagnose the problem.





Possible solutions that occurred to me:
. an initial "hello"-"yes i'm here" exchange to validate the address



That one seems reasonable to me. Seems like it would take just a few more lines of code in the loop that tries to find a working socket to check that we can send a byte and receive it. You'd have to be careful not to block if the socket is indeed not working ... also, is it safe to assume that a byte sent with send() is *immediately* ready to recv()?




This patch attempts to implement the idea, with safety in case the packet is not immediately available.


comments welcome

cheers

andrew
Index: src/backend/postmaster/pgstat.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v
retrieving revision 1.61
diff -c -r1.61 pgstat.c
*** src/backend/postmaster/pgstat.c     15 Mar 2004 16:21:37 -0000      1.61
--- src/backend/postmaster/pgstat.c     21 Mar 2004 16:41:23 -0000
***************
*** 191,196 ****
--- 191,199 ----
                           *addr,
                                hints;
        int                     ret;
+       fd_set      rset;
+       struct timeval tv;
+       char        test_byte;
  
        /*
         * Force start of collector daemon if something to collect
***************
*** 307,312 ****
--- 310,351 ----
                        pgStatSock = -1;
                        continue;
                }
+ 
+ #define TESTBYTEVAL 99
+ 
+               /* try to send and receive a test byte on the socket */
+ 
+               FD_ZERO(&rset);
+               FD_SET(pgStatSock, &rset);
+               tv.tv_sec = 0;
+               tv.tv_usec = 500000;
+               test_byte = TESTBYTEVAL;
+               send(pgStatSock,&test_byte,1,0);
+               test_byte++;
+               if(select(pgStatSock+1,&rset,NULL,NULL,&tv) > 0 && 
+                  FD_ISSET(pgStatSock,&rset))
+               {
+                       recv(pgStatSock,&test_byte,1,0);
+                       if(test_byte != TESTBYTEVAL)
+                       {
+                               ereport(LOG,
+                                               (errcode_for_socket_access(),
+                                                errmsg("incorrect test value on 
send/receive on socket for statistics collector: %m")));
+                       closesocket(pgStatSock);
+                       pgStatSock = -1;
+                       continue;
+                       }
+               }
+               else
+               {
+                       ereport(LOG,
+                                       (errcode_for_socket_access(),
+                                        errmsg("could send/receive on socket for 
statistics collector: %m")));
+                       closesocket(pgStatSock);
+                       pgStatSock = -1;
+                       continue;
+               }
+               
  
                /* If we get here, we have a working socket */
                break;
---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to [EMAIL PROTECTED] so that your
      message can get through to the mailing list cleanly

Reply via email to