Commit cfeafe5e authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Use a 64-bit type to hold sockets on win64.

On win64, sockets are of type UINT_PTR; on win32 they're u_int;
elsewhere they're int.  The correct windows way to check a socket for
being set is to compare it with INVALID_SOCKET; elsewhere you see if
it is negative.

On Libevent 2, all callbacks take sockets as evutil_socket_t; we've
been passing them int.

This patch should fix compilation and correctness when built for
64-bit windows.  Fixes bug 3270.
parent 1ba1bdee
Loading
Loading
Loading
Loading

changes/bug3270

0 → 100644
+4 −0
Original line number Diff line number Diff line
  o Minor bugfixes
    - Use a wide type to hold sockets when built for 64-bit Windows builds.
      Fixes bug 3270.
+17 −15
Original line number Diff line number Diff line
@@ -841,7 +841,7 @@ socket_accounting_unlock(void)
 * Windows, where close()ing a socket doesn't work.  Returns 0 on success, -1
 * on failure. */
int
tor_close_socket(int s)
tor_close_socket(tor_socket_t s)
{
  int r = 0;

@@ -894,8 +894,10 @@ tor_close_socket(int s)
/** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
 * now an open socket. */
static INLINE void
mark_socket_open(int s)
mark_socket_open(tor_socket_t s)
{
  /* XXXX This bitarray business will NOT work on windows: sockets aren't
     small ints there. */
  if (s > max_socket) {
    if (max_socket == -1) {
      open_sockets = bitarray_init_zero(s+128);
@@ -917,11 +919,11 @@ mark_socket_open(int s)
/** @} */

/** As socket(), but counts the number of open sockets. */
int
tor_socket_t
tor_open_socket(int domain, int type, int protocol)
{
  int s = socket(domain, type, protocol);
  if (s >= 0) {
  tor_socket_t s = socket(domain, type, protocol);
  if (SOCKET_OK(s)) {
    socket_accounting_lock();
    ++n_sockets_open;
    mark_socket_open(s);
@@ -931,11 +933,11 @@ tor_open_socket(int domain, int type, int protocol)
}

/** As socket(), but counts the number of open sockets. */
int
tor_socket_t
tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len)
{
  int s = accept(sockfd, addr, len);
  if (s >= 0) {
  tor_socket_t s = accept(sockfd, addr, len);
  if (SOCKET_OK(s)) {
    socket_accounting_lock();
    ++n_sockets_open;
    mark_socket_open(s);
@@ -958,7 +960,7 @@ get_n_open_sockets(void)
/** Turn <b>socket</b> into a nonblocking socket.
 */
void
set_socket_nonblocking(int socket)
set_socket_nonblocking(tor_socket_t socket)
{
#if defined(MS_WINDOWS)
  unsigned long nonblocking = 1;
@@ -986,7 +988,7 @@ set_socket_nonblocking(int socket)
 **/
/* It would be nicer just to set errno, but that won't work for windows. */
int
tor_socketpair(int family, int type, int protocol, int fd[2])
tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
{
//don't use win32 socketpairs (they are always bad)
#if defined(HAVE_SOCKETPAIR) && !defined(MS_WINDOWS)
@@ -1011,9 +1013,9 @@ tor_socketpair(int family, int type, int protocol, int fd[2])
     * for now, and really, when localhost is down sometimes, we
     * have other problems too.
     */
    int listener = -1;
    int connector = -1;
    int acceptor = -1;
    tor_socket_t listener = -1;
    tor_socket_t connector = -1;
    tor_socket_t acceptor = -1;
    struct sockaddr_in listen_addr;
    struct sockaddr_in connect_addr;
    int size;
@@ -2577,11 +2579,11 @@ in_main_thread(void)
 */
#if defined(MS_WINDOWS)
int
tor_socket_errno(int sock)
tor_socket_errno(tor_socket_t sock)
{
  int optval, optvallen=sizeof(optval);
  int err = WSAGetLastError();
  if (err == WSAEWOULDBLOCK && sock >= 0) {
  if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
    if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
      return err;
    if (optval)
+15 −6
Original line number Diff line number Diff line
@@ -390,9 +390,18 @@ int tor_fd_seekend(int fd);
typedef int socklen_t;
#endif

int tor_close_socket(int s);
int tor_open_socket(int domain, int type, int protocol);
int tor_accept_socket(int sockfd, struct sockaddr *addr, socklen_t *len);
#ifdef MS_WINDOWS
#define tor_socket_t intptr_t
#define SOCKET_OK(s) ((s) != INVALID_SOCKET)
#else
#define tor_socket_t int
#define SOCKET_OK(s) ((s) >= 0)
#endif

int tor_close_socket(tor_socket_t s);
tor_socket_t tor_open_socket(int domain, int type, int protocol);
tor_socket_t tor_accept_socket(int sockfd, struct sockaddr *addr,
                                  socklen_t *len);
int get_n_open_sockets(void);

#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
@@ -464,8 +473,8 @@ int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
const char *tor_inet_ntop(int af, const void *src, char *dst, size_t len);
int tor_inet_pton(int af, const char *src, void *dst);
int tor_lookup_hostname(const char *name, uint32_t *addr) ATTR_NONNULL((1,2));
void set_socket_nonblocking(int socket);
int tor_socketpair(int family, int type, int protocol, int fd[2]);
void set_socket_nonblocking(tor_socket_t socket);
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]);
int network_init(void);

/* For stupid historical reasons, windows sockets have an independent
@@ -492,7 +501,7 @@ int network_init(void);
  ((e) == WSAEMFILE || (e) == WSAENOBUFS)
/** Return true if e is EADDRINUSE or the local equivalent. */
#define ERRNO_IS_EADDRINUSE(e)      ((e) == WSAEADDRINUSE)
int tor_socket_errno(int sock);
int tor_socket_errno(tor_socket_t sock);
const char *tor_socket_strerror(int e);
#else
#define ERRNO_IS_EAGAIN(e)           ((e) == EAGAIN)
+4 −0
Original line number Diff line number Diff line
@@ -9,11 +9,15 @@
struct event;
struct event_base;


#ifdef HAVE_EVENT2_EVENT_H
#include <event2/util.h>
#else
#ifndef EVUTIL_SOCKET_DEFINED
#define EVUTIL_SOCKET_DEFINED
#define evutil_socket_t int
#endif
#endif

void configure_libevent_logging(void);
void suppress_libevent_log_msg(const char *msg);
+4 −4
Original line number Diff line number Diff line
@@ -1568,7 +1568,7 @@ rate_limit_log(ratelim_t *lim, time_t now)
 * was returned by open().  Return the number of bytes written, or -1
 * on error.  Only use if fd is a blocking fd.  */
ssize_t
write_all(int fd, const char *buf, size_t count, int isSocket)
write_all(tor_socket_t fd, const char *buf, size_t count, int isSocket)
{
  size_t written = 0;
  ssize_t result;
@@ -1578,7 +1578,7 @@ write_all(int fd, const char *buf, size_t count, int isSocket)
    if (isSocket)
      result = tor_socket_send(fd, buf+written, count-written, 0);
    else
      result = write(fd, buf+written, count-written);
      result = write((int)fd, buf+written, count-written);
    if (result<0)
      return -1;
    written += result;
@@ -1592,7 +1592,7 @@ write_all(int fd, const char *buf, size_t count, int isSocket)
 * open().  Return the number of bytes read, or -1 on error. Only use
 * if fd is a blocking fd. */
ssize_t
read_all(int fd, char *buf, size_t count, int isSocket)
read_all(tor_socket_t fd, char *buf, size_t count, int isSocket)
{
  size_t numread = 0;
  ssize_t result;
@@ -1604,7 +1604,7 @@ read_all(int fd, char *buf, size_t count, int isSocket)
    if (isSocket)
      result = tor_socket_recv(fd, buf+numread, count-numread, 0);
    else
      result = read(fd, buf+numread, count-numread);
      result = read((int)fd, buf+numread, count-numread);
    if (result<0)
      return -1;
    else if (result == 0)
Loading