mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Temporary fix for the problem that pg_stat_activity, inet_client_addr(),
and inet_server_addr() fail if the client connected over a "scoped" IPv6 address. In this case getnameinfo() will return a string ending with a poorly-standardized "%something" zone specifier, which these functions try to feed to network_in(), which won't take it. So that we don't lose functionality altogether, suppress the zone specifier before giving the string to network_in(). Per report from Brian Hirt. TODO: probably someday the inet type should support scoped IPv6 addresses, and then this patch should be reverted. Backpatch to 8.2 ... is it worth going further?
This commit is contained in:
parent
d42e2b7502
commit
2f6d85101b
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* PostgreSQL type definitions for the INET and CIDR types.
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.66 2006/10/04 00:29:59 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.66.2.1 2007/05/17 23:31:59 tgl Exp $
|
||||
*
|
||||
* Jon Postel RIP 16 Oct 1998
|
||||
*/
|
||||
@ -1138,6 +1138,8 @@ inet_client_addr(PG_FUNCTION_ARGS)
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
|
||||
|
||||
PG_RETURN_INET_P(network_in(remote_host, false));
|
||||
}
|
||||
|
||||
@ -1212,6 +1214,8 @@ inet_server_addr(PG_FUNCTION_ARGS)
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
|
||||
|
||||
PG_RETURN_INET_P(network_in(local_host, false));
|
||||
}
|
||||
|
||||
@ -1483,3 +1487,32 @@ inetmi(PG_FUNCTION_ARGS)
|
||||
|
||||
PG_RETURN_INT64(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* clean_ipv6_addr --- remove any '%zone' part from an IPv6 address string
|
||||
*
|
||||
* XXX This should go away someday!
|
||||
*
|
||||
* This is a kluge needed because we don't yet support zones in stored inet
|
||||
* values. Since the result of getnameinfo() might include a zone spec,
|
||||
* call this to remove it anywhere we want to feed getnameinfo's output to
|
||||
* network_in. Beats failing entirely.
|
||||
*
|
||||
* An alternative approach would be to let network_in ignore %-parts for
|
||||
* itself, but that would mean we'd silently drop zone specs in user input,
|
||||
* which seems not such a good idea.
|
||||
*/
|
||||
void
|
||||
clean_ipv6_addr(int addr_family, char *addr)
|
||||
{
|
||||
#ifdef HAVE_IPV6
|
||||
if (addr_family == AF_INET6)
|
||||
{
|
||||
char *pct = strchr(addr, '%');
|
||||
|
||||
if (pct)
|
||||
*pct = '\0';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.34 2006/10/04 00:29:59 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/pgstatfuncs.c,v 1.34.2.1 2007/05/17 23:31:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -485,6 +485,8 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
|
||||
if (ret)
|
||||
PG_RETURN_NULL();
|
||||
|
||||
clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
|
||||
|
||||
PG_RETURN_INET_P(DirectFunctionCall1(inet_in,
|
||||
CStringGetDatum(remote_host)));
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.282.2.1 2007/01/03 22:39:35 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.282.2.2 2007/05/17 23:31:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -767,6 +767,7 @@ extern Datum inetor(PG_FUNCTION_ARGS);
|
||||
extern Datum inetpl(PG_FUNCTION_ARGS);
|
||||
extern Datum inetmi_int8(PG_FUNCTION_ARGS);
|
||||
extern Datum inetmi(PG_FUNCTION_ARGS);
|
||||
extern void clean_ipv6_addr(int addr_family, char *addr);
|
||||
|
||||
/* mac.c */
|
||||
extern Datum macaddr_in(PG_FUNCTION_ARGS);
|
||||
|
Loading…
Reference in New Issue
Block a user