Function: inet_client_addr() Args: none Return type: INET (null on AF_UNIX or some catastrophic failure) IPv6 safe: yes
The attached patch includes documentation and the relevant code. If there aren't any problems, I think this patch is ready to be committed.
If someone wants a way to return the path of AF_UNIX connections, I firmly believe that it should live in a similar, but different function, otherwise PL code (or whatever) will have to tease out whether it's a local or remote connection. Not that I think demand is there for it, but if need be, there should be two more functions written: unix_client_addr() and just client_addr(). unix_client_addr() returns TEXT and the path to the socket and client_addr() returns a TEXT wrapped version of whatever is in MyProcPort->remote_host. -sc
Index: src/backend/utils/adt/network.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/network.c,v retrieving revision 1.49 diff -u -r1.49 network.c --- src/backend/utils/adt/network.c 1 Dec 2003 18:50:19 -0000 1.49 +++ src/backend/utils/adt/network.c 14 May 2004 22:04:22 -0000 @@ -14,7 +14,9 @@ #include <arpa/inet.h> #include "catalog/pg_type.h" +#include "libpq/libpq-be.h" #include "libpq/pqformat.h" +#include "miscadmin.h" #include "utils/builtins.h" #include "utils/inet.h" @@ -128,6 +130,26 @@ char *src = PG_GETARG_CSTRING(0); PG_RETURN_INET_P(network_in(src, 1)); +} + +/* INET that the client is connecting from */ +Datum +inet_client_addr(PG_FUNCTION_ARGS) +{ + if (MyProcPort == NULL) + PG_RETURN_NULL(); + + switch (MyProcPort->raddr.addr.ss_family) { + case AF_INET: +#ifdef HAVE_IPV6 + case AF_INET6: +#endif + break; + default: + PG_RETURN_NULL(); + } + + PG_RETURN_INET_P(network_in(MyProcPort->remote_host, 0)); } /* Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/func.sgml,v retrieving revision 1.201 diff -u -r1.201 func.sgml --- doc/src/sgml/func.sgml 10 May 2004 22:44:42 -0000 1.201 +++ doc/src/sgml/func.sgml 14 May 2004 22:04:23 -0000 @@ -6583,6 +6583,12 @@ </row> <row> + <entry><function>inet_client_addr</function></entry> + <entry><type>inet</type></entry> + <entry>address of the remote connection</entry> + </row> + + <row> <entry><function>session_user</function></entry> <entry><type>name</type></entry> <entry>session user name</entry> @@ -6636,6 +6642,14 @@ they must be called without trailing parentheses. </para> </note> + + <para> + <function>inet_client_addr</function> returns the IPv4 or IPv6 + (if configured) address of the host connecting to the database. + If the connection is local and not a network connection, + <function>inet_client_addr</function> returns + <literal>NULL</literal>. + </para> <para> <function>current_schema</function> returns the name of the schema that is Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v retrieving revision 1.328 diff -u -r1.328 pg_proc.h --- src/include/catalog/pg_proc.h 7 May 2004 16:57:16 -0000 1.328 +++ src/include/catalog/pg_proc.h 14 May 2004 22:04:25 -0000 @@ -2343,6 +2343,8 @@ DESCR("I/O"); DATA(insert OID = 911 ( inet_out PGNSP PGUID 12 f f t f i 1 2275 "869" _null_ inet_out - _null_ )); DESCR("I/O"); +DATA(insert OID = 912 ( inet_client_addr PGNSP PGUID 12 f f f f s 0 869 "" _null_ inet_client_addr - _null_ )); +DESCR("Returns the INET address of the client connected to the backend"); /* for cidr type support */ DATA(insert OID = 1267 ( cidr_in PGNSP PGUID 12 f f t f i 1 650 "2275" _null_ cidr_in - _null_ )); Index: src/include/utils/builtins.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v retrieving revision 1.237 diff -u -r1.237 builtins.h --- src/include/utils/builtins.h 5 May 2004 04:48:47 -0000 1.237 +++ src/include/utils/builtins.h 14 May 2004 22:04:25 -0000 @@ -645,6 +645,7 @@ void *dst, size_t size); /* network.c */ +extern Datum inet_client_addr(PG_FUNCTION_ARGS); extern Datum inet_in(PG_FUNCTION_ARGS); extern Datum inet_out(PG_FUNCTION_ARGS); extern Datum inet_recv(PG_FUNCTION_ARGS);
% psql -h 192.168.102.100 template1 template1=# SELECT inet_client_addr(); inet_client_addr ------------------ 192.168.102.100 (1 row)
template1=# \q % echo $PGHOST tcsh: PGHOST: Undefined variable. % psql template1 template1=# SELECT inet_client_addr(); inet_client_addr ------------------
(1 row)
template1=# SELECT inet_client_addr() IS NULL; ?column? ---------- t (1 row)
template1=# \q % psql -h 127.0.0.1 template1 template1=# SELECT inet_client_addr() IS NULL; ?column? ---------- f (1 row)
template1=# SELECT inet_client_addr(); inet_client_addr ------------------ 127.0.0.1 (1 row)
template1=# \q % psql -h localhost template1 template1=# SELECT inet_client_addr(); inet_client_addr ------------------ ::1 (1 row)
-- Sean Chittenden
---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend