diff options
Diffstat (limited to 'src/backend')
| -rw-r--r-- | src/backend/libpq/auth.c | 20 | ||||
| -rw-r--r-- | src/backend/libpq/hba.c | 205 | ||||
| -rw-r--r-- | src/backend/libpq/ip.c | 231 | ||||
| -rw-r--r-- | src/backend/libpq/pg_hba.conf.sample | 4 | ||||
| -rw-r--r-- | src/backend/libpq/pqcomm.c | 207 | ||||
| -rw-r--r-- | src/backend/postmaster/pgstat.c | 61 | ||||
| -rw-r--r-- | src/backend/postmaster/postmaster.c | 291 |
7 files changed, 558 insertions, 461 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 2b0d2d65a8..46965e3bcb 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.101 2003/04/25 03:28:55 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.102 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); diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index 4310261a16..c277c90d1b 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.102 2003/06/12 07:00:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/hba.c,v 1.103 2003/06/12 07:36:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -542,9 +542,14 @@ static void parse_hba(List *line, hbaPort *port, bool *found_p, bool *error_p) { int line_number; - char *token; - char *db; - char *user; + 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) - goto hba_syntax; + /* Check if it has a CIDR suffix and if so isolate it */ + cidr_slash = index(token,'/'); + if (cidr_slash) + { + *cidr_slash = '\0'; + } - /* Read the mask field. */ - line = lnext(line); - if (!line) + 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; - token = lfirst(line); + } - if(SockAddr_pton(&mask, token) < 0) - 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; + } - if(file_ip_addr.sa.sa_family != mask.sa.sa_family) - goto hba_syntax; + /* 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); + + 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->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; + 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: diff --git a/src/backend/libpq/ip.c b/src/backend/libpq/ip.c index 203317be4e..59bee56e21 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.11 2003/06/12 07:00:57 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/ip.c,v 1.12 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,20 +36,19 @@ #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, - struct addrinfo **result); +#ifdef HAVE_UNIX_SOCKETS +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: + if (addr->ss_family == AF_INET) + return rangeSockAddrAF_INET((struct sockaddr_in *)addr, + (struct sockaddr_in *)netaddr, + (struct sockaddr_in *)netmask); #ifdef HAVE_IPV6 - inet_ntop(AF_INET, &sa->in.sin_addr, dst, cnt); -#else - StrNCpy(dst, inet_ntoa(sa->in.sin_addr), cnt); + else if (addr->ss_family == AF_INET6) + return rangeSockAddrAF_INET6((struct sockaddr_in6 *)addr, + (struct sockaddr_in6 *)netaddr, + (struct sockaddr_in6 *)netmask); #endif - break; -#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; -#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 + struct sockaddr_in6 mask6; +#endif + + bits = strtol(numbits, &endptr, 10); + + if (*numbits == '\0' || *endptr != '\0') + { + return -1; + } + if ((bits < 0) || (family == AF_INET && bits > 32) #ifdef HAVE_IPV6 - if (strchr(src, ':')) - family = AF_INET6; + || (family == AF_INET6 && bits > 128) #endif + ) + { + return -1; + } - sa->sa.sa_family = family; + *mask = &sock; switch (family) { case AF_INET: -#ifdef HAVE_IPV6 - return inet_pton(AF_INET, src, &sa->in.sin_addr); -#else - return inet_aton(src, &sa->in.sin_addr); -#endif - + 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 - return 0; + sock.ss_family = family; + return 0; } - int -rangeSockAddr(const SockAddr *addr, const SockAddr *netaddr, - const SockAddr *netmask) +rangeSockAddrAF_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 */ diff --git a/src/backend/libpq/pg_hba.conf.sample b/src/backend/libpq/pg_hba.conf.sample index 1116debbc1..52c0bd4d73 100644 --- a/src/backend/libpq/pg_hba.conf.sample +++ b/src/backend/libpq/pg_hba.conf.sample @@ -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 + diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index ea4ff64468..2cd2c9223f 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.156 2003/06/09 17:59:19 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.157 2003/06/12 07:36:51 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -199,33 +199,30 @@ StreamDoUnlink(void) int StreamServerPort(int family, char *hostName, unsigned short portNumber, - char *unixSocketName, int *fdP) + char *unixSocketName, int ListenSocket[], int MaxListen) { int fd, err; int maxconn; int one = 1; int ret; - char portNumberStr[64]; - char *service; - struct addrinfo *addrs = NULL; - struct addrinfo hint; - -#ifdef HAVE_UNIX_SOCKETS - Assert(family == AF_UNIX || isAF_INETx(family)); -#else - Assert(isAF_INETx(family)); -#endif + char portNumberStr[64]; + char *service; + struct addrinfo *addrs = NULL, *addr; + struct addrinfo hint; + 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,73 +243,132 @@ 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) { - elog(LOG, "server socket failure: socket(): %s", - strerror(errno)); - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; - } + 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; + } - if (isAF_INETx(family)) - { - if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, - sizeof(one))) == -1) + /* 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: setsockopt(SO_REUSEADDR): %s", + elog(LOG, "server socket failure: socket(): %s", strerror(errno)); - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; + continue; } - } - Assert(addrs->ai_next == NULL && addrs->ai_family == family); - err = bind(fd, addrs->ai_addr, addrs->ai_addrlen); - if (err < 0) - { - elog(LOG, "server socket failure: bind(): %s\n" - "\tIs another postmaster already running on port %d?", - strerror(errno), (int) portNumber); - if (family == AF_UNIX) - elog(LOG, "\tIf not, remove socket node (%s) and retry.", - sock_path); - else - elog(LOG, "\tIf not, wait a few seconds and retry."); - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; - } + + + if (!IS_AF_UNIX(addr->ai_family)) + { + if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, + (char *) &one, sizeof(one))) == -1) + { + elog(LOG, "server socket failure: " + "setsockopt(SO_REUSEADDR): %s", + strerror(errno)); + 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 + + /* + * 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" + "\tIs another postmaster already running on " + "port %d?", strerror(errno), (int) portNumber); + if (addr->ai_family == AF_UNIX) + { + elog(LOG, "\tIf not, remove socket node (%s) " + "and retry.", sock_path); + } + else + { + elog(LOG, "\tIf not, wait a few seconds and " + "retry."); + } + closesocket(fd); + continue; + } #ifdef HAVE_UNIX_SOCKETS - if (family == AF_UNIX) - { - if (Setup_AF_UNIX() != STATUS_OK) + if (addr->ai_family == AF_UNIX) { - freeaddrinfo2(hint.ai_family, addrs); - return STATUS_ERROR; + if (Setup_AF_UNIX() != STATUS_OK) + { + 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?). - */ - maxconn = MaxBackends * 2; - if (maxconn > PG_SOMAXCONN) - maxconn = PG_SOMAXCONN; + /* + * 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) + maxconn = PG_SOMAXCONN; + + err = listen(fd, maxconn); + if (err < 0) + { + elog(LOG, "server socket failure: listen(): %s", + strerror(errno)); + closesocket(fd); + continue; + } + ListenSocket[listen_index] = fd; + added++; + } - err = listen(fd, maxconn); - if (err < 0) + freeaddrinfo(addrs); + + if (!added) { - elog(LOG, "server socket failure: listen(): %s", - strerror(errno)); - freeaddrinfo2(hint.ai_family, addrs); return STATUS_ERROR; } - - *fdP = fd; - freeaddrinfo2(hint.ai_family, addrs); 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->raddr); + port->raddr.salen = sizeof(port->raddr.addr); if ((port->sock = accept(server_fd, - (struct sockaddr *) &port->raddr, - &addrlen)) < 0) + (struct sockaddr *) &port->raddr.addr, + &port->raddr.salen)) < 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->laddr); - if (getsockname(port->sock, (struct sockaddr *) & port->laddr, - &addrlen) < 0) + port->laddr.salen = sizeof(port->laddr.addr); + if (getsockname(port->sock, (struct sockaddr *) & port->laddr.addr, + &port->laddr.salen) < 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) { diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 2b8708fc5d..a0495fff85 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.36 2003/05/15 16:35:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.37 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,9 +1628,9 @@ pgstat_recvbuffer(void) if (FD_ISSET(pgStatSock, &rfds)) { fromlen = sizeof(fromaddr); - len = recvfrom(pgStatSock, - (char *) &input_buffer, sizeof(PgStat_Msg), 0, - (struct sockaddr *) &fromaddr, &fromlen); + len = recvfrom(pgStatSock, (char *) &input_buffer, + sizeof(PgStat_Msg), 0, + (struct sockaddr *) &fromaddr, &fromlen); if (len < 0) { elog(LOG, "PGSTATBUFF: recvfrom() failed: %m"); @@ -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; /* diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 5b16d06a99..e32a668bc7 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.332 2003/06/11 06:56:06 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.333 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 @@ -384,10 +379,11 @@ reg_reply(DNSServiceRegistrationReplyErrorType errorCode, void *context) int PostmasterMain(int argc, char *argv[]) { - int opt; - int status; + int opt; + int status; char original_extraoptions[MAXPGPATH]; - char *potential_DataDir = NULL; + 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, - (unsigned short) PostPortNumber, - UnixSocketDir, - &ServerSock_INET); - if (status != STATUS_OK) + if (VirtualHost && VirtualHost[0]) { - elog(LOG, "IPv6 support disabled --- perhaps the kernel does not support IPv6"); -#endif - status = StreamServerPort(AF_INET, VirtualHost, - (unsigned short) PostPortNumber, - UnixSocketDir, - &ServerSock_INET); + 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, ListenSocket, MAXLISTEN); + if (status != STATUS_OK) + { + 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, 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, - (unsigned short) PostPortNumber, - UnixSocketDir, - &ServerSock_UNIX); + status = StreamServerPort(AF_UNIX, NULL, + (unsigned short) PostPortNumber, + 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 timezone tz; + struct timeval now, later; + struct timezone tz; + int i; gettimeofday(&now, &tz); @@ -1065,40 +1080,22 @@ 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) + if (ListenSocket[i] != -1 && FD_ISSET(ListenSocket[i], &rmask)) { - 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)) - { - port = ConnCreate(ServerSock_INET); - if (port) - { - BackendStartup(port); - - /* - * We no longer need the open socket or port structure in - * this process - */ - StreamClose(port->sock); - ConnFree(port); + port = ConnCreate(ListenSocket[i]); + if (port) + { + BackendStartup(port); + + /* + * We no longer need the open socket + * or port structure in this process + */ + StreamClose(port->sock); + ConnFree(port); + } } } @@ -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) - { - FD_SET(ServerSock_INET, rmask); - if (ServerSock_INET > nsocks) - nsocks = ServerSock_INET; + int fd = ListenSocket[i]; + if (fd != -1) + { + 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,19 +2222,20 @@ split_opts(char **argv, int *argcp, char *s) static int BackendFork(Port *port) { - char *remote_host; - char **av; - int maxac; - int ac; + char **av; + int maxac; + int ac; char debugbuf[32]; char protobuf[32]; #ifdef EXEC_BACKEND char pbuf[NAMEDATALEN + 256]; #endif - int i; - int status; - struct timeval now; - struct timezone tz; + int i; + 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,63 +2283,37 @@ 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); - } - } - - if (remote_host == NULL) - remote_host = pstrdup(host_addr); - - if (Log_connections) - elog(LOG, "connection received: host=%s port=%hu", - remote_host, remote_port); - - if (LogSourcePort) - { - /* modify remote_host for use in ps status */ - 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; - } + getnameinfo((struct sockaddr *)&port->raddr.addr, + port->raddr.salen, + remote_host, sizeof(remote_host), + remote_port, sizeof(remote_host), + NI_NUMERICHOST | NI_NUMERICSERV); } - else + + if (Log_connections) { - /* not AF_INET */ - remote_host = "[local]"; + elog(LOG, "connection received: host=%s port=%s", + remote_host, remote_port); + } - if (Log_connections) - elog(LOG, "connection received: host=%s", - remote_host); + if (LogSourcePort) + { + /* modify remote_host for use in ps status */ + int slen = strlen(remote_host) + 10; + char *str = palloc(slen); + + 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); } |
