Ignore:
Timestamp:
Jun 18, 2009, 6:27:45 PM (16 years ago)
Author:
ydario
Message:

Minor updates, backout imm changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wsock32/wsock32.cpp

    r9887 r21308  
    5555#include <winuser32.h>
    5656#include <wprocess.h>
    57 #include <misc.h>
     57#include <dbglog.h>
     58
     59#include <sys/types.h>
     60#include <sys/socket.h>
     61#include <net/if.h>
    5862
    5963#include "wsock32.h"
     
    212216            strcpy(msg, "WSAEHOSTUNREACH");
    213217            break;
     218        case WSAETIMEDOUT:
     219            strcpy(msg, "WSAETIMEDOUT");
     220            break;
    214221        default:
    215222            strcpy(msg, "unknown");
     
    663670
    664671   if(ret == SOCKET_ERROR) {
    665         WSASetLastError(wsaErrno());
    666         return SOCKET_ERROR;
     672        if(wsaErrno() == WSAEWOULDBLOCK) {
     673            struct timeval tv;
     674            int optlen = sizeof(tv);
     675            ret = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, &optlen);
     676            if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) {
     677                  dprintf(("WSAEWOULDBLOCK: recv timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec));
     678                  WSASetLastError(WSAETIMEDOUT);
     679            }
     680            else  WSASetLastError(WSAEWOULDBLOCK);
     681            ret = SOCKET_ERROR;
     682        }
     683        else WSASetLastError(wsaErrno());
    667684   }
    668685   else
     
    684701        else
    685702        if(state & SS_ISCONNECTED && flags != MSG_PEEK) {
    686                 dprintf(("recv returned 0, but socket is still connected -> return WSAWOULDBLOCK"));
     703                dprintf(("recv returned 0, but socket is still connected -> return WSAEWOULDBLOCK"));
    687704                WSASetLastError(WSAEWOULDBLOCK);
    688705                return SOCKET_ERROR;
     
    699716   }
    700717
    701    //Reset FD_READ event flagfor WSAAsyncSelect thread if one was created for this socket
     718   //Reset FD_READ event flag for WSAAsyncSelect thread if one was created for this socket
    702719   EnableAsyncEvent(s, FD_READ);
    703720   return ret;
     
    732749
    733750   if(ret == SOCKET_ERROR) {
    734         WSASetLastError(wsaErrno());
     751        if(wsaErrno() == WSAEWOULDBLOCK) {
     752            struct timeval tv;
     753            int optlen = sizeof(tv);
     754            ret = getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, &optlen);
     755            if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) {
     756                  dprintf(("WSAEWOULDBLOCK: recvfrom timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec));
     757                  WSASetLastError(WSAETIMEDOUT);
     758            }
     759            else  WSASetLastError(WSAEWOULDBLOCK);
     760            ret = SOCKET_ERROR;
     761        }
     762        else WSASetLastError(wsaErrno());
    735763   }
    736764   else {
     
    789817
    790818   if(ret == SOCKET_ERROR) {
    791         WSASetLastError(wsaErrno());
     819        if(wsaErrno() == WSAEWOULDBLOCK) {
     820            struct timeval tv;
     821            int optlen = sizeof(tv);
     822            ret = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, &optlen);
     823            if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) {
     824                  dprintf(("WSAEWOULDBLOCK: send timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec));
     825                  WSASetLastError(WSAETIMEDOUT);
     826            }
     827            else  WSASetLastError(WSAEWOULDBLOCK);
     828            ret = SOCKET_ERROR;
     829        }
     830        else WSASetLastError(wsaErrno());
    792831   }
    793832   else WSASetLastError(NO_ERROR);
     
    844883
    845884   if(ret == SOCKET_ERROR) {
    846         WSASetLastError(wsaErrno());
     885        if(wsaErrno() == WSAEWOULDBLOCK) {
     886            struct timeval tv;
     887            int optlen = sizeof(tv);
     888            ret = getsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv, &optlen);
     889            if(ret == 0 && (tv.tv_sec > 0 || tv.tv_usec > 0)) {
     890                  dprintf(("WSAEWOULDBLOCK: sendto timeout set to %ds%dus -> return WSAETIMEDOUT", tv.tv_sec, tv.tv_usec));
     891                  WSASetLastError(WSAETIMEDOUT);
     892            }
     893            else  WSASetLastError(WSAEWOULDBLOCK);
     894            ret = SOCKET_ERROR;
     895        }
     896        else WSASetLastError(wsaErrno());
    847897   }
    848898   else WSASetLastError(NO_ERROR);
     
    906956
    907957        sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
    908         if(readfds) {
     958        if(readfds && nrread) {
    909959                memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
    910960        }
    911         if(writefds) {
     961        if(writefds && nrwrite) {
    912962                memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
    913963        }
    914         if(exceptfds) {
     964        if(exceptfds && nrexcept) {
    915965                memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
    916966        }
     
    940990                        for(i=0;i<nrread;i++) {
    941991                                if(socktmp[i] != -1) {
    942                                         readfds->fd_array[i] = socktmp[i];
     992                                        readfds->fd_array[j] = socktmp[i];
     993                                        dprintf(("Socket %d read pending", socktmp[i]));
    943994                                        j++;
    944995                                }
     
    9521003                        for(i=0;i<nrwrite;i++) {
    9531004                                if(socktmp[i] != -1) {
    954                                         writefds->fd_array[i] = socktmp[i];
     1005                                        writefds->fd_array[j] = socktmp[i];
     1006                                        dprintf(("Socket %d write pending", socktmp[i]));
    9551007                                        j++;
    9561008                                }
     
    9631015                        for(i=0;i<nrexcept;i++) {
    9641016                                if(socktmp[i] != -1) {
    965                                         exceptfds->fd_array[i] = socktmp[i];
     1017                                        exceptfds->fd_array[j] = socktmp[i];
    9661018                                        j++;
    9671019                                }
     
    9841036   return ret;
    9851037}
     1038#ifdef DEBUG_LOGGING
     1039//******************************************************************************
     1040//******************************************************************************
     1041char *debugsockopt(int optname)
     1042{
     1043    switch(optname) {
     1044    case SO_DONTLINGER:
     1045         return "SO_DONTLINGER";
     1046    case SO_LINGER:
     1047         return "SO_LINGER";
     1048    case SO_REUSEADDR:
     1049         return "SO_REUSEADDR";
     1050    case SO_SNDTIMEO:
     1051         return "SO_SNDTIMEO";
     1052    case SO_RCVTIMEO:
     1053         return "SO_RCVTIMEO";
     1054    case SO_SNDBUF:
     1055         return "SO_SNDBUF";
     1056    case SO_RCVBUF:
     1057         return "SO_RCVBUF";
     1058    case SO_BROADCAST:
     1059         return "SO_BROADCAST";
     1060    case SO_DEBUG:
     1061         return "SO_DEBUG";
     1062    case SO_KEEPALIVE:
     1063         return "SO_KEEPALIVE";
     1064    case SO_DONTROUTE:
     1065         return "SO_DONTROUTE";
     1066    case SO_OOBINLINE:
     1067         return "SO_OOBINLINE";
     1068    case SO_TYPE:
     1069         return "SO_TYPE";
     1070    case SO_ERROR:
     1071         return "SO_ERROR";
     1072    case SO_SNDLOWAT:
     1073         return "SO_SNDLOWAT";
     1074    case SO_RCVLOWAT:
     1075         return "SO_RCVLOWAT";
     1076    case SO_USELOOPBACK:
     1077         return "SO_USELOOPBACK";
     1078    case SO_ACCEPTCONN:
     1079         return "SO_ACCEPTCONN";
     1080    default:
     1081        return "unknown option";
     1082    }
     1083}
     1084#endif
    9861085//******************************************************************************
    9871086//******************************************************************************
     
    10641163        case SO_SNDTIMEO:
    10651164        case SO_RCVTIMEO:
     1165        {
     1166                if(optlen < (int)sizeof(int))
     1167                {
     1168                        dprintf(("SO_RCVTIMEO, SO_SNDTIMEO, optlen too small"));
     1169                        WSASetLastError(WSAEFAULT);
     1170                        return SOCKET_ERROR;
     1171                }
    10661172          // convert "int" to "struct timeval"
    10671173          struct timeval tv;
    1068           tv.tv_sec = *optval / 1000;
    1069           tv.tv_usec = (*optval % 1000) * 1000;
     1174                tv.tv_sec = (*(int *)optval) / 1000;
     1175                tv.tv_usec = ((*(int *)optval) % 1000) * 1000;
     1176                if(optname == SO_SNDTIMEO) {
     1177                     dprintf(("SO_SNDTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec));
     1178                }
     1179                else dprintf(("SO_RCVTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec));
     1180
    10701181          ret = setsockopt(s, level, optname, (char *)&tv, sizeof(tv) );
    10711182          break;
     1183        }
     1184
     1185        case SO_REUSEADDR:
     1186                if(optlen < (int)sizeof(int)) {
     1187                        dprintf(("SO_REUSEADDR, optlen too small"));
     1188                        WSASetLastError(WSAEFAULT);
     1189                        return SOCKET_ERROR;
     1190                }
     1191                dprintf(("option SO_REUSEADDR value %d", *(int *)optval));
     1192                ret = setsockopt(s, level, SO_REUSEADDR, (char *)optval, optlen);
     1193                if(ret) {
     1194                    dprintf(("setsockopt SO_REUSEADDR failed!!"));
     1195                }
     1196                ret = setsockopt(s, level, SO_REUSEPORT_OS2, (char *)optval, optlen);
     1197                if(ret) {
     1198                    dprintf(("setsockopt SO_REUSEPORT failed!!"));
     1199                }
     1200                break;
    10721201
    10731202        case SO_BROADCAST:
     
    10761205        case SO_DONTROUTE:
    10771206        case SO_OOBINLINE:
    1078         case SO_REUSEADDR:
     1207        case SO_ERROR:
     1208        case SO_SNDLOWAT:
     1209        case SO_RCVLOWAT:
     1210        case SO_ACCEPTCONN:
     1211        case SO_USELOOPBACK:
    10791212                if(optlen < (int)sizeof(int)) {
    1080                         dprintf(("SOL_SOCKET, SO_REUSEADDR, optlen too small"));
     1213                        dprintf(("%s optlen too small", debugsockopt(optname)));
    10811214                        WSASetLastError(WSAEFAULT);
    10821215                        return SOCKET_ERROR;
    10831216                }
     1217                dprintf(("option %s = %x", debugsockopt(optname), *(int *)optval));
    10841218                ret = setsockopt(s, level, optname, (char *)optval, optlen);
    10851219                break;
     
    11531287           {
    11541288               u_int flLoop;
    1155                if (optlen < sizeof(u_char))
     1289               if (optlen < sizeof(u_int))
    11561290               {
    11571291                   dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
     
    11611295               flLoop = (*optval == 0) ? 0 : 1;
    11621296               dprintf(("IP_MULTICAST_LOOP %d", *optval));
    1163                ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, optlen);
     1297               ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)&flLoop, sizeof(u_char));
    11641298               break;
    11651299           }
     
    11671301           case IP_MULTICAST_TTL:
    11681302           case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
    1169                if (optlen < sizeof(u_char))
     1303               if (optlen < sizeof(u_int))
    11701304               {
    11711305                   dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
     
    11731307                   return SOCKET_ERROR;
    11741308               }
    1175                ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
     1309               dprintf(("IP_MULTICAST_TTL %d", *optval));
     1310               ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, sizeof(u_char));
    11761311               break;
    11771312
     
    12101345               dprintf(("IPPROTO_IP, IP_HDRINCL 0x%x", val));
    12111346               ret = setsockopt(s, IPPROTO_IP, IP_HDRINCL_OS2, (char *)&val, optlen);
     1347               break;
     1348
     1349           case IP_DONTFRAGMENT:
     1350           case WS2_IPPROTO_OPT(IP_DONTFRAGMENT_WS2):
     1351               //MSDN says these options are silently ignored
     1352               dprintf(("IPPROTO_IP: IP_DONTFRAGMENT ignored"));
     1353               ret = 0;
    12121354               break;
    12131355
     
    12691411                break;
    12701412
     1413        case SO_REUSEADDR:
     1414                if(optlen == NULL || *optlen < sizeof(int)) {
     1415                        WSASetLastError(WSAEFAULT);
     1416                        return SOCKET_ERROR;
     1417                }
     1418                ret = getsockopt(s, level, SO_REUSEADDR, (char *)optval, optlen);
     1419                dprintf(("getsockopt SO_REUSEADDR returned %d", *(int *)optval, optname));
     1420                break;
     1421                break;
     1422
     1423        case SO_SNDTIMEO:
     1424        case SO_RCVTIMEO:
     1425        {
     1426                if(optlen == NULL || *optlen < sizeof(int))
     1427                {
     1428                        dprintf(("SO_RCVTIMEO, SO_SNDTIMEO, optlen too small"));
     1429                        WSASetLastError(WSAEFAULT);
     1430                        return SOCKET_ERROR;
     1431                }
     1432                struct timeval tv;
     1433                int size = sizeof(tv);
     1434                ret = getsockopt(s, level, optname, (char *)&tv, &size );
     1435
     1436                // convert "struct timeval" to "int"
     1437                *(int *)optval = (tv.tv_sec * 1000) + tv.tv_usec/1000;
     1438                if(optname == SO_SNDTIMEO) {
     1439                     dprintf(("SO_SNDTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec));
     1440                }
     1441                else dprintf(("SO_RCVTIMEO: int val %x sec %d, usec %d", *(int *)optval, tv.tv_sec, tv.tv_usec));
     1442
     1443                break;
     1444        }
     1445
    12711446        case SO_SNDBUF:
    12721447        case SO_RCVBUF:
     
    12761451        case SO_DONTROUTE:
    12771452        case SO_OOBINLINE:
    1278         case SO_REUSEADDR:
    12791453        case SO_TYPE:
     1454        case SO_ERROR:
     1455        case SO_SNDLOWAT:
     1456        case SO_RCVLOWAT:
     1457        case SO_USELOOPBACK:
    12801458                if(optlen == NULL || *optlen < sizeof(int)) {
    12811459                        WSASetLastError(WSAEFAULT);
     
    12831461                }
    12841462                ret = getsockopt(s, level, optname, (char *)optval, optlen);
     1463                dprintf(("getsockopt %s returned %d", debugsockopt(optname), *(int *)optval));
    12851464                break;
     1465
    12861466        case SO_ACCEPTCONN:
    12871467                if(optlen == NULL || *optlen < sizeof(int)) {
     
    12941474                        *(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN;
    12951475                        *optlen = sizeof(BOOL);
     1476                        dprintf(("SO_ACCEPTCONN returned %d", *(BOOL *)optval));
    12961477                }
    12971478                break;
     
    13571538               break;
    13581539
     1540           case IP_MULTICAST_LOOP_WS2: //for buggy applications that intended to call ws_32.getsockopt
    13591541           case IP_MULTICAST_LOOP:
    13601542           case WS2_IPPROTO_OPT(IP_MULTICAST_LOOP_WS2):
    13611543           {
    1362                if (*optlen < sizeof(u_char))
     1544               if (*optlen < sizeof(u_int))
    13631545               {
    13641546                   dprintf(("IPPROTO_IP, IP_MULTICAST_LOOP/IP_MULTICAST_TTL, optlen too small"));
     
    13661548                   return SOCKET_ERROR;
    13671549               }
     1550               memset(optval, 0, *optlen);
    13681551               ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP_OS2, (char *)optval, optlen);
    13691552               break;
     
    13721555           case IP_MULTICAST_TTL:
    13731556           case WS2_IPPROTO_OPT(IP_MULTICAST_TTL_WS2):
    1374                if (*optlen < sizeof(u_char))
     1557               if (*optlen < sizeof(u_int))
    13751558               {
    13761559                   dprintf(("IPPROTO_IP, IP_MULTICAST_TTL, optlen too small"));
     
    13781561                   return SOCKET_ERROR;
    13791562               }
     1563               memset(optval, 0, *optlen);
    13801564               ret = getsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL_OS2, (char *)optval, optlen);
     1565               dprintf(("getsockopt IP_MULTICAST_TTL_OS2 returned %d, size %d", (int)*optval, *optlen));
    13811566               break;
    13821567
     
    13891574                   return SOCKET_ERROR;
    13901575               }
     1576               memset(optval, 0, *optlen);
    13911577               ret = getsockopt(s, IPPROTO_IP, IP_TTL_OS2, (char *)optval, optlen);
    13921578               break;
     
    14151601               }
    14161602               break;
     1603
     1604           case IP_DONTFRAGMENT:
     1605           case WS2_IPPROTO_OPT(IP_DONTFRAGMENT_WS2):
     1606               //MSDN says these options are silently ignored
     1607               if (*optlen < sizeof(u_int))
     1608               {
     1609                   dprintf(("IP_DONTFRAGMENT, IP_DONTFRAGMENT_WS2, optlen too small"));
     1610                   WSASetLastError(WSAEFAULT);
     1611                   return SOCKET_ERROR;
     1612               }
     1613               dprintf(("IPPROTO_IP: IP_DONTFRAGMENT ignored"));
     1614               *optlen = sizeof(u_int);
     1615               *(int *)optval = 0;
     1616               ret = 0;
     1617               break;
     1618
    14171619
    14181620           default:
     
    14811683//      I.e. start ISDNPM without dialing in. gethostbyname will query
    14821684//      each name server and retry several times (60+ seconds per name server)
     1685//
     1686static struct ws_hostent localhost;
     1687static DWORD  localhost_address;
     1688static DWORD  localhost_addrlist[2] = {(DWORD)&localhost_address, 0};
     1689static DWORD  localhost_aliaslist[1] = {0};
    14831690//******************************************************************************
    14841691ODINFUNCTION1(ws_hostent *,OS2gethostbyname,
     
    14931700
    14941701    dprintf(("gethostbyname %s", name));
    1495     if(gethostname(localhostname, sizeof(localhostname)) == NO_ERROR)
     1702    if (!gethostname(localhostname, sizeof(localhostname)))
    14961703    {
    1497         if(!strcmp(name, localhostname)) {
     1704        /*
     1705         * This is a fast non-blocking path for the hostname of this machine.
     1706         * It's probably not 100% correct though..
     1707         */
     1708        if (!strcmp(name, localhostname))
     1709        {
     1710            /*
     1711             * Lookup lan0 address, and move on to lo address if that fails.
     1712             */
     1713            sock_init();                /* ??? */
     1714            int s = socket(PF_INET, SOCK_STREAM, 0);
     1715            if (s >= 0)
     1716            {
     1717                struct ifreq  ifr = {0};
     1718                strcpy(ifr.ifr_name, "lan0");
     1719                int rc = ioctl(s, SIOCGIFADDR, (char*)&ifr, sizeof(ifr));
     1720                if (rc == -1)
     1721                {
     1722                    strcpy(ifr.ifr_name, "lo");
     1723                    rc = ioctl(s, SIOCGIFADDR, (char*)&ifr, sizeof(ifr));
     1724                }
     1725                soclose(s);
     1726
     1727                if (rc != -1)
     1728                {
     1729                    /* ASSUMES: family is AF_INET */
     1730                    /* Doesn't work with aliases on lan0. */
     1731                    struct sockaddr_in *addr = (struct sockaddr_in *)&ifr.ifr_addr;
     1732
     1733                    localhost_address       = *(unsigned long *)&addr->sin_addr;
     1734                    localhost.h_name        = "localhost"; /* This is what the old workaround did. */
     1735                    localhost.h_addrtype    = AF_INET;
     1736                    localhost.h_length      = 4;
     1737                    localhost.h_addr_list   = (char **)&localhost_addrlist[0];
     1738                    localhost.h_aliases     = (char **)&localhost_aliaslist[0];
     1739                    WSASetLastError(NO_ERROR);
     1740                    return &localhost;
     1741                }
     1742            }
     1743
     1744            /*
     1745             * bail out..
     1746             */
    14981747            strcpy(localhostname, "localhost");
    14991748            name = localhostname;
Note: See TracChangeset for help on using the changeset viewer.