Skip to content

Commit a86b2da

Browse files
committed
check socket creation errors against PGINVALID_SOCKET
Previously, in some places, socket creation errors were checked for negative values, which is not true for Windows because sockets are unsigned. This masked socket creation errors on Windows. Backpatch through 9.0. 8.4 doesn't have the infrastructure to fix this.
1 parent 79eb0eb commit a86b2da

File tree

7 files changed

+42
-17
lines changed

7 files changed

+42
-17
lines changed

src/backend/libpq/auth.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,7 +1664,7 @@ ident_inet(const SockAddr remote_addr,
16641664

16651665
sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
16661666
ident_serv->ai_protocol);
1667-
if (sock_fd < 0)
1667+
if (sock_fd == PGINVALID_SOCKET)
16681668
{
16691669
ereport(LOG,
16701670
(errcode_for_socket_access(),
@@ -1744,7 +1744,7 @@ ident_inet(const SockAddr remote_addr,
17441744
ident_response)));
17451745

17461746
ident_inet_done:
1747-
if (sock_fd >= 0)
1747+
if (sock_fd != PGINVALID_SOCKET)
17481748
closesocket(sock_fd);
17491749
pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
17501750
pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
@@ -2750,7 +2750,7 @@ CheckRADIUSAuth(Port *port)
27502750
packet->length = htons(packet->length);
27512751

27522752
sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
2753-
if (sock < 0)
2753+
if (sock == PGINVALID_SOCKET)
27542754
{
27552755
ereport(LOG,
27562756
(errmsg("could not create RADIUS socket: %m")));

src/backend/libpq/ip.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
552552
int error;
553553

554554
sock = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
555-
if (sock == SOCKET_ERROR)
555+
if (sock == INVALID_SOCKET)
556556
return -1;
557557

558558
while (n_ii < 1024)
@@ -675,7 +675,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
675675
total;
676676

677677
sock = socket(AF_INET, SOCK_DGRAM, 0);
678-
if (sock == -1)
678+
if (sock == PGINVALID_SOCKET)
679679
return -1;
680680

681681
while (n_buffer < 1024 * 100)
@@ -716,7 +716,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
716716
#ifdef HAVE_IPV6
717717
/* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */
718718
sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
719-
if (sock6 == -1)
719+
if (sock6 == PGINVALID_SOCKET)
720720
{
721721
free(buffer);
722722
close(sock);
@@ -793,10 +793,10 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
793793
char *ptr,
794794
*buffer = NULL;
795795
size_t n_buffer = 1024;
796-
int sock;
796+
pgsocket sock;
797797

798798
sock = socket(AF_INET, SOCK_DGRAM, 0);
799-
if (sock == -1)
799+
if (sock == PGINVALID_SOCKET)
800800
return -1;
801801

802802
while (n_buffer < 1024 * 100)

src/backend/libpq/pqcomm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
351351
break;
352352
}
353353

354-
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
354+
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
355355
{
356356
ereport(LOG,
357357
(errcode_for_socket_access(),
@@ -594,7 +594,7 @@ StreamConnection(pgsocket server_fd, Port *port)
594594
port->raddr.salen = sizeof(port->raddr.addr);
595595
if ((port->sock = accept(server_fd,
596596
(struct sockaddr *) & port->raddr.addr,
597-
&port->raddr.salen)) < 0)
597+
&port->raddr.salen)) == PGINVALID_SOCKET)
598598
{
599599
ereport(LOG,
600600
(errcode_for_socket_access(),

src/backend/port/win32/socket.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ int
131131
pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
132132
{
133133
static HANDLE waitevent = INVALID_HANDLE_VALUE;
134-
static SOCKET current_socket = -1;
134+
static SOCKET current_socket = INVALID_SOCKET;
135135
static int isUDP = 0;
136136
HANDLE events[2];
137137
int r;

src/backend/postmaster/postmaster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,7 @@ ConnCreate(int serverFd)
19821982

19831983
if (StreamConnection(serverFd, port) != STATUS_OK)
19841984
{
1985-
if (port->sock >= 0)
1985+
if (port->sock != PGINVALID_SOCKET)
19861986
StreamClose(port->sock);
19871987
ConnFree(port);
19881988
return NULL;

src/interfaces/libpq/fe-connect.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,8 +1480,23 @@ PQconnectPoll(PGconn *conn)
14801480
conn->raddr.salen = addr_cur->ai_addrlen;
14811481

14821482
/* Open a socket */
1483-
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1484-
if (conn->sock < 0)
1483+
{
1484+
/*
1485+
* While we use 'pgsocket' as the socket type in the
1486+
* backend, we use 'int' for libpq socket values.
1487+
* This requires us to map PGINVALID_SOCKET to -1
1488+
* on Windows.
1489+
* See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx
1490+
*/
1491+
pgsocket sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1492+
#ifdef WIN32
1493+
if (sock == PGINVALID_SOCKET)
1494+
conn->sock = -1;
1495+
else
1496+
#endif
1497+
conn->sock = sock;
1498+
}
1499+
if (conn->sock == -1)
14851500
{
14861501
/*
14871502
* ignore socket() failure if we have more addresses
@@ -2892,7 +2907,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
28922907
char *errbuf, int errbufsize)
28932908
{
28942909
int save_errno = SOCK_ERRNO;
2895-
int tmpsock = -1;
2910+
pgsocket tmpsock = PGINVALID_SOCKET;
28962911
char sebuf[256];
28972912
int maxlen;
28982913
struct
@@ -2905,7 +2920,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
29052920
* We need to open a temporary connection to the postmaster. Do this with
29062921
* only kernel calls.
29072922
*/
2908-
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) < 0)
2923+
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
29092924
{
29102925
strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
29112926
goto cancel_errReturn;
@@ -2976,7 +2991,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
29762991
maxlen);
29772992
strcat(errbuf, "\n");
29782993
}
2979-
if (tmpsock >= 0)
2994+
if (tmpsock != PGINVALID_SOCKET)
29802995
closesocket(tmpsock);
29812996
SOCK_ERRNO_SET(save_errno);
29822997
return FALSE;
@@ -4389,6 +4404,15 @@ PQerrorMessage(const PGconn *conn)
43894404
return conn->errorMessage.data;
43904405
}
43914406

4407+
/*
4408+
* In Windows, socket values are unsigned, and an invalid socket value
4409+
* (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
4410+
* warning). Ideally we would return an unsigned value for PQsocket() on
4411+
* Windows, but that would cause the function's return value to differ from
4412+
* Unix, so we just return -1 for invalid sockets.
4413+
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
4414+
* http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
4415+
*/
43924416
int
43934417
PQsocket(const PGconn *conn)
43944418
{

src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ struct pg_conn
342342
PGnotify *notifyTail; /* newest unreported Notify msg */
343343

344344
/* Connection data */
345+
/* See PQconnectPoll() for how we use 'int' and not 'pgsocket'. */
345346
int sock; /* Unix FD for socket, -1 if not connected */
346347
SockAddr laddr; /* Local address */
347348
SockAddr raddr; /* Remote address */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy