Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+3
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

+32-9
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

+8-12
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)