Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6e5f8d4

Browse files
committed
psql: Show IP address in \conninfo
When hostaddr is given, the actual IP address that psql is connected tocan be totally unexpected for the given host. The more verbose outputwe now generate makes things clearer. Since the "host" and "hostaddr"parts of the conninfo could come from different sources (say, one ofthem is in the service specification or a URI-style conninfo and theother is not), this is not as silly as it may first appear. This isalso definitely useful if the hostname resolves to multiple addresses.Author: Fabien CoelhoReviewed-by: Pavel Stehule, Arthur ZakirovDiscussion:https://postgr.es/m/alpine.DEB.2.21.1810261532380.27686@lancrehttps://postgr.es/m/alpine.DEB.2.21.1808201323020.13832@lancre
1 parent7ee5f88 commit6e5f8d4

File tree

6 files changed

+172
-41
lines changed

6 files changed

+172
-41
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,36 @@ char *PQhost(const PGconn *conn);
17351735
</listitem>
17361736
</varlistentry>
17371737

1738+
1739+
<varlistentry id="libpq-pqhostaddr">
1740+
<term>
1741+
<function>PQhostaddr</function>
1742+
<indexterm>
1743+
<primary>PQhostaddr</primary>
1744+
</indexterm>
1745+
</term>
1746+
1747+
<listitem>
1748+
<para>
1749+
Returns the server IP address of the active connection.
1750+
This can be the address that a host name resolved to,
1751+
or an IP address provided through the <literal>hostaddr</literal>
1752+
parameter.
1753+
<synopsis>
1754+
char *PQhostaddr(const PGconn *conn);
1755+
</synopsis>
1756+
</para>
1757+
1758+
<para>
1759+
<function>PQhostaddr</function> returns <symbol>NULL</symbol> if the
1760+
<parameter>conn</parameter> argument is <symbol>NULL</symbol>.
1761+
Otherwise, if there is an error producing the host information
1762+
(perhaps if the connection has not been fully established or
1763+
there was an error), it returns an empty string.
1764+
</para>
1765+
</listitem>
1766+
</varlistentry>
1767+
17381768
<varlistentry id="libpq-pqport">
17391769
<term>
17401770
<function>PQport</function>

‎src/bin/psql/command.c

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -596,14 +596,30 @@ exec_command_conninfo(PsqlScanState scan_state, bool active_branch)
596596
else
597597
{
598598
char*host=PQhost(pset.db);
599+
char*hostaddr=PQhostaddr(pset.db);
599600

600-
/* If the host is an absolute path, the connection is via socket */
601+
/*
602+
* If the host is an absolute path, the connection is via socket
603+
* unless overriden by hostaddr
604+
*/
601605
if (is_absolute_path(host))
602-
printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
603-
db,PQuser(pset.db),host,PQport(pset.db));
606+
{
607+
if (hostaddr&&*hostaddr)
608+
printf(_("You are connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
609+
db,PQuser(pset.db),hostaddr,PQport(pset.db));
610+
else
611+
printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
612+
db,PQuser(pset.db),host,PQport(pset.db));
613+
}
604614
else
605-
printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
606-
db,PQuser(pset.db),host,PQport(pset.db));
615+
{
616+
if (hostaddr&&*hostaddr&&strcmp(host,hostaddr)!=0)
617+
printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
618+
db,PQuser(pset.db),host,hostaddr,PQport(pset.db));
619+
else
620+
printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
621+
db,PQuser(pset.db),host,PQport(pset.db));
622+
}
607623
printSSLInfo();
608624
}
609625
}
@@ -2854,6 +2870,7 @@ do_connect(enum trivalue reuse_previous_specification,
28542870
PGconn*o_conn=pset.db,
28552871
*n_conn;
28562872
char*password=NULL;
2873+
char*hostaddr=NULL;
28572874
boolkeep_password;
28582875
boolhas_connection_string;
28592876
boolreuse_previous;
@@ -2894,12 +2911,27 @@ do_connect(enum trivalue reuse_previous_specification,
28942911
}
28952912

28962913
/* grab missing values from the old connection */
2897-
if (!user&&reuse_previous)
2898-
user=PQuser(o_conn);
2899-
if (!host&&reuse_previous)
2900-
host=PQhost(o_conn);
2901-
if (!port&&reuse_previous)
2902-
port=PQport(o_conn);
2914+
if (reuse_previous)
2915+
{
2916+
if (!user)
2917+
user=PQuser(o_conn);
2918+
if (host&&strcmp(host,PQhost(o_conn))==0)
2919+
{
2920+
/*
2921+
* if we are targetting the same host, reuse its hostaddr for
2922+
* consistency
2923+
*/
2924+
hostaddr=PQhostaddr(o_conn);
2925+
}
2926+
if (!host)
2927+
{
2928+
host=PQhost(o_conn);
2929+
/* also set hostaddr for consistency */
2930+
hostaddr=PQhostaddr(o_conn);
2931+
}
2932+
if (!port)
2933+
port=PQport(o_conn);
2934+
}
29032935

29042936
/*
29052937
* Any change in the parameters read above makes us discard the password.
@@ -2961,13 +2993,18 @@ do_connect(enum trivalue reuse_previous_specification,
29612993

29622994
while (true)
29632995
{
2964-
#definePARAMS_ARRAY_SIZE8
2996+
#definePARAMS_ARRAY_SIZE9
29652997
constchar**keywords=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*keywords));
29662998
constchar**values=pg_malloc(PARAMS_ARRAY_SIZE*sizeof(*values));
29672999
intparamnum=-1;
29683000

29693001
keywords[++paramnum]="host";
29703002
values[paramnum]=host;
3003+
if (hostaddr&&*hostaddr)
3004+
{
3005+
keywords[++paramnum]="hostaddr";
3006+
values[paramnum]=hostaddr;
3007+
}
29713008
keywords[++paramnum]="port";
29723009
values[paramnum]=port;
29733010
keywords[++paramnum]="user";
@@ -3071,14 +3108,27 @@ do_connect(enum trivalue reuse_previous_specification,
30713108
param_is_newly_set(PQport(o_conn),PQport(pset.db)))
30723109
{
30733110
char*host=PQhost(pset.db);
3111+
char*hostaddr=PQhostaddr(pset.db);
30743112

30753113
/* If the host is an absolute path, the connection is via socket */
30763114
if (is_absolute_path(host))
3077-
printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3078-
PQdb(pset.db),PQuser(pset.db),host,PQport(pset.db));
3115+
{
3116+
if (hostaddr&&*hostaddr)
3117+
printf(_("You are now connected to database \"%s\" as user \"%s\" on address \"%s\" at port \"%s\".\n"),
3118+
PQdb(pset.db),PQuser(pset.db),hostaddr,PQport(pset.db));
3119+
else
3120+
printf(_("You are now connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
3121+
PQdb(pset.db),PQuser(pset.db),host,PQport(pset.db));
3122+
}
30793123
else
3080-
printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3081-
PQdb(pset.db),PQuser(pset.db),host,PQport(pset.db));
3124+
{
3125+
if (hostaddr&&*hostaddr&&strcmp(host,hostaddr)!=0)
3126+
printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" (address \"%s\") at port \"%s\".\n"),
3127+
PQdb(pset.db),PQuser(pset.db),host,hostaddr,PQport(pset.db));
3128+
else
3129+
printf(_("You are now connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
3130+
PQdb(pset.db),PQuser(pset.db),host,PQport(pset.db));
3131+
}
30823132
}
30833133
else
30843134
printf(_("You are now connected to database \"%s\" as user \"%s\".\n"),

‎src/interfaces/libpq/exports.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,4 @@ PQsetErrorContextVisibility 170
173173
PQresultVerboseErrorMessage 171
174174
PQencryptPasswordConn 172
175175
PQresultMemorySize 173
176+
PQhostaddr 174

‎src/interfaces/libpq/fe-connect.c

Lines changed: 73 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,39 @@ connectNoDelay(PGconn *conn)
14711471
return1;
14721472
}
14731473

1474+
/* ----------
1475+
* Write currently connected IP address into host_addr (of len host_addr_len).
1476+
* If unable to, set it to the empty string.
1477+
* ----------
1478+
*/
1479+
staticvoid
1480+
getHostaddr(PGconn*conn,char*host_addr,inthost_addr_len)
1481+
{
1482+
structsockaddr_storage*addr=&conn->raddr.addr;
1483+
1484+
if (conn->connhost[conn->whichhost].type==CHT_HOST_ADDRESS)
1485+
strlcpy(host_addr,conn->connhost[conn->whichhost].hostaddr,host_addr_len);
1486+
elseif (addr->ss_family==AF_INET)
1487+
{
1488+
if (inet_net_ntop(AF_INET,
1489+
&((structsockaddr_in*)addr)->sin_addr.s_addr,
1490+
32,
1491+
host_addr,host_addr_len)==NULL)
1492+
host_addr[0]='\0';
1493+
}
1494+
#ifdefHAVE_IPV6
1495+
elseif (addr->ss_family==AF_INET6)
1496+
{
1497+
if (inet_net_ntop(AF_INET6,
1498+
&((structsockaddr_in6*)addr)->sin6_addr.s6_addr,
1499+
128,
1500+
host_addr,host_addr_len)==NULL)
1501+
host_addr[0]='\0';
1502+
}
1503+
#endif
1504+
else
1505+
host_addr[0]='\0';
1506+
}
14741507

14751508
/* ----------
14761509
* connectFailureMessage -
@@ -1504,34 +1537,12 @@ connectFailureMessage(PGconn *conn, int errorno)
15041537
charhost_addr[NI_MAXHOST];
15051538
constchar*displayed_host;
15061539
constchar*displayed_port;
1507-
structsockaddr_storage*addr=&conn->raddr.addr;
15081540

15091541
/*
15101542
* Optionally display the network address with the hostname. This is
15111543
* useful to distinguish between IPv4 and IPv6 connections.
15121544
*/
1513-
if (conn->connhost[conn->whichhost].type==CHT_HOST_ADDRESS)
1514-
strlcpy(host_addr,conn->connhost[conn->whichhost].hostaddr,NI_MAXHOST);
1515-
elseif (addr->ss_family==AF_INET)
1516-
{
1517-
if (inet_net_ntop(AF_INET,
1518-
&((structsockaddr_in*)addr)->sin_addr.s_addr,
1519-
32,
1520-
host_addr,sizeof(host_addr))==NULL)
1521-
strcpy(host_addr,"???");
1522-
}
1523-
#ifdefHAVE_IPV6
1524-
elseif (addr->ss_family==AF_INET6)
1525-
{
1526-
if (inet_net_ntop(AF_INET6,
1527-
&((structsockaddr_in6*)addr)->sin6_addr.s6_addr,
1528-
128,
1529-
host_addr,sizeof(host_addr))==NULL)
1530-
strcpy(host_addr,"???");
1531-
}
1532-
#endif
1533-
else
1534-
strcpy(host_addr, "???");
1545+
getHostaddr(conn,host_addr,NI_MAXHOST);
15351546

15361547
/* To which host and port were we actually connecting? */
15371548
if (conn->connhost[conn->whichhost].type==CHT_HOST_ADDRESS)
@@ -1548,14 +1559,14 @@ connectFailureMessage(PGconn *conn, int errorno)
15481559
* looked-up IP address.
15491560
*/
15501561
if (conn->connhost[conn->whichhost].type!=CHT_HOST_ADDRESS&&
1562+
strlen(host_addr)>0&&
15511563
strcmp(displayed_host,host_addr)!=0)
15521564
appendPQExpBuffer(&conn->errorMessage,
15531565
libpq_gettext("could not connect to server: %s\n"
15541566
"\tIs the server running on host \"%s\" (%s) and accepting\n"
15551567
"\tTCP/IP connections on port %s?\n"),
15561568
SOCK_STRERROR(errorno,sebuf,sizeof(sebuf)),
1557-
displayed_host,
1558-
host_addr,
1569+
displayed_host,host_addr,
15591570
displayed_port);
15601571
else
15611572
appendPQExpBuffer(&conn->errorMessage,
@@ -2286,6 +2297,7 @@ PQconnectPoll(PGconn *conn)
22862297
*/
22872298
{
22882299
structaddrinfo*addr_cur=conn->addr_cur;
2300+
charhost_addr[NI_MAXHOST];
22892301

22902302
/*
22912303
* Advance to next possible host, if we've tried all of
@@ -2302,6 +2314,21 @@ PQconnectPoll(PGconn *conn)
23022314
addr_cur->ai_addrlen);
23032315
conn->raddr.salen=addr_cur->ai_addrlen;
23042316

2317+
/* set connip */
2318+
if (conn->connip!=NULL)
2319+
{
2320+
free(conn->connip);
2321+
conn->connip=NULL;
2322+
}
2323+
2324+
getHostaddr(conn,host_addr,NI_MAXHOST);
2325+
if (strlen(host_addr)>0)
2326+
conn->connip=strdup(host_addr);
2327+
/*
2328+
* purposely ignore strdup failure; not a big problem if
2329+
* it fails anyway.
2330+
*/
2331+
23052332
conn->sock=socket(addr_cur->ai_family,SOCK_STREAM,0);
23062333
if (conn->sock==PGINVALID_SOCKET)
23072334
{
@@ -3665,6 +3692,8 @@ freePGconn(PGconn *conn)
36653692
free(conn->sslcompression);
36663693
if (conn->requirepeer)
36673694
free(conn->requirepeer);
3695+
if (conn->connip)
3696+
free(conn->connip);
36683697
#if defined(ENABLE_GSS)|| defined(ENABLE_SSPI)
36693698
if (conn->krbsrvname)
36703699
free(conn->krbsrvname);
@@ -6172,6 +6201,25 @@ PQhost(const PGconn *conn)
61726201
return"";
61736202
}
61746203

6204+
char*
6205+
PQhostaddr(constPGconn*conn)
6206+
{
6207+
if (!conn)
6208+
returnNULL;
6209+
6210+
if (conn->connhost!=NULL)
6211+
{
6212+
if (conn->connhost[conn->whichhost].hostaddr!=NULL&&
6213+
conn->connhost[conn->whichhost].hostaddr[0]!='\0')
6214+
returnconn->connhost[conn->whichhost].hostaddr;
6215+
6216+
if (conn->connip!=NULL)
6217+
returnconn->connip;
6218+
}
6219+
6220+
return"";
6221+
}
6222+
61756223
char*
61766224
PQport(constPGconn*conn)
61776225
{

‎src/interfaces/libpq/libpq-fe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ extern char *PQdb(const PGconn *conn);
312312
externchar*PQuser(constPGconn*conn);
313313
externchar*PQpass(constPGconn*conn);
314314
externchar*PQhost(constPGconn*conn);
315+
externchar*PQhostaddr(constPGconn*conn);
315316
externchar*PQport(constPGconn*conn);
316317
externchar*PQtty(constPGconn*conn);
317318
externchar*PQoptions(constPGconn*conn);

‎src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ struct pg_conn
397397
intnconnhost;/* # of hosts named in conn string */
398398
intwhichhost;/* host we're currently trying/connected to */
399399
pg_conn_host*connhost;/* details about each named host */
400+
char*connip;/* IP address for current network connection */
400401

401402
/* Connection data */
402403
pgsocketsock;/* FD for socket, PGINVALID_SOCKET if

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp