Re: Crash on attempt to connect to nonstarted server

Поиск
Список
Период
Сортировка
От Bruce Momjian
Тема Re: Crash on attempt to connect to nonstarted server
Дата
Msg-id 201012181626.oBIGQdE16865@momjian.us
обсуждение исходный текст
Список pgsql-hackers
bruce wrote:
> Magnus Hagander wrote:
> > I get a crash on win32 when connecting to a server that's not started.
> > In fe-connect.c, we have:
> >
> >         display_host_addr = (conn->pghostaddr == NULL) &&
> >             (strcmp(conn->pghost, host_addr) != 0);
> >
> > In my case, conn->pghost is NULL at this point, as is
> > conn->pghostaddr. Thus, it crashes in strcmp().
>
> I have researched this with Magnus, and was able to reproduce the
> failure.  It happens only on Win32 because that is missing unix-domain
> sockets so "" maps to localhost, which is an IP address.  I have applied
> the attached patch.  The new output is:
>
>     $ psql test
>     psql: could not connect to server: Connection refused
>         Is the server running on host "???" and accepting
>         TCP/IP connections on port 5432?
>
> Note the "???".  This happens because the mapping of "" to localhost
> happens below the libpq library variable level.

I made a mistake in the fix from yesterday.  I added code to test for
NULL, but in fact what I should have done was to allow a NULL hostname
to trigger the printing of the IP address because it will never match an
IP number.

The attached applied, patch fixes this, and uses the same logic as in
connectDBStart() to print 'localhost' for connection failures.  I also
added code to use DefaultHost consistently in that file.  With the patch
the new Win32 output for a down server is:

    $ pql test
    psql: could not connect to server: Connection refused
            Is the server running on host "localhost" (127.0.0.1) and accepting
            TCP/IP connections on port 5432?

    $ psql -h "" test
    psql: could not connect to server: Connection refused
            Is the server running on host "localhost" (127.0.0.1) and accepting
            TCP/IP connections on port 5432?

I am amazed we were printing "???" all these years on this very popular
platform.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 8d9400b..bf8beb7 100644
*** /tmp/rgI5Ne_fe-connect.c    Sat Dec 18 11:21:07 2010
--- src/interfaces/libpq/fe-connect.c    Sat Dec 18 11:10:09 2010
*************** connectFailureMessage(PGconn *conn, int
*** 1030,1049 ****
          else
              strcpy(host_addr, "???");

          display_host_addr = (conn->pghostaddr == NULL) &&
!                             (conn->pghost != NULL) &&
!                             (strcmp(conn->pghost, host_addr) != 0);

          appendPQExpBuffer(&conn->errorMessage,
                            libpq_gettext("could not connect to server: %s\n"
                       "\tIs the server running on host \"%s\"%s%s%s and accepting\n"
                                          "\tTCP/IP connections on port %s?\n"),
                            SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
!                           conn->pghostaddr
                            ? conn->pghostaddr
!                           : (conn->pghost
                               ? conn->pghost
!                              : "???"),
                            /* display the IP address only if not already output */
                            display_host_addr ? " (" : "",
                            display_host_addr ? host_addr : "",
--- 1030,1054 ----
          else
              strcpy(host_addr, "???");

+         /*
+          *    If the user did not supply an IP address using 'hostaddr', and
+          *    'host' was missing or does not match our lookup, display the
+          *    looked-up IP address.
+          */
          display_host_addr = (conn->pghostaddr == NULL) &&
!                             ((conn->pghost == NULL) ||
!                              (strcmp(conn->pghost, host_addr) != 0));

          appendPQExpBuffer(&conn->errorMessage,
                            libpq_gettext("could not connect to server: %s\n"
                       "\tIs the server running on host \"%s\"%s%s%s and accepting\n"
                                          "\tTCP/IP connections on port %s?\n"),
                            SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)),
!                           (conn->pghostaddr && conn->pghostaddr[0] != '\0')
                            ? conn->pghostaddr
!                           : (conn->pghost && conn->pghost[0] != '\0')
                               ? conn->pghost
!                              : DefaultHost,
                            /* display the IP address only if not already output */
                            display_host_addr ? " (" : "",
                            display_host_addr ? host_addr : "",
*************** connectDBStart(PGconn *conn)
*** 1304,1310 ****
          UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
  #else
          /* Without Unix sockets, default to localhost instead */
!         node = "localhost";
          hint.ai_family = AF_UNSPEC;
  #endif   /* HAVE_UNIX_SOCKETS */
      }
--- 1309,1315 ----
          UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
  #else
          /* Without Unix sockets, default to localhost instead */
!         node = DefaultHost;
          hint.ai_family = AF_UNSPEC;
  #endif   /* HAVE_UNIX_SOCKETS */
      }
*************** ldapServiceLookup(const char *purl, PQco
*** 3388,3394 ****
      /* hostname */
      hostname = url + strlen(LDAP_URL);
      if (*hostname == '/')        /* no hostname? */
!         hostname = "localhost"; /* the default */

      /* dn, "distinguished name" */
      p = strchr(url + strlen(LDAP_URL), '/');
--- 3393,3399 ----
      /* hostname */
      hostname = url + strlen(LDAP_URL);
      if (*hostname == '/')        /* no hostname? */
!         hostname = DefaultHost; /* the default */

      /* dn, "distinguished name" */
      p = strchr(url + strlen(LDAP_URL), '/');

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Florian Pflug
Дата:
Сообщение: Re: proposal : cross-column stats
Следующее
От: Tomas Vondra
Дата:
Сообщение: Re: proposal : cross-column stats