Skip to content

Commit bed499e

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 61df3d0 commit bed499e

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
@@ -1677,7 +1677,7 @@ ident_inet(hbaPort *port)
16771677

16781678
sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
16791679
ident_serv->ai_protocol);
1680-
if (sock_fd < 0)
1680+
if (sock_fd == PGINVALID_SOCKET)
16811681
{
16821682
ereport(LOG,
16831683
(errcode_for_socket_access(),
@@ -1757,7 +1757,7 @@ ident_inet(hbaPort *port)
17571757
ident_response)));
17581758

17591759
ident_inet_done:
1760-
if (sock_fd >= 0)
1760+
if (sock_fd != PGINVALID_SOCKET)
17611761
closesocket(sock_fd);
17621762
pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
17631763
pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
@@ -2580,7 +2580,7 @@ CheckRADIUSAuth(Port *port)
25802580
packet->length = htons(packet->length);
25812581

25822582
sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
2583-
if (sock < 0)
2583+
if (sock == PGINVALID_SOCKET)
25842584
{
25852585
ereport(LOG,
25862586
(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
@@ -547,7 +547,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
547547
int error;
548548

549549
sock = WSASocket(AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
550-
if (sock == SOCKET_ERROR)
550+
if (sock == INVALID_SOCKET)
551551
return -1;
552552

553553
while (n_ii < 1024)
@@ -670,7 +670,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
670670
total;
671671

672672
sock = socket(AF_INET, SOCK_DGRAM, 0);
673-
if (sock == -1)
673+
if (sock == PGINVALID_SOCKET)
674674
return -1;
675675

676676
while (n_buffer < 1024 * 100)
@@ -711,7 +711,7 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
711711
#ifdef HAVE_IPV6
712712
/* We'll need an IPv6 socket too for the SIOCGLIFNETMASK ioctls */
713713
sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
714-
if (sock6 == -1)
714+
if (sock6 == PGINVALID_SOCKET)
715715
{
716716
free(buffer);
717717
close(sock);
@@ -788,10 +788,10 @@ pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
788788
char *ptr,
789789
*buffer = NULL;
790790
size_t n_buffer = 1024;
791-
int sock;
791+
pgsocket sock;
792792

793793
sock = socket(AF_INET, SOCK_DGRAM, 0);
794-
if (sock == -1)
794+
if (sock == PGINVALID_SOCKET)
795795
return -1;
796796

797797
while (n_buffer < 1024 * 100)

src/backend/libpq/pqcomm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
363363
break;
364364
}
365365

366-
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
366+
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
367367
{
368368
ereport(LOG,
369369
(errcode_for_socket_access(),
@@ -606,7 +606,7 @@ StreamConnection(pgsocket server_fd, Port *port)
606606
port->raddr.salen = sizeof(port->raddr.addr);
607607
if ((port->sock = accept(server_fd,
608608
(struct sockaddr *) & port->raddr.addr,
609-
&port->raddr.salen)) < 0)
609+
&port->raddr.salen)) == PGINVALID_SOCKET)
610610
{
611611
ereport(LOG,
612612
(errcode_for_socket_access(),

src/backend/port/win32/socket.c

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

src/backend/postmaster/postmaster.c

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

20142014
if (StreamConnection(serverFd, port) != STATUS_OK)
20152015
{
2016-
if (port->sock >= 0)
2016+
if (port->sock != PGINVALID_SOCKET)
20172017
StreamClose(port->sock);
20182018
ConnFree(port);
20192019
return NULL;

src/interfaces/libpq/fe-connect.c

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

15871587
/* Open a socket */
1588-
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1589-
if (conn->sock < 0)
1588+
{
1589+
/*
1590+
* While we use 'pgsocket' as the socket type in the
1591+
* backend, we use 'int' for libpq socket values.
1592+
* This requires us to map PGINVALID_SOCKET to -1
1593+
* on Windows.
1594+
* See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx
1595+
*/
1596+
pgsocket sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1597+
#ifdef WIN32
1598+
if (sock == PGINVALID_SOCKET)
1599+
conn->sock = -1;
1600+
else
1601+
#endif
1602+
conn->sock = sock;
1603+
}
1604+
if (conn->sock == -1)
15901605
{
15911606
/*
15921607
* ignore socket() failure if we have more addresses
@@ -3123,7 +3138,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
31233138
char *errbuf, int errbufsize)
31243139
{
31253140
int save_errno = SOCK_ERRNO;
3126-
int tmpsock = -1;
3141+
pgsocket tmpsock = PGINVALID_SOCKET;
31273142
char sebuf[256];
31283143
int maxlen;
31293144
struct
@@ -3136,7 +3151,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
31363151
* We need to open a temporary connection to the postmaster. Do this with
31373152
* only kernel calls.
31383153
*/
3139-
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) < 0)
3154+
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
31403155
{
31413156
strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
31423157
goto cancel_errReturn;
@@ -3207,7 +3222,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
32073222
maxlen);
32083223
strcat(errbuf, "\n");
32093224
}
3210-
if (tmpsock >= 0)
3225+
if (tmpsock != PGINVALID_SOCKET)
32113226
closesocket(tmpsock);
32123227
SOCK_ERRNO_SET(save_errno);
32133228
return FALSE;
@@ -4620,6 +4635,15 @@ PQerrorMessage(const PGconn *conn)
46204635
return conn->errorMessage.data;
46214636
}
46224637

4638+
/*
4639+
* In Windows, socket values are unsigned, and an invalid socket value
4640+
* (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
4641+
* warning). Ideally we would return an unsigned value for PQsocket() on
4642+
* Windows, but that would cause the function's return value to differ from
4643+
* Unix, so we just return -1 for invalid sockets.
4644+
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
4645+
* http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
4646+
*/
46234647
int
46244648
PQsocket(const PGconn *conn)
46254649
{

src/interfaces/libpq/libpq-int.h

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

350350
/* Connection data */
351+
/* See PQconnectPoll() for how we use 'int' and not 'pgsocket'. */
351352
int sock; /* Unix FD for socket, -1 if not connected */
352353
SockAddr laddr; /* Local address */
353354
SockAddr raddr; /* Remote address */

0 commit comments

Comments
 (0)