summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane2003-07-23 23:30:41 +0000
committerTom Lane2003-07-23 23:30:41 +0000
commitdf63503dc2fbe59292a65c685479bf1a439b9b4d (patch)
tree4f1b242db11a03e2f2ed78092e90f72f416dcd49 /src/backend
parent93395de092fbec103b2949ba46c2642ef875405c (diff)
Have a go at fixing various outstanding portability issues in code that
was modified for IPv6. Use a robust definition of struct sockaddr_storage, do a proper configure test to see if ss_len exists, don't assume that getnameinfo() will handle AF_UNIX sockets, don't trust getaddrinfo to return the protocol we ask for, etc. This incorporates several outstanding patches from Kurt Roeckx, but I'm to blame for anything that doesn't work ...
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/libpq/auth.c11
-rw-r--r--src/backend/libpq/hba.c55
-rw-r--r--src/backend/libpq/ip.c114
-rw-r--r--src/backend/libpq/pqcomm.c47
-rw-r--r--src/backend/postmaster/pgstat.c33
-rw-r--r--src/backend/postmaster/postmaster.c141
6 files changed, 258 insertions, 143 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index ca6bfcf4d7..a24f097846 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.104 2003/07/22 19:00:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.105 2003/07/23 23:30:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -434,11 +434,10 @@ ClientAuthentication(Port *port)
{
char hostinfo[NI_MAXHOST];
- getnameinfo((struct sockaddr *) &port->raddr.addr,
- port->raddr.salen,
- hostinfo, sizeof(hostinfo),
- NULL, 0,
- NI_NUMERICHOST);
+ getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+ hostinfo, sizeof(hostinfo),
+ NULL, 0,
+ NI_NUMERICHOST);
ereport(FATAL,
(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index f0bd0b8515..0d98e729a4 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.106 2003/07/22 21:19:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.107 2003/07/23 23:30:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -648,31 +648,33 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
hints.ai_next = NULL;
/* Get the IP address either way */
- ret = getaddrinfo2(token, NULL, &hints, &file_ip_addr);
+ ret = getaddrinfo_all(token, NULL, &hints, &file_ip_addr);
if (ret || !file_ip_addr)
{
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("failed to interpret IP address \"%s\" in config file: %s",
+ errmsg("could not interpret IP address \"%s\" in config file: %s",
token, gai_strerror(ret))));
if (cidr_slash)
*cidr_slash = '/';
goto hba_syntax;
}
+ if (cidr_slash)
+ *cidr_slash = '/';
+
if (file_ip_addr->ai_family != port->raddr.addr.ss_family)
{
/* Wrong address family. */
- freeaddrinfo2(hints.ai_family, file_ip_addr);
+ freeaddrinfo_all(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)
+ file_ip_addr->ai_family) < 0)
goto hba_syntax;
}
else
@@ -683,13 +685,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
goto hba_syntax;
token = lfirst(line);
- ret = getaddrinfo2(token, NULL, &hints, &file_ip_mask);
+ ret = getaddrinfo_all(token, NULL, &hints, &file_ip_mask);
if (ret || !file_ip_mask)
goto hba_syntax;
mask = (struct sockaddr_storage *)file_ip_mask->ai_addr;
- if(file_ip_addr->ai_family != mask->ss_family)
+ if (file_ip_addr->ai_family != mask->ss_family)
goto hba_syntax;
}
@@ -703,12 +705,13 @@ parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p)
/* Must meet network restrictions */
if (!rangeSockAddr(&port->raddr.addr,
- (struct sockaddr_storage *)file_ip_addr->ai_addr, mask))
+ (struct sockaddr_storage *)file_ip_addr->ai_addr,
+ mask))
goto hba_freeaddr;
- freeaddrinfo2(hints.ai_family, file_ip_addr);
+ freeaddrinfo_all(hints.ai_family, file_ip_addr);
if (file_ip_mask)
- freeaddrinfo2(hints.ai_family, file_ip_mask);
+ freeaddrinfo_all(hints.ai_family, file_ip_mask);
}
else
goto hba_syntax;
@@ -731,16 +734,16 @@ hba_syntax:
else
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
- errmsg("missing entry in pg_hba.conf file at end of line %d",
+ errmsg("missing field in pg_hba.conf file at end of line %d",
line_number)));
*error_p = true;
hba_freeaddr:
if (file_ip_addr)
- freeaddrinfo2(hints.ai_family, file_ip_addr);
+ freeaddrinfo_all(hints.ai_family, file_ip_addr);
if (file_ip_mask)
- freeaddrinfo2(hints.ai_family, file_ip_mask);
+ freeaddrinfo_all(hints.ai_family, file_ip_mask);
}
@@ -1209,14 +1212,14 @@ ident_inet(const SockAddr remote_addr,
* Might look a little weird to first convert it to text and
* then back to sockaddr, but it's protocol independent.
*/
- 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);
+ getnameinfo_all(&remote_addr.addr, remote_addr.salen,
+ remote_addr_s, sizeof(remote_addr_s),
+ remote_port, sizeof(remote_port),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ getnameinfo_all(&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;
@@ -1227,7 +1230,7 @@ ident_inet(const SockAddr remote_addr,
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
- rc = getaddrinfo2(remote_addr_s, ident_port, &hints, &ident_serv);
+ rc = getaddrinfo_all(remote_addr_s, ident_port, &hints, &ident_serv);
if (rc || !ident_serv)
return false; /* we don't expect this to happen */
@@ -1239,7 +1242,7 @@ ident_inet(const SockAddr remote_addr,
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
- rc = getaddrinfo2(local_addr_s, NULL, &hints, &la);
+ rc = getaddrinfo_all(local_addr_s, NULL, &hints, &la);
if (rc || !la)
return false; /* we don't expect this to happen */
@@ -1323,8 +1326,8 @@ ident_inet(const SockAddr remote_addr,
ident_inet_done:
if (sock_fd >= 0)
closesocket(sock_fd);
- freeaddrinfo2(remote_addr.addr.ss_family, ident_serv);
- freeaddrinfo2(local_addr.addr.ss_family, la);
+ freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
+ freeaddrinfo_all(local_addr.addr.ss_family, la);
return ident_return;
}
diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c
index 091b381ec1..c5a0a485ef 100644
--- a/src/backend/libpq/ip.c
+++ b/src/backend/libpq/ip.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.15 2003/06/12 08:15:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.16 2003/07/23 23:30:40 tgl Exp $
*
* This file and the IPV6 implementation were initially provided by
* Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
@@ -53,15 +53,20 @@ static int rangeSockAddrAF_INET6(const struct sockaddr_in6 *addr,
static int getaddrinfo_unix(const char *path,
const struct addrinfo *hintsp,
struct addrinfo **result);
+
+static int getnameinfo_unix(const struct sockaddr_un *sa, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags);
#endif
/*
- * getaddrinfo2 - get address info for Unix, IPv4 and IPv6 sockets
+ * getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets
*/
int
-getaddrinfo2(const char *hostname, const char *servname,
- const struct addrinfo *hintp, struct addrinfo **result)
+getaddrinfo_all(const char *hostname, const char *servname,
+ const struct addrinfo *hintp, struct addrinfo **result)
{
#ifdef HAVE_UNIX_SOCKETS
if (hintp != NULL && hintp->ai_family == AF_UNIX)
@@ -75,7 +80,7 @@ getaddrinfo2(const char *hostname, const char *servname,
/*
- * freeaddrinfo2 - free addrinfo structures for IPv4, IPv6, or Unix
+ * freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix
*
* Note: the ai_family field of the original hint structure must be passed
* so that we can tell whether the addrinfo struct was built by the system's
@@ -84,12 +89,12 @@ getaddrinfo2(const char *hostname, const char *servname,
* not safe to look at ai_family in the addrinfo itself.
*/
void
-freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
+freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai)
{
#ifdef HAVE_UNIX_SOCKETS
if (hint_ai_family == AF_UNIX)
{
- /* struct was built by getaddrinfo_unix (see getaddrinfo2) */
+ /* struct was built by getaddrinfo_unix (see getaddrinfo_all) */
while (ai != NULL)
{
struct addrinfo *p = ai;
@@ -109,11 +114,53 @@ freeaddrinfo2(int hint_ai_family, struct addrinfo *ai)
}
+/*
+ * getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets
+ *
+ * The API of this routine differs from the standard getnameinfo() definition
+ * in two ways: first, the addr parameter is declared as sockaddr_storage
+ * rather than struct sockaddr, and second, the node and service fields are
+ * guaranteed to be filled with something even on failure return.
+ */
+int
+getnameinfo_all(const struct sockaddr_storage *addr, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags)
+{
+ int rc;
+
+#ifdef HAVE_UNIX_SOCKETS
+ if (addr && addr->ss_family == AF_UNIX)
+ rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
+ node, nodelen,
+ service, servicelen,
+ flags);
+ else
+#endif
+ rc = getnameinfo((const struct sockaddr *) addr, salen,
+ node, nodelen,
+ service, servicelen,
+ flags);
+
+ if (rc != 0)
+ {
+ if (node)
+ StrNCpy(node, "???", nodelen);
+ if (service)
+ StrNCpy(service, "???", servicelen);
+ }
+
+ return rc;
+}
+
+
#if defined(HAVE_UNIX_SOCKETS)
+
/* -------
* getaddrinfo_unix - get unix socket info using IPv6-compatible API
*
- * Bug: only one addrinfo is set even though hintsp is NULL or
+ * Bugs: only one addrinfo is set even though hintsp is NULL or
* ai_socktype is 0
* AI_CANONNAME is not supported.
* -------
@@ -176,12 +223,59 @@ getaddrinfo_unix(const char *path, const struct addrinfo *hintsp,
strcpy(unp->sun_path, path);
-#if SALEN
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
unp->sun_len = sizeof(struct sockaddr_un);
-#endif /* SALEN */
+#endif
+
+ return 0;
+}
+
+/*
+ * Convert an address to a hostname.
+ */
+static int
+getnameinfo_unix(const struct sockaddr_un *sa, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags)
+{
+ int ret = -1;
+
+ /* Invalid arguments. */
+ if (sa == NULL || sa->sun_family != AF_UNIX ||
+ (node == NULL && service == NULL))
+ {
+ return EAI_FAIL;
+ }
+
+ /* We don't support those. */
+ if ((node && !(flags & NI_NUMERICHOST))
+ || (service && !(flags & NI_NUMERICSERV)))
+ {
+ return EAI_FAIL;
+ }
+
+ if (node)
+ {
+ ret = snprintf(node, nodelen, "%s", "localhost");
+ if (ret == -1 || ret > nodelen)
+ {
+ return EAI_MEMORY;
+ }
+ }
+
+ if (service)
+ {
+ ret = snprintf(service, servicelen, "%s", sa->sun_path);
+ if (ret == -1 || ret > servicelen)
+ {
+ return EAI_MEMORY;
+ }
+ }
return 0;
}
+
#endif /* HAVE_UNIX_SOCKETS */
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 7f3013925a..7cd9e23f32 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -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.158 2003/07/22 19:00:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.159 2003/07/23 23:30:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -190,16 +190,18 @@ StreamDoUnlink(void)
#endif /* HAVE_UNIX_SOCKETS */
/*
- * StreamServerPort -- open a sock stream "listening" port.
+ * StreamServerPort -- open a "listening" port to accept connections.
*
- * This initializes the Postmaster's connection-accepting port *fdP.
+ * Successfully opened sockets are added to the ListenSocket[] array,
+ * at the first position that isn't -1.
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
int
StreamServerPort(int family, char *hostName, unsigned short portNumber,
- char *unixSocketName, int ListenSocket[], int MaxListen)
+ char *unixSocketName,
+ int ListenSocket[], int MaxListen)
{
int fd,
err;
@@ -216,7 +218,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
/* Initialize hint structure */
MemSet(&hint, 0, sizeof(hint));
hint.ai_family = family;
- hint.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
+ hint.ai_flags = AI_PASSIVE;
hint.ai_socktype = SOCK_STREAM;
#ifdef HAVE_UNIX_SOCKETS
@@ -234,13 +236,18 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
service = portNumberStr;
}
- ret = getaddrinfo2(hostName, service, &hint, &addrs);
- if (ret || addrs == NULL)
+ ret = getaddrinfo_all(hostName, service, &hint, &addrs);
+ if (ret || !addrs)
{
- ereport(LOG,
- (errmsg("failed to translate hostname to address: %s",
- gai_strerror(ret))));
- freeaddrinfo2(hint.ai_family, addrs);
+ if (hostName)
+ ereport(LOG,
+ (errmsg("could not translate hostname \"%s\", service \"%s\" to address: %s",
+ hostName, service, gai_strerror(ret))));
+ else
+ ereport(LOG,
+ (errmsg("could not translate service \"%s\" to address: %s",
+ service, gai_strerror(ret))));
+ freeaddrinfo_all(hint.ai_family, addrs);
return STATUS_ERROR;
}
@@ -250,7 +257,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
/* Only set up a unix domain socket when
* they really asked for it. The service/port
- * is different in that case. */
+ * is different in that case.
+ */
continue;
}
@@ -258,17 +266,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
for (; listen_index < MaxListen; listen_index++)
{
if (ListenSocket[listen_index] == -1)
- {
break;
- }
}
- if (listen_index == MaxListen)
+ if (listen_index >= MaxListen)
{
/* Nothing found. */
break;
}
- if ((fd = socket(addr->ai_family, addr->ai_socktype,
- addr->ai_protocol)) < 0)
+
+ if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
{
ereport(LOG,
(errcode_for_socket_access(),
@@ -276,8 +282,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
continue;
}
-
-
if (!IS_AF_UNIX(addr->ai_family))
{
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
@@ -363,12 +367,11 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
added++;
}
- freeaddrinfo(addrs);
+ freeaddrinfo_all(hint.ai_family, addrs);
if (!added)
- {
return STATUS_ERROR;
- }
+
return STATUS_OK;
}
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 5ed1247e95..f8882737ee 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.39 2003/07/22 19:13:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.40 2003/07/23 23:30:40 tgl Exp $
* ----------
*/
#include "postgres.h"
@@ -147,7 +147,7 @@ void
pgstat_init(void)
{
ACCEPT_TYPE_ARG3 alen;
- struct addrinfo *addr = NULL, hints;
+ struct addrinfo *addrs = NULL, *addr, hints;
int ret;
/*
@@ -189,17 +189,27 @@ pgstat_init(void)
hints.ai_addr = NULL;
hints.ai_canonname = NULL;
hints.ai_next = NULL;
- ret = getaddrinfo2("localhost", NULL, &hints, &addr);
- if (ret || !addr)
+ ret = getaddrinfo_all("localhost", NULL, &hints, &addrs);
+ if (ret || !addrs)
{
ereport(LOG,
- (errmsg("getaddrinfo2(\"localhost\") failed: %s",
+ (errmsg("could not resolve \"localhost\": %s",
gai_strerror(ret))));
goto startup_failed;
}
- if ((pgStatSock = socket(addr->ai_family,
- addr->ai_socktype, addr->ai_protocol)) < 0)
+ for (addr = addrs; addr; addr = addr->ai_next)
+ {
+#ifdef HAVE_UNIX_SOCKETS
+ /* Ignore AF_UNIX sockets, if any are returned. */
+ if (addr->ai_family == AF_UNIX)
+ continue;
+#endif
+ if ((pgStatSock = socket(addr->ai_family, SOCK_DGRAM, 0)) >= 0)
+ break;
+ }
+
+ if (!addr || pgStatSock < 0)
{
ereport(LOG,
(errcode_for_socket_access(),
@@ -218,8 +228,9 @@ pgstat_init(void)
errmsg("could not bind socket for statistics: %m")));
goto startup_failed;
}
- freeaddrinfo2(hints.ai_family, addr);
- addr = NULL;
+
+ freeaddrinfo_all(hints.ai_family, addrs);
+ addrs = NULL;
alen = sizeof(pgStatAddr);
if (getsockname(pgStatSock, (struct sockaddr *)&pgStatAddr, &alen) < 0)
@@ -272,8 +283,8 @@ pgstat_init(void)
return;
startup_failed:
- if (addr)
- freeaddrinfo2(hints.ai_family, addr);
+ if (addrs)
+ freeaddrinfo_all(hints.ai_family, addrs);
if (pgStatSock >= 0)
closesocket(pgStatSock);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 614c76e64e..fb64781bf8 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.335 2003/07/22 20:29:13 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.336 2003/07/23 23:30:40 tgl Exp $
*
* NOTES
*
@@ -168,9 +168,9 @@ int ReservedBackends;
static char *progname = (char *) NULL;
-/* The sockets we're listening to. */
+/* The socket(s) we're listening to. */
#define MAXLISTEN 10
-int ListenSocket[MAXLISTEN];
+static int ListenSocket[MAXLISTEN];
/* Used to reduce macros tests */
#ifdef EXEC_BACKEND
@@ -277,7 +277,7 @@ static int ServerLoop(void);
static int BackendStartup(Port *port);
static int ProcessStartupPacket(Port *port, bool SSLdone);
static void processCancelRequest(Port *port, void *pkt);
-static int initMasks(fd_set *rmask, fd_set *wmask);
+static int initMasks(fd_set *rmask);
static void report_fork_failure_to_client(Port *port, int errnum);
enum CAC_state
{
@@ -727,73 +727,80 @@ PostmasterMain(int argc, char *argv[])
* Establish input sockets.
*/
for (i = 0; i < MAXLISTEN; i++)
- {
ListenSocket[i] = -1;
- }
+
if (NetServer)
{
if (VirtualHost && VirtualHost[0])
{
- char *p, *q;
+ char *curhost, *endptr;
char c = 0;
- q = VirtualHost;
- do
+ curhost = VirtualHost;
+ for (;;)
{
- p = strchr(q, ' ');
- if (p)
+ while (*curhost == ' ') /* skip any extra spaces */
+ curhost++;
+ if (*curhost == '\0')
+ break;
+ endptr = strchr(curhost, ' ');
+ if (endptr)
{
- c = *p;
- *p = '\0';
+ c = *endptr;
+ *endptr = '\0';
}
- status = StreamServerPort(AF_UNSPEC, q,
- (unsigned short) PostPortNumber,
- UnixSocketDir, ListenSocket, MAXLISTEN);
+ status = StreamServerPort(AF_UNSPEC, curhost,
+ (unsigned short) PostPortNumber,
+ UnixSocketDir,
+ ListenSocket, MAXLISTEN);
if (status != STATUS_OK)
{
- postmaster_error("cannot create tcpip "
- "listen socket for: %s", p);
+ postmaster_error("could not create listen socket for \"%s\"",
+ curhost);
}
- if (p)
+ if (endptr)
{
- *p = c;
- q = p + 1;
+ *endptr = c;
+ curhost = endptr + 1;
}
+ else
+ break;
}
- while (p);
}
else
{
status = StreamServerPort(AF_UNSPEC, NULL,
- (unsigned short) PostPortNumber,
- UnixSocketDir, ListenSocket, MAXLISTEN);
+ (unsigned short) PostPortNumber,
+ UnixSocketDir,
+ ListenSocket, MAXLISTEN);
if (status != STATUS_OK)
{
- postmaster_error("cannot create tcpip listen "
- "socket.");
+ postmaster_error("could not create TCP/IP listen socket");
}
}
+
#ifdef USE_RENDEZVOUS
- if (rendezvous_name != NULL)
- {
- DNSServiceRegistrationCreate(rendezvous_name,
- "_postgresql._tcp.",
- "",
- htonl(PostPortNumber),
- "",
- (DNSServiceRegistrationReply)reg_reply,
- NULL);
- }
+ if (rendezvous_name != NULL)
+ {
+ DNSServiceRegistrationCreate(rendezvous_name,
+ "_postgresql._tcp.",
+ "",
+ htonl(PostPortNumber),
+ "",
+ (DNSServiceRegistrationReply)reg_reply,
+ NULL);
+ }
#endif
}
#ifdef HAVE_UNIX_SOCKETS
status = StreamServerPort(AF_UNIX, NULL,
- (unsigned short) PostPortNumber,
- UnixSocketDir, ListenSocket, MAXLISTEN);
+ (unsigned short) PostPortNumber,
+ UnixSocketDir,
+ ListenSocket, MAXLISTEN);
if (status != STATUS_OK)
{
- postmaster_error("cannot create UNIX stream port");
+ postmaster_error("could not create UNIX stream port");
ExitPostmaster(1);
}
#endif
@@ -994,7 +1001,7 @@ usage(const char *progname)
static int
ServerLoop(void)
{
- fd_set readmask, writemask;
+ fd_set readmask;
int nSockets;
struct timeval now, later;
struct timezone tz;
@@ -1002,13 +1009,12 @@ ServerLoop(void)
gettimeofday(&now, &tz);
- nSockets = initMasks(&readmask, &writemask);
+ nSockets = initMasks(&readmask);
for (;;)
{
Port *port;
- fd_set rmask,
- wmask;
+ fd_set rmask;
struct timeval timeout;
/*
@@ -1057,11 +1063,11 @@ ServerLoop(void)
* Wait for something to happen.
*/
memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set));
- memcpy((char *) &wmask, (char *) &writemask, sizeof(fd_set));
PG_SETMASK(&UnBlockSig);
- if (select(nSockets, &rmask, &wmask, (fd_set *) NULL, &timeout) < 0)
+ if (select(nSockets, &rmask, (fd_set *) NULL,
+ (fd_set *) NULL, &timeout) < 0)
{
PG_SETMASK(&BlockSig);
if (errno == EINTR || errno == EWOULDBLOCK)
@@ -1096,12 +1102,14 @@ ServerLoop(void)
}
/*
- * New connection pending on our well-known port's socket? If so,
+ * New connection pending on any of our sockets? If so,
* fork a child process to deal with it.
*/
for (i = 0; i < MAXLISTEN; i++)
{
- if (ListenSocket[i] != -1 && FD_ISSET(ListenSocket[i], &rmask))
+ if (ListenSocket[i] == -1)
+ break;
+ if (FD_ISSET(ListenSocket[i], &rmask))
{
port = ConnCreate(ListenSocket[i]);
if (port)
@@ -1126,28 +1134,27 @@ ServerLoop(void)
/*
- * Initialise the read and write masks for select() for the well-known ports
+ * Initialise the masks for select() for the ports
* we are listening on. Return the number of sockets to listen on.
*/
static int
-initMasks(fd_set *rmask, fd_set *wmask)
+initMasks(fd_set *rmask)
{
int nsocks = -1;
int i;
FD_ZERO(rmask);
- FD_ZERO(wmask);
for (i = 0; i < MAXLISTEN; i++)
{
int fd = ListenSocket[i];
- if (fd != -1)
- {
- FD_SET(fd, rmask);
- if (fd > nsocks)
- nsocks = fd;
- }
+
+ if (fd == -1)
+ break;
+ FD_SET(fd, rmask);
+ if (fd > nsocks)
+ nsocks = fd;
}
return nsocks + 1;
@@ -2352,17 +2359,15 @@ BackendFork(Port *port)
*/
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))
- {
- getnameinfo((struct sockaddr *)&port->raddr.addr,
- port->raddr.salen,
- remote_host, sizeof(remote_host),
- remote_port, sizeof(remote_host),
- NI_NUMERICHOST | NI_NUMERICSERV);
+ if (getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+ remote_host, sizeof(remote_host),
+ remote_port, sizeof(remote_port),
+ (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV))
+ {
+ getnameinfo_all(&port->raddr.addr, port->raddr.salen,
+ remote_host, sizeof(remote_host),
+ remote_port, sizeof(remote_port),
+ NI_NUMERICHOST | NI_NUMERICSERV);
}
if (Log_connections)
@@ -2373,7 +2378,7 @@ BackendFork(Port *port)
if (LogSourcePort)
{
/* modify remote_host for use in ps status */
- char tmphost[sizeof(remote_host) + 10];
+ char tmphost[NI_MAXHOST];
snprintf(tmphost, sizeof(tmphost), "%s:%s", remote_host, remote_port);
StrNCpy(remote_host, tmphost, sizeof(remote_host));