Skip to content

Commit 313f56c

Browse files
committed
Tweak libpq's PQhost, PQhostaddr, and psql's \connect
Fixes some problems introduced by 6e5f8d4: * When reusing conninfo data from the previous connection in \connect, the host address should only be reused if it was specified as hostaddr; if it wasn't, then 'host' is resolved afresh. We were reusing the same IP address, which ignores a possible DNS change as well as any other addresses that the name resolves to than the one that was used in the original connection. * PQhost, PQhostaddr: Don't present user-specified hostaddr when we have an inet_net_ntop-produced equivalent address. The latter has been put in canonical format, which is cleaner (so it produces "127.0.0.1" when given "host=2130706433", for example). * Document the hostaddr-reusing aspect of \connect. * Fix some code comments Author: Fabien Coelho Reported-by: Noah Misch Discussion: https://postgr.es/m/20190527203713.GA58392@gust.leadboat.com
1 parent 3da73d6 commit 313f56c

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,9 @@ testdb=>
911911
<replaceable class="parameter">host</replaceable> or
912912
<replaceable class="parameter">port</replaceable>
913913
as <literal>-</literal> is equivalent to omitting that parameter.
914+
If <literal>hostaddr</literal> was specified in the original
915+
connection's <structname>conninfo</structname>, that address is reused
916+
for the new connection (disregarding any other host specification).
914917
</para>
915918

916919
<para>

src/bin/psql/command.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,6 +2870,26 @@ param_is_newly_set(const char *old_val, const char *new_val)
28702870
return false;
28712871
}
28722872

2873+
/* return whether the connection has 'hostaddr' in its conninfo */
2874+
static bool
2875+
has_hostaddr(PGconn *conn)
2876+
{
2877+
bool used = false;
2878+
PQconninfoOption *ciopt = PQconninfo(conn);
2879+
2880+
for (PQconninfoOption *p = ciopt; p->keyword != NULL; p++)
2881+
{
2882+
if (strcmp(p->keyword, "hostaddr") == 0 && p->val != NULL)
2883+
{
2884+
used = true;
2885+
break;
2886+
}
2887+
}
2888+
2889+
PQconninfoFree(ciopt);
2890+
return used;
2891+
}
2892+
28732893
/*
28742894
* do_connect -- handler for \connect
28752895
*
@@ -2929,24 +2949,24 @@ do_connect(enum trivalue reuse_previous_specification,
29292949
port = NULL;
29302950
}
29312951

2932-
/* grab missing values from the old connection */
2952+
/*
2953+
* Grab missing values from the old connection. If we grab host (or host
2954+
* is the same as before) and hostaddr was set, grab that too.
2955+
*/
29332956
if (reuse_previous)
29342957
{
29352958
if (!user)
29362959
user = PQuser(o_conn);
2937-
if (host && strcmp(host, PQhost(o_conn)) == 0)
2960+
if (host && strcmp(host, PQhost(o_conn)) == 0 &&
2961+
has_hostaddr(o_conn))
29382962
{
2939-
/*
2940-
* if we are targeting the same host, reuse its hostaddr for
2941-
* consistency
2942-
*/
29432963
hostaddr = PQhostaddr(o_conn);
29442964
}
29452965
if (!host)
29462966
{
29472967
host = PQhost(o_conn);
2948-
/* also set hostaddr for consistency */
2949-
hostaddr = PQhostaddr(o_conn);
2968+
if (has_hostaddr(o_conn))
2969+
hostaddr = PQhostaddr(o_conn);
29502970
}
29512971
if (!port)
29522972
port = PQport(o_conn);
@@ -3129,7 +3149,10 @@ do_connect(enum trivalue reuse_previous_specification,
31293149
char *host = PQhost(pset.db);
31303150
char *hostaddr = PQhostaddr(pset.db);
31313151

3132-
/* If the host is an absolute path, the connection is via socket */
3152+
/*
3153+
* If the host is an absolute path, the connection is via socket
3154+
* unless overridden by hostaddr
3155+
*/
31333156
if (is_absolute_path(host))
31343157
{
31353158
if (hostaddr && *hostaddr)

src/interfaces/libpq/fe-connect.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,9 +1536,7 @@ getHostaddr(PGconn *conn, char *host_addr, int host_addr_len)
15361536
{
15371537
struct sockaddr_storage *addr = &conn->raddr.addr;
15381538

1539-
if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
1540-
strlcpy(host_addr, conn->connhost[conn->whichhost].hostaddr, host_addr_len);
1541-
else if (addr->ss_family == AF_INET)
1539+
if (addr->ss_family == AF_INET)
15421540
{
15431541
if (inet_net_ntop(AF_INET,
15441542
&((struct sockaddr_in *) addr)->sin_addr.s_addr,
@@ -6463,6 +6461,10 @@ PQhost(const PGconn *conn)
64636461

64646462
if (conn->connhost != NULL)
64656463
{
6464+
/*
6465+
* Return the verbatim host value provided by user, or hostaddr in its
6466+
* lack.
6467+
*/
64666468
if (conn->connhost[conn->whichhost].host != NULL &&
64676469
conn->connhost[conn->whichhost].host[0] != '\0')
64686470
return conn->connhost[conn->whichhost].host;
@@ -6480,15 +6482,9 @@ PQhostaddr(const PGconn *conn)
64806482
if (!conn)
64816483
return NULL;
64826484

6483-
if (conn->connhost != NULL)
6484-
{
6485-
if (conn->connhost[conn->whichhost].hostaddr != NULL &&
6486-
conn->connhost[conn->whichhost].hostaddr[0] != '\0')
6487-
return conn->connhost[conn->whichhost].hostaddr;
6488-
6489-
if (conn->connip != NULL)
6490-
return conn->connip;
6491-
}
6485+
/* Return the parsed IP address */
6486+
if (conn->connhost != NULL && conn->connip != NULL)
6487+
return conn->connip;
64926488

64936489
return "";
64946490
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy