Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mono / io-layer / sockets.c
index 079e01d6528d34836db0626f355d13c6de895f2b..6f8fdd50c4b653afafe310a21b374d298592bb78 100644 (file)
 #include <sys/sendfile.h>
 #endif
 
-#undef DEBUG
+#if 0
+#define DEBUG(...) g_message(__VA_ARGS__)
+#else
+#define DEBUG(...)
+#endif
 
 static guint32 startup_count=0;
 static guint32 in_cleanup = 0;
@@ -79,9 +83,7 @@ static void socket_close (gpointer handle, gpointer data)
        int ret;
        struct _WapiHandle_socket *socket_handle = (struct _WapiHandle_socket *)data;
 
-#ifdef DEBUG
-       g_message ("%s: closing socket handle %p", __func__, handle);
-#endif
+       DEBUG ("%s: closing socket handle %p", __func__, handle);
 
        if (startup_count == 0 && !in_cleanup) {
                WSASetLastError (WSANOTINITIALISED);
@@ -100,9 +102,7 @@ static void socket_close (gpointer handle, gpointer data)
        
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: close error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: close error: %s", __func__, strerror (errno));
                errnum = errno_to_WSA (errnum, __func__);
                if (!in_cleanup)
                        WSASetLastError (errnum);
@@ -131,9 +131,7 @@ int WSAStartup(guint32 requested, WapiWSAData *data)
        data->wVersion = requested < data->wHighVersion? requested:
                data->wHighVersion;
 
-#ifdef DEBUG
-       g_message ("%s: high version 0x%x", __func__, data->wHighVersion);
-#endif
+       DEBUG ("%s: high version 0x%x", __func__, data->wHighVersion);
        
        strncpy (data->szDescription, "WAPI", WSADESCRIPTION_LEN);
        strncpy (data->szSystemStatus, "groovy", WSASYS_STATUS_LEN);
@@ -150,9 +148,7 @@ cleanup_close (gpointer handle, gpointer data)
 
 int WSACleanup(void)
 {
-#ifdef DEBUG
-       g_message ("%s: cleaning up", __func__);
-#endif
+       DEBUG ("%s: cleaning up", __func__);
 
        if (--startup_count) {
                /* Do nothing */
@@ -228,9 +224,7 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
 
        if (new_fd == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: accept error: %s", __func__, strerror(errno));
-#endif
+               DEBUG ("%s: accept error: %s", __func__, strerror(errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -239,9 +233,7 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
        }
 
        if (new_fd >= _wapi_fd_reserve) {
-#ifdef DEBUG
-               g_message ("%s: File descriptor is too big", __func__);
-#endif
+               DEBUG ("%s: File descriptor is too big", __func__);
 
                WSASetLastError (WSASYSCALLFAILURE);
                
@@ -263,10 +255,8 @@ guint32 _wapi_accept(guint32 fd, struct sockaddr *addr, socklen_t *addrlen)
                return(INVALID_SOCKET);
        }
 
-#ifdef DEBUG
-       g_message ("%s: returning newly accepted socket handle %p with",
+       DEBUG ("%s: returning newly accepted socket handle %p with",
                   __func__, new_handle);
-#endif
        
        return(new_fd);
 }
@@ -289,9 +279,7 @@ int _wapi_bind(guint32 fd, struct sockaddr *my_addr, socklen_t addrlen)
        ret = bind (fd, my_addr, addrlen);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: bind error: %s", __func__, strerror(errno));
-#endif
+               DEBUG ("%s: bind error: %s", __func__, strerror(errno));
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
                
@@ -326,10 +314,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
                errnum = errno;
                
                if (errno != EINTR) {
-#ifdef DEBUG
-                       g_message ("%s: connect error: %s", __func__,
+                       DEBUG ("%s: connect error: %s", __func__,
                                   strerror (errnum));
-#endif
 
                        errnum = errno_to_WSA (errnum, __func__);
                        if (errnum == WSAEINPROGRESS)
@@ -349,7 +335,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
                                                          (gpointer *)&socket_handle);
                                if (ok == FALSE) {
                                        /* ECONNRESET means the socket was closed by another thread */
-                                       if (errnum != WSAECONNRESET)
+                                       /* Async close on mac raises ECONNABORTED. */
+                                       if (errnum != WSAECONNRESET && errnum != WSAENETDOWN)
                                                g_warning ("%s: error looking up socket handle %p (error %d)", __func__, handle, errnum);
                                } else {
                                        socket_handle->saved_error = errnum;
@@ -365,10 +352,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
                        if (errno != EINTR) {
                                errnum = errno_to_WSA (errno, __func__);
 
-#ifdef DEBUG
-                               g_message ("%s: connect poll error: %s",
+                               DEBUG ("%s: connect poll error: %s",
                                           __func__, strerror (errno));
-#endif
 
                                WSASetLastError (errnum);
                                return(SOCKET_ERROR);
@@ -380,10 +365,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
                                &len) == -1) {
                        errnum = errno_to_WSA (errno, __func__);
 
-#ifdef DEBUG
-                       g_message ("%s: connect getsockopt error: %s",
+                       DEBUG ("%s: connect getsockopt error: %s",
                                   __func__, strerror (errno));
-#endif
 
                        WSASetLastError (errnum);
                        return(SOCKET_ERROR);
@@ -401,10 +384,8 @@ int _wapi_connect(guint32 fd, const struct sockaddr *serv_addr,
                                socket_handle->saved_error = errnum;
                        }
                        
-#ifdef DEBUG
-                       g_message ("%s: connect getsockopt returned error: %s",
+                       DEBUG ("%s: connect getsockopt returned error: %s",
                                   __func__, strerror (so_error));
-#endif
 
                        WSASetLastError (errnum);
                        return(SOCKET_ERROR);
@@ -432,10 +413,8 @@ int _wapi_getpeername(guint32 fd, struct sockaddr *name, socklen_t *namelen)
        ret = getpeername (fd, name, namelen);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: getpeername error: %s", __func__,
+               DEBUG ("%s: getpeername error: %s", __func__,
                           strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -464,10 +443,8 @@ int _wapi_getsockname(guint32 fd, struct sockaddr *name, socklen_t *namelen)
        ret = getsockname (fd, name, namelen);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: getsockname error: %s", __func__,
+               DEBUG ("%s: getsockname error: %s", __func__,
                           strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -508,10 +485,8 @@ int _wapi_getsockopt(guint32 fd, int level, int optname, void *optval,
        ret = getsockopt (fd, level, optname, tmp_val, optlen);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: getsockopt error: %s", __func__,
+               DEBUG ("%s: getsockopt error: %s", __func__,
                           strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -567,9 +542,7 @@ int _wapi_listen(guint32 fd, int backlog)
        ret = listen (fd, backlog);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: listen error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: listen error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -637,9 +610,7 @@ int _wapi_recvfrom(guint32 fd, void *buf, size_t len, int recv_flags,
        
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: recv error: %s", __func__, strerror(errno));
-#endif
+               DEBUG ("%s: recv error: %s", __func__, strerror(errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -684,9 +655,7 @@ _wapi_recvmsg(guint32 fd, struct msghdr *msg, int recv_flags)
        
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: recvmsg error: %s", __func__, strerror(errno));
-#endif
+               DEBUG ("%s: recvmsg error: %s", __func__, strerror(errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -718,9 +687,7 @@ int _wapi_send(guint32 fd, const void *msg, size_t len, int send_flags)
 
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: send error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: send error: %s", __func__, strerror (errno));
 
 #ifdef O_NONBLOCK
                /* At least linux returns EAGAIN/EWOULDBLOCK when the timeout has been set on
@@ -762,9 +729,7 @@ int _wapi_sendto(guint32 fd, const void *msg, size_t len, int send_flags,
 
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: send error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: send error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -797,9 +762,7 @@ _wapi_sendmsg(guint32 fd,  const struct msghdr *msg, int send_flags)
 
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: sendmsg error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: sendmsg error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -815,6 +778,10 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
        gpointer handle = GUINT_TO_POINTER (fd);
        int ret;
        const void *tmp_val;
+#if defined (__linux__)
+       /* This has its address taken so it cannot be moved to the if block which uses it */
+       int bufsize = 0;
+#endif
        struct timeval tv;
        
        if (startup_count == 0) {
@@ -842,7 +809,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
                 * buffer sizes "to allow space for bookkeeping
                 * overhead."
                 */
-               int bufsize = *((int *) optval);
+               bufsize = *((int *) optval);
 
                bufsize /= 2;
                tmp_val = &bufsize;
@@ -852,10 +819,8 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
        ret = setsockopt (fd, level, optname, tmp_val, optlen);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: setsockopt error: %s", __func__,
+               DEBUG ("%s: setsockopt error: %s", __func__,
                           strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -913,10 +878,8 @@ int _wapi_shutdown(guint32 fd, int how)
        ret = shutdown (fd, how);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: shutdown error: %s", __func__,
+               DEBUG ("%s: shutdown error: %s", __func__,
                           strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -943,15 +906,14 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
        if (fd == -1 && domain == AF_INET && type == SOCK_RAW &&
            protocol == 0) {
                /* Retry with protocol == 4 (see bug #54565) */
+               // https://bugzilla.novell.com/show_bug.cgi?id=MONO54565
                socket_handle.protocol = 4;
                fd = socket (AF_INET, SOCK_RAW, 4);
        }
        
        if (fd == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: socket error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: socket error: %s", __func__, strerror (errno));
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
 
@@ -959,10 +921,8 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
        }
 
        if (fd >= _wapi_fd_reserve) {
-#ifdef DEBUG
-               g_message ("%s: File descriptor is too big (%d >= %d)",
+               DEBUG ("%s: File descriptor is too big (%d >= %d)",
                           __func__, fd, _wapi_fd_reserve);
-#endif
 
                WSASetLastError (WSASYSCALLFAILURE);
                close (fd);
@@ -972,6 +932,7 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
 
        /* .net seems to set this by default for SOCK_STREAM, not for
         * SOCK_DGRAM (see bug #36322)
+        * https://bugzilla.novell.com/show_bug.cgi?id=MONO36322
         *
         * It seems winsock has a rather different idea of what
         * SO_REUSEADDR means.  If it's set, then a new socket can be
@@ -982,6 +943,7 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
         * behaves as though any other system would when SO_REUSEADDR
         * is true, so we don't need to do anything else here.  See
         * bug 53992.
+        * https://bugzilla.novell.com/show_bug.cgi?id=MONO53992
         */
        {
                int ret, true = 1;
@@ -991,9 +953,7 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
                if (ret == -1) {
                        int errnum = errno;
 
-#ifdef DEBUG
-                       g_message ("%s: Error setting SO_REUSEADDR", __func__);
-#endif
+                       DEBUG ("%s: Error setting SO_REUSEADDR", __func__);
                        
                        errnum = errno_to_WSA (errnum, __func__);
                        WSASetLastError (errnum);
@@ -1015,9 +975,7 @@ guint32 _wapi_socket(int domain, int type, int protocol, void *unused,
                return(INVALID_SOCKET);
        }
 
-#ifdef DEBUG
-       g_message ("%s: returning socket handle %p", __func__, handle);
-#endif
+       DEBUG ("%s: returning socket handle %p", __func__, handle);
 
        return(fd);
 }
@@ -1033,10 +991,8 @@ struct hostent *_wapi_gethostbyname(const char *hostname)
 
        he = gethostbyname (hostname);
        if (he == NULL) {
-#ifdef DEBUG
-               g_message ("%s: gethostbyname error: %s", __func__,
+               DEBUG ("%s: gethostbyname error: %s", __func__,
                           strerror (h_errno));
-#endif
 
                switch(h_errno) {
                case HOST_NOT_FOUND:
@@ -1084,9 +1040,7 @@ static gboolean socket_disconnect (guint32 fd)
        if (newsock == -1) {
                gint errnum = errno;
 
-#ifdef DEBUG
-               g_message ("%s: socket error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: socket error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -1106,9 +1060,7 @@ static gboolean socket_disconnect (guint32 fd)
        if (ret == -1) {
                gint errnum = errno;
                
-#ifdef DEBUG
-               g_message ("%s: dup2 error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: dup2 error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -1124,9 +1076,7 @@ static gboolean socket_disconnect (guint32 fd)
 static gboolean wapi_disconnectex (guint32 fd, WapiOverlapped *overlapped,
                                   guint32 flags, guint32 reserved)
 {
-#ifdef DEBUG
-       g_message ("%s: called on socket %d!", __func__, fd);
-#endif
+       DEBUG ("%s: called on socket %d!", __func__, fd);
        
        if (reserved != 0) {
                WSASetLastError (WSAEINVAL);
@@ -1348,13 +1298,13 @@ WSAIoctl (guint32 fd, gint32 command,
                        keepalivetime /= 1000;
                        if (keepalivetime == 0 || rem >= 500)
                                keepalivetime++;
-                       ret = setsockopt (fd, SOL_TCP, TCP_KEEPIDLE, &keepalivetime, sizeof (uint32_t));
+                       ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepalivetime, sizeof (uint32_t));
                        if (ret == 0) {
                                rem = keepaliveinterval % 1000;
                                keepaliveinterval /= 1000;
                                if (keepaliveinterval == 0 || rem >= 500)
                                        keepaliveinterval++;
-                               ret = setsockopt (fd, SOL_TCP, TCP_KEEPINTVL, &keepaliveinterval, sizeof (uint32_t));
+                               ret = setsockopt (fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepaliveinterval, sizeof (uint32_t));
                        }
                        if (ret != 0) {
                                gint errnum = errno;
@@ -1375,10 +1325,8 @@ WSAIoctl (guint32 fd, gint32 command,
        ret = ioctl (fd, command, buffer);
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message("%s: WSAIoctl error: %s", __func__,
+               DEBUG("%s: WSAIoctl error: %s", __func__,
                          strerror (errno));
-#endif
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -1475,9 +1423,7 @@ int ioctlsocket(guint32 fd, gint32 command, gpointer arg)
 
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: ioctl error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: ioctl error: %s", __func__, strerror (errno));
 
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);
@@ -1519,9 +1465,7 @@ int _wapi_select(int nfds G_GNUC_UNUSED, fd_set *readfds, fd_set *writefds,
 
        if (ret == -1) {
                gint errnum = errno;
-#ifdef DEBUG
-               g_message ("%s: select error: %s", __func__, strerror (errno));
-#endif
+               DEBUG ("%s: select error: %s", __func__, strerror (errno));
                errnum = errno_to_WSA (errnum, __func__);
                WSASetLastError (errnum);