Received: from malur.postgresql.org ([2a02:16a8:dc51::56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fpIne-0001jN-K6 for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Aug 2018 19:46:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1fpInc-0007kV-RO for pgsql-hackers@arkaria.postgresql.org; Mon, 13 Aug 2018 19:46:44 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fpInc-0007kO-JT for pgsql-hackers@lists.postgresql.org; Mon, 13 Aug 2018 19:46:44 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1fpInY-0006i8-Ko for pgsql-hackers@lists.postgresql.org; Mon, 13 Aug 2018 19:46:44 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id w7DJkY2O027729; Mon, 13 Aug 2018 15:46:35 -0400 From: Tom Lane To: Fabien COELHO cc: PostgreSQL Developers Subject: Re: libpq should not look up all host addresses at once In-reply-to: References: <4913.1533827102@sss.pgh.pa.us> Comments: In-reply-to Fabien COELHO message dated "Sat, 11 Aug 2018 12:18:48 +0200" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaa0" Content-ID: <27657.1534189498.0@sss.pgh.pa.us> Date: Mon, 13 Aug 2018 15:46:34 -0400 Message-ID: <27728.1534189594@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk ------- =_aaaaaaaaaa0 Content-Type: text/plain; charset="us-ascii" Content-ID: <27657.1534189498.1@sss.pgh.pa.us> Fabien COELHO writes: > Patch compiles, global "make check" ok, although I'm unsure whether the > feature is actually tested somewhere. I think not:-( Yeah, it's hard to test this stuff without either opening up security hazards or making unwarranted assumptions about the local network setup. I think that the standard regression tests only use Unix-socket communication (except on Windows) for exactly that reason, and that makes it hard to do anything much about regression-testing this feature. > As you noted in another message, a small doc update should be needed. Check. Proposed doc patch attached. (Only the last hunk is actually specific to this patch, the rest is cleanup that I noticed while looking around for possibly-relevant text.) > I'd consider wrapping some of the logic. I'd check the port first, then > move the host resolution stuff into a function. Don't really see the value of either ... regards, tom lane ------- =_aaaaaaaaaa0 Content-Type: text/x-diff; name="libpq-delay-getaddrinfo-docs.patch"; charset="us-ascii" Content-ID: <27657.1534189498.2@sss.pgh.pa.us> Content-Description: libpq-delay-getaddrinfo-docs.patch Content-Transfer-Encoding: quoted-printable diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index 80e55f5..7c150f3 100644 *** a/doc/src/sgml/libpq.sgml --- b/doc/src/sgml/libpq.sgml *************** PostgresPollingStatusType PQconnectPoll( *** 303,311 **** ! The hostaddr and host pa= rameters are used appropriately to ensure that ! name and reverse name queries are not made. See the documentat= ion of ! these parameters in fo= r details. = --- 303,311 ---- ! The hostaddr parameter must be used appropr= iately ! to prevent DNS queries from being made. See the documentation= of ! this parameter in for = details. = *************** PostgresPollingStatusType PQconnectPoll( *** 318,324 **** = ! You ensure that the socket is in the appropriate state before calling PQconnectPoll, as describe= d below. --- 318,324 ---- = ! You must ensure that the socket is in the appropriate state before calling PQconnectPoll, as describe= d below. *************** PostgresPollingStatusType PQconnectPoll( *** 326,349 **** = ! Note: use of PQconnectStartParams is analogo= us to ! PQconnectStart shown below. ! ! = ! ! To begin a nonblocking connection request, call conn =3D= PQconnectStart("connection_info_string"). ! If conn is null, then libpq has been unable to allocate a new PGconn ! structure. Otherwise, a valid PGconn poi= nter is returned (though not yet ! representing a valid connection to the database). On return from ! PQconnectStart, call status =3D PQs= tatus(conn). If status equals ! CONNECTION_BAD, PQconnectStart has failed. = ! If PQconnectStart succeeds, the next stage i= s to poll ! libpq so that it can proceed with the = connection sequence. Use PQsocket(conn) to obtain the descriptor = of the socket underlying the database connection. Loop thus: If PQconnectPoll(conn) last retur= ned PGRES_POLLING_READING, wait until the socket is = ready to read (as indicated by select(), po= ll(), or --- 326,352 ---- = ! To begin a nonblocking connection request, ! call PQconnectStart ! or PQconnectStartParams. If the result is n= ull, ! then libpq has been unable to allocate= a ! new PGconn structure. Otherwise, a ! valid PGconn pointer is returned (though= not ! yet representing a valid connection to the database). Next ! call PQstatus(conn). If the result ! is CONNECTION_BAD, the connection attempt has al= ready ! failed, typically because of invalid connection parameters. = ! If PQconnectStart ! or PQconnectStartParams succeeds, the next s= tage ! is to poll libpq so that it can procee= d with ! the connection sequence. Use PQsocket(conn) to obtain the descriptor = of the socket underlying the database connection. + (Caution: do not assume that the socket remains the same + across PQconnectPoll calls.) Loop thus: If PQconnectPoll(conn) last retur= ned PGRES_POLLING_READING, wait until the socket is = ready to read (as indicated by select(), po= ll(), or *************** PostgresPollingStatusType PQconnectPoll( *** 352,360 **** Conversely, if PQconnectPoll(conn) last retu= rned PGRES_POLLING_WRITING, wait until the socket is = ready to write, then call PQconnectPoll(conn) agai= n. ! If you have yet to call ! PQconnectPoll, i.e., just after the call to ! PQconnectStart, behave as if it last returne= d PGRES_POLLING_WRITING. Continue this loop until PQconnectPoll(conn) returns PGRES_POLLING_FAILED, indicating the connection = procedure --- 355,362 ---- Conversely, if PQconnectPoll(conn) last retu= rned PGRES_POLLING_WRITING, wait until the socket is = ready to write, then call PQconnectPoll(conn) agai= n. ! On the first iteration, i.e. if you have yet to call ! PQconnectPoll, behave as if it last returned PGRES_POLLING_WRITING. Continue this loop until PQconnectPoll(conn) returns PGRES_POLLING_FAILED, indicating the connection = procedure *************** switch(PQstatus(conn)) *** 479,488 **** = ! Note that if PQconnectStart returns a non-nu= ll pointer, you must call ! PQfinish when you are finished with it, in o= rder to dispose of ! the structure and any associated memory blocks. This must be done= even if ! the connection attempt fails or is abandoned. --- 481,492 ---- = ! Note that when PQconnectStart ! or PQconnectStartParams returns a non-null ! pointer, you must call PQfinish when you are ! finished with it, in order to dispose of the structure and any ! associated memory blocks. This must be done even if the connecti= on ! attempt fails or is abandoned. *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 913,919 **** It is possible to specify multiple hosts to connect to, so that t= hey are tried in the given order. In the Keyword/Value format, the host, hostaddr, and port options = accept a comma-separated ! list of values. The same number of elements must be given in each= option, such that e.g. the first hostaddr corresponds to th= e first host name, the second hostaddr corresponds to the second = host name, and so forth. As an exception, if only one port is sp= ecified, it --- 917,924 ---- It is possible to specify multiple hosts to connect to, so that t= hey are tried in the given order. In the Keyword/Value format, the host, hostaddr, and port options = accept a comma-separated ! list of values. The same number of elements must be given in each ! option that is specified, such that e.g. the first hostaddr corresponds to th= e first host name, the second hostaddr corresponds to the second = host name, and so forth. As an exception, if only one port is sp= ecified, it *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 922,930 **** = In the connection URI format, you can list multiple host= :port pairs ! separated by commas, in the host component of = the URI. In either ! format, a single host name can also translate to multiple network= addresses. A ! common example of this is a host that has both an IPv4 and an IPv= 6 address. = --- 927,939 ---- = In the connection URI format, you can list multiple host= :port pairs ! separated by commas, in the host component of = the URI. ! ! = ! ! In either format, a single host name can translate to multiple ne= twork ! addresses. A common example of this is a host that has both an IP= v4 and ! an IPv6 address. = *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 958,966 **** Name of host to connect to.host name If a host name begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the ! name of the directory in which the socket file is stored. If ! multiple host names are specified, each will be tried in turn in ! the order given. The default behavior when host is not specified, or is empty, is to connect to a Unix-domain socketUnix domain socket in /tmp (or whatever socket directory was spec= ified --- 967,974 ---- Name of host to connect to.host name If a host name begins with a slash, it specifies Unix-domain communication rather than TCP/IP communication; the value is the ! name of the directory in which the socket file is stored. ! The default behavior when host is not specified, or is empty, is to connect to a Unix-domain socketUnix domain socket in /tmp (or whatever socket directory was spec= ified *************** postgresql://%2Fvar%2Flib%2Fpostgresql/d *** 997,1004 **** ! If host is specified without host= addr, ! a host name lookup occurs. --- 1005,1016 ---- ! If host is specified ! without hostaddr, a host name lookup occur= s. ! (When using PQconnectPoll, the lookup oc= curs ! when PQconnectPoll first considers this = host ! name, and it may cause PQconnectPoll to = block ! for a significant amount of time.) ------- =_aaaaaaaaaa0--