Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4180934

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 848b9f0 commit 4180934

File tree

7 files changed

+42
-17
lines changed

7 files changed

+42
-17
lines changed

src/backend/libpq/auth.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,7 @@ ident_inet(hbaPort *port)
14631463

14641464
sock_fd = socket(ident_serv->ai_family, ident_serv->ai_socktype,
14651465
ident_serv->ai_protocol);
1466-
if (sock_fd < 0)
1466+
if (sock_fd == PGINVALID_SOCKET)
14671467
{
14681468
ereport(LOG,
14691469
(errcode_for_socket_access(),
@@ -1543,7 +1543,7 @@ ident_inet(hbaPort *port)
15431543
ident_response)));
15441544

15451545
ident_inet_done:
1546-
if (sock_fd >= 0)
1546+
if (sock_fd != PGINVALID_SOCKET)
15471547
closesocket(sock_fd);
15481548
pg_freeaddrinfo_all(remote_addr.addr.ss_family, ident_serv);
15491549
pg_freeaddrinfo_all(local_addr.addr.ss_family, la);
@@ -2361,7 +2361,7 @@ CheckRADIUSAuth(Port *port)
23612361
packet->length = htons(packet->length);
23622362

23632363
sock = socket(serveraddrs[0].ai_family, SOCK_DGRAM, 0);
2364-
if (sock < 0)
2364+
if (sock == PGINVALID_SOCKET)
23652365
{
23662366
ereport(LOG,
23672367
(errmsg("could not create RADIUS socket: %m")));

src/backend/libpq/ip.c

+5-5
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

+2-2
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
392392
break;
393393
}
394394

395-
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) < 0)
395+
if ((fd = socket(addr->ai_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
396396
{
397397
ereport(LOG,
398398
(errcode_for_socket_access(),
@@ -632,7 +632,7 @@ StreamConnection(pgsocket server_fd, Port *port)
632632
port->raddr.salen = sizeof(port->raddr.addr);
633633
if ((port->sock = accept(server_fd,
634634
(struct sockaddr *) & port->raddr.addr,
635-
&port->raddr.salen)) < 0)
635+
&port->raddr.salen)) == PGINVALID_SOCKET)
636636
{
637637
ereport(LOG,
638638
(errcode_for_socket_access(),

src/backend/port/win32/socket.c

+1-1
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ ConnCreate(int serverFd)
21692169

21702170
if (StreamConnection(serverFd, port) != STATUS_OK)
21712171
{
2172-
if (port->sock >= 0)
2172+
if (port->sock != PGINVALID_SOCKET)
21732173
StreamClose(port->sock);
21742174
ConnFree(port);
21752175
return NULL;

src/interfaces/libpq/fe-connect.c

+29-5
Original file line numberDiff line numberDiff line change
@@ -1632,8 +1632,23 @@ PQconnectPoll(PGconn *conn)
16321632
conn->raddr.salen = addr_cur->ai_addrlen;
16331633

16341634
/* Open a socket */
1635-
conn->sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1636-
if (conn->sock < 0)
1635+
{
1636+
/*
1637+
* While we use 'pgsocket' as the socket type in the
1638+
* backend, we use 'int' for libpq socket values.
1639+
* This requires us to map PGINVALID_SOCKET to -1
1640+
* on Windows.
1641+
* See http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx
1642+
*/
1643+
pgsocket sock = socket(addr_cur->ai_family, SOCK_STREAM, 0);
1644+
#ifdef WIN32
1645+
if (sock == PGINVALID_SOCKET)
1646+
conn->sock = -1;
1647+
else
1648+
#endif
1649+
conn->sock = sock;
1650+
}
1651+
if (conn->sock == -1)
16371652
{
16381653
/*
16391654
* ignore socket() failure if we have more addresses
@@ -3136,7 +3151,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
31363151
char *errbuf, int errbufsize)
31373152
{
31383153
int save_errno = SOCK_ERRNO;
3139-
int tmpsock = -1;
3154+
pgsocket tmpsock = PGINVALID_SOCKET;
31403155
char sebuf[256];
31413156
int maxlen;
31423157
struct
@@ -3149,7 +3164,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
31493164
* We need to open a temporary connection to the postmaster. Do this with
31503165
* only kernel calls.
31513166
*/
3152-
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) < 0)
3167+
if ((tmpsock = socket(raddr->addr.ss_family, SOCK_STREAM, 0)) == PGINVALID_SOCKET)
31533168
{
31543169
strlcpy(errbuf, "PQcancel() -- socket() failed: ", errbufsize);
31553170
goto cancel_errReturn;
@@ -3220,7 +3235,7 @@ internal_cancel(SockAddr *raddr, int be_pid, int be_key,
32203235
maxlen);
32213236
strcat(errbuf, "\n");
32223237
}
3223-
if (tmpsock >= 0)
3238+
if (tmpsock != PGINVALID_SOCKET)
32243239
closesocket(tmpsock);
32253240
SOCK_ERRNO_SET(save_errno);
32263241
return FALSE;
@@ -5300,6 +5315,15 @@ PQerrorMessage(const PGconn *conn)
53005315
return conn->errorMessage.data;
53015316
}
53025317

5318+
/*
5319+
* In Windows, socket values are unsigned, and an invalid socket value
5320+
* (INVALID_SOCKET) is ~0, which equals -1 in comparisons (with no compiler
5321+
* warning). Ideally we would return an unsigned value for PQsocket() on
5322+
* Windows, but that would cause the function's return value to differ from
5323+
* Unix, so we just return -1 for invalid sockets.
5324+
* http://msdn.microsoft.com/en-us/library/windows/desktop/cc507522%28v=vs.85%29.aspx
5325+
* http://stackoverflow.com/questions/10817252/why-is-invalid-socket-defined-as-0-in-winsock2-h-c
5326+
*/
53035327
int
53045328
PQsocket(const PGconn *conn)
53055329
{

src/interfaces/libpq/libpq-int.h

+1
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ struct pg_conn
364364
PGnotify *notifyTail; /* newest unreported Notify msg */
365365

366366
/* Connection data */
367+
/* See PQconnectPoll() for how we use 'int' and not 'pgsocket'. */
367368
int sock; /* Unix FD for socket, -1 if not connected */
368369
SockAddr laddr; /* Local address */
369370
SockAddr raddr; /* Remote address */

0 commit comments

Comments
 (0)