Обсуждение: duplicate connection failure messages
This surprised me: psql -p 55555 -h localhost psql: could not connect to server: Connection refused Is the server running on host "localhost" and accepting TCP/IP connections on port 55555? could not connect to server: Connection refused Is the server running on host "localhost" and accepting TCP/IPconnections on port 55555? It shows the same error message twice. I can reproduce this back to PG 8.2. It appears to have something to do with localhost resolving to an IPv4 and an IPv6 address, since it doesn't happen with other host names that only resolve to one address. However, fe-connect.c claims: /* * Try to initiate a connection to one of the addresses * returned by pg_getaddrinfo_all(). conn->addr_cur isthe * next one to try. We fail when we run out of addresses * (reporting the error returned for the *last* alternative, * which may not be what users expect :-(). */
On Wed, Oct 13, 2010 at 21:21, Peter Eisentraut <peter_e@gmx.net> wrote: > This surprised me: > > psql -p 55555 -h localhost > psql: could not connect to server: Connection refused > Is the server running on host "localhost" and accepting > TCP/IP connections on port 55555? > could not connect to server: Connection refused > Is the server running on host "localhost" and accepting > TCP/IP connections on port 55555? > > It shows the same error message twice. I can reproduce this back to PG > 8.2. > > It appears to have something to do with localhost resolving to an IPv4 > and an IPv6 address, since it doesn't happen with other host names that > only resolve to one address. However, fe-connect.c claims: > > /* > * Try to initiate a connection to one of the addresses > * returned by pg_getaddrinfo_all(). conn->addr_cur is the > * next one to try. We fail when we run out of addresses > * (reporting the error returned for the *last* alternative, > * which may not be what users expect :-(). > */ That comment is out of date. I implemented the "keep all error messages and append them to each other" feature to make sure it didn't throw away the interesting error message and replaced it with a generic one later, must've missed that comment - at least it should be changed. And I agree it's not very friendly in this specific case - I wonder if we should log it as "localhost (127.0.0.1) and "localhost (::1)" (and similar for any other case that returns more than one address). -- Magnus Hagander Me: http://www.hagander.net/ Work: http://www.redpill-linpro.com/
Excerpts from Magnus Hagander's message of jue oct 14 02:30:36 -0300 2010: > And I agree it's not very friendly in this specific case - I > wonder if we should log it as "localhost (127.0.0.1) and "localhost > (::1)" (and similar for any other case that returns more than one > address). +1 -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
On tor, 2010-10-14 at 07:30 +0200, Magnus Hagander wrote: > And I agree it's not very friendly in this specific case - I > wonder if we should log it as "localhost (127.0.0.1) and "localhost > (::1)" (and similar for any other case that returns more than one > address). That looks good.
Peter Eisentraut wrote: > On tor, 2010-10-14 at 07:30 +0200, Magnus Hagander wrote: > > And I agree it's not very friendly in this specific case - I > > wonder if we should log it as "localhost (127.0.0.1) and "localhost > > (::1)" (and similar for any other case that returns more than one > > address). > > That looks good. I have developed the attached patch to report whether IPv4 or IPv6 are being used. I could not find the numeric value as alwasy populated, and this seems clearer too: $ pql -h localhost test psql: could not connect to server: Connection refused Is the server running on host "localhost" (IPv4) and accepting TCP/IP connections on port 5432? $ psql -h 127.0.0.1 test psql: could not connect to server: Connection refused Is the server running on host "127.0.0.1" (IPv4) and accepting TCP/IP connections on port 5432? -- 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 8f318a1..bf85b49 100644 *** a/src/interfaces/libpq/fe-connect.c --- b/src/interfaces/libpq/fe-connect.c *************** connectFailureMessage(PGconn *conn, int *** 962,968 **** { appendPQExpBuffer(&conn->errorMessage, libpq_gettext("could not connect to server: %s\n" ! "\tIs the server running on host \"%s\" and accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr --- 962,968 ---- { appendPQExpBuffer(&conn->errorMessage, libpq_gettext("could not connect to server: %s\n" ! "\tIs the server running on host \"%s\" (%s) and accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr *************** connectFailureMessage(PGconn *conn, int *** 970,975 **** --- 970,980 ---- : (conn->pghost ? conn->pghost : "???"), + (conn->addr_cur->ai_family == AF_INET) ? "IPv4" : + #ifdef HAVE_IPV6 + (conn->addr_cur->ai_family == AF_INET6) ? "IPv6" : + #endif + "???", conn->pgport); } }
Bruce Momjian <bruce@momjian.us> writes: > I have developed the attached patch to report whether IPv4 or IPv6 are > being used. What's the use of that exactly? It doesn't really respond to Peter's concern, I think. regards, tom lane
Tom Lane wrote: > Bruce Momjian <bruce@momjian.us> writes: > > I have developed the attached patch to report whether IPv4 or IPv6 are > > being used. > > What's the use of that exactly? It doesn't really respond to Peter's > concern, I think. Peter liked: > And I agree it's not very friendly in this specific case - I > wonder if we should log it as "localhost (127.0.0.1) and "localhost > (::1)" (and similar for any other case that returns more than one > address). What this will show is: localhost (IPv4)localhost (IPv6) Is that good? I can't figure out how to do ::1 because when you supply a host _name_, there is no reverse mapping done. Looking at the code, we test for a host name, then a host ip, and don't assume they are both set. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
On Fri, Nov 12, 2010 at 15:02, Bruce Momjian <bruce@momjian.us> wrote: > Tom Lane wrote: >> Bruce Momjian <bruce@momjian.us> writes: >> > I have developed the attached patch to report whether IPv4 or IPv6 are >> > being used. >> >> What's the use of that exactly? It doesn't really respond to Peter's >> concern, I think. > > Peter liked: > >> And I agree it's not very friendly in this specific case - I >> wonder if we should log it as "localhost (127.0.0.1) and "localhost >> (::1)" (and similar for any other case that returns more than one >> address). > > What this will show is: > > localhost (IPv4) > localhost (IPv6) > > Is that good? I can't figure out how to do ::1 because when you supply > a host _name_, there is no reverse mapping done. Looking at the code, > we test for a host name, then a host ip, and don't assume they are both > set. The address is in conn->raddr, no? When you've put in a host name, we do a forward lookup, so conn->raddr should contain ::1 already? You only need the reverse mapping to get the "localhost" part, if I read the code correctly? -- Magnus Hagander Me: http://www.hagander.net/ Work: http://www.redpill-linpro.com/
Magnus Hagander wrote: > On Fri, Nov 12, 2010 at 15:02, Bruce Momjian <bruce@momjian.us> wrote: > > Tom Lane wrote: > >> Bruce Momjian <bruce@momjian.us> writes: > >> > I have developed the attached patch to report whether IPv4 or IPv6 are > >> > being used. > >> > >> What's the use of that exactly? ?It doesn't really respond to Peter's > >> concern, I think. > > > > Peter liked: > > > >> And I agree it's not very friendly in this specific case - I > >> wonder if we should log it as "localhost (127.0.0.1) and "localhost > >> (::1)" (and similar for any other case that returns more than one > >> address). > > > > What this will show is: > > > > ? ? ? ?localhost (IPv4) > > ? ? ? ?localhost (IPv6) > > > > Is that good? ?I can't figure out how to do ::1 because when you supply > > a host _name_, there is no reverse mapping done. ?Looking at the code, > > we test for a host name, then a host ip, and don't assume they are both > > set. > > The address is in conn->raddr, no? When you've put in a host name, we > do a forward lookup, so conn->raddr should contain ::1 already? You > only need the reverse mapping to get the "localhost" part, if I read > the code correctly? OK, I found out how to get the IP address with the attached patch. The problem is that only pghost is set, never pghostaddr. I am not even sure how that would get set for this code because my tests show it is not: $ psql -h localhost test pghost = localhost --> pghostaddr = (null) 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 127.0.0.1 test pghost = 127.0.0.1 pghostaddr = (null) psql: could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432? To get this to work, I compared pghost with the raddr value, and printed the IP address if it was not already printed. There is still a problem about threading that I can fix. Is this what we want? -- 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 8f318a1..f3307f3 100644 *** a/src/interfaces/libpq/fe-connect.c --- b/src/interfaces/libpq/fe-connect.c *************** connectFailureMessage(PGconn *conn, int *** 960,968 **** else #endif /* HAVE_UNIX_SOCKETS */ { appendPQExpBuffer(&conn->errorMessage, libpq_gettext("could not connect to server: %s\n" ! "\tIs the server running on host \"%s\" and accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr --- 960,976 ---- else #endif /* HAVE_UNIX_SOCKETS */ { + struct sockaddr_in *remote_addr = (struct sockaddr_in *) &conn->raddr.addr; + /* not thread safe */ + char *remote_ip = inet_ntoa(remote_addr->sin_addr); + bool host_ip_match = strcmp(conn->pghost, remote_ip) == 0; + + fprintf(stderr, "pghost = %s\n", conn->pghost); + fprintf(stderr, "pghostaddr = %s\n", conn->pghostaddr); + appendPQExpBuffer(&conn->errorMessage, libpq_gettext("could not connect to server: %s\n" ! "\tIs the server running on host \"%s\" %s%s%sand accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr *************** connectFailureMessage(PGconn *conn, int *** 970,975 **** --- 978,987 ---- : (conn->pghost ? conn->pghost : "???"), + /* display the IP address only if not already output */ + !host_ip_match ? "(" : "", + !host_ip_match ? remote_ip : "", + !host_ip_match ? ") " : "", conn->pgport); } }
Excerpts from Bruce Momjian's message of sáb nov 13 22:36:31 -0300 2010: > OK, I found out how to get the IP address with the attached patch. The > problem is that only pghost is set, never pghostaddr. I am not even > sure how that would get set for this code because my tests show it is > not: This doesn't work for IPv6 addresses, though. pghostaddr is specified by the user on the command line as an optimization to avoid DNS lookups IIRC, which is why you don't see the code setting it. -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera wrote: > Excerpts from Bruce Momjian's message of sáb nov 13 22:36:31 -0300 2010: > > > OK, I found out how to get the IP address with the attached patch. The > > problem is that only pghost is set, never pghostaddr. I am not even > > sure how that would get set for this code because my tests show it is > > not: > > This doesn't work for IPv6 addresses, though. > > pghostaddr is specified by the user on the command line as an > optimization to avoid DNS lookups IIRC, which is why you don't see the > code setting it. OK, I doubt we want to add complexity to improve this, so I see our options as: o ignore the problemo display IPv4/IPv6 labelso display only an IPv6 labelo something else Comments? -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Excerpts from Bruce Momjian's message of mié nov 17 13:04:46 -0300 2010: > OK, I doubt we want to add complexity to improve this, so I see our > options as: > > o ignore the problem > o display IPv4/IPv6 labels > o display only an IPv6 label > o something else I think we should use inet_ntop where available to print the address. -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera wrote: > Excerpts from Bruce Momjian's message of mié nov 17 13:04:46 -0300 2010: > > > OK, I doubt we want to add complexity to improve this, so I see our > > options as: > > > > o ignore the problem > > o display IPv4/IPv6 labels > > o display only an IPv6 label > > o something else > > I think we should use inet_ntop where available to print the address. Good idea because inet_ntop() is thread-safe. Does that work on IPv6? You indicated that inet_ntoa() does not. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Alvaro Herrera wrote: > Excerpts from Bruce Momjian's message of mié nov 17 13:04:46 -0300 2010: > > > OK, I doubt we want to add complexity to improve this, so I see our > > options as: > > > > o ignore the problem > > o display IPv4/IPv6 labels > > o display only an IPv6 label > > o something else > > I think we should use inet_ntop where available to print the address. FYI, I see we use inet_ntoa() in getaddrinfo.c. That is not thread-safe and I should replace it with inet_ntop(). -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Excerpts from Bruce Momjian's message of vie nov 19 00:17:59 -0300 2010: > Alvaro Herrera wrote: > > Excerpts from Bruce Momjian's message of mi nov 17 13:04:46 -0300 2010: > > > > > OK, I doubt we want to add complexity to improve this, so I see our > > > options as: > > > > > > o ignore the problem > > > o display IPv4/IPv6 labels > > > o display only an IPv6 label > > > o something else > > > > I think we should use inet_ntop where available to print the address. > > Good idea because inet_ntop() is thread-safe. Does that work on IPv6? > You indicated that inet_ntoa() does not. According to opengroup.org, IPv6 should work if the underlying libraries support it, whereas inet_ntoa explicitely does not. http://www.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html http://www.opengroup.org/onlinepubs/009695399/functions/inet_addr.html -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera <alvherre@commandprompt.com> writes: > Excerpts from Bruce Momjian's message of vie nov 19 00:17:59 -0300 2010: >> Alvaro Herrera wrote: >>> I think we should use inet_ntop where available to print the address. >> >> Good idea because inet_ntop() is thread-safe. Does that work on IPv6? >> You indicated that inet_ntoa() does not. > According to opengroup.org, IPv6 should work if the underlying libraries > support it, whereas inet_ntoa explicitely does not. > http://www.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html > http://www.opengroup.org/onlinepubs/009695399/functions/inet_addr.html I get the impression that you guys have forgotten the existence of src/backend/utils/adt/inet_net_ntop.c regards, tom lane
Tom Lane wrote: > Alvaro Herrera <alvherre@commandprompt.com> writes: > > Excerpts from Bruce Momjian's message of vie nov 19 00:17:59 -0300 2010: > >> Alvaro Herrera wrote: > >>> I think we should use inet_ntop where available to print the address. > >> > >> Good idea because inet_ntop() is thread-safe. Does that work on IPv6? > >> You indicated that inet_ntoa() does not. > > > According to opengroup.org, IPv6 should work if the underlying libraries > > support it, whereas inet_ntoa explicitely does not. > > http://www.opengroup.org/onlinepubs/009695399/functions/inet_ntop.html > > http://www.opengroup.org/onlinepubs/009695399/functions/inet_addr.html > > I get the impression that you guys have forgotten the existence of > src/backend/utils/adt/inet_net_ntop.c Yeah, that is nice, but we are calling this from libpq, not the backend. Let me work up a patch. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Excerpts from Bruce Momjian's message of vie nov 19 16:43:33 -0300 2010: > Tom Lane wrote: > > I get the impression that you guys have forgotten the existence of > > src/backend/utils/adt/inet_net_ntop.c > > Yeah, that is nice, but we are calling this from libpq, not the backend. > Let me work up a patch. Actually the code seems agnostic (no ereport, palloc etc) so maybe it could just be moved to src/port. -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera wrote: > Excerpts from Bruce Momjian's message of vie nov 19 16:43:33 -0300 2010: > > Tom Lane wrote: > > > > I get the impression that you guys have forgotten the existence of > > > src/backend/utils/adt/inet_net_ntop.c > > > > Yeah, that is nice, but we are calling this from libpq, not the backend. > > Let me work up a patch. > > Actually the code seems agnostic (no ereport, palloc etc) so maybe it > could just be moved to src/port. I was wondering that. I am unclear if we need it though --- can we not assume inet_ntop() exists on all systems? We assumed inet_ntoa() did. Of course, the buildfarm will tell us. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Bruce Momjian <bruce@momjian.us> writes: > I was wondering that. I am unclear if we need it though --- can we not > assume inet_ntop() exists on all systems? We assumed inet_ntoa() did. The Single Unix Spec includes inet_ntoa but not inet_ntop. > Of course, the buildfarm will tell us. The buildfarm unfortunately contains only a subset of the platforms we care about. I don't think this problem is large enough to justify taking a portability risk by depending on non-SUS library functions. If you want to do this, please do it as suggested previously, ie depend on the copy of the code we have internally. regards, tom lane
Tom Lane wrote: > Bruce Momjian <bruce@momjian.us> writes: > > I was wondering that. I am unclear if we need it though --- can we not > > assume inet_ntop() exists on all systems? We assumed inet_ntoa() did. > > The Single Unix Spec includes inet_ntoa but not inet_ntop. > > > Of course, the buildfarm will tell us. > > The buildfarm unfortunately contains only a subset of the platforms > we care about. I don't think this problem is large enough to justify > taking a portability risk by depending on non-SUS library functions. > > If you want to do this, please do it as suggested previously, ie depend > on the copy of the code we have internally. I assume you are suggesting to use our inet_net_ntop() even if the system has inet_ntop(). -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Bruce Momjian <bruce@momjian.us> writes: > I assume you are suggesting to use our inet_net_ntop() even if the > system has inet_ntop(). If you're going to have code to do the former, it doesn't seem to be worth the trouble to also have code that does the latter ... regards, tom lane
Tom Lane wrote: > Bruce Momjian <bruce@momjian.us> writes: > > I assume you are suggesting to use our inet_net_ntop() even if the > > system has inet_ntop(). > > If you're going to have code to do the former, it doesn't seem to be > worth the trouble to also have code that does the latter ... OK, we will not call inet_ntop() at all. I moved the CIDR part of adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining "net" part to /port/inet_net_ntop.c. I then changed all uses of inet_ntoa to use inet_net_ntop(). While this churn would perhaps not be warranted just to allow for better error messages, I found pg_getaddrinfo_all() being called from libpq::connectDBStart(), which makes it not thread-safe. I am not excited about backpatching it but it is a threading bug. The output is as expected: $ psql -h localhost 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 127.0.0.1 test psql: could not connect to server: Connection refused Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432? -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. + diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml index a911c50..814c27a 100644 *** /tmp/pgrevert.8208/Z2NPcb_libpq.sgml Sat Nov 20 18:06:46 2010 --- doc/src/sgml/libpq.sgml Sat Nov 20 17:11:04 2010 *************** PGconn *PQconnectdbParams(const char **k *** 170,180 **** If <literal>host</> is specified without <literal>hostaddr</>, a host name lookup occurs. If <literal>hostaddr</> is specified without <literal>host</>, ! the value for <literal>hostaddr</> gives the server address. The connection attempt will fail in any of the cases where a host name is required. If both <literal>host</> and <literal>hostaddr</> are specified, ! the value for <literal>hostaddr</> gives the server address. The value for <literal>host</> is ignored unless needed for authentication or verification purposes, in which case it will be used as the host name. Note that authentication is likely to fail --- 170,180 ---- If <literal>host</> is specified without <literal>hostaddr</>, a host name lookup occurs. If <literal>hostaddr</> is specified without <literal>host</>, ! the value for <literal>hostaddr</> gives the server network address. The connection attempt will fail in any of the cases where a host name is required. If both <literal>host</> and <literal>hostaddr</> are specified, ! the value for <literal>hostaddr</> gives the server network address. The value for <literal>host</> is ignored unless needed for authentication or verification purposes, in which case it will be used as the host name. Note that authentication is likely to fail diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index be272b5..ce28abd 100644 *** /tmp/pgrevert.8208/zxOcga_Makefile Sat Nov 20 18:06:46 2010 --- src/backend/utils/adt/Makefile Sat Nov 20 17:11:04 2010 *************** OBJS = acl.o arrayfuncs.o array_userfunc *** 23,29 **** oid.o oracle_compat.o pseudotypes.o rowtypes.o \ regexp.o regproc.o ruleutils.o selfuncs.o \ tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \ ! network.o mac.o inet_net_ntop.o inet_net_pton.o \ ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \ ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o trigfuncs.o \ tsginidx.o tsgistidx.o tsquery.o tsquery_cleanup.o tsquery_gist.o \ --- 23,29 ---- oid.o oracle_compat.o pseudotypes.o rowtypes.o \ regexp.o regproc.o ruleutils.o selfuncs.o \ tid.o timestamp.o varbit.o varchar.o varlena.o version.o xid.o \ ! network.o mac.o inet_cidr_ntop.o inet_net_pton.o \ ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \ ascii.o quote.o pgstatfuncs.o encode.o dbsize.o genfile.o trigfuncs.o \ tsginidx.o tsgistidx.o tsquery.o tsquery_cleanup.o tsquery_gist.o \ diff --git a/src/include/port.h b/src/include/port.h index 2048768..0cfbed8 100644 *** /tmp/pgrevert.8208/DZNlKd_port.h Sat Nov 20 18:06:46 2010 --- src/include/port.h Sat Nov 20 17:11:42 2010 *************** extern void qsort_arg(void *base, size_t *** 437,440 **** --- 437,444 ---- /* port/chklocale.c */ extern int pg_get_encoding_from_locale(const char *ctype); + /* port/inet_net_ntop.c */ + extern char *inet_net_ntop(int af, const void *src, int bits, + char *dst, size_t size); + #endif /* PG_PORT_H */ diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index ae267ab..88eac70 100644 *** /tmp/pgrevert.8208/1NPEOc_builtins.h Sat Nov 20 18:06:46 2010 --- src/include/utils/builtins.h Sat Nov 20 17:11:42 2010 *************** extern Datum chr (PG_FUNCTION_ARGS); *** 793,801 **** extern Datum repeat(PG_FUNCTION_ARGS); extern Datum ascii(PG_FUNCTION_ARGS); ! /* inet_net_ntop.c */ ! extern char *inet_net_ntop(int af, const void *src, int bits, ! char *dst, size_t size); extern char *inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size); --- 793,799 ---- extern Datum repeat(PG_FUNCTION_ARGS); extern Datum ascii(PG_FUNCTION_ARGS); ! /* inet_cidr_ntop.c */ extern char *inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size); diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 8f318a1..8011604 100644 *** /tmp/pgrevert.8208/7EVSqc_fe-connect.c Sat Nov 20 18:06:46 2010 --- src/interfaces/libpq/fe-connect.c Sat Nov 20 17:42:54 2010 *************** connectFailureMessage(PGconn *conn, int *** 960,968 **** else #endif /* HAVE_UNIX_SOCKETS */ { appendPQExpBuffer(&conn->errorMessage, libpq_gettext("could not connect to server: %s\n" ! "\tIs the server running on host \"%s\" and accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr --- 960,987 ---- else #endif /* HAVE_UNIX_SOCKETS */ { + char host_addr[NI_MAXHOST]; + bool display_host_addr; + struct sockaddr_in *host_addr_struct = (struct sockaddr_in *) + &conn->raddr.addr; + + /* + * Optionally display the network address with the hostname. + * This is useful to distinguish between IPv4 and IPv6 connections. + */ + if (conn->pghostaddr != NULL) + strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST); + else if (inet_net_ntop(conn->addr_cur->ai_family, &host_addr_struct->sin_addr, + host_addr_struct->sin_family == AF_INET ? 32 : 128, + host_addr, sizeof(host_addr)) == NULL) + strcpy(host_addr, "???"); + + display_host_addr = !conn->pghostaddr && + 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%sand accepting\n" "\tTCP/IP connections on port %s?\n"), SOCK_STRERROR(errorno, sebuf, sizeof(sebuf)), conn->pghostaddr *************** connectFailureMessage(PGconn *conn, int *** 970,975 **** --- 989,998 ---- : (conn->pghost ? conn->pghost : "???"), + /* display the IP address only if not already output */ + display_host_addr ? "(" : "", + display_host_addr ? host_addr : "", + display_host_addr ? ") " : "", conn->pgport); } } diff --git a/src/port/Makefile b/src/port/Makefile index 327ec72..711f633 100644 *** /tmp/pgrevert.8208/9HEr9d_Makefile Sat Nov 20 18:06:46 2010 --- src/port/Makefile Sat Nov 20 17:11:04 2010 *************** include $(top_builddir)/src/Makefile.glo *** 30,36 **** override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o noblock.o path.o \ pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o ifneq (,$(filter $(PORTNAME),cygwin win32)) OBJS += pipe.o --- 30,36 ---- override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS) LIBS += $(PTHREAD_LIBS) ! OBJS = $(LIBOBJS) chklocale.o dirmod.o exec.o inet_net_ntop.o noblock.o path.o \ pgsleep.o pgstrcasecmp.o qsort.o qsort_arg.o sprompt.o thread.o ifneq (,$(filter $(PORTNAME),cygwin win32)) OBJS += pipe.o diff --git a/src/port/getaddrinfo.c b/src/port/getaddrinfo.c index f867744..807f5bd 100644 *** /tmp/pgrevert.8208/vneSVc_getaddrinfo.c Sat Nov 20 18:06:46 2010 --- src/port/getaddrinfo.c Sat Nov 20 17:21:02 2010 *************** getnameinfo(const struct sockaddr * sa, *** 388,403 **** if (node) { - int ret = -1; - if (sa->sa_family == AF_INET) { ! char *p; ! ! p = inet_ntoa(((struct sockaddr_in *) sa)->sin_addr); ! ret = snprintf(node, nodelen, "%s", p); } ! if (ret == -1 || ret > nodelen) return EAI_MEMORY; } --- 388,401 ---- if (node) { if (sa->sa_family == AF_INET) { ! if (inet_net_ntop(AF_INET, ((struct sockaddr_in *) sa)->sin_addr, ! sa->sa_family == AF_INET ? 32 : 128, ! node, nodelen) == NULL) ! return EAI_MEMORY; } ! else return EAI_MEMORY; } diff --git a/src/backend/utils/adt/inet_cidr_ntop.c b/src/backend/utils/adt/inet_cidr_ntop.c index ...5f2a3d3 . *** /dev/null Sat Nov 20 18:04:30 2010 --- src/backend/utils/adt/inet_cidr_ntop.c Sat Nov 20 17:16:32 2010 *************** *** 0 **** --- 1,295 ---- + /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * src/backend/utils/adt/inet_net_ntop.c + */ + + #if defined(LIBC_SCCS) && !defined(lint) + static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $"; + #endif + + #include "postgres.h" + + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + + #include "utils/builtins.h" + #include "utils/inet.h" + + + #ifdef SPRINTF_CHAR + #define SPRINTF(x) strlen(sprintf/**/x) + #else + #define SPRINTF(x) ((size_t)sprintf x) + #endif + + static char *inet_cidr_ntop_ipv4(const u_char *src, int bits, + char *dst, size_t size); + static char *inet_cidr_ntop_ipv6(const u_char *src, int bits, + char *dst, size_t size); + + /* + * char * + * inet_cidr_ntop(af, src, bits, dst, size) + * convert network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * author: + * Paul Vixie (ISC), July 1996 + */ + char * + inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) + { + switch (af) + { + case PGSQL_AF_INET: + return (inet_cidr_ntop_ipv4(src, bits, dst, size)); + case PGSQL_AF_INET6: + return (inet_cidr_ntop_ipv6(src, bits, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + } + + + /* + * static char * + * inet_cidr_ntop_ipv4(src, bits, dst, size) + * convert IPv4 network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0b11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), July 1996 + */ + static char * + inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) + { + char *odst = dst; + char *t; + u_int m; + int b; + + if (bits < 0 || bits > 32) + { + errno = EINVAL; + return (NULL); + } + + if (bits == 0) + { + if (size < sizeof "0") + goto emsgsize; + *dst++ = '0'; + size--; + *dst = '\0'; + } + + /* Format whole octets. */ + for (b = bits / 8; b > 0; b--) + { + if (size <= sizeof "255.") + goto emsgsize; + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b > 1) + { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t) (dst - t); + } + + /* Format partial octet. */ + b = bits % 8; + if (b > 0) + { + if (size <= sizeof ".255") + goto emsgsize; + t = dst; + if (dst != odst) + *dst++ = '.'; + m = ((1 << b) - 1) << (8 - b); + dst += SPRINTF((dst, "%u", *src & m)); + size -= (size_t) (dst - t); + } + + /* Format CIDR /width. */ + if (size <= sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); + } + + /* + * static char * + * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size) + * convert IPv6 network number from network to presentation format. + * generates CIDR style result always. Picks the shortest representation + * unless the IP is really IPv4. + * always prints specified number of bits (bits). + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Vadim Kogan (UCB), June 2001 + * Original version (IPv4) by Paul Vixie (ISC), July 1996 + */ + + static char * + inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) + { + u_int m; + int b; + int p; + int zero_s, + zero_l, + tmp_zero_s, + tmp_zero_l; + int i; + int is_ipv4 = 0; + unsigned char inbuf[16]; + char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; + char *cp; + int words; + u_char *s; + + if (bits < 0 || bits > 128) + { + errno = EINVAL; + return (NULL); + } + + cp = outbuf; + + if (bits == 0) + { + *cp++ = ':'; + *cp++ = ':'; + *cp = '\0'; + } + else + { + /* Copy src to private buffer. Zero host part. */ + p = (bits + 7) / 8; + memcpy(inbuf, src, p); + memset(inbuf + p, 0, 16 - p); + b = bits % 8; + if (b != 0) + { + m = ~0 << (8 - b); + inbuf[p - 1] &= m; + } + + s = inbuf; + + /* how many words need to be displayed in output */ + words = (bits + 15) / 16; + if (words == 1) + words = 2; + + /* Find the longest substring of zero's */ + zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; + for (i = 0; i < (words * 2); i += 2) + { + if ((s[i] | s[i + 1]) == 0) + { + if (tmp_zero_l == 0) + tmp_zero_s = i / 2; + tmp_zero_l++; + } + else + { + if (tmp_zero_l && zero_l < tmp_zero_l) + { + zero_s = tmp_zero_s; + zero_l = tmp_zero_l; + tmp_zero_l = 0; + } + } + } + + if (tmp_zero_l && zero_l < tmp_zero_l) + { + zero_s = tmp_zero_s; + zero_l = tmp_zero_l; + } + + if (zero_l != words && zero_s == 0 && ((zero_l == 6) || + ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || + ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) + is_ipv4 = 1; + + /* Format whole words. */ + for (p = 0; p < words; p++) + { + if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) + { + /* Time to skip some zeros */ + if (p == zero_s) + *cp++ = ':'; + if (p == words - 1) + *cp++ = ':'; + s++; + s++; + continue; + } + + if (is_ipv4 && p > 5) + { + *cp++ = (p == 6) ? ':' : '.'; + cp += SPRINTF((cp, "%u", *s++)); + /* we can potentially drop the last octet */ + if (p != 7 || bits > 120) + { + *cp++ = '.'; + cp += SPRINTF((cp, "%u", *s++)); + } + } + else + { + if (cp != outbuf) + *cp++ = ':'; + cp += SPRINTF((cp, "%x", *s * 256 + s[1])); + s += 2; + } + } + } + /* Format CIDR /width. */ + (void) SPRINTF((cp, "/%u", bits)); + if (strlen(outbuf) + 1 > size) + goto emsgsize; + strcpy(dst, outbuf); + + return (dst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); + } diff --git a/src/backend/utils/adt/inet_net_ntop.c b/src/backend/utils/adt/inet_net_ntop.c index 3d7fb65..e69de29 100644 *** /tmp/pgrevert.8208/zi7lid_inet_net_ntop.c Sat Nov 20 18:06:46 2010 --- /dev/null Sat Nov 20 18:04:30 2010 *************** *** 1,530 **** - /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * src/backend/utils/adt/inet_net_ntop.c - */ - - #if defined(LIBC_SCCS) && !defined(lint) - static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $"; - #endif - - #include "postgres.h" - - #include <sys/types.h> - #include <sys/socket.h> - #include <netinet/in.h> - #include <arpa/inet.h> - - #include "utils/builtins.h" - #include "utils/inet.h" - - - #define NS_IN6ADDRSZ 16 - #define NS_INT16SZ 2 - - #ifdef SPRINTF_CHAR - #define SPRINTF(x) strlen(sprintf/**/x) - #else - #define SPRINTF(x) ((size_t)sprintf x) - #endif - - static char *inet_net_ntop_ipv4(const u_char *src, int bits, - char *dst, size_t size); - static char *inet_cidr_ntop_ipv4(const u_char *src, int bits, - char *dst, size_t size); - static char *inet_net_ntop_ipv6(const u_char *src, int bits, - char *dst, size_t size); - static char *inet_cidr_ntop_ipv6(const u_char *src, int bits, - char *dst, size_t size); - - /* - * char * - * inet_cidr_ntop(af, src, bits, dst, size) - * convert network number from network to presentation format. - * generates CIDR style result always. - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * author: - * Paul Vixie (ISC), July 1996 - */ - char * - inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) - { - switch (af) - { - case PGSQL_AF_INET: - return (inet_cidr_ntop_ipv4(src, bits, dst, size)); - case PGSQL_AF_INET6: - return (inet_cidr_ntop_ipv6(src, bits, dst, size)); - default: - errno = EAFNOSUPPORT; - return (NULL); - } - } - - - /* - * static char * - * inet_cidr_ntop_ipv4(src, bits, dst, size) - * convert IPv4 network number from network to presentation format. - * generates CIDR style result always. - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0b11110000 in its fourth octet. - * author: - * Paul Vixie (ISC), July 1996 - */ - static char * - inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) - { - char *odst = dst; - char *t; - u_int m; - int b; - - if (bits < 0 || bits > 32) - { - errno = EINVAL; - return (NULL); - } - - if (bits == 0) - { - if (size < sizeof "0") - goto emsgsize; - *dst++ = '0'; - size--; - *dst = '\0'; - } - - /* Format whole octets. */ - for (b = bits / 8; b > 0; b--) - { - if (size <= sizeof "255.") - goto emsgsize; - t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b > 1) - { - *dst++ = '.'; - *dst = '\0'; - } - size -= (size_t) (dst - t); - } - - /* Format partial octet. */ - b = bits % 8; - if (b > 0) - { - if (size <= sizeof ".255") - goto emsgsize; - t = dst; - if (dst != odst) - *dst++ = '.'; - m = ((1 << b) - 1) << (8 - b); - dst += SPRINTF((dst, "%u", *src & m)); - size -= (size_t) (dst - t); - } - - /* Format CIDR /width. */ - if (size <= sizeof "/32") - goto emsgsize; - dst += SPRINTF((dst, "/%u", bits)); - return (odst); - - emsgsize: - errno = EMSGSIZE; - return (NULL); - } - - /* - * static char * - * inet_cidr_ntop_ipv6(src, bits, fakebits, dst, size) - * convert IPv6 network number from network to presentation format. - * generates CIDR style result always. Picks the shortest representation - * unless the IP is really IPv4. - * always prints specified number of bits (bits). - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0x11110000 in its fourth octet. - * author: - * Vadim Kogan (UCB), June 2001 - * Original version (IPv4) by Paul Vixie (ISC), July 1996 - */ - - static char * - inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) - { - u_int m; - int b; - int p; - int zero_s, - zero_l, - tmp_zero_s, - tmp_zero_l; - int i; - int is_ipv4 = 0; - unsigned char inbuf[16]; - char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; - char *cp; - int words; - u_char *s; - - if (bits < 0 || bits > 128) - { - errno = EINVAL; - return (NULL); - } - - cp = outbuf; - - if (bits == 0) - { - *cp++ = ':'; - *cp++ = ':'; - *cp = '\0'; - } - else - { - /* Copy src to private buffer. Zero host part. */ - p = (bits + 7) / 8; - memcpy(inbuf, src, p); - memset(inbuf + p, 0, 16 - p); - b = bits % 8; - if (b != 0) - { - m = ~0 << (8 - b); - inbuf[p - 1] &= m; - } - - s = inbuf; - - /* how many words need to be displayed in output */ - words = (bits + 15) / 16; - if (words == 1) - words = 2; - - /* Find the longest substring of zero's */ - zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; - for (i = 0; i < (words * 2); i += 2) - { - if ((s[i] | s[i + 1]) == 0) - { - if (tmp_zero_l == 0) - tmp_zero_s = i / 2; - tmp_zero_l++; - } - else - { - if (tmp_zero_l && zero_l < tmp_zero_l) - { - zero_s = tmp_zero_s; - zero_l = tmp_zero_l; - tmp_zero_l = 0; - } - } - } - - if (tmp_zero_l && zero_l < tmp_zero_l) - { - zero_s = tmp_zero_s; - zero_l = tmp_zero_l; - } - - if (zero_l != words && zero_s == 0 && ((zero_l == 6) || - ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || - ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) - is_ipv4 = 1; - - /* Format whole words. */ - for (p = 0; p < words; p++) - { - if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) - { - /* Time to skip some zeros */ - if (p == zero_s) - *cp++ = ':'; - if (p == words - 1) - *cp++ = ':'; - s++; - s++; - continue; - } - - if (is_ipv4 && p > 5) - { - *cp++ = (p == 6) ? ':' : '.'; - cp += SPRINTF((cp, "%u", *s++)); - /* we can potentially drop the last octet */ - if (p != 7 || bits > 120) - { - *cp++ = '.'; - cp += SPRINTF((cp, "%u", *s++)); - } - } - else - { - if (cp != outbuf) - *cp++ = ':'; - cp += SPRINTF((cp, "%x", *s * 256 + s[1])); - s += 2; - } - } - } - /* Format CIDR /width. */ - (void) SPRINTF((cp, "/%u", bits)); - if (strlen(outbuf) + 1 > size) - goto emsgsize; - strcpy(dst, outbuf); - - return (dst); - - emsgsize: - errno = EMSGSIZE; - return (NULL); - } - - - /* - * char * - * inet_net_ntop(af, src, bits, dst, size) - * convert host/network address from network to presentation format. - * "src"'s size is determined from its "af". - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * 192.5.5.1/28 has a nonzero host part, which means it isn't a network - * as called for by inet_net_pton() but it can be a host address with - * an included netmask. - * author: - * Paul Vixie (ISC), October 1998 - */ - char * - inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) - { - switch (af) - { - case PGSQL_AF_INET: - return (inet_net_ntop_ipv4(src, bits, dst, size)); - case PGSQL_AF_INET6: - return (inet_net_ntop_ipv6(src, bits, dst, size)); - default: - errno = EAFNOSUPPORT; - return (NULL); - } - } - - /* - * static char * - * inet_net_ntop_ipv4(src, bits, dst, size) - * convert IPv4 network address from network to presentation format. - * "src"'s size is determined from its "af". - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0b11110000 in its fourth octet. - * author: - * Paul Vixie (ISC), October 1998 - */ - static char * - inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) - { - char *odst = dst; - char *t; - int len = 4; - int b; - - if (bits < 0 || bits > 32) - { - errno = EINVAL; - return (NULL); - } - - /* Always format all four octets, regardless of mask length. */ - for (b = len; b > 0; b--) - { - if (size <= sizeof ".255") - goto emsgsize; - t = dst; - if (dst != odst) - *dst++ = '.'; - dst += SPRINTF((dst, "%u", *src++)); - size -= (size_t) (dst - t); - } - - /* don't print masklen if 32 bits */ - if (bits != 32) - { - if (size <= sizeof "/32") - goto emsgsize; - dst += SPRINTF((dst, "/%u", bits)); - } - - return (odst); - - emsgsize: - errno = EMSGSIZE; - return (NULL); - } - - static int - decoct(const u_char *src, int bytes, char *dst, size_t size) - { - char *odst = dst; - char *t; - int b; - - for (b = 1; b <= bytes; b++) - { - if (size <= sizeof "255.") - return (0); - t = dst; - dst += SPRINTF((dst, "%u", *src++)); - if (b != bytes) - { - *dst++ = '.'; - *dst = '\0'; - } - size -= (size_t) (dst - t); - } - return (dst - odst); - } - - static char * - inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) - { - /* - * Note that int32_t and int16_t need only be "at least" large enough to - * contain a value of the specified size. On some systems, like Crays, - * there is no such thing as an integer variable with 16 bits. Keep this - * in mind if you think this function should have been coded to use - * pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; - char *tp; - struct - { - int base, - len; - } best, cur; - u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i; - - if ((bits < -1) || (bits > 128)) - { - errno = EINVAL; - return (NULL); - } - - /* - * Preprocess: Copy the input (bytewise) array into a wordwise array. Find - * the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - best.base = -1; - cur.base = -1; - best.len = 0; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) - { - if (words[i] == 0) - { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } - else - { - if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) - { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) - { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) - { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) - *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) - { - int n; - - n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp)); - if (n == 0) - { - errno = EMSGSIZE; - return (NULL); - } - tp += strlen(tp); - break; - } - tp += SPRINTF((tp, "%x", words[i])); - } - - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) - *tp++ = ':'; - *tp = '\0'; - - if (bits != -1 && bits != 128) - tp += SPRINTF((tp, "/%u", bits)); - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t) (tp - tmp) > size) - { - errno = EMSGSIZE; - return (NULL); - } - strcpy(dst, tmp); - return (dst); - } --- 0 ---- diff --git a/src/port/inet_net_ntop.c b/src/port/inet_net_ntop.c index ...02d3a7c . *** /dev/null Sat Nov 20 18:04:30 2010 --- src/port/inet_net_ntop.c Sat Nov 20 17:14:44 2010 *************** *** 0 **** --- 1,275 ---- + /* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * src/backend/utils/adt/inet_net_ntop.c + */ + + #if defined(LIBC_SCCS) && !defined(lint) + static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.2 2004/03/09 09:17:27 marka Exp $"; + #endif + + #include "postgres.h" + + #include <sys/types.h> + #include <sys/socket.h> + #include <netinet/in.h> + #include <arpa/inet.h> + + #include "utils/inet.h" + + + #define NS_IN6ADDRSZ 16 + #define NS_INT16SZ 2 + + #ifdef SPRINTF_CHAR + #define SPRINTF(x) strlen(sprintf/**/x) + #else + #define SPRINTF(x) ((size_t)sprintf x) + #endif + + static char *inet_net_ntop_ipv4(const u_char *src, int bits, + char *dst, size_t size); + static char *inet_net_ntop_ipv6(const u_char *src, int bits, + char *dst, size_t size); + + + /* + * char * + * inet_net_ntop(af, src, bits, dst, size) + * convert host/network address from network to presentation format. + * "src"'s size is determined from its "af". + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * 192.5.5.1/28 has a nonzero host part, which means it isn't a network + * as called for by inet_net_pton() but it can be a host address with + * an included netmask. + * author: + * Paul Vixie (ISC), October 1998 + */ + char * + inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) + { + switch (af) + { + case PGSQL_AF_INET: + return (inet_net_ntop_ipv4(src, bits, dst, size)); + case PGSQL_AF_INET6: + return (inet_net_ntop_ipv6(src, bits, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } + } + + /* + * static char * + * inet_net_ntop_ipv4(src, bits, dst, size) + * convert IPv4 network address from network to presentation format. + * "src"'s size is determined from its "af". + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0b11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), October 1998 + */ + static char * + inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) + { + char *odst = dst; + char *t; + int len = 4; + int b; + + if (bits < 0 || bits > 32) + { + errno = EINVAL; + return (NULL); + } + + /* Always format all four octets, regardless of mask length. */ + for (b = len; b > 0; b--) + { + if (size <= sizeof ".255") + goto emsgsize; + t = dst; + if (dst != odst) + *dst++ = '.'; + dst += SPRINTF((dst, "%u", *src++)); + size -= (size_t) (dst - t); + } + + /* don't print masklen if 32 bits */ + if (bits != 32) + { + if (size <= sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + } + + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); + } + + static int + decoct(const u_char *src, int bytes, char *dst, size_t size) + { + char *odst = dst; + char *t; + int b; + + for (b = 1; b <= bytes; b++) + { + if (size <= sizeof "255.") + return (0); + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b != bytes) + { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t) (dst - t); + } + return (dst - odst); + } + + static char * + inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) + { + /* + * Note that int32_t and int16_t need only be "at least" large enough to + * contain a value of the specified size. On some systems, like Crays, + * there is no such thing as an integer variable with 16 bits. Keep this + * in mind if you think this function should have been coded to use + * pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255/128"]; + char *tp; + struct + { + int base, + len; + } best, cur; + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; + + if ((bits < -1) || (bits > 128)) + { + errno = EINVAL; + return (NULL); + } + + /* + * Preprocess: Copy the input (bytewise) array into a wordwise array. Find + * the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + cur.base = -1; + best.len = 0; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) + { + if (words[i] == 0) + { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } + else + { + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) + { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) + { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) + { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) + { + int n; + + n = decoct(src + 12, 4, tp, sizeof tmp - (tp - tmp)); + if (n == 0) + { + errno = EMSGSIZE; + return (NULL); + } + tp += strlen(tp); + break; + } + tp += SPRINTF((tp, "%x", words[i])); + } + + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp = '\0'; + + if (bits != -1 && bits != 128) + tp += SPRINTF((tp, "/%u", bits)); + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t) (tp - tmp) > size) + { + errno = EMSGSIZE; + return (NULL); + } + strcpy(dst, tmp); + return (dst); + } +
Bruce Momjian wrote: > Tom Lane wrote: > > Bruce Momjian <bruce@momjian.us> writes: > > > I assume you are suggesting to use our inet_net_ntop() even if the > > > system has inet_ntop(). > > > > If you're going to have code to do the former, it doesn't seem to be > > worth the trouble to also have code that does the latter ... > > OK, we will not call inet_ntop() at all. I moved the CIDR part of > adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining > "net" part to /port/inet_net_ntop.c. > > I then changed all uses of inet_ntoa to use inet_net_ntop(). While this > churn would perhaps not be warranted just to allow for better error > messages, I found pg_getaddrinfo_all() being called from > libpq::connectDBStart(), which makes it not thread-safe. I am not > excited about backpatching it but it is a threading bug. > > The output is as expected: > > $ psql -h localhost 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 127.0.0.1 test > psql: could not connect to server: Connection refused > Is the server running on host "127.0.0.1" and accepting > TCP/IP connections on port 5432? Applied. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Excerpts from Bruce Momjian's message of mié nov 24 19:04:30 -0300 2010: > Bruce Momjian wrote: > > OK, we will not call inet_ntop() at all. I moved the CIDR part of > > adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining > > "net" part to /port/inet_net_ntop.c. > Applied. This broke dugong in the ecpg tests. -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Alvaro Herrera wrote: > Excerpts from Bruce Momjian's message of nov 24 19:04:30 -0300 2010: > > Bruce Momjian wrote: > > > > OK, we will not call inet_ntop() at all. I moved the CIDR part of > > > adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining > > > "net" part to /port/inet_net_ntop.c. > > > Applied. > > This broke dugong in the ecpg tests. I stopped checking the build page after a few hours, but I see the failure now. I have reviewed the libpq Makefile and I believe I am now properly added port/inet_net_ntop.c. I improved the comments as well. Patch attached and applied. Thansk for the heads-up. -- 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/Makefile b/src/interfaces/libpq/Makefile index b327ee5..74ae79a 100644 *** /tmp/mhssze_Makefile Wed Nov 24 21:42:22 2010 --- src/interfaces/libpq/Makefile Wed Nov 24 21:04:00 2010 *************** endif *** 27,39 **** # Need to recompile any libpgport object files because we need these # object files to use the same compile flags as libpq. If we used # the object files from libpgport, this would not be true on all ! # platforms. LIBS := $(LIBS:-lpgport=) OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \ libpq-events.o \ ! md5.o ip.o wchar.o encnames.o noblock.o pgstrcasecmp.o thread.o \ $(filter crypt.o getaddrinfo.o inet_aton.o open.o snprintf.o strerror.o strlcpy.o win32error.o, $(LIBOBJS)) ifeq ($(PORTNAME), cygwin) --- 27,40 ---- # Need to recompile any libpgport object files because we need these # object files to use the same compile flags as libpq. If we used # the object files from libpgport, this would not be true on all ! # platforms. We filter some object files so we only use object ! # files configure says we need. LIBS := $(LIBS:-lpgport=) OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \ libpq-events.o \ ! md5.o ip.o wchar.o encnames.o inet_net_ntop.o noblock.o pgstrcasecmp.o thread.o \ $(filter crypt.o getaddrinfo.o inet_aton.o open.o snprintf.o strerror.o strlcpy.o win32error.o, $(LIBOBJS)) ifeq ($(PORTNAME), cygwin) *************** backend_src = $(top_srcdir)/src/backend *** 80,86 **** # For port modules, this only happens if configure decides the module # is needed (see filter hack in OBJS, above). ! crypt.c getaddrinfo.c inet_aton.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.c win32error.cpgsleep.c: % : $(top_srcdir)/src/port/% rm -f $@ && $(LN_S) $< . md5.c ip.c: % : $(backend_src)/libpq/% --- 81,87 ---- # For port modules, this only happens if configure decides the module # is needed (see filter hack in OBJS, above). ! crypt.c getaddrinfo.c inet_aton.c inet_net_ntop.c noblock.c open.c pgstrcasecmp.c snprintf.c strerror.c strlcpy.c thread.cwin32error.c pgsleep.c: % : $(top_srcdir)/src/port/% rm -f $@ && $(LN_S) $< . md5.c ip.c: % : $(backend_src)/libpq/%
bruce wrote: > Alvaro Herrera wrote: > > Excerpts from Bruce Momjian's message of nov 24 19:04:30 -0300 2010: > > > Bruce Momjian wrote: > > > > > > OK, we will not call inet_ntop() at all. I moved the CIDR part of > > > > adt/inet_net_ntop.c into adt/inet_cidr_ntop.c, and moved the remaining > > > > "net" part to /port/inet_net_ntop.c. > > > > > Applied. > > > > This broke dugong in the ecpg tests. > > I stopped checking the build page after a few hours, but I see the > failure now. > > I have reviewed the libpq Makefile and I believe I am now properly added > port/inet_net_ntop.c. I improved the comments as well. > > Patch attached and applied. Thansk for the heads-up. OK, dugong is green now, so I think I got it. :-) -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
On lör, 2010-11-20 at 18:07 -0500, Bruce Momjian wrote: > The output is as expected: > > $ psql -h localhost 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 127.0.0.1 test > psql: could not connect to server: Connection refused > Is the server running on host "127.0.0.1" and accepting > TCP/IP connections on port 5432? Thanks for working on this. However, the example I posted at the beginning of this thread now does this: $ ./psql -p 55555 -h localhost psql: could not connect to server: Connection refused Is the server running on host "localhost" (???) and accepting TCP/IP connections on port 55555? 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 55555? The "???" should presumably be "::1". Also, this comment should be updated: /* * Try to initiate a connection to one of the addresses * returned by pg_getaddrinfo_all(). conn->addr_cur isthe * next one to try. We fail when we run out of addresses * (reporting the error returned for the *last* alternative, * which may not be what users expect :-(). */
Excerpts from Peter Eisentraut's message of vie nov 26 11:06:24 -0300 2010: > Thanks for working on this. However, the example I posted at the > beginning of this thread now does this: > > $ ./psql -p 55555 -h localhost > psql: could not connect to server: Connection refused > Is the server running on host "localhost" (???) and accepting > TCP/IP connections on port 55555? Shouldn't connectFailureMessage receive addr_cur as parameter? Otherwise it's not clear that it's getting the right params to report. -- Álvaro Herrera <alvherre@commandprompt.com> The PostgreSQL Company - Command Prompt, Inc. PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Peter Eisentraut wrote: > On l?r, 2010-11-20 at 18:07 -0500, Bruce Momjian wrote: > > The output is as expected: > > > > $ psql -h localhost 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 127.0.0.1 test > > psql: could not connect to server: Connection refused > > Is the server running on host "127.0.0.1" and accepting > > TCP/IP connections on port 5432? > > Thanks for working on this. However, the example I posted at the > beginning of this thread now does this: > > $ ./psql -p 55555 -h localhost > psql: could not connect to server: Connection refused > Is the server running on host "localhost" (???) and accepting > TCP/IP connections on port 55555? > 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 55555? > > The "???" should presumably be "::1". OK, I updated the code to always use cur_addr in the code --- let me know if that doesn't fix it. > Also, this comment should be updated: > > /* > * Try to initiate a connection to one of the addresses > * returned by pg_getaddrinfo_all(). conn->addr_cur is the > * next one to try. We fail when we run out of addresses > * (reporting the error returned for the *last* alternative, > * which may not be what users expect :-(). > */ Thanks, comment udpated. It was wrong even before because we were reporting all failures even before I Started. -- 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 6593f21..8b55167 100644 *** /tmp/HkJ20a_fe-connect.c Fri Nov 26 11:48:13 2010 --- src/interfaces/libpq/fe-connect.c Fri Nov 26 11:36:28 2010 *************** connectFailureMessage(PGconn *conn, int *** 989,996 **** { char host_addr[NI_MAXHOST]; bool display_host_addr; - struct sockaddr_in *host_addr_struct = (struct sockaddr_in *) - &conn->raddr.addr; /* * Optionally display the network address with the hostname. --- 989,994 ---- *************** connectFailureMessage(PGconn *conn, int *** 998,1005 **** */ if (conn->pghostaddr != NULL) strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST); ! else if (inet_net_ntop(conn->addr_cur->ai_family, &host_addr_struct->sin_addr, ! host_addr_struct->sin_family == AF_INET ? 32 : 128, host_addr, sizeof(host_addr)) == NULL) strcpy(host_addr, "???"); --- 996,1004 ---- */ if (conn->pghostaddr != NULL) strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST); ! else if (inet_net_ntop(conn->addr_cur->ai_family, ! &conn->addr_cur->ai_addr, ! conn->addr_cur->ai_family == AF_INET ? 32 : 128, host_addr, sizeof(host_addr)) == NULL) strcpy(host_addr, "???");
Alvaro Herrera wrote: > Excerpts from Peter Eisentraut's message of vie nov 26 11:06:24 -0300 2010: > > > Thanks for working on this. However, the example I posted at the > > beginning of this thread now does this: > > > > $ ./psql -p 55555 -h localhost > > psql: could not connect to server: Connection refused > > Is the server running on host "localhost" (???) and accepting > > TCP/IP connections on port 55555? > > Shouldn't connectFailureMessage receive addr_cur as parameter? > Otherwise it's not clear that it's getting the right params to report. I am passing conn so I changed the code to always use addr_cur. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
On fre, 2010-11-26 at 11:53 -0500, Bruce Momjian wrote: > OK, I updated the code to always use cur_addr in the code --- let me > know if that doesn't fix it. Now it's even more wrong: psql: could not connect to server: Connection refused Is the server running on host "localhost" (???) and accepting TCP/IP connections on port 55555? could not connect to server: Connection refused Is the server running on host "localhost" (232.106.56.8) and accepting TCP/IP connections on port 55555?
Peter Eisentraut wrote: > On fre, 2010-11-26 at 11:53 -0500, Bruce Momjian wrote: > > OK, I updated the code to always use cur_addr in the code --- let me > > know if that doesn't fix it. > > Now it's even more wrong: > > psql: could not connect to server: Connection refused > Is the server running on host "localhost" (???) and accepting > TCP/IP connections on port 55555? > could not connect to server: Connection refused > Is the server running on host "localhost" (232.106.56.8) and accepting > TCP/IP connections on port 55555? Yep, even worse. I have applied the attached patch, which gives me the right IPv4 value. I can't test IPv6. I am finding the sock_addr structures confusing. -- 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 44a3c71..cdf8ee4 100644 *** /tmp/VwLJNa_fe-connect.c Fri Nov 26 13:18:16 2010 --- src/interfaces/libpq/fe-connect.c Fri Nov 26 13:11:12 2010 *************** connectFailureMessage(PGconn *conn, int *** 989,994 **** --- 989,996 ---- { char host_addr[NI_MAXHOST]; bool display_host_addr; + struct sockaddr_in *host_addr_struct = (struct sockaddr_in *) + &conn->raddr.addr; /* * Optionally display the network address with the hostname. *************** connectFailureMessage(PGconn *conn, int *** 996,1004 **** */ if (conn->pghostaddr != NULL) strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST); ! else if (inet_net_ntop(conn->addr_cur->ai_family, ! &conn->addr_cur->ai_addr, ! conn->addr_cur->ai_family == AF_INET ? 32 : 128, host_addr, sizeof(host_addr)) == NULL) strcpy(host_addr, "???"); --- 998,1006 ---- */ if (conn->pghostaddr != NULL) strlcpy(host_addr, conn->pghostaddr, NI_MAXHOST); ! else if (inet_net_ntop(host_addr_struct->sin_family, ! &host_addr_struct->sin_addr.s_addr, ! host_addr_struct->sin_family == AF_INET ? 32 : 128, host_addr, sizeof(host_addr)) == NULL) strcpy(host_addr, "???");
On fre, 2010-11-26 at 13:27 -0500, Bruce Momjian wrote: > Peter Eisentraut wrote: > > On fre, 2010-11-26 at 11:53 -0500, Bruce Momjian wrote: > > > OK, I updated the code to always use cur_addr in the code --- let me > > > know if that doesn't fix it. > > > > Now it's even more wrong: > > > > psql: could not connect to server: Connection refused > > Is the server running on host "localhost" (???) and accepting > > TCP/IP connections on port 55555? > > could not connect to server: Connection refused > > Is the server running on host "localhost" (232.106.56.8) and accepting > > TCP/IP connections on port 55555? > > Yep, even worse. I have applied the attached patch, which gives me the > right IPv4 value. I can't test IPv6. We're back to psql: could not connect to server: Connection refused Is the server running on host "localhost" (???) and accepting TCP/IP connections on port 55555? 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 55555?
Peter Eisentraut wrote: > On fre, 2010-11-26 at 13:27 -0500, Bruce Momjian wrote: > > Peter Eisentraut wrote: > > > On fre, 2010-11-26 at 11:53 -0500, Bruce Momjian wrote: > > > > OK, I updated the code to always use cur_addr in the code --- let me > > > > know if that doesn't fix it. > > > > > > Now it's even more wrong: > > > > > > psql: could not connect to server: Connection refused > > > Is the server running on host "localhost" (???) and accepting > > > TCP/IP connections on port 55555? > > > could not connect to server: Connection refused > > > Is the server running on host "localhost" (232.106.56.8) and accepting > > > TCP/IP connections on port 55555? > > > > Yep, even worse. I have applied the attached patch, which gives me the > > right IPv4 value. I can't test IPv6. > > We're back to > > psql: could not connect to server: Connection refused > Is the server running on host "localhost" (???) and accepting > TCP/IP connections on port 55555? > 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 55555? OK, good. :-O I just realize I can easily test this on Ubuntu so let me get that working now. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Bruce Momjian wrote: > Peter Eisentraut wrote: > > On fre, 2010-11-26 at 13:27 -0500, Bruce Momjian wrote: > > > Peter Eisentraut wrote: > > > > On fre, 2010-11-26 at 11:53 -0500, Bruce Momjian wrote: > > > > > OK, I updated the code to always use cur_addr in the code --- let me > > > > > know if that doesn't fix it. > > > > > > > > Now it's even more wrong: > > > > > > > > psql: could not connect to server: Connection refused > > > > Is the server running on host "localhost" (???) and accepting > > > > TCP/IP connections on port 55555? > > > > could not connect to server: Connection refused > > > > Is the server running on host "localhost" (232.106.56.8) and accepting > > > > TCP/IP connections on port 55555? > > > > > > Yep, even worse. I have applied the attached patch, which gives me the > > > right IPv4 value. I can't test IPv6. > > > > We're back to > > > > psql: could not connect to server: Connection refused > > Is the server running on host "localhost" (???) and accepting > > TCP/IP connections on port 55555? > > 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 55555? > > OK, good. :-O I just realize I can easily test this on Ubuntu so let > me get that working now. OK, Tom and I both found the problem --- our data type assumed INET6 was INET + 1, while libc had other ideas. Here is the new, I guess correct, output from Ubuntu: $ /usr/local/pgsql/bin/psql -h localhost testpsql: could not connect to server: Connection refused Is the server runningon host "localhost" (::) and accepting TCP/IP connections on port 5432?could not connect to server: Connectionrefused Is the server running on host "localhost" (127.0.0.1) andaccepting TCP/IP connections on port 5432? Is "::" correct? -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
Bruce Momjian <bruce@momjian.us> writes: > Is "::" correct? I don't think so ... I get this, even sillier, response: $ psql -h ::1 -p 5433 regression psql: could not connect to server: Connection refused Is the server running on host "::1" (::) and accepting TCP/IP connections on port 5433? Seems like a logic bug in inet_net_ntop_ipv6. Before we waste mental effort finding it for ourselves, has anyone checked for fixes in the upstream code lately? regards, tom lane
I wrote: > Seems like a logic bug in inet_net_ntop_ipv6. um ... no, it's connectFailureMessage's fault. regards, tom lane