Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
b4cea00a
Commit
b4cea00a
authored
Jun 12, 2003
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
IPv6 cleanups.
Kurt Roeckx Andrew Dunstan
parent
e5549a27
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
900 additions
and
581 deletions
+900
-581
config/c-library.m4
config/c-library.m4
+16
-5
configure
configure
+65
-0
configure.in
configure.in
+2
-1
src/backend/libpq/auth.c
src/backend/libpq/auth.c
+9
-11
src/backend/libpq/hba.c
src/backend/libpq/hba.c
+146
-59
src/backend/libpq/ip.c
src/backend/libpq/ip.c
+99
-132
src/backend/libpq/pg_hba.conf.sample
src/backend/libpq/pg_hba.conf.sample
+3
-1
src/backend/libpq/pqcomm.c
src/backend/libpq/pqcomm.c
+130
-77
src/backend/postmaster/pgstat.c
src/backend/postmaster/pgstat.c
+43
-18
src/backend/postmaster/postmaster.c
src/backend/postmaster/postmaster.c
+128
-163
src/include/getaddrinfo.h
src/include/getaddrinfo.h
+20
-5
src/include/libpq/ip.h
src/include/libpq/ip.h
+12
-7
src/include/libpq/libpq.h
src/include/libpq/libpq.h
+3
-2
src/include/libpq/pqcomm.h
src/include/libpq/pqcomm.h
+41
-39
src/include/pg_config.h.in
src/include/pg_config.h.in
+6
-0
src/include/pg_config_manual.h
src/include/pg_config_manual.h
+4
-5
src/include/port/bsdi.h
src/include/port/bsdi.h
+0
-4
src/interfaces/libpq/fe-connect.c
src/interfaces/libpq/fe-connect.c
+45
-28
src/interfaces/libpq/libpq-int.h
src/interfaces/libpq/libpq-int.h
+1
-2
src/port/getaddrinfo.c
src/port/getaddrinfo.c
+127
-22
No files found.
config/c-library.m4
View file @
b4cea00a
# Macros that test various C library quirks
# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.
19 2003/05/22 16:39:26 tgl
Exp $
# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.
20 2003/06/12 07:36:51 momjian
Exp $
# PGAC_VAR_INT_TIMEZONE
...
...
@@ -87,11 +87,10 @@ AC_DEFUN([PGAC_UNION_SEMUN],
# PGAC_STRUCT_SOCKADDR_UN
# -----------------------
# If `struct sockaddr_un' exists, define HAVE_STRUCT_SOCKADDR_UN. If
# it is missing then one could define it as { short int sun_family;
# char sun_path[108]; }. (Requires test for <sys/un.h>!)
# If `struct sockaddr_un' exists, define HAVE_UNIX_SOCKETS.
# (Requires test for <sys/un.h>!)
AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN],
[AC_CHECK_TYPES([struct sockaddr_un], [], [],
[AC_CHECK_TYPES([struct sockaddr_un], [
AC_DEFINE(HAVE_UNIX_SOCKETS, 1, [Define to 1 if you have unix sockets.])
], [],
[#include <sys/types.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
...
...
@@ -99,6 +98,18 @@ AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN],
])])# PGAC_STRUCT_SOCKADDR_UN
# PGAC_STRUCT_SOCKADDR_STORAGE
# ----------------------------
# If `struct sockaddr_storage' exists, define HAVE_STRUCT_SOCKADDR_STORAGE. If
# it is missing then one could define it.
AC_DEFUN([PGAC_STRUCT_SOCKADDR_STORAGE],
[AC_CHECK_TYPES([struct sockaddr_storage], [], [],
[#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
])])# PGAC_STRUCT_SOCKADDR_STORAGE
# PGAC_STRUCT_ADDRINFO
# -----------------------
# If `struct addrinfo' exists, define HAVE_STRUCT_ADDRINFO.
...
...
configure
View file @
b4cea00a
...
...
@@ -9892,6 +9892,71 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
cat
>>
confdefs.h
<<
\
_ACEOF
#define HAVE_UNIX_SOCKETS 1
_ACEOF
fi
echo
"
$as_me
:
$LINENO
: checking for struct sockaddr_storage"
>
&5
echo
$ECHO_N
"checking for struct sockaddr_storage...
$ECHO_C
"
>
&6
if
test
"
${
ac_cv_type_struct_sockaddr_storage
+set
}
"
=
set
;
then
echo
$ECHO_N
"(cached)
$ECHO_C
"
>
&6
else
cat
>
conftest.
$ac_ext
<<
_ACEOF
#line
$LINENO
"configure"
#include "confdefs.h"
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int
main ()
{
if ((struct sockaddr_storage *) 0)
return 0;
if (sizeof (struct sockaddr_storage))
return 0;
;
return 0;
}
_ACEOF
rm
-f
conftest.
$ac_objext
if
{
(
eval echo
"
$as_me
:
$LINENO
:
\"
$ac_compile
\"
"
)
>
&5
(
eval
$ac_compile
)
2>&5
ac_status
=
$?
echo
"
$as_me
:
$LINENO
:
\$
? =
$ac_status
"
>
&5
(
exit
$ac_status
)
;
}
&&
{
ac_try
=
'test -s conftest.$ac_objext'
{
(
eval echo
"
$as_me
:
$LINENO
:
\"
$ac_try
\"
"
)
>
&5
(
eval
$ac_try
)
2>&5
ac_status
=
$?
echo
"
$as_me
:
$LINENO
:
\$
? =
$ac_status
"
>
&5
(
exit
$ac_status
)
;
}
;
}
;
then
ac_cv_type_struct_sockaddr_storage
=
yes
else
echo
"
$as_me
: failed program was:"
>
&5
cat
conftest.
$ac_ext
>
&5
ac_cv_type_struct_sockaddr_storage
=
no
fi
rm
-f
conftest.
$ac_objext
conftest.
$ac_ext
fi
echo
"
$as_me
:
$LINENO
: result:
$ac_cv_type_struct_sockaddr_storage
"
>
&5
echo
"
${
ECHO_T
}
$ac_cv_type_struct_sockaddr_storage
"
>
&6
if
test
$ac_cv_type_struct_sockaddr_storage
=
yes
;
then
cat
>>
confdefs.h
<<
_ACEOF
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
_ACEOF
fi
echo
"
$as_me
:
$LINENO
: checking for struct addrinfo"
>
&5
...
...
configure.in
View file @
b4cea00a
dnl Process this file with autoconf to produce a configure script.
dnl $Header: /cvsroot/pgsql/configure.in,v 1.25
8 2003/06/11 06:56:06
momjian Exp $
dnl $Header: /cvsroot/pgsql/configure.in,v 1.25
9 2003/06/12 07:36:50
momjian Exp $
dnl
dnl Developers, please strive to achieve this order:
dnl
...
...
@@ -789,6 +789,7 @@ PGAC_C_FUNCNAME_SUPPORT
PGAC_STRUCT_TIMEZONE
PGAC_UNION_SEMUN
PGAC_STRUCT_SOCKADDR_UN
PGAC_STRUCT_SOCKADDR_STORAGE
PGAC_STRUCT_ADDRINFO
AC_CHECK_TYPES([struct cmsgcred, struct fcred, struct sockcred], [], [],
...
...
src/backend/libpq/auth.c
View file @
b4cea00a
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.10
1 2003/04/25 03:28:55 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.10
2 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -415,15 +415,13 @@ ClientAuthentication(Port *port)
* out the less clueful good guys.
*/
{
const
char
*
hostinfo
=
"localhost"
;
#ifdef HAVE_IPV6
char
ip_hostinfo
[
INET6_ADDRSTRLEN
];
#else
char
ip_hostinfo
[
INET_ADDRSTRLEN
];
#endif
if
(
isAF_INETx
(
port
->
raddr
.
sa
.
sa_family
)
)
hostinfo
=
SockAddr_ntop
(
&
port
->
raddr
,
ip_hostinfo
,
sizeof
(
ip_hostinfo
),
1
);
char
hostinfo
[
NI_MAXHOST
];
getnameinfo
(
(
struct
sockaddr
*
)
&
port
->
raddr
.
addr
,
port
->
raddr
.
salen
,
hostinfo
,
sizeof
(
hostinfo
),
NULL
,
0
,
NI_NUMERICHOST
);
elog
(
FATAL
,
"No pg_hba.conf entry for host %s, user %s, database %s"
,
...
...
@@ -464,7 +462,7 @@ ClientAuthentication(Port *port)
elog
(
FATAL
,
"pg_local_sendauth: can't do setsockopt: %m"
);
}
#endif
if
(
port
->
raddr
.
sa
.
sa
_family
==
AF_UNIX
)
if
(
port
->
raddr
.
addr
.
ss
_family
==
AF_UNIX
)
sendAuthRequest
(
port
,
AUTH_REQ_SCM_CREDS
);
#endif
status
=
authident
(
port
);
...
...
src/backend/libpq/hba.c
View file @
b4cea00a
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.10
2 2003/06/12 07:00:57
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.10
3 2003/06/12 07:36:51
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -545,6 +545,11 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
char
*
token
;
char
*
db
;
char
*
user
;
struct
addrinfo
*
file_ip_addr
=
NULL
,
*
file_ip_mask
=
NULL
;
struct
addrinfo
hints
;
struct
sockaddr_storage
*
mask
;
char
*
cidr_slash
;
int
ret
;
Assert
(
line
!=
NIL
);
line_number
=
lfirsti
(
line
);
...
...
@@ -582,12 +587,11 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
port
->
auth_method
==
uaKrb5
)
goto
hba_syntax
;
if
(
port
->
raddr
.
sa
.
sa
_family
!=
AF_UNIX
)
if
(
port
->
raddr
.
addr
.
ss
_family
!=
AF_UNIX
)
return
;
}
else
if
(
strcmp
(
token
,
"host"
)
==
0
||
strcmp
(
token
,
"hostssl"
)
==
0
)
{
SockAddr
file_ip_addr
,
mask
;
if
(
strcmp
(
token
,
"hostssl"
)
==
0
)
{
...
...
@@ -618,26 +622,77 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto
hba_syntax
;
user
=
lfirst
(
line
);
/* Read the IP address field. */
/* Read the IP address field.
(with or without CIDR netmask)
*/
line
=
lnext
(
line
);
if
(
!
line
)
goto
hba_syntax
;
token
=
lfirst
(
line
);
if
(
SockAddr_pton
(
&
file_ip_addr
,
token
)
<
0
)
/* Check if it has a CIDR suffix and if so isolate it */
cidr_slash
=
index
(
token
,
'/'
);
if
(
cidr_slash
)
{
*
cidr_slash
=
'\0'
;
}
hints
.
ai_flags
=
AI_NUMERICHOST
;
hints
.
ai_family
=
PF_UNSPEC
;
hints
.
ai_socktype
=
0
;
hints
.
ai_protocol
=
0
;
hints
.
ai_addrlen
=
0
;
hints
.
ai_canonname
=
NULL
;
hints
.
ai_addr
=
NULL
;
hints
.
ai_next
=
NULL
;
/* Get the IP address either way */
ret
=
getaddrinfo2
(
token
,
NULL
,
&
hints
,
&
file_ip_addr
);
if
(
ret
)
{
elog
(
LOG
,
"getaddrinfo2() returned %d"
,
ret
);
if
(
cidr_slash
)
{
*
cidr_slash
=
'/'
;
}
goto
hba_syntax
;
}
if
(
file_ip_addr
->
ai_family
!=
port
->
raddr
.
addr
.
ss_family
)
{
/* Wrong address family. */
freeaddrinfo2
(
hints
.
ai_family
,
file_ip_addr
);
return
;
}
/* Get the netmask */
if
(
cidr_slash
)
{
*
cidr_slash
=
'/'
;
if
(
SockAddr_cidr_mask
(
&
mask
,
cidr_slash
+
1
,
file_ip_addr
->
ai_family
)
<
0
)
{
goto
hba_syntax
;
}
}
else
{
/* Read the mask field. */
line
=
lnext
(
line
);
if
(
!
line
)
goto
hba_syntax
;
token
=
lfirst
(
line
);
if
(
SockAddr_pton
(
&
mask
,
token
)
<
0
)
ret
=
getaddrinfo2
(
token
,
NULL
,
&
hints
,
&
file_ip_mask
);
if
(
ret
)
{
goto
hba_syntax
;
}
mask
=
(
struct
sockaddr_storage
*
)
file_ip_mask
->
ai_addr
;
if
(
file_ip_addr
.
sa
.
sa_family
!=
mask
.
sa
.
sa_family
)
if
(
file_ip_addr
->
ai_family
!=
mask
->
ss_family
)
{
goto
hba_syntax
;
}
}
/* Read the rest of the line. */
line
=
lnext
(
line
);
...
...
@@ -648,9 +703,16 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto
hba_syntax
;
/* Must meet network restrictions */
if
(
!
isAF_INETx
(
port
->
raddr
.
sa
.
sa_family
)
||
!
rangeSockAddr
(
&
port
->
raddr
,
&
file_ip_addr
,
&
mask
))
return
;
if
(
!
rangeSockAddr
(
&
port
->
raddr
.
addr
,
(
struct
sockaddr_storage
*
)
file_ip_addr
->
ai_addr
,
mask
))
{
goto
hba_freeaddr
;
}
freeaddrinfo2
(
hints
.
ai_family
,
file_ip_addr
);
if
(
file_ip_mask
)
{
freeaddrinfo2
(
hints
.
ai_family
,
file_ip_mask
);
}
}
else
goto
hba_syntax
;
...
...
@@ -670,6 +732,16 @@ hba_syntax:
line
?
(
const
char
*
)
lfirst
(
line
)
:
"(end of line)"
);
*
error_p
=
true
;
hba_freeaddr:
if
(
file_ip_addr
)
{
freeaddrinfo2
(
hints
.
ai_family
,
file_ip_addr
);
}
if
(
file_ip_mask
)
{
freeaddrinfo2
(
hints
.
ai_family
,
file_ip_mask
);
}
return
;
}
...
...
@@ -1106,10 +1178,8 @@ interpret_ident_response(char *ident_response,
* But iff we're unable to get the information from ident, return false.
*/
static
bool
ident_inet
(
const
struct
in_addr
remote_ip_addr
,
const
struct
in_addr
local_ip_addr
,
const
ushort
remote_port
,
const
ushort
local_port
,
ident_inet
(
const
SockAddr
remote_addr
,
const
SockAddr
local_addr
,
char
*
ident_user
)
{
int
sock_fd
,
/* File descriptor for socket on which we
...
...
@@ -1117,8 +1187,39 @@ ident_inet(const struct in_addr remote_ip_addr,
rc
;
/* Return code from a locally called
* function */
bool
ident_return
;
char
remote_addr_s
[
NI_MAXHOST
];
char
remote_port
[
NI_MAXSERV
];
char
local_addr_s
[
NI_MAXHOST
];
char
local_port
[
NI_MAXSERV
];
char
ident_port
[
NI_MAXSERV
];
struct
addrinfo
*
ident_serv
=
NULL
,
*
la
=
NULL
,
hints
;
/* Might look a little weird to first convert it to text and
* then back to sockaddr, but it's protocol indepedant. */
getnameinfo
((
struct
sockaddr
*
)
&
remote_addr
.
addr
,
remote_addr
.
salen
,
remote_addr_s
,
sizeof
(
remote_addr_s
),
remote_port
,
sizeof
(
remote_port
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
getnameinfo
((
struct
sockaddr
*
)
&
local_addr
.
addr
,
local_addr
.
salen
,
local_addr_s
,
sizeof
(
local_addr_s
),
local_port
,
sizeof
(
local_port
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
snprintf
(
ident_port
,
sizeof
(
ident_port
),
"%d"
,
IDENT_PORT
);
hints
.
ai_flags
=
AI_NUMERICHOST
;
hints
.
ai_family
=
remote_addr
.
addr
.
ss_family
;
hints
.
ai_socktype
=
SOCK_STREAM
;
hints
.
ai_protocol
=
0
;
hints
.
ai_addrlen
=
0
;
hints
.
ai_canonname
=
NULL
;
hints
.
ai_addr
=
NULL
;
hints
.
ai_next
=
NULL
;
getaddrinfo2
(
remote_addr_s
,
ident_port
,
&
hints
,
&
ident_serv
);
getaddrinfo2
(
local_addr_s
,
NULL
,
&
hints
,
&
la
);
sock_fd
=
socket
(
ident_serv
->
ai_family
,
ident_serv
->
ai_socktype
,
ident_serv
->
ai_protocol
);
sock_fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
IPPROTO_IP
);
if
(
sock_fd
==
-
1
)
{
elog
(
LOG
,
"Failed to create socket on which to talk to Ident server: %m"
);
...
...
@@ -1126,42 +1227,27 @@ ident_inet(const struct in_addr remote_ip_addr,
}
else
{
struct
sockaddr_in
ident_server
;
struct
sockaddr_in
la
;
/*
* Socket address of Ident server on the system from which client
* is attempting to connect to us.
*/
ident_server
.
sin_family
=
AF_INET
;
ident_server
.
sin_port
=
htons
(
IDENT_PORT
);
ident_server
.
sin_addr
=
remote_ip_addr
;
/*
* Bind to the address which the client originally contacted,
* otherwise the ident server won't be able to match up the right
* connection. This is necessary if the PostgreSQL server is
* running on an IP alias.
*/
memset
(
&
la
,
0
,
sizeof
(
la
));
la
.
sin_family
=
AF_INET
;
la
.
sin_addr
=
local_ip_addr
;
rc
=
bind
(
sock_fd
,
(
struct
sockaddr
*
)
&
la
,
sizeof
(
la
));
rc
=
bind
(
sock_fd
,
la
->
ai_addr
,
la
->
ai_addrlen
);
if
(
rc
==
0
)
{
rc
=
connect
(
sock_fd
,
(
struct
sockaddr
*
)
&
ident_server
,
sizeof
(
ident_server
)
);
rc
=
connect
(
sock_fd
,
ident_serv
->
ai_addr
,
ident_serv
->
ai_addrlen
);
}
if
(
rc
!=
0
)
{
/* save_errno is in case inet_ntoa changes errno */
int
save_errno
=
errno
;
elog
(
LOG
,
"Unable to connect to Ident server on the host which is "
"trying to connect to Postgres "
"(IP address %s, Port %d): %s"
,
inet_ntoa
(
remote_ip_addr
),
IDENT_PORT
,
strerror
(
save_errno
));
"(Address %s, Port %s): %s"
,
remote_addr_s
,
ident_port
,
strerror
(
save_errno
));
ident_return
=
false
;
}
else
...
...
@@ -1169,8 +1255,8 @@ ident_inet(const struct in_addr remote_ip_addr,
char
ident_query
[
80
];
/* The query we send to the Ident server */
snprintf
(
ident_query
,
sizeof
(
ident_query
),
"%
d,%d
\n
"
,
ntohs
(
remote_port
),
ntohs
(
local_port
)
);
snprintf
(
ident_query
,
sizeof
(
ident_query
),
"%
s,%s
\r
\n
"
,
remote_port
,
local_port
);
/* loop in case send is interrupted */
do
{
...
...
@@ -1181,10 +1267,9 @@ ident_inet(const struct in_addr remote_ip_addr,
int
save_errno
=
errno
;
elog
(
LOG
,
"Unable to send query to Ident server on the host which is "
"trying to connect to Postgres (Host %s, Port %
d
), "
"trying to connect to Postgres (Host %s, Port %
s
), "
"even though we successfully connected to it: %s"
,
inet_ntoa
(
remote_ip_addr
),
IDENT_PORT
,
strerror
(
save_errno
));
remote_addr_s
,
ident_port
,
strerror
(
save_errno
));
ident_return
=
false
;
}
else
...
...
@@ -1199,9 +1284,9 @@ ident_inet(const struct in_addr remote_ip_addr,
elog
(
LOG
,
"Unable to receive response from Ident server "
"on the host which is "
"trying to connect to Postgres (Host %s, Port %
d
), "
"trying to connect to Postgres (Host %s, Port %
s
), "
"even though we successfully sent our query to it: %s"
,
inet_ntoa
(
remote_ip_addr
),
IDENT_PORT
,
remote_addr_s
,
ident_port
,
strerror
(
save_errno
));
ident_return
=
false
;
}
...
...
@@ -1215,6 +1300,8 @@ ident_inet(const struct in_addr remote_ip_addr,
closesocket
(
sock_fd
);
}
}
freeaddrinfo2
(
hints
.
ai_family
,
la
);
freeaddrinfo2
(
hints
.
ai_family
,
ident_serv
);
return
ident_return
;
}
...
...
@@ -1371,13 +1458,13 @@ authident(hbaPort *port)
{
char
ident_user
[
IDENT_USERNAME_MAX
+
1
];
switch
(
port
->
raddr
.
sa
.
sa
_family
)
switch
(
port
->
raddr
.
addr
.
ss
_family
)
{
case
AF_INET
:
if
(
!
ident_inet
(
port
->
raddr
.
in
.
sin_addr
,
port
->
laddr
.
in
.
sin_addr
,
port
->
raddr
.
in
.
sin_port
,
port
->
laddr
.
in
.
sin_port
,
ident_user
))
#ifdef HAVE_IPV6
case
AF_INET6
:
#endif
if
(
!
ident_inet
(
port
->
raddr
,
port
->
laddr
,
ident_user
))
return
STATUS_ERROR
;
break
;
case
AF_UNIX
:
...
...
src/backend/libpq/ip.c
View file @
b4cea00a
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.1
1 2003/06/12 07:00:57
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.1
2 2003/06/12 07:36:51
momjian Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
...
...
@@ -36,19 +36,18 @@
#include "libpq/ip.h"
static
int
rangeSockAddrAF_INET
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
);
static
int
rangeSockAddrAF_INET
(
const
struct
sockaddr_in
*
addr
,
const
struct
sockaddr_in
*
netaddr
,
const
struct
sockaddr_in
*
netmask
);
#ifdef HAVE_IPV6
static
int
rangeSockAddrAF_INET6
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
);
static
void
convSockAddr6to4
(
const
SockAddr
*
src
,
SockAddr
*
dst
);
static
int
rangeSockAddrAF_INET6
(
const
struct
sockaddr_in6
*
addr
,
const
struct
sockaddr_in6
*
netaddr
,
const
struct
sockaddr_in6
*
netmask
);
#endif
#ifdef HAVE_UNIX_SOCKETS
static
int
getaddrinfo_unix
(
const
char
*
path
,
const
struct
addrinfo
*
hintsp
,
static
int
getaddrinfo_unix
(
const
char
*
path
,
const
struct
addrinfo
*
hintsp
,
struct
addrinfo
**
result
);
#endif
...
...
@@ -127,6 +126,11 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
MemSet
(
&
hints
,
0
,
sizeof
(
hints
));
if
(
strlen
(
path
)
>=
sizeof
(
unp
->
sun_path
))
{
return
EAI_FAIL
;
}
if
(
hintsp
==
NULL
)
{
hints
.
ai_family
=
AF_UNIX
;
...
...
@@ -141,7 +145,7 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
if
(
hints
.
ai_family
!=
AF_UNIX
)
{
/* shouldn't have been called */
return
EAI_
ADDRFAMILY
;
return
EAI_
FAIL
;
}
aip
=
calloc
(
1
,
sizeof
(
struct
addrinfo
));
...
...
@@ -166,8 +170,6 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
aip
->
ai_addr
=
(
struct
sockaddr
*
)
unp
;
aip
->
ai_addrlen
=
sizeof
(
struct
sockaddr_un
);
if
(
strlen
(
path
)
>=
sizeof
(
unp
->
sun_path
))
return
EAI_SERVICE
;
strcpy
(
unp
->
sun_path
,
path
);
#if SALEN
...
...
@@ -178,121 +180,110 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
}
#endif
/* HAVE_UNIX_SOCKETS */
/* ----------
* SockAddr_ntop - set IP address string from SockAddr
*
* parameters... sa : SockAddr union
* dst : buffer for address string
* cnt : sizeof dst
* v4conv: non-zero: if address is IPv4 mapped IPv6 address then
* convert to IPv4 address.
* returns... pointer to dst
* if sa.sa_family is not AF_INET or AF_INET6 dst is set as empy string.
* ----------
*/
char
*
SockAddr_ntop
(
const
SockAddr
*
sa
,
char
*
dst
,
size_t
cnt
,
int
v4conv
)
int
rangeSockAddr
(
const
struct
sockaddr_storage
*
addr
,
const
struct
sockaddr_storage
*
netaddr
,
const
struct
sockaddr_storage
*
netmask
)
{
switch
(
sa
->
sa
.
sa_family
)
{
case
AF_INET
:
#ifdef HAVE_IPV6
inet_ntop
(
AF_INET
,
&
sa
->
in
.
sin_addr
,
dst
,
cnt
);
#else
StrNCpy
(
dst
,
inet_ntoa
(
sa
->
in
.
sin_addr
),
cnt
);
#endif
break
;
if
(
addr
->
ss_family
==
AF_INET
)
return
rangeSockAddrAF_INET
((
struct
sockaddr_in
*
)
addr
,
(
struct
sockaddr_in
*
)
netaddr
,
(
struct
sockaddr_in
*
)
netmask
);
#ifdef HAVE_IPV6
case
AF_INET6
:
inet_ntop
(
AF_INET6
,
&
sa
->
in6
.
sin6_addr
,
dst
,
cnt
);
if
(
v4conv
&&
IN6_IS_ADDR_V4MAPPED
(
&
sa
->
in6
.
sin6_addr
))
strcpy
(
dst
,
dst
+
7
);
break
;
else
if
(
addr
->
ss_family
==
AF_INET6
)
return
rangeSockAddrAF_INET6
((
struct
sockaddr_in6
*
)
addr
,
(
struct
sockaddr_in6
*
)
netaddr
,
(
struct
sockaddr_in6
*
)
netmask
);
#endif
default:
dst
[
0
]
=
'\0'
;
break
;
}
return
dst
;
else
return
0
;
}
/*
* SockAddr_pton - IPv6 pton
* SockAddr_cidr_mask - make a network mask of the appropriate family
* and required number of significant bits
*
* Note: Returns a static pointer for the mask, so it's not thread safe,
* and a second call will overwrite the data.
*/
int
SockAddr_
pton
(
SockAddr
*
sa
,
const
char
*
src
)
SockAddr_
cidr_mask
(
struct
sockaddr_storage
**
mask
,
char
*
numbits
,
int
family
)
{
int
family
=
AF_INET
;
long
bits
;
char
*
endptr
;
static
struct
sockaddr_storage
sock
;
struct
sockaddr_in
mask4
;
#ifdef HAVE_IPV6
if
(
strchr
(
src
,
':'
))
family
=
AF_INET6
;
struct
sockaddr_in6
mask6
;
#endif
sa
->
sa
.
sa_family
=
family
;
bits
=
strtol
(
numbits
,
&
endptr
,
10
)
;
switch
(
family
)
if
(
*
numbits
==
'\0'
||
*
endptr
!=
'\0'
)
{
case
AF_INET
:
return
-
1
;
}
if
((
bits
<
0
)
||
(
family
==
AF_INET
&&
bits
>
32
)
#ifdef HAVE_IPV6
return
inet_pton
(
AF_INET
,
src
,
&
sa
->
in
.
sin_addr
);
#else
return
inet_aton
(
src
,
&
sa
->
in
.
sin_addr
);
||
(
family
==
AF_INET6
&&
bits
>
128
)
#endif
)
{
return
-
1
;
}
*
mask
=
&
sock
;
switch
(
family
)
{
case
AF_INET
:
mask4
.
sin_addr
.
s_addr
=
htonl
((
0xffffffffUL
<<
(
32
-
bits
))
&
0xffffffffUL
);
memcpy
(
&
sock
,
&
mask4
,
sizeof
(
mask4
));
break
;
#ifdef HAVE_IPV6
case
AF_INET6
:
return
inet_pton
(
AF_INET6
,
src
,
&
sa
->
in6
.
sin6_addr
);
{
int
i
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(
bits
<=
0
)
{
mask6
.
sin6_addr
.
s6_addr
[
i
]
=
0
;
}
else
if
(
bits
>=
8
)
{
mask6
.
sin6_addr
.
s6_addr
[
i
]
=
0xff
;
}
else
{
mask6
.
sin6_addr
.
s6_addr
[
i
]
=
(
0xff
<<
(
8
-
bits
))
&
0xff
;
}
bits
-=
8
;
}
memcpy
(
&
sock
,
&
mask6
,
sizeof
(
mask6
));
break
;
}
#endif
default:
return
-
1
;
}
}
/*
* isAF_INETx - check to see if sa is AF_INET or AF_INET6
*/
int
isAF_INETx
(
const
int
family
)
{
if
(
family
==
AF_INET
#ifdef HAVE_IPV6
||
family
==
AF_INET6
#endif
)
return
1
;
else
sock
.
ss_family
=
family
;
return
0
;
}
int
rangeSockAddr
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
)
rangeSockAddr
AF_INET
(
const
struct
sockaddr_in
*
addr
,
const
struct
sockaddr_in
*
netaddr
,
const
struct
sockaddr_in
*
netmask
)
{
if
(
addr
->
sa
.
sa_family
==
AF_INET
)
return
rangeSockAddrAF_INET
(
addr
,
netaddr
,
netmask
);
#ifdef HAVE_IPV6
else
if
(
addr
->
sa
.
sa_family
==
AF_INET6
)
return
rangeSockAddrAF_INET6
(
addr
,
netaddr
,
netmask
);
#endif
else
return
0
;
}
static
int
rangeSockAddrAF_INET
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
)
{
if
(
addr
->
sa
.
sa_family
!=
AF_INET
||
netaddr
->
sa
.
sa_family
!=
AF_INET
||
netmask
->
sa
.
sa_family
!=
AF_INET
)
return
0
;
if
(((
addr
->
in
.
sin_addr
.
s_addr
^
netaddr
->
in
.
sin_addr
.
s_addr
)
&
netmask
->
in
.
sin_addr
.
s_addr
)
==
0
)
if
(((
addr
->
sin_addr
.
s_addr
^
netaddr
->
sin_addr
.
s_addr
)
&
netmask
->
sin_addr
.
s_addr
)
==
0
)
return
1
;
else
return
0
;
...
...
@@ -300,46 +291,22 @@ rangeSockAddrAF_INET(const SockAddr *addr, const SockAddr *netaddr,
#ifdef HAVE_IPV6
static
int
rangeSockAddrAF_INET6
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
)
int
rangeSockAddrAF_INET6
(
const
struct
sockaddr_in6
*
addr
,
const
struct
sockaddr_in6
*
netaddr
,
const
struct
sockaddr_in6
*
netmask
)
{
int
i
;
if
(
IN6_IS_ADDR_V4MAPPED
(
&
addr
->
in6
.
sin6_addr
))
{
SockAddr
addr4
;
convSockAddr6to4
(
addr
,
&
addr4
);
if
(
rangeSockAddrAF_INET
(
&
addr4
,
netaddr
,
netmask
))
return
1
;
}
if
(
netaddr
->
sa
.
sa_family
!=
AF_INET6
||
netmask
->
sa
.
sa_family
!=
AF_INET6
)
return
0
;
for
(
i
=
0
;
i
<
16
;
i
++
)
{
if
(((
addr
->
in6
.
sin6_addr
.
s6_addr
[
i
]
^
netaddr
->
in6
.
sin6_addr
.
s6_addr
[
i
])
&
netmask
->
in6
.
sin6_addr
.
s6_addr
[
i
])
!=
0
)
if
(((
addr
->
sin6_addr
.
s6_addr
[
i
]
^
netaddr
->
sin6_addr
.
s6_addr
[
i
])
&
netmask
->
sin6_addr
.
s6_addr
[
i
])
!=
0
)
return
0
;
}
return
1
;
}
#endif
static
void
convSockAddr6to4
(
const
SockAddr
*
src
,
SockAddr
*
dst
)
{
MemSet
(
dst
,
0
,
sizeof
(
*
dst
));
dst
->
in
.
sin_family
=
AF_INET
;
/* both src and dst are assumed to be in network byte order */
dst
->
in
.
sin_port
=
src
->
in6
.
sin6_port
;
memcpy
(
&
dst
->
in
.
sin_addr
.
s_addr
,
((
char
*
)
(
&
src
->
in6
.
sin6_addr
.
s6_addr
))
+
12
,
sizeof
(
struct
in_addr
));
}
#endif
/* HAVE_IPV6 */
src/backend/libpq/pg_hba.conf.sample
View file @
b4cea00a
...
...
@@ -46,4 +46,6 @@
local all all trust
host all all 127.0.0.1 255.255.255.255 trust
host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff trust
host all all ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff trust
host all all ::ffff:127.0.0.1/128 trust
src/backend/libpq/pqcomm.c
View file @
b4cea00a
...
...
@@ -30,7 +30,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.15
6 2003/06/09 17:59:19 tgl
Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.15
7 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -199,7 +199,7 @@ StreamDoUnlink(void)
int
StreamServerPort
(
int
family
,
char
*
hostName
,
unsigned
short
portNumber
,
char
*
unixSocketName
,
int
*
fdP
)
char
*
unixSocketName
,
int
ListenSocket
[],
int
MaxListen
)
{
int
fd
,
err
;
...
...
@@ -208,24 +208,21 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
int
ret
;
char
portNumberStr
[
64
];
char
*
service
;
struct
addrinfo
*
addrs
=
NULL
;
struct
addrinfo
*
addrs
=
NULL
,
*
addr
;
struct
addrinfo
hint
;
#ifdef HAVE_UNIX_SOCKETS
Assert
(
family
==
AF_UNIX
||
isAF_INETx
(
family
));
#else
Assert
(
isAF_INETx
(
family
));
#endif
int
listen_index
=
0
;
int
added
=
0
;
/* Initialize hint structure */
MemSet
(
&
hint
,
0
,
sizeof
(
hint
));
hint
.
ai_family
=
family
;
hint
.
ai_flags
=
AI_PASSIVE
;
hint
.
ai_flags
=
AI_PASSIVE
|
AI_ADDRCONFIG
;
hint
.
ai_socktype
=
SOCK_STREAM
;
#ifdef HAVE_UNIX_SOCKETS
if
(
family
==
AF_UNIX
)
{
/* Lock_AF_UNIX will also fill in sock_path. */
if
(
Lock_AF_UNIX
(
portNumber
,
unixSocketName
)
!=
STATUS_OK
)
return
STATUS_ERROR
;
service
=
sock_path
;
...
...
@@ -246,57 +243,109 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
return
STATUS_ERROR
;
}
if
((
fd
=
socket
(
family
,
SOCK_STREAM
,
0
))
<
0
)
for
(
addr
=
addrs
;
addr
;
addr
=
addr
->
ai_next
)
{
if
(
!
IS_AF_UNIX
(
family
)
&&
IS_AF_UNIX
(
addr
->
ai_family
))
{
/* Only set up a unix domain socket when
* they really asked for it. The service/port
* is different in that case. */
continue
;
}
/* See if there is still room to add 1 more socket. */
for
(;
listen_index
<
MaxListen
;
listen_index
++
)
{
if
(
ListenSocket
[
listen_index
]
==
-
1
)
{
break
;
}
}
if
(
listen_index
==
MaxListen
)
{
/* Nothing found. */
break
;
}
if
((
fd
=
socket
(
addr
->
ai_family
,
addr
->
ai_socktype
,
addr
->
ai_protocol
))
<
0
)
{
elog
(
LOG
,
"server socket failure: socket(): %s"
,
strerror
(
errno
));
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
return
STATUS_ERROR
;
continue
;
}
if
(
isAF_INETx
(
family
))
if
(
!
IS_AF_UNIX
(
addr
->
ai_family
))
{
if
((
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
one
,
sizeof
(
one
)))
==
-
1
)
if
((
setsockopt
(
fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
(
char
*
)
&
one
,
sizeof
(
one
)))
==
-
1
)
{
elog
(
LOG
,
"server socket failure: setsockopt(SO_REUSEADDR): %s"
,
elog
(
LOG
,
"server socket failure: "
"setsockopt(SO_REUSEADDR): %s"
,
strerror
(
errno
));
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
return
STATUS_ERROR
;
closesocket
(
fd
);
continue
;
}
}
#ifdef IPV6_V6ONLY
if
(
addr
->
ai_family
==
AF_INET6
)
{
if
(
setsockopt
(
fd
,
IPPROTO_IPV6
,
IPV6_V6ONLY
,
(
char
*
)
&
one
,
sizeof
(
one
))
==
-
1
)
{
elog
(
LOG
,
"server socket failure: "
"setsockopt(IPV6_V6ONLY): %s"
,
strerror
(
errno
));
closesocket
(
fd
);
continue
;
}
}
#endif
Assert
(
addrs
->
ai_next
==
NULL
&&
addrs
->
ai_family
==
family
);
err
=
bind
(
fd
,
addrs
->
ai_addr
,
addrs
->
ai_addrlen
);
/*
* Note: This might fail on some OS's, like Linux
* older than 2.4.21-pre3, that don't have the IPV6_V6ONLY
* socket option, and map ipv4 addresses to ipv6. It will
* show ::ffff:ipv4 for all ipv4 connections.
*/
err
=
bind
(
fd
,
addr
->
ai_addr
,
addr
->
ai_addrlen
);
if
(
err
<
0
)
{
elog
(
LOG
,
"server socket failure: bind(): %s
\n
"
"
\t
Is another postmaster already running on port %d?"
,
strerror
(
errno
),
(
int
)
portNumber
);
if
(
family
==
AF_UNIX
)
elog
(
LOG
,
"
\t
If not, remove socket node (%s) and retry."
,
sock_path
);
"
\t
Is another postmaster already running on "
"port %d?"
,
strerror
(
errno
),
(
int
)
portNumber
);
if
(
addr
->
ai_family
==
AF_UNIX
)
{
elog
(
LOG
,
"
\t
If not, remove socket node (%s) "
"and retry."
,
sock_path
);
}
else
elog
(
LOG
,
"
\t
If not, wait a few seconds and retry."
);
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
return
STATUS_ERROR
;
{
elog
(
LOG
,
"
\t
If not, wait a few seconds and "
"retry."
);
}
closesocket
(
fd
);
continue
;
}
#ifdef HAVE_UNIX_SOCKETS
if
(
family
==
AF_UNIX
)
if
(
addr
->
ai_
family
==
AF_UNIX
)
{
if
(
Setup_AF_UNIX
()
!=
STATUS_OK
)
{
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
return
STATUS_ERROR
;
closesocket
(
fd
);
break
;
}
}
#endif
/*
* Select appropriate accept-queue length limit. PG_SOMAXCONN is only
* intended to provide a clamp on the request on platforms where an
* overly large request provokes a kernel error (are there any?).
* Select appropriate accept-queue length limit. PG_SOMAXCONN
* is only intended to provide a clamp on the request on
* platforms where an overly large request provokes a kernel
* error (are there any?).
*/
maxconn
=
MaxBackends
*
2
;
if
(
maxconn
>
PG_SOMAXCONN
)
...
...
@@ -307,12 +356,19 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
elog
(
LOG
,
"server socket failure: listen(): %s"
,
strerror
(
errno
));
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
return
STATUS_ERROR
;
closesocket
(
fd
);
continue
;
}
ListenSocket
[
listen_index
]
=
fd
;
added
++
;
}
*
fdP
=
fd
;
freeaddrinfo2
(
hint
.
ai_family
,
addrs
);
freeaddrinfo
(
addrs
);
if
(
!
added
)
{
return
STATUS_ERROR
;
}
return
STATUS_OK
;
}
...
...
@@ -325,10 +381,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
static
int
Lock_AF_UNIX
(
unsigned
short
portNumber
,
char
*
unixSocketName
)
{
SockAddr
saddr
;
/* just used to get socket path */
UNIXSOCK_PATH
(
saddr
.
un
,
portNumber
,
unixSocketName
);
strcpy
(
sock_path
,
saddr
.
un
.
sun_path
);
UNIXSOCK_PATH
(
sock_path
,
portNumber
,
unixSocketName
);
/*
* Grab an interlock file associated with the socket file.
...
...
@@ -422,13 +475,11 @@ Setup_AF_UNIX(void)
int
StreamConnection
(
int
server_fd
,
Port
*
port
)
{
ACCEPT_TYPE_ARG3
addrlen
;
/* accept connection (and fill in the client (remote) address) */
addrlen
=
sizeof
(
port
->
r
addr
);
port
->
raddr
.
salen
=
sizeof
(
port
->
raddr
.
addr
);
if
((
port
->
sock
=
accept
(
server_fd
,
(
struct
sockaddr
*
)
&
port
->
r
addr
,
&
addr
len
))
<
0
)
(
struct
sockaddr
*
)
&
port
->
raddr
.
addr
,
&
port
->
raddr
.
sa
len
))
<
0
)
{
elog
(
LOG
,
"StreamConnection: accept() failed: %m"
);
return
STATUS_ERROR
;
...
...
@@ -444,25 +495,27 @@ StreamConnection(int server_fd, Port *port)
#endif
/* fill in the server (local) address */
addrlen
=
sizeof
(
port
->
l
addr
);
if
(
getsockname
(
port
->
sock
,
(
struct
sockaddr
*
)
&
port
->
laddr
,
&
addr
len
)
<
0
)
port
->
laddr
.
salen
=
sizeof
(
port
->
laddr
.
addr
);
if
(
getsockname
(
port
->
sock
,
(
struct
sockaddr
*
)
&
port
->
laddr
.
addr
,
&
port
->
laddr
.
sa
len
)
<
0
)
{
elog
(
LOG
,
"StreamConnection: getsockname() failed: %m"
);
return
STATUS_ERROR
;
}
/* select NODELAY and KEEPALIVE options if it's a TCP connection */
if
(
isAF_INETx
(
port
->
laddr
.
sa
.
sa
_family
))
if
(
!
IS_AF_UNIX
(
port
->
laddr
.
addr
.
ss
_family
))
{
int
on
=
1
;
#ifdef TCP_NODELAY
if
(
setsockopt
(
port
->
sock
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
char
*
)
&
on
,
sizeof
(
on
))
<
0
)
{
elog
(
LOG
,
"StreamConnection: setsockopt(TCP_NODELAY) failed: %m"
);
return
STATUS_ERROR
;
}
#endif
if
(
setsockopt
(
port
->
sock
,
SOL_SOCKET
,
SO_KEEPALIVE
,
(
char
*
)
&
on
,
sizeof
(
on
))
<
0
)
{
...
...
src/backend/postmaster/pgstat.c
View file @
b4cea00a
...
...
@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.3
6 2003/05/15 16:35:29
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.3
7 2003/06/12 07:36:51
momjian Exp $
* ----------
*/
#include "postgres.h"
...
...
@@ -22,7 +22,9 @@
#include <fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
...
...
@@ -36,6 +38,7 @@
#include "catalog/pg_shadow.h"
#include "catalog/pg_database.h"
#include "libpq/pqsignal.h"
#include "libpq/libpq.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "utils/memutils.h"
...
...
@@ -69,7 +72,7 @@ bool pgstat_is_running = false;
*/
static
int
pgStatSock
=
-
1
;
static
int
pgStatPipe
[
2
];
static
struct
sockaddr_
in
pgStatAddr
;
static
struct
sockaddr_
storage
pgStatAddr
;
static
int
pgStatPmPipe
[
2
]
=
{
-
1
,
-
1
};
static
int
pgStatPid
;
...
...
@@ -141,7 +144,9 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
void
pgstat_init
(
void
)
{
int
alen
;
ACCEPT_TYPE_ARG3
alen
;
struct
addrinfo
*
addr
,
hints
;
int
ret
;
/*
* Force start of collector daemon if something to collect
...
...
@@ -174,7 +179,24 @@ pgstat_init(void)
/*
* Create the UDP socket for sending and receiving statistic messages
*/
if
((
pgStatSock
=
socket
(
PF_INET
,
SOCK_DGRAM
,
0
))
<
0
)
hints
.
ai_flags
=
AI_PASSIVE
;
hints
.
ai_family
=
PF_UNSPEC
;
hints
.
ai_socktype
=
SOCK_DGRAM
;
hints
.
ai_protocol
=
0
;
hints
.
ai_addrlen
=
0
;
hints
.
ai_addr
=
NULL
;
hints
.
ai_canonname
=
NULL
;
hints
.
ai_next
=
NULL
;
ret
=
getaddrinfo2
(
"localhost"
,
NULL
,
&
hints
,
&
addr
);
if
(
ret
||
!
addr
)
{
elog
(
LOG
,
"PGSTAT: getaddrinfo2() failed: %s"
,
gai_strerror
(
ret
));
goto
startup_failed
;
}
if
((
pgStatSock
=
socket
(
addr
->
ai_family
,
addr
->
ai_socktype
,
addr
->
ai_protocol
))
<
0
)
{
elog
(
LOG
,
"PGSTAT: socket() failed: %m"
);
goto
startup_failed
;
...
...
@@ -184,16 +206,16 @@ pgstat_init(void)
* Bind it to a kernel assigned port on localhost and get the assigned
* port via getsockname().
*/
pgStatAddr
.
sin_family
=
AF_INET
;
pgStatAddr
.
sin_port
=
htons
(
0
);
inet_aton
(
"127.0.0.1"
,
&
(
pgStatAddr
.
sin_addr
));
alen
=
sizeof
(
pgStatAddr
);
if
(
bind
(
pgStatSock
,
(
struct
sockaddr
*
)
&
pgStatAddr
,
alen
)
<
0
)
if
(
bind
(
pgStatSock
,
addr
->
ai_addr
,
addr
->
ai_addrlen
)
<
0
)
{
elog
(
LOG
,
"PGSTAT: bind(
127.0.0.1
) failed: %m"
);
elog
(
LOG
,
"PGSTAT: bind() failed: %m"
);
goto
startup_failed
;
}
if
(
getsockname
(
pgStatSock
,
(
struct
sockaddr
*
)
&
pgStatAddr
,
&
alen
)
<
0
)
freeaddrinfo2
(
hints
.
ai_family
,
addr
);
addr
=
NULL
;
alen
=
sizeof
(
pgStatAddr
);
if
(
getsockname
(
pgStatSock
,
(
struct
sockaddr
*
)
&
pgStatAddr
,
&
alen
)
<
0
)
{
elog
(
LOG
,
"PGSTAT: getsockname() failed: %m"
);
goto
startup_failed
;
...
...
@@ -235,6 +257,11 @@ pgstat_init(void)
return
;
startup_failed:
if
(
addr
)
{
freeaddrinfo2
(
hints
.
ai_family
,
addr
);
}
if
(
pgStatSock
>=
0
)
closesocket
(
pgStatSock
);
pgStatSock
=
-
1
;
...
...
@@ -1496,7 +1523,7 @@ pgstat_recvbuffer(void)
int
msg_send
=
0
;
/* next send index in buffer */
int
msg_recv
=
0
;
/* next receive index */
int
msg_have
=
0
;
/* number of bytes stored */
struct
sockaddr_
in
fromaddr
;
struct
sockaddr_
storage
fromaddr
;
int
fromlen
;
bool
overflow
=
false
;
...
...
@@ -1601,8 +1628,8 @@ pgstat_recvbuffer(void)
if
(
FD_ISSET
(
pgStatSock
,
&
rfds
))
{
fromlen
=
sizeof
(
fromaddr
);
len
=
recvfrom
(
pgStatSock
,
(
char
*
)
&
input_buffer
,
sizeof
(
PgStat_Msg
),
0
,
len
=
recvfrom
(
pgStatSock
,
(
char
*
)
&
input_buffer
,
sizeof
(
PgStat_Msg
),
0
,
(
struct
sockaddr
*
)
&
fromaddr
,
&
fromlen
);
if
(
len
<
0
)
{
...
...
@@ -1629,9 +1656,7 @@ pgstat_recvbuffer(void)
* kernel-level check due to having used connect(), but let's
* do it anyway.)
*/
if
(
fromaddr
.
sin_addr
.
s_addr
!=
pgStatAddr
.
sin_addr
.
s_addr
)
continue
;
if
(
fromaddr
.
sin_port
!=
pgStatAddr
.
sin_port
)
if
(
memcmp
(
&
fromaddr
,
&
pgStatAddr
,
fromlen
))
continue
;
/*
...
...
src/backend/postmaster/postmaster.c
View file @
b4cea00a
...
...
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.33
2 2003/06/11 06:56:06
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.33
3 2003/06/12 07:36:51
momjian Exp $
*
* NOTES
*
...
...
@@ -168,14 +168,9 @@ int ReservedBackends;
static
char
*
progname
=
(
char
*
)
NULL
;
/*
* Default Values
*/
static
int
ServerSock_INET
=
INVALID_SOCK
;
/* stream socket server */
#ifdef HAVE_UNIX_SOCKETS
static
int
ServerSock_UNIX
=
INVALID_SOCK
;
/* stream socket server */
#endif
/* The sockets we're listening to. */
#define MAXLISTEN 10
int
ListenSocket
[
MAXLISTEN
];
/* Used to reduce macros tests */
#ifdef EXEC_BACKEND
...
...
@@ -388,6 +383,7 @@ PostmasterMain(int argc, char *argv[])
int
status
;
char
original_extraoptions
[
MAXPGPATH
];
char
*
potential_DataDir
=
NULL
;
int
i
;
*
original_extraoptions
=
'\0'
;
...
...
@@ -713,32 +709,53 @@ PostmasterMain(int argc, char *argv[])
/*
* Establish input sockets.
*/
for
(
i
=
0
;
i
<
MAXLISTEN
;
i
++
)
{
ListenSocket
[
i
]
=
-
1
;
}
if
(
NetServer
)
{
#ifdef HAVE_IPV6
/* Try INET6 first. May fail if kernel doesn't support IP6 */
status
=
StreamServerPort
(
AF_INET6
,
VirtualHost
,
if
(
VirtualHost
&&
VirtualHost
[
0
])
{
char
*
p
,
*
q
;
char
c
=
0
;
q
=
VirtualHost
;
do
{
p
=
strchr
(
q
,
' '
);
if
(
p
)
{
c
=
*
p
;
*
p
=
'\0'
;
}
status
=
StreamServerPort
(
AF_UNSPEC
,
q
,
(
unsigned
short
)
PostPortNumber
,
UnixSocketDir
,
&
ServerSock_INET
);
UnixSocketDir
,
ListenSocket
,
MAXLISTEN
);
if
(
status
!=
STATUS_OK
)
{
elog
(
LOG
,
"IPv6 support disabled --- perhaps the kernel does not support IPv6"
);
#endif
status
=
StreamServerPort
(
AF_INET
,
VirtualHost
,
postmaster_error
(
"cannot create tcpip "
"listen socket for: %s"
,
p
);
}
if
(
p
)
{
*
p
=
c
;
q
=
p
+
1
;
}
}
while
(
p
);
}
else
{
status
=
StreamServerPort
(
AF_UNSPEC
,
NULL
,
(
unsigned
short
)
PostPortNumber
,
UnixSocketDir
,
&
ServerSock_INET
);
UnixSocketDir
,
ListenSocket
,
MAXLISTEN
);
if
(
status
!=
STATUS_OK
)
{
postmaster_error
(
"cannot create
INET stream port"
);
ExitPostmaster
(
1
);
postmaster_error
(
"cannot create
tcpip listen "
"socket."
);
}
#ifdef HAVE_IPV6
else
elog
(
LOG
,
"IPv4 socket created"
);
}
#endif
#ifdef USE_RENDEZVOUS
if
(
service_name
!=
NULL
)
{
...
...
@@ -754,10 +771,9 @@ PostmasterMain(int argc, char *argv[])
}
#ifdef HAVE_UNIX_SOCKETS
status
=
StreamServerPort
(
AF_UNIX
,
VirtualHost
,
status
=
StreamServerPort
(
AF_UNIX
,
NULL
,
(
unsigned
short
)
PostPortNumber
,
UnixSocketDir
,
&
ServerSock_UNIX
);
UnixSocketDir
,
ListenSocket
,
MAXLISTEN
);
if
(
status
!=
STATUS_OK
)
{
postmaster_error
(
"cannot create UNIX stream port"
);
...
...
@@ -961,12 +977,11 @@ usage(const char *progname)
static
int
ServerLoop
(
void
)
{
fd_set
readmask
,
writemask
;
fd_set
readmask
,
writemask
;
int
nSockets
;
struct
timeval
now
,
later
;
struct
timeval
now
,
later
;
struct
timezone
tz
;
int
i
;
gettimeofday
(
&
now
,
&
tz
);
...
...
@@ -1065,42 +1080,24 @@ ServerLoop(void)
* New connection pending on our well-known port's socket? If so,
* fork a child process to deal with it.
*/
#ifdef HAVE_UNIX_SOCKETS
if
(
ServerSock_UNIX
!=
INVALID_SOCK
&&
FD_ISSET
(
ServerSock_UNIX
,
&
rmask
))
for
(
i
=
0
;
i
<
MAXLISTEN
;
i
++
)
{
port
=
ConnCreate
(
ServerSock_UNIX
);
if
(
port
)
{
BackendStartup
(
port
);
/*
* We no longer need the open socket or port structure in
* this process
*/
StreamClose
(
port
->
sock
);
ConnFree
(
port
);
}
}
#endif
if
(
ServerSock_INET
!=
INVALID_SOCK
&&
FD_ISSET
(
ServerSock_INET
,
&
rmask
))
if
(
ListenSocket
[
i
]
!=
-
1
&&
FD_ISSET
(
ListenSocket
[
i
],
&
rmask
))
{
port
=
ConnCreate
(
ServerSock_INET
);
port
=
ConnCreate
(
ListenSocket
[
i
]
);
if
(
port
)
{
BackendStartup
(
port
);
/*
* We no longer need the open socket or port structure in
*
this process
* We no longer need the open socket
* or port structure in
this process
*/
StreamClose
(
port
->
sock
);
ConnFree
(
port
);
}
}
}
/* If we have lost the stats collector, try to start a new one */
if
(
!
pgstat_is_running
)
...
...
@@ -1118,25 +1115,20 @@ static int
initMasks
(
fd_set
*
rmask
,
fd_set
*
wmask
)
{
int
nsocks
=
-
1
;
int
i
;
FD_ZERO
(
rmask
);
FD_ZERO
(
wmask
);
#ifdef HAVE_UNIX_SOCKETS
if
(
ServerSock_UNIX
!=
INVALID_SOCK
)
for
(
i
=
0
;
i
<
MAXLISTEN
;
i
++
)
{
FD_SET
(
ServerSock_UNIX
,
rmask
);
if
(
ServerSock_UNIX
>
nsocks
)
nsocks
=
ServerSock_UNIX
;
}
#endif
if
(
ServerSock_INET
!=
INVALID_SOCK
)
int
fd
=
ListenSocket
[
i
];
if
(
fd
!=
-
1
)
{
FD_SET
(
ServerSock_INET
,
rmask
);
if
(
ServerSock_INET
>
nsocks
)
nsocks
=
ServerSock_INET
;
FD_SET
(
fd
,
rmask
);
if
(
fd
>
nsocks
)
nsocks
=
fd
;
}
}
return
nsocks
+
1
;
...
...
@@ -1220,7 +1212,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
#ifdef USE_SSL
/* No SSL when disabled or on Unix sockets */
if
(
!
EnableSSL
||
port
->
laddr
.
sa
.
sa
_family
!=
AF_INET
)
if
(
!
EnableSSL
||
port
->
laddr
.
addr
.
ss
_family
!=
AF_INET
)
SSLok
=
'N'
;
else
SSLok
=
'S'
;
/* Support for SSL */
...
...
@@ -1560,14 +1552,18 @@ ConnFree(Port *conn)
void
ClosePostmasterPorts
(
bool
pgstat_too
)
{
int
i
;
/* Close the listen sockets */
if
(
NetServer
)
StreamClose
(
ServerSock_INET
);
ServerSock_INET
=
INVALID_SOCK
;
#ifdef HAVE_UNIX_SOCKETS
StreamClose
(
ServerSock_UNIX
);
ServerSock_UNIX
=
INVALID_SOCK
;
#endif
for
(
i
=
0
;
i
<
MAXLISTEN
;
i
++
)
{
if
(
ListenSocket
[
i
]
!=
-
1
)
{
StreamClose
(
ListenSocket
[
i
]);
ListenSocket
[
i
]
=
-
1
;
}
}
/* Close pgstat control sockets, unless we're starting pgstat itself */
if
(
pgstat_too
)
pgstat_close_sockets
();
...
...
@@ -2226,7 +2222,6 @@ split_opts(char **argv, int *argcp, char *s)
static
int
BackendFork
(
Port
*
port
)
{
char
*
remote_host
;
char
**
av
;
int
maxac
;
int
ac
;
...
...
@@ -2239,6 +2234,8 @@ BackendFork(Port *port)
int
status
;
struct
timeval
now
;
struct
timezone
tz
;
char
remote_host
[
NI_MAXHOST
];
char
remote_port
[
NI_MAXSERV
];
/*
* Let's clean up ourselves as the postmaster child
...
...
@@ -2286,43 +2283,26 @@ BackendFork(Port *port)
/*
* Get the remote host name and port for logging and status display.
*/
if
(
isAF_INETx
(
port
->
raddr
.
sa
.
sa_family
))
remote_host
[
0
]
=
'\0'
;
remote_port
[
0
]
=
'\0'
;
if
(
!
getnameinfo
((
struct
sockaddr
*
)
&
port
->
raddr
.
addr
,
port
->
raddr
.
salen
,
remote_host
,
sizeof
(
remote_host
),
remote_port
,
sizeof
(
remote_host
),
(
log_hostname
?
0
:
NI_NUMERICHOST
)
|
NI_NUMERICSERV
))
{
unsigned
short
remote_port
;
char
*
host_addr
;
#ifdef HAVE_IPV6
char
ip_hostinfo
[
INET6_ADDRSTRLEN
];
#else
char
ip_hostinfo
[
INET_ADDRSTRLEN
];
#endif
remote_port
=
ntohs
(
port
->
raddr
.
in
.
sin_port
);
host_addr
=
SockAddr_ntop
(
&
port
->
raddr
,
ip_hostinfo
,
sizeof
(
ip_hostinfo
),
1
);
remote_host
=
NULL
;
if
(
log_hostname
)
{
struct
hostent
*
host_ent
;
host_ent
=
gethostbyaddr
((
char
*
)
&
port
->
raddr
.
in
.
sin_addr
,
sizeof
(
port
->
raddr
.
in
.
sin_addr
),
AF_INET
);
if
(
host_ent
)
{
remote_host
=
palloc
(
strlen
(
host_addr
)
+
strlen
(
host_ent
->
h_name
)
+
3
);
sprintf
(
remote_host
,
"%s[%s]"
,
host_ent
->
h_name
,
host_addr
);
}
getnameinfo
((
struct
sockaddr
*
)
&
port
->
raddr
.
addr
,
port
->
raddr
.
salen
,
remote_host
,
sizeof
(
remote_host
),
remote_port
,
sizeof
(
remote_host
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
}
if
(
remote_host
==
NULL
)
remote_host
=
pstrdup
(
host_addr
);
if
(
Log_connections
)
elog
(
LOG
,
"connection received: host=%s port=%hu"
,
{
elog
(
LOG
,
"connection received: host=%s port=%s"
,
remote_host
,
remote_port
);
}
if
(
LogSourcePort
)
{
...
...
@@ -2330,19 +2310,10 @@ BackendFork(Port *port)
int
slen
=
strlen
(
remote_host
)
+
10
;
char
*
str
=
palloc
(
slen
);
snprintf
(
str
,
slen
,
"%s:%hu"
,
remote_host
,
remote_port
);
pfree
(
remote_host
);
remote_host
=
str
;
}
}
else
{
/* not AF_INET */
remote_host
=
"[local]"
;
if
(
Log_connections
)
elog
(
LOG
,
"connection received: host=%s"
,
remote_host
);
snprintf
(
str
,
slen
,
"%s:%s"
,
remote_host
,
remote_port
);
strncpy
(
remote_host
,
str
,
sizeof
(
remote_host
));
remote_host
[
sizeof
(
remote_host
)
-
1
]
=
'\0'
;
pfree
(
str
);
}
/*
...
...
@@ -2516,14 +2487,8 @@ ExitPostmaster(int status)
*
* MUST -- vadim 05-10-1999
*/
if
(
ServerSock_INET
!=
INVALID_SOCK
)
StreamClose
(
ServerSock_INET
);
ServerSock_INET
=
INVALID_SOCK
;
#ifdef HAVE_UNIX_SOCKETS
if
(
ServerSock_UNIX
!=
INVALID_SOCK
)
StreamClose
(
ServerSock_UNIX
);
ServerSock_UNIX
=
INVALID_SOCK
;
#endif
/* Should I use true instead? */
ClosePostmasterPorts
(
false
);
proc_exit
(
status
);
}
...
...
src/include/getaddrinfo.h
View file @
b4cea00a
...
...
@@ -16,7 +16,7 @@
*
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* $Id: getaddrinfo.h,v 1.
2 2003/04/02 00:49:28 tgl
Exp $
* $Id: getaddrinfo.h,v 1.
3 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -44,19 +44,26 @@ struct addrinfo {
#define EAI_NONAME -2
#define EAI_AGAIN -3
#define EAI_FAIL -4
#define EAI_NODATA -5
#define EAI_FAMILY -6
#define EAI_SOCKTYPE -7
#define EAI_SERVICE -8
#define EAI_ADDRFAMILY -9
#define EAI_MEMORY -10
#define EAI_SYSTEM -11
#define AI_PASSIVE 0x0001
#define AI_NUMERICHOST 0x0004
#define NI_NUMERICHOST 1
#define NI_NUMERICSERV 2
#endif
/* HAVE_STRUCT_ADDRINFO */
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#define NI_MAXSERV 32
#endif
#ifndef HAVE_GETADDRINFO
...
...
@@ -76,10 +83,18 @@ struct addrinfo {
#endif
#define gai_strerror pg_gai_strerror
#ifdef getnameinfo
#undef getnameinfo
#endif
#define getnameinfo pg_getnameinfo
extern
int
getaddrinfo
(
const
char
*
node
,
const
char
*
service
,
const
struct
addrinfo
*
hints
,
struct
addrinfo
**
res
);
extern
void
freeaddrinfo
(
struct
addrinfo
*
res
);
extern
const
char
*
gai_strerror
(
int
errcode
);
extern
int
getnameinfo
(
const
struct
sockaddr
*
sa
,
int
salen
,
char
*
node
,
int
nodelen
,
char
*
service
,
int
servicelen
,
int
flags
);
#endif
/* HAVE_GETADDRINFO */
...
...
src/include/libpq/ip.h
View file @
b4cea00a
...
...
@@ -5,7 +5,7 @@
*
* Copyright (c) 2003, PostgreSQL Global Development Group
*
* $Id: ip.h,v 1.
7 2003/06/12 07:00:57
momjian Exp $
* $Id: ip.h,v 1.
8 2003/06/12 07:36:51
momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -21,12 +21,17 @@ extern int getaddrinfo2(const char *hostname, const char *servname,
struct
addrinfo
**
result
);
extern
void
freeaddrinfo2
(
int
hint_ai_family
,
struct
addrinfo
*
ai
);
extern
char
*
SockAddr_ntop
(
const
SockAddr
*
sa
,
char
*
dst
,
size_t
cnt
,
int
v4conv
);
extern
int
SockAddr_pton
(
SockAddr
*
sa
,
const
char
*
src
);
extern
int
rangeSockAddr
(
const
struct
sockaddr_storage
*
addr
,
const
struct
sockaddr_storage
*
netaddr
,
const
struct
sockaddr_storage
*
netmask
);
extern
int
isAF_INETx
(
const
int
family
);
extern
int
rangeSockAddr
(
const
SockAddr
*
addr
,
const
SockAddr
*
netaddr
,
const
SockAddr
*
netmask
);
extern
int
SockAddr_cidr_mask
(
struct
sockaddr_storage
**
mask
,
char
*
numbits
,
int
family
);
#ifdef HAVE_UNIX_SOCKETS
#define IS_AF_UNIX(fam) (fam == AF_UNIX)
#else
#define IS_AF_UNIX(fam) (0)
#endif
#endif
/* IP_H */
src/include/libpq/libpq.h
View file @
b4cea00a
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq.h,v 1.5
7 2003/04/19 00:02:29 tgl
Exp $
* $Id: libpq.h,v 1.5
8 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -46,7 +46,8 @@ typedef struct
* prototypes for functions in pqcomm.c
*/
extern
int
StreamServerPort
(
int
family
,
char
*
hostName
,
unsigned
short
portNumber
,
char
*
unixSocketName
,
int
*
fdP
);
unsigned
short
portNumber
,
char
*
unixSocketName
,
int
ListenSocket
[],
int
MaxListen
);
extern
int
StreamConnection
(
int
server_fd
,
Port
*
port
);
extern
void
StreamClose
(
int
sock
);
extern
void
TouchSocketFile
(
void
);
...
...
src/include/libpq/pqcomm.h
View file @
b4cea00a
...
...
@@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pqcomm.h,v 1.8
5 2003/05/08 18:33:32 tgl
Exp $
* $Id: pqcomm.h,v 1.8
6 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -32,58 +32,60 @@
#include <netinet/in.h>
#endif
/* not WIN32 */
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
/* Define a struct sockaddr_storage if we don't have one. */
/*
* Desired design of maximum size and alignment
*/
#define _SS_MAXSIZE 128
/* Implementation specific max size */
#define _SS_ALIGNSIZE (sizeof (int64_t))
/* Implementation specific desired alignment */
/*
* Definitions used for sockaddr_storage structure paddings design.
*/
#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (sa_family_t))
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t) + \
_SS_PAD1SIZE + _SS_ALIGNSIZE))
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
struct
sockaddr_storage
{
#ifdef SALEN
uint8_t
__ss_len
;
/* address length */
#endif
#ifndef HAVE_STRUCT_SOCKADDR_UN
struct
sockaddr_un
{
short
int
sun_family
;
/* AF_UNIX */
char
sun_path
[
108
];
/* path name (gag) */
sa_family_t
ss_family
;
/* address family */
char
__ss_pad1
[
_SS_PAD1SIZE
];
/* 6 byte pad, this is to make implementation
* specific pad up to alignment field that
* follows explicit in the data structure */
int64_t
__ss_align
;
/* field to force desired structure
* storage alignment */
char
__ss_pad2
[
_SS_PAD2SIZE
];
/* 112 byte pad to achieve desired size,
* _SS_MAXSIZE value minus size of ss_family
* __ss_pad1, __ss_align fields is 112 */
};
#endif
/* Define a generic socket address type. */
typedef
union
SockAddr
{
struct
sockaddr
sa
;
struct
sockaddr_in
in
;
#ifdef HAVE_IPV6
struct
sockaddr_in6
in6
;
#endif
struct
sockaddr_un
un
;
typedef
struct
{
struct
sockaddr_storage
addr
;
ACCEPT_TYPE_ARG3
salen
;
}
SockAddr
;
/* Some systems don't have it, so default it to 0 so it doesn't
* have any effect on those systems. */
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
#endif
/* Configure the UNIX socket location for the well known port. */
#define UNIXSOCK_PATH(
sun
,port,defpath) \
snprintf(
(sun).sun_path, sizeof((sun).sun_
path), "%s/.s.PGSQL.%d", \
#define UNIXSOCK_PATH(
path
,port,defpath) \
snprintf(
path, sizeof(
path), "%s/.s.PGSQL.%d", \
((defpath) && *(defpath) != '\0') ? (defpath) : \
DEFAULT_PGSOCKET_DIR, \
(port))
/*
* We do this because sun_len is in BSD's struct, while others don't.
* We never actually set BSD's sun_len, and I can't think of a
* platform-safe way of doing it, but the code still works. bjm
*/
#if defined(SUN_LEN)
#define UNIXSOCK_LEN(sun) \
(SUN_LEN(&(sun)))
#else
#define UNIXSOCK_LEN(sun) \
(strlen((sun).sun_path) + offsetof(struct sockaddr_un, sun_path))
#endif
/*
* These manipulate the frontend/backend protocol version number.
*
...
...
src/include/pg_config.h.in
View file @
b4cea00a
...
...
@@ -411,6 +411,9 @@
/* Define to 1 if the system has the type `struct fcred'. */
#undef HAVE_STRUCT_FCRED
/* Define to 1 if the system has the type `struct sockaddr_storage'. */
#undef HAVE_STRUCT_SOCKADDR_STORAGE
/* Define to 1 if the system has the type `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN
...
...
@@ -487,6 +490,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have unix sockets. */
#undef HAVE_UNIX_SOCKETS
/* Define to 1 if you have the `utime' function. */
#undef HAVE_UTIME
...
...
src/include/pg_config_manual.h
View file @
b4cea00a
...
...
@@ -6,7 +6,7 @@
* for developers. If you edit any of these, be sure to do a *full*
* rebuild (and an initdb if noted).
*
* $Id: pg_config_manual.h,v 1.
3 2003/05/15 16:35:29
momjian Exp $
* $Id: pg_config_manual.h,v 1.
4 2003/06/12 07:36:51
momjian Exp $
*------------------------------------------------------------------------
*/
...
...
@@ -127,11 +127,10 @@
#define BITS_PER_BYTE 8
/*
* Define this if your operating system supports AF_UNIX family
* sockets.
* Disable UNIX sockets for those operating system.
*/
#if
!defined(__QNX__) && !defined(__BEOS__) && !
defined(WIN32)
#
define HAVE_UNIX_SOCKETS 1
#if
defined(__QNX__) || defined(__BEOS__) ||
defined(WIN32)
#
undef HAVE_UNIX_SOCKETS
#endif
/*
...
...
src/include/port/bsdi.h
View file @
b4cea00a
...
...
@@ -9,7 +9,3 @@
typedef
unsigned
char
slock_t
;
/* This is marked as obsoleted in BSD/OS 4.3. */
#ifndef EAI_ADDRFAMILY
#define EAI_ADDRFAMILY 1
#endif
src/interfaces/libpq/fe-connect.c
View file @
b4cea00a
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.24
3 2003/06/09 17:59:19 tgl
Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.24
4 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -727,6 +727,7 @@ connectMakeNonblocking(PGconn *conn)
static
int
connectNoDelay
(
PGconn
*
conn
)
{
#ifdef TCP_NODELAY
int
on
=
1
;
if
(
setsockopt
(
conn
->
sock
,
IPPROTO_TCP
,
TCP_NODELAY
,
...
...
@@ -738,6 +739,7 @@ connectNoDelay(PGconn *conn)
SOCK_STRERROR
(
SOCK_ERRNO
));
return
0
;
}
#endif
return
1
;
}
...
...
@@ -751,15 +753,20 @@ connectNoDelay(PGconn *conn)
static
void
connectFailureMessage
(
PGconn
*
conn
,
int
errorno
)
{
if
(
conn
->
raddr
.
sa
.
sa_family
==
AF_UNIX
)
char
hostname
[
NI_MAXHOST
];
char
service
[
NI_MAXHOST
];
getnameinfo
((
struct
sockaddr
*
)
&
conn
->
raddr
.
addr
,
conn
->
raddr
.
salen
,
hostname
,
sizeof
(
hostname
),
service
,
sizeof
(
service
),
NI_NUMERICHOST
|
NI_NUMERICSERV
);
if
(
conn
->
raddr
.
addr
.
ss_family
==
AF_UNIX
)
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not connect to server: %s
\n
"
"
\t
Is the server running locally and accepting
\n
"
"
\t
connections on Unix domain socket
\"
%s
\"
?
\n
"
),
SOCK_STRERROR
(
errorno
),
conn
->
raddr
.
un
.
sun_path
);
SOCK_STRERROR
(
errorno
),
service
);
else
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
...
...
@@ -808,6 +815,7 @@ connectDBStart(PGconn *conn)
/* Initialize hint structure */
MemSet
(
&
hint
,
0
,
sizeof
(
hint
));
hint
.
ai_socktype
=
SOCK_STREAM
;
hint
.
ai_family
=
AF_UNSPEC
;
/* Set up port number as a string */
if
(
conn
->
pgport
!=
NULL
&&
conn
->
pgport
[
0
]
!=
'\0'
)
...
...
@@ -829,17 +837,15 @@ connectDBStart(PGconn *conn)
node
=
conn
->
pghost
;
hint
.
ai_family
=
AF_UNSPEC
;
}
#ifdef HAVE_UNIX_SOCKETS
else
{
/* pghostaddr and pghost are NULL, so use Unix domain socket */
#ifdef HAVE_UNIX_SOCKETS
node
=
"unix"
;
node
=
NULL
;
hint
.
ai_family
=
AF_UNIX
;
UNIXSOCK_PATH
(
conn
->
raddr
.
un
,
portnum
,
conn
->
pgunixsocket
);
conn
->
raddr_len
=
UNIXSOCK_LEN
(
conn
->
raddr
.
un
);
StrNCpy
(
portstr
,
conn
->
raddr
.
un
.
sun_path
,
sizeof
(
portstr
));
#endif
/* HAVE_UNIX_SOCKETS */
UNIXSOCK_PATH
(
portstr
,
portnum
,
conn
->
pgunixsocket
);
}
#endif
/* HAVE_UNIX_SOCKETS */
/* Use getaddrinfo2() to resolve the address */
ret
=
getaddrinfo2
(
node
,
portstr
,
&
hint
,
&
addrs
);
...
...
@@ -1066,11 +1072,10 @@ keep_going: /* We will come back to here until there
/* Remember current address for possible error msg */
memcpy
(
&
conn
->
raddr
,
addr_cur
->
ai_addr
,
addr_cur
->
ai_addrlen
);
conn
->
raddr_len
=
addr_cur
->
ai_addrlen
;
/* Open a socket */
conn
->
sock
=
socket
(
addr_cur
->
ai_family
,
SOCK_STREAM
,
addr_cur
->
ai_socktype
,
addr_cur
->
ai_protocol
);
if
(
conn
->
sock
<
0
)
{
...
...
@@ -1093,13 +1098,23 @@ keep_going: /* We will come back to here until there
* Select socket options: no delay of outgoing data for
* TCP sockets, and nonblock mode. Fail if this fails.
*/
if
(
isAF_INETx
(
addr_cur
->
ai_family
))
if
(
!
IS_AF_UNIX
(
addr_cur
->
ai_family
))
{
if
(
!
connectNoDelay
(
conn
))
break
;
{
closesocket
(
conn
->
sock
);
conn
->
sock
=
-
1
;
conn
->
addr_cur
=
addr_cur
->
ai_next
;
continue
;
}
}
if
(
connectMakeNonblocking
(
conn
)
==
0
)
break
;
{
closesocket
(
conn
->
sock
);
conn
->
sock
=
-
1
;
conn
->
addr_cur
=
addr_cur
->
ai_next
;
continue
;
}
/*
* Start/make connection. This should not block, since
* we are in nonblock mode. If it does, well, too bad.
...
...
@@ -1163,7 +1178,6 @@ retry_connect:
case
CONNECTION_STARTED
:
{
ACCEPT_TYPE_ARG3
laddrlen
;
int
optval
;
ACCEPT_TYPE_ARG3
optlen
=
sizeof
(
optval
);
...
...
@@ -1212,8 +1226,10 @@ retry_connect:
}
/* Fill in the client address */
laddrlen
=
sizeof
(
conn
->
laddr
);
if
(
getsockname
(
conn
->
sock
,
&
conn
->
laddr
.
sa
,
&
laddrlen
)
<
0
)
conn
->
laddr
.
salen
=
sizeof
(
conn
->
laddr
.
addr
);
if
(
getsockname
(
conn
->
sock
,
(
struct
sockaddr
*
)
&
conn
->
laddr
.
addr
,
&
conn
->
laddr
.
salen
)
<
0
)
{
printfPQExpBuffer
(
&
conn
->
errorMessage
,
libpq_gettext
(
"could not get client address from socket: %s
\n
"
),
...
...
@@ -1240,7 +1256,7 @@ retry_connect:
*/
#ifdef HAVE_UNIX_SOCKETS
if
(
conn
->
raddr
.
sa
.
sa
_family
==
AF_UNIX
)
if
(
conn
->
raddr
.
addr
.
ss
_family
==
AF_UNIX
)
{
/* Don't bother requesting SSL over a Unix socket */
conn
->
allow_ssl_try
=
false
;
...
...
@@ -2044,14 +2060,15 @@ PQrequestCancel(PGconn *conn)
* We need to open a temporary connection to the postmaster. Use the
* information saved by connectDB to do this with only kernel calls.
*/
if
((
tmpsock
=
socket
(
conn
->
raddr
.
sa
.
sa
_family
,
SOCK_STREAM
,
0
))
<
0
)
if
((
tmpsock
=
socket
(
conn
->
raddr
.
addr
.
ss
_family
,
SOCK_STREAM
,
0
))
<
0
)
{
strcpy
(
conn
->
errorMessage
.
data
,
"PQrequestCancel() -- socket() failed: "
);
goto
cancel_errReturn
;
}
retry3:
if
(
connect
(
tmpsock
,
&
conn
->
raddr
.
sa
,
conn
->
raddr_len
)
<
0
)
if
(
connect
(
tmpsock
,
(
struct
sockaddr
*
)
&
conn
->
raddr
.
addr
,
conn
->
raddr
.
salen
)
<
0
)
{
if
(
SOCK_ERRNO
==
EINTR
)
/* Interrupted system call - we'll just try again */
...
...
src/interfaces/libpq/libpq-int.h
View file @
b4cea00a
...
...
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: libpq-int.h,v 1.7
2 2003/06/09 17:59:19 tgl
Exp $
* $Id: libpq-int.h,v 1.7
3 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -263,7 +263,6 @@ struct pg_conn
int
sock
;
/* Unix FD for socket, -1 if not connected */
SockAddr
laddr
;
/* Local address */
SockAddr
raddr
;
/* Remote address */
int
raddr_len
;
/* Length of remote address */
ProtocolVersion
pversion
;
/* FE/BE protocol version in use */
char
sversion
[
8
];
/* The first few bytes of server version */
...
...
src/port/getaddrinfo.c
View file @
b4cea00a
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.
3 2003/04/27 23:56:53 tgl
Exp $
* $Header: /cvsroot/pgsql/src/port/getaddrinfo.c,v 1.
4 2003/06/12 07:36:51 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -16,28 +16,50 @@
/* This is intended to be used in both frontend and backend, so use c.h */
#include "c.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef HAVE_UNIX_SOCKETS
#include <sys/un.h>
#endif
#include "getaddrinfo.h"
/*
* get address info for ipv4 sockets.
*
* Bugs: - only one addrinfo is set even though hintp is NULL or
* ai_socktype is 0
* - AI_CANONNAME is not supported.
* - servname can only be a number, not text.
*/
int
getaddrinfo
(
const
char
*
node
,
const
char
*
service
,
const
struct
addrinfo
*
hint
s
,
const
struct
addrinfo
*
hint
p
,
struct
addrinfo
**
res
)
{
struct
addrinfo
*
ai
;
struct
sockaddr_in
sin
,
*
psin
;
struct
addrinfo
hints
;
if
(
hintp
==
NULL
)
{
memset
(
&
hints
,
0
,
sizeof
(
hints
));
hints
.
ai_family
=
AF_INET
;
hints
.
ai_socktype
=
SOCK_STREAM
;
}
else
{
memcpy
(
&
hints
,
hintp
,
sizeof
(
hints
));
}
if
(
!
hints
||
(
hints
->
ai_family
!=
AF_INET
&&
hints
->
ai_family
!=
AF_UNSPEC
))
if
(
hints
.
ai_family
!=
AF_INET
&&
hints
.
ai_family
!=
AF_UNSPEC
)
return
EAI_FAMILY
;
if
(
hints
->
ai_socktype
!=
SOCK_STREAM
)
return
EAI_SOCKTYPE
;
if
(
hints
.
ai_socktype
==
0
)
hints
.
ai_socktype
=
SOCK_STREAM
;
if
(
!
node
&&
!
service
)
return
EAI_NONAME
;
...
...
@@ -50,9 +72,12 @@ getaddrinfo(const char *node, const char *service,
{
if
(
node
[
0
]
==
'\0'
)
sin
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
else
if
(
hints
->
ai_flags
&
AI_NUMERICHOST
)
else
if
(
hints
.
ai_flags
&
AI_NUMERICHOST
)
{
if
(
!
inet_aton
(
node
,
&
sin
.
sin_addr
))
{
inet_aton
(
node
,
&
sin
.
sin_addr
);
return
EAI_FAIL
;
}
}
else
{
...
...
@@ -64,9 +89,8 @@ getaddrinfo(const char *node, const char *service,
switch
(
h_errno
)
{
case
HOST_NOT_FOUND
:
return
EAI_NONAME
;
case
NO_DATA
:
return
EAI_NO
DATA
;
return
EAI_NO
NAME
;
case
TRY_AGAIN
:
return
EAI_AGAIN
;
case
NO_RECOVERY
:
...
...
@@ -75,14 +99,14 @@ getaddrinfo(const char *node, const char *service,
}
}
if
(
hp
->
h_addrtype
!=
AF_INET
)
return
EAI_
ADDRFAMILY
;
return
EAI_
FAIL
;
memcpy
(
&
(
sin
.
sin_addr
),
hp
->
h_addr
,
hp
->
h_length
);
}
}
else
{
if
(
hints
->
ai_flags
&
AI_PASSIVE
)
if
(
hints
.
ai_flags
&
AI_PASSIVE
)
sin
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
else
sin
.
sin_addr
.
s_addr
=
htonl
(
INADDR_LOOPBACK
);
...
...
@@ -90,10 +114,16 @@ getaddrinfo(const char *node, const char *service,
if
(
service
)
sin
.
sin_port
=
htons
((
unsigned
short
)
atoi
(
service
));
#if SALEN
sin
.
sin_len
=
sizeof
(
sin
);
#endif
ai
=
malloc
(
sizeof
(
*
ai
));
if
(
!
ai
)
{
return
EAI_MEMORY
;
}
psin
=
malloc
(
sizeof
(
*
psin
));
if
(
!
psin
)
{
...
...
@@ -103,9 +133,10 @@ getaddrinfo(const char *node, const char *service,
memcpy
(
psin
,
&
sin
,
sizeof
(
*
psin
));
ai
->
ai_flags
=
0
;
ai
->
ai_family
=
AF_INET
;
ai
->
ai_socktype
=
SOCK_STREAM
;
ai
->
ai_protocol
=
IPPROTO_TCP
;
ai
->
ai_socktype
=
hints
.
ai_socktype
;
ai
->
ai_protocol
=
hints
.
ai_protocol
;
ai
->
ai_addrlen
=
sizeof
(
*
psin
);
ai
->
ai_addr
=
(
struct
sockaddr
*
)
psin
;
ai
->
ai_canonname
=
NULL
;
...
...
@@ -140,9 +171,6 @@ gai_strerror(int errcode)
case
EAI_NONAME
:
hcode
=
HOST_NOT_FOUND
;
break
;
case
EAI_NODATA
:
hcode
=
NO_DATA
;
break
;
case
EAI_AGAIN
:
hcode
=
TRY_AGAIN
;
break
;
...
...
@@ -160,8 +188,6 @@ gai_strerror(int errcode)
{
case
EAI_NONAME
:
return
"Unknown host"
;
case
EAI_NODATA
:
return
"No address associated with name"
;
case
EAI_AGAIN
:
return
"Host name lookup failure"
;
case
EAI_FAIL
:
...
...
@@ -171,3 +197,82 @@ gai_strerror(int errcode)
#endif
/* HAVE_HSTRERROR */
}
/*
* Convert an address to a hostname.
*
* Bugs: - Only supports NI_NUMERICHOST and NI_NUMERICSERV
* It will never resolv a hostname.
* - No IPv6 support.
*/
int
getnameinfo
(
const
struct
sockaddr
*
sa
,
int
salen
,
char
*
node
,
int
nodelen
,
char
*
service
,
int
servicelen
,
int
flags
)
{
sa_family_t
family
;
int
ret
=
-
1
;
/* Invalid arguments. */
if
(
sa
==
NULL
||
(
node
==
NULL
&&
service
==
NULL
))
{
return
EAI_FAIL
;
}
/* We don't support those. */
if
((
node
&&
!
(
flags
&
NI_NUMERICHOST
))
||
(
service
&&
!
(
flags
&
NI_NUMERICSERV
)))
{
return
EAI_FAIL
;
}
family
=
sa
->
sa_family
;
#ifdef HAVE_IPV6
if
(
family
==
AF_INET6
)
{
return
EAI_FAMILY
;
}
#endif
if
(
service
)
{
if
(
family
==
AF_INET
)
{
ret
=
snprintf
(
service
,
servicelen
,
"%d"
,
ntohs
(((
struct
sockaddr_in
*
)
sa
)
->
sin_port
));
}
#ifdef HAVE_UNIX_SOCKETS
else
if
(
family
==
AF_UNIX
)
{
ret
=
snprintf
(
service
,
servicelen
,
"%s"
,
((
struct
sockaddr_un
*
)
sa
)
->
sun_path
);
}
#endif
if
(
ret
==
-
1
||
ret
>
servicelen
)
{
return
EAI_MEMORY
;
}
}
if
(
node
)
{
if
(
family
==
AF_INET
)
{
char
*
p
;
p
=
inet_ntoa
(((
struct
sockaddr_in
*
)
sa
)
->
sin_addr
);
ret
=
snprintf
(
node
,
nodelen
,
"%s"
,
p
);
}
#ifdef HAVE_UNIX_SOCKETS
else
if
(
family
==
AF_UNIX
)
{
ret
=
snprintf
(
node
,
nodelen
,
"%s"
,
"localhost"
);
}
#endif
if
(
ret
==
-
1
||
ret
>
nodelen
)
{
return
EAI_MEMORY
;
}
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment