00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "msocketdevice.h"
00045 #include "qwindowdefs.h"
00046 #include <QDateTime>
00047
00048 #include <QCoreApplication>
00049 #include "mythlogging.h"
00050
00051 #include <string.h>
00052
00053 #if defined (QT_NO_IPV6)
00054 # include <windows.h>
00055 # include <winsock.h>
00056 #else
00057 # if defined (Q_CC_BOR) || defined (Q_CC_GNU)
00058 # include <winsock2.h>
00059 # elif defined (Q_CC_INTEL)
00060 # include <winsock.h>
00061 # else
00062 # include <windows.h>
00063 # if defined(Q_OS_WINCE)
00064 # include <winsock.h>
00065 # endif
00066 # endif
00067
00068 # define QT_SS_MAXSIZE 128
00069 # define QT_SS_ALIGNSIZE (sizeof(__int64))
00070 # define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short))
00071 # define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE))
00072
00073 struct qt_sockaddr_storage
00074 {
00075 short ss_family;
00076 char __ss_pad1[QT_SS_PAD1SIZE];
00077 __int64 __ss_align;
00078 char __ss_pad2[QT_SS_PAD2SIZE];
00079 };
00080
00081
00082
00083
00084
00085 struct qt_in6_addr
00086 {
00087 u_char qt_s6_addr[16];
00088 };
00089
00090 typedef struct
00091 {
00092 short sin6_family;
00093 u_short sin6_port;
00094 u_long sin6_flowinfo;
00095
00096 struct qt_in6_addr sin6_addr;
00097 u_long sin6_scope_id;
00098 } qt_sockaddr_in6;
00099
00100 #endif
00101
00102 #ifndef AF_INET6
00103 #define AF_INET6 23
00104 #endif
00105
00106 #ifndef NO_ERRNO_H
00107 # if defined(Q_OS_WINCE)
00108 # include "qfunctions_wince.h"
00109 # else
00110 # include <errno.h>
00111 # endif
00112 #endif
00113
00114
00115 #if defined(SOCKLEN_T)
00116 #undef SOCKLEN_T
00117 #endif
00118
00119 #define SOCKLEN_T int // #### Winsock 1.1
00120
00121 static int initialized = 0x00;
00122
00123 static void cleanupWinSock()
00124 {
00125 WSACleanup();
00126 initialized = 0x00;
00127 }
00128
00129 static inline void qt_socket_getportaddr(struct sockaddr *sa,
00130 quint16 *port, QHostAddress *addr)
00131 {
00132 #if !defined (QT_NO_IPV6)
00133
00134 if (sa->sa_family == AF_INET6)
00135 {
00136 qt_sockaddr_in6 *sa6 = (qt_sockaddr_in6 *)sa;
00137 Q_IPV6ADDR tmp;
00138
00139 for (int i = 0; i < 16; ++i)
00140 tmp.c[i] = sa6->sin6_addr.qt_s6_addr[i];
00141
00142 QHostAddress a(tmp);
00143
00144 *addr = a;
00145
00146 *port = ntohs(sa6->sin6_port);
00147
00148 return;
00149 }
00150
00151 #endif
00152
00153 struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
00154
00155 QHostAddress a(ntohl(sa4->sin_addr.s_addr));
00156
00157 *port = ntohs(sa4->sin_port);
00158
00159 *addr = a;
00160 }
00161
00162 void MSocketDevice::init()
00163 {
00164 #if !defined(QT_NO_IPV6)
00165
00166 if (!initialized)
00167 {
00168 WSAData wsadata;
00169
00170
00171 if (WSAStartup(MAKEWORD(2, 0), &wsadata) != 0)
00172 {
00173 # if defined(QSOCKETDEVICE_DEBUG)
00174 qDebug("MSocketDevice: WinSock v2.0 initialization failed, disabling IPv6 support.");
00175 # endif
00176 }
00177 else
00178 {
00179 qAddPostRoutine(cleanupWinSock);
00180 initialized = 0x20;
00181 return;
00182 }
00183 }
00184
00185 #endif
00186
00187 if (!initialized)
00188 {
00189 WSAData wsadata;
00190
00191 if (WSAStartup(MAKEWORD(1, 1), &wsadata) != 0)
00192 {
00193 #if defined(QT_CHECK_NULL)
00194 qWarning("MSocketDevice: WinSock initialization failed");
00195 #endif
00196 #if defined(QSOCKETDEVICE_DEBUG)
00197 qDebug("MSocketDevice: WinSock initialization failed");
00198 #endif
00199 return;
00200 }
00201
00202 qAddPostRoutine(cleanupWinSock);
00203
00204 initialized = 0x11;
00205 }
00206 }
00207
00208 MSocketDevice::Protocol MSocketDevice::getProtocol() const
00209 {
00210 if (isValid())
00211 {
00212 #if !defined (QT_NO_IPV6)
00213
00214 struct qt_sockaddr_storage sa;
00215 #else
00216
00217 struct sockaddr_in sa;
00218 #endif
00219 memset(&sa, 0, sizeof(sa));
00220 SOCKLEN_T sz = sizeof(sa);
00221
00222 if (!::getsockname(fd, (struct sockaddr *)&sa, &sz))
00223 {
00224 #if !defined (QT_NO_IPV6)
00225
00226 switch (sa.ss_family)
00227 {
00228
00229 case AF_INET:
00230 return IPv4;
00231
00232 case AF_INET6:
00233 return IPv6;
00234
00235 default:
00236 return Unknown;
00237 }
00238
00239 #else
00240 switch (sa.sin_family)
00241 {
00242
00243 case AF_INET:
00244 return IPv4;
00245
00246 default:
00247 return Unknown;
00248 }
00249
00250 #endif
00251 }
00252 }
00253
00254 return Unknown;
00255 }
00256
00257 int MSocketDevice::createNewSocket()
00258 {
00259 #if !defined(QT_NO_IPV6)
00260 SOCKET s;
00261
00262
00263 if (initialized >= 0x20 && protocol() == IPv6)
00264 {
00265 s = ::socket(AF_INET6, t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
00266 }
00267 else
00268 {
00269 s = ::socket(AF_INET, t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
00270 }
00271
00272 #else
00273 SOCKET s = ::socket(AF_INET, t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
00274
00275 #endif
00276 if (s == INVALID_SOCKET)
00277 {
00278 switch (WSAGetLastError())
00279 {
00280
00281 case WSANOTINITIALISED:
00282 e = Impossible;
00283 break;
00284
00285 case WSAENETDOWN:
00286
00287 e = NetworkFailure;
00288
00289 break;
00290
00291 case WSAEMFILE:
00292 e = NoFiles;
00293 break;
00294
00295 case WSAEINPROGRESS:
00296
00297 case WSAENOBUFS:
00298 e = NoResources;
00299 break;
00300
00301 case WSAEAFNOSUPPORT:
00302
00303 case WSAEPROTOTYPE:
00304
00305 case WSAEPROTONOSUPPORT:
00306
00307 case WSAESOCKTNOSUPPORT:
00308 e = InternalError;
00309 break;
00310
00311 default:
00312 e = UnknownError;
00313 break;
00314 }
00315 }
00316 else
00317 {
00318 return s;
00319 }
00320
00321 return -1;
00322 }
00323
00324
00325 void MSocketDevice::close()
00326 {
00327 if (fd == -1 || !isOpen())
00328 return;
00329
00330 setOpenMode(NotOpen);
00331
00332 ::closesocket(fd);
00333
00334 #if defined(QSOCKETDEVICE_DEBUG)
00335 qDebug("MSocketDevice::close: Closed socket %x", fd);
00336
00337 #endif
00338 fd = -1;
00339
00340 fetchConnectionParameters();
00341
00342 QIODevice::close();
00343 }
00344
00345
00346 bool MSocketDevice::blocking() const
00347 {
00348 return true;
00349 }
00350
00351
00352 void MSocketDevice::setBlocking(bool enable)
00353 {
00354 #if defined(QSOCKETDEVICE_DEBUG)
00355 qDebug("MSocketDevice::setBlocking( %d )", enable);
00356 #endif
00357
00358 if (!isValid())
00359 return;
00360
00361 unsigned long dummy = enable ? 0 : 1;
00362
00363 ioctlsocket(fd, FIONBIO, &dummy);
00364 }
00365
00366
00367 int MSocketDevice::option(Option opt) const
00368 {
00369 if (!isValid())
00370 return -1;
00371
00372 int n = -1;
00373
00374 int v = -1;
00375
00376 switch (opt)
00377 {
00378
00379 case Broadcast:
00380 n = SO_BROADCAST;
00381 break;
00382
00383 case ReceiveBuffer:
00384 n = SO_RCVBUF;
00385 break;
00386
00387 case ReuseAddress:
00388 n = SO_REUSEADDR;
00389 break;
00390
00391 case SendBuffer:
00392 n = SO_SNDBUF;
00393 break;
00394
00395 case Keepalive:
00396 n = SO_KEEPALIVE;
00397 break;
00398 }
00399
00400 if (n != -1)
00401 {
00402 SOCKLEN_T len = sizeof(v);
00403 int r = ::getsockopt(fd, SOL_SOCKET, n, (char*) & v, &len);
00404
00405 if (r != SOCKET_ERROR)
00406 return v;
00407
00408 if (!e)
00409 {
00410 MSocketDevice *that = (MSocketDevice*)this;
00411
00412 switch (WSAGetLastError())
00413 {
00414
00415 case WSANOTINITIALISED:
00416 that->e = Impossible;
00417 break;
00418
00419 case WSAENETDOWN:
00420 that->e = NetworkFailure;
00421 break;
00422
00423 case WSAEFAULT:
00424
00425 case WSAEINVAL:
00426
00427 case WSAENOPROTOOPT:
00428 that->e = InternalError;
00429 break;
00430
00431 case WSAEINPROGRESS:
00432 that->e = NoResources;
00433 break;
00434
00435 case WSAENOTSOCK:
00436 that->e = Impossible;
00437 break;
00438
00439 default:
00440 that->e = UnknownError;
00441 break;
00442 }
00443 }
00444
00445 return -1;
00446 }
00447
00448 return v;
00449 }
00450
00451
00452 void MSocketDevice::setOption(Option opt, int v)
00453 {
00454 if (!isValid())
00455 return;
00456
00457 int n = -1;
00458
00459 switch (opt)
00460 {
00461
00462 case Broadcast:
00463 n = SO_BROADCAST;
00464 break;
00465
00466 case ReceiveBuffer:
00467 n = SO_RCVBUF;
00468 break;
00469
00470 case ReuseAddress:
00471 n = SO_REUSEADDR;
00472 break;
00473
00474 case SendBuffer:
00475 n = SO_SNDBUF;
00476 break;
00477
00478 case Keepalive:
00479 n = SO_KEEPALIVE;
00480 break;
00481
00482 default:
00483 return;
00484 }
00485
00486 int r = ::setsockopt(fd, SOL_SOCKET, n, (char*) & v, sizeof(v));
00487
00488 if (r == SOCKET_ERROR && e == NoError)
00489 {
00490 switch (WSAGetLastError())
00491 {
00492
00493 case WSANOTINITIALISED:
00494 e = Impossible;
00495 break;
00496
00497 case WSAENETDOWN:
00498 e = NetworkFailure;
00499 break;
00500
00501 case WSAEFAULT:
00502
00503 case WSAEINVAL:
00504
00505 case WSAENOPROTOOPT:
00506 e = InternalError;
00507 break;
00508
00509 case WSAEINPROGRESS:
00510 e = NoResources;
00511 break;
00512
00513 case WSAENETRESET:
00514
00515 case WSAENOTCONN:
00516 e = Impossible;
00517 break;
00518
00519 case WSAENOTSOCK:
00520 e = Impossible;
00521 break;
00522
00523 default:
00524 e = UnknownError;
00525 break;
00526 }
00527 }
00528 }
00529
00530
00531 bool MSocketDevice::connect(const QHostAddress &addr, quint16 port)
00532 {
00533 if (isValid() && addr.protocol() != pa.protocol())
00534 {
00535 close();
00536 fd = -1;
00537 }
00538
00539 if (!isValid())
00540 {
00541 #if !defined(QT_NO_IPV6)
00542
00543 if (addr.protocol() == QAbstractSocket::IPv6Protocol)
00544 {
00545 setProtocol(IPv6);
00546 LOG(VB_SOCKET, LOG_INFO,
00547 "MSocketDevice::connect: setting Protocol to IPv6");
00548 }
00549 else
00550 #endif
00551 if (addr.protocol() == QAbstractSocket::IPv4Protocol)
00552 {
00553 setProtocol(IPv4);
00554 LOG(VB_SOCKET, LOG_INFO,
00555 "MSocketDevice::connect: setting Protocol to IPv4");
00556 }
00557
00558 LOG(VB_SOCKET, LOG_INFO,
00559
00560 "MSocketDevice::connect: attempting to create new socket");
00561 MSocketDevice::setSocket(createNewSocket(), t);
00562
00563
00564
00565 if (!isValid())
00566 return false;
00567 }
00568
00569 pa = addr;
00570
00571 pp = port;
00572
00573 struct sockaddr_in a4;
00574
00575 struct sockaddr *aa;
00576 SOCKLEN_T aalen;
00577
00578 #if !defined(QT_NO_IPV6)
00579 qt_sockaddr_in6 a6;
00580
00581 if (initialized >= 0x20 && addr.protocol() == QAbstractSocket::IPv6Protocol)
00582 {
00583 memset(&a6, 0, sizeof(a6));
00584 a6.sin6_family = AF_INET6;
00585 a6.sin6_port = htons(port);
00586 Q_IPV6ADDR ip6 = addr.toIPv6Address();
00587 memcpy(&a6.sin6_addr.qt_s6_addr, &ip6, sizeof(ip6));
00588
00589 aalen = sizeof(a6);
00590 aa = (struct sockaddr *) & a6;
00591 }
00592 else
00593 #endif
00594 if (addr.protocol() == QAbstractSocket::IPv4Protocol)
00595 {
00596 memset(&a4, 0, sizeof(a4));
00597 a4.sin_family = AF_INET;
00598 a4.sin_port = htons(port);
00599 a4.sin_addr.s_addr = htonl(addr.toIPv4Address());
00600
00601 aalen = sizeof(a4);
00602 aa = (struct sockaddr *) & a4;
00603 }
00604 else
00605 {
00606 e = Impossible;
00607 return false;
00608 }
00609
00610 int r = ::connect(fd, aa, aalen);
00611
00612 if (r == SOCKET_ERROR)
00613 {
00614 switch (WSAGetLastError())
00615 {
00616
00617 case WSANOTINITIALISED:
00618 e = Impossible;
00619 break;
00620
00621 case WSAENETDOWN:
00622 e = NetworkFailure;
00623 break;
00624
00625 case WSAEADDRINUSE:
00626
00627 case WSAEINPROGRESS:
00628
00629 case WSAENOBUFS:
00630 e = NoResources;
00631 break;
00632
00633 case WSAEINTR:
00634 e = UnknownError;
00635 break;
00636
00637 case WSAEALREADY:
00638
00639 break;
00640
00641 case WSAEADDRNOTAVAIL:
00642 e = ConnectionRefused;
00643 break;
00644
00645 case WSAEAFNOSUPPORT:
00646
00647 case WSAEFAULT:
00648 e = InternalError;
00649 break;
00650
00651 case WSAEINVAL:
00652 break;
00653
00654 case WSAECONNREFUSED:
00655 e = ConnectionRefused;
00656 break;
00657
00658 case WSAEISCONN:
00659 goto successful;
00660
00661 case WSAENETUNREACH:
00662
00663 case WSAETIMEDOUT:
00664 e = NetworkFailure;
00665 break;
00666
00667 case WSAENOTSOCK:
00668 e = Impossible;
00669 break;
00670
00671 case WSAEWOULDBLOCK:
00672 break;
00673
00674 case WSAEACCES:
00675 e = Inaccessible;
00676 break;
00677
00678 case 10107:
00679
00680
00681 goto successful;
00682
00683 default:
00684 e = UnknownError;
00685 break;
00686 }
00687
00688 return false;
00689 }
00690
00691 successful:
00692
00693 fetchConnectionParameters();
00694 return true;
00695 }
00696
00697
00698 bool MSocketDevice::bind(const QHostAddress &address, quint16 port)
00699 {
00700 if (!isValid())
00701 return false;
00702
00703 int r;
00704
00705 struct sockaddr_in a4;
00706
00707 #if !defined(QT_NO_IPV6)
00708 qt_sockaddr_in6 a6;
00709
00710 if (initialized >= 0x20 && address.protocol() == QAbstractSocket::IPv6Protocol)
00711 {
00712 memset(&a6, 0, sizeof(a6));
00713 a6.sin6_family = AF_INET6;
00714 a6.sin6_port = htons(port);
00715 Q_IPV6ADDR tmp = address.toIPv6Address();
00716 memcpy(&a6.sin6_addr.qt_s6_addr, &tmp, sizeof(tmp));
00717
00718 r = ::bind(fd, (struct sockaddr *) & a6, sizeof(struct qt_sockaddr_storage));
00719 }
00720 else
00721 #endif
00722 if (address.protocol() == QAbstractSocket::IPv4Protocol)
00723 {
00724 memset(&a4, 0, sizeof(a4));
00725 a4.sin_family = AF_INET;
00726 a4.sin_port = htons(port);
00727 a4.sin_addr.s_addr = htonl(address.toIPv4Address());
00728
00729 r = ::bind(fd, (struct sockaddr*) & a4, sizeof(struct sockaddr_in));
00730 }
00731 else
00732 {
00733 e = Impossible;
00734 return false;
00735 }
00736
00737 if (r == SOCKET_ERROR)
00738 {
00739 switch (WSAGetLastError())
00740 {
00741
00742 case WSANOTINITIALISED:
00743 e = Impossible;
00744 break;
00745
00746 case WSAENETDOWN:
00747 e = NetworkFailure;
00748 break;
00749
00750 case WSAEACCES:
00751 e = Inaccessible;
00752 break;
00753
00754 case WSAEADDRNOTAVAIL:
00755 e = Inaccessible;
00756 break;
00757
00758 case WSAEFAULT:
00759 e = InternalError;
00760 break;
00761
00762 case WSAEINPROGRESS:
00763
00764 case WSAENOBUFS:
00765 e = NoResources;
00766 break;
00767
00768 case WSAEADDRINUSE:
00769
00770 case WSAEINVAL:
00771 e = AlreadyBound;
00772 break;
00773
00774 case WSAENOTSOCK:
00775 e = Impossible;
00776 break;
00777
00778 default:
00779 e = UnknownError;
00780 break;
00781 }
00782
00783 return false;
00784 }
00785
00786 fetchConnectionParameters();
00787
00788 return true;
00789 }
00790
00791
00792 bool MSocketDevice::listen(int backlog)
00793 {
00794 if (!isValid())
00795 return false;
00796
00797 if (::listen(fd, backlog) >= 0)
00798 return true;
00799
00800 if (!e)
00801 e = Impossible;
00802
00803 return false;
00804 }
00805
00806
00807 int MSocketDevice::accept()
00808 {
00809 if (!isValid())
00810 return -1;
00811
00812 #if !defined(QT_NO_IPV6)
00813
00814 struct qt_sockaddr_storage a;
00815
00816 #else
00817
00818 struct sockaddr a;
00819
00820 #endif
00821 SOCKLEN_T l = sizeof(a);
00822
00823 bool done;
00824
00825 SOCKET s;
00826
00827 do
00828 {
00829 s = ::accept(fd, (struct sockaddr*) & a, &l);
00830
00831 done = true;
00832
00833 if (s == INVALID_SOCKET && e == NoError)
00834 {
00835 switch (WSAGetLastError())
00836 {
00837
00838 case WSAEINTR:
00839 done = false;
00840 break;
00841
00842 case WSANOTINITIALISED:
00843 e = Impossible;
00844 break;
00845
00846 case WSAENETDOWN:
00847
00848 case WSAEOPNOTSUPP:
00849
00850
00851
00852 break;
00853
00854 case WSAEFAULT:
00855 e = InternalError;
00856 break;
00857
00858 case WSAEMFILE:
00859
00860 case WSAEINPROGRESS:
00861
00862 case WSAENOBUFS:
00863 e = NoResources;
00864 break;
00865
00866 case WSAEINVAL:
00867
00868 case WSAENOTSOCK:
00869 e = Impossible;
00870 break;
00871
00872 case WSAEWOULDBLOCK:
00873 break;
00874
00875 default:
00876 e = UnknownError;
00877 break;
00878 }
00879 }
00880 }
00881 while (!done);
00882
00883 return s;
00884 }
00885
00886
00887 qint64 MSocketDevice::bytesAvailable() const
00888 {
00889 if (!isValid())
00890 return -1;
00891
00892 u_long nbytes = 0;
00893
00894 if (::ioctlsocket(fd, FIONREAD, &nbytes) < 0)
00895 return -1;
00896
00897
00898
00899
00900
00901
00902 if (nbytes == 1 && t == Datagram)
00903 {
00904 char c;
00905
00906 if (::recvfrom(fd, &c, sizeof(c), MSG_PEEK, 0, 0) == SOCKET_ERROR)
00907 return 0;
00908 }
00909
00910 return nbytes;
00911 }
00912
00913
00914 qint64 MSocketDevice::waitForMore(int msecs, bool *timeout) const
00915 {
00916 if (!isValid())
00917 return -1;
00918
00919 fd_set fds;
00920
00921 memset(&fds, 0, sizeof(fd_set));
00922
00923 fds.fd_count = 1;
00924
00925 fds.fd_array[0] = fd;
00926
00927 struct timeval tv;
00928
00929 tv.tv_sec = msecs / 1000;
00930
00931 tv.tv_usec = (msecs % 1000) * 1000;
00932
00933 int rv = select(fd + 1, &fds, 0, 0, msecs < 0 ? 0 : &tv);
00934
00935 if (rv < 0)
00936 return -1;
00937
00938 if (timeout)
00939 {
00940 if (rv == 0)
00941 *timeout = true;
00942 else
00943 *timeout = false;
00944 }
00945
00946 return bytesAvailable();
00947 }
00948
00949
00950 qint64 MSocketDevice::readData(char *data, qint64 maxlen)
00951 {
00952 if (maxlen == 0)
00953 return 0;
00954
00955 #if defined(QT_CHECK_NULL)
00956 if (data == 0)
00957 {
00958 qWarning("MSocketDevice::readBlock: Null pointer error");
00959 return -1;
00960 }
00961
00962 #endif
00963 #if defined(QT_CHECK_STATE)
00964 if (!isValid())
00965 {
00966 qWarning("MSocketDevice::readBlock: Invalid socket");
00967 return -1;
00968 }
00969
00970 if (!isOpen())
00971 {
00972 qWarning("MSocketDevice::readBlock: Device is not open");
00973 return -1;
00974 }
00975
00976 if (!isReadable())
00977 {
00978 qWarning("MSocketDevice::readBlock: Read operation not permitted");
00979 return -1;
00980 }
00981
00982 #endif
00983 qint64 r = 0;
00984
00985 if (t == Datagram)
00986 {
00987 #if !defined(QT_NO_IPV6)
00988
00989
00990
00991
00992 struct qt_sockaddr_storage a;
00993 #else
00994
00995 struct sockaddr_in a;
00996 #endif
00997 memset(&a, 0, sizeof(a));
00998 SOCKLEN_T sz;
00999 sz = sizeof(a);
01000 r = ::recvfrom(fd, data, maxlen, 0, (struct sockaddr *) & a, &sz);
01001 qt_socket_getportaddr((struct sockaddr *)(&a), &pp, &pa);
01002 }
01003 else
01004 {
01005 r = ::recv(fd, data, maxlen, 0);
01006 }
01007
01008 if (r == 0 && t == Stream && maxlen > 0)
01009 {
01010 if (WSAGetLastError() != WSAEWOULDBLOCK)
01011 {
01012
01013 close();
01014 }
01015 }
01016 else if (r == SOCKET_ERROR && e == NoError)
01017 {
01018 switch (WSAGetLastError())
01019 {
01020
01021 case WSANOTINITIALISED:
01022 e = Impossible;
01023 break;
01024
01025 case WSAECONNABORTED:
01026 close();
01027 r = 0;
01028 break;
01029
01030 case WSAETIMEDOUT:
01031
01032 case WSAECONNRESET:
01033
01034
01035
01036
01037
01038
01039
01040
01041 if (t != Datagram)
01042 close();
01043
01044 r = 0;
01045
01046 break;
01047
01048 case WSAENETDOWN:
01049
01050 case WSAENETRESET:
01051 e = NetworkFailure;
01052
01053 break;
01054
01055 case WSAEFAULT:
01056
01057 case WSAENOTCONN:
01058
01059 case WSAESHUTDOWN:
01060
01061 case WSAEINVAL:
01062 e = Impossible;
01063
01064 break;
01065
01066 case WSAEINTR:
01067
01068 r = 0;
01069
01070 break;
01071
01072 case WSAEINPROGRESS:
01073 e = NoResources;
01074
01075 break;
01076
01077 case WSAENOTSOCK:
01078 e = Impossible;
01079
01080 break;
01081
01082 case WSAEOPNOTSUPP:
01083 e = InternalError;
01084
01085 break;
01086
01087 case WSAEWOULDBLOCK:
01088 break;
01089
01090 case WSAEMSGSIZE:
01091 e = NoResources;
01092
01093 break;
01094
01095 case WSAEISCONN:
01096
01097 r = 0;
01098
01099 break;
01100
01101 default:
01102 e = UnknownError;
01103
01104 break;
01105 }
01106 }
01107
01108 return r;
01109 }
01110
01111
01112 qint64 MSocketDevice::writeData(const char *data, qint64 len)
01113 {
01114 if (len == 0)
01115 return 0;
01116
01117 if (data == 0)
01118 {
01119 #if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
01120 qWarning("MSocketDevice::writeBlock: Null pointer error");
01121 #endif
01122 return -1;
01123 }
01124
01125 if (!isValid())
01126 {
01127 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01128 qWarning("MSocketDevice::writeBlock: Invalid socket");
01129 #endif
01130 return -1;
01131 }
01132
01133 if (!isOpen())
01134 {
01135 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01136 qWarning("MSocketDevice::writeBlock: Device is not open");
01137 #endif
01138 return -1;
01139 }
01140
01141 if (!isWritable())
01142 {
01143 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01144 qWarning("MSocketDevice::writeBlock: Write operation not permitted");
01145 #endif
01146 return -1;
01147 }
01148
01149 bool done = false;
01150
01151 qint64 r = 0;
01152
01153 while (!done)
01154 {
01155
01156 r = ::send(fd, data, (len > 64 * 1024 ? 64 * 1024 : len), 0);
01157 done = true;
01158
01159 if (r == SOCKET_ERROR && e == NoError)
01160 {
01161 switch (WSAGetLastError())
01162 {
01163
01164 case WSANOTINITIALISED:
01165 e = Impossible;
01166 break;
01167
01168 case WSAENETDOWN:
01169
01170 case WSAEACCES:
01171
01172 case WSAENETRESET:
01173
01174 case WSAESHUTDOWN:
01175
01176 case WSAEHOSTUNREACH:
01177 e = NetworkFailure;
01178 break;
01179
01180 case WSAECONNABORTED:
01181
01182 case WSAECONNRESET:
01183
01184 close();
01185 r = 0;
01186 break;
01187
01188 case WSAEINTR:
01189 done = false;
01190 break;
01191
01192 case WSAEINPROGRESS:
01193 e = NoResources;
01194
01195 break;
01196
01197 case WSAEFAULT:
01198
01199 case WSAEOPNOTSUPP:
01200 e = InternalError;
01201 break;
01202
01203 case WSAENOBUFS:
01204
01205 break;
01206
01207 case WSAEMSGSIZE:
01208 e = NoResources;
01209 break;
01210
01211 case WSAENOTCONN:
01212
01213 case WSAENOTSOCK:
01214
01215 case WSAEINVAL:
01216 e = Impossible;
01217 break;
01218
01219 case WSAEWOULDBLOCK:
01220 r = 0;
01221 break;
01222
01223 default:
01224 e = UnknownError;
01225 break;
01226 }
01227 }
01228 }
01229
01230 return r;
01231 }
01232
01233
01234 qint64 MSocketDevice::writeBlock(const char * data, quint64 len,
01235 const QHostAddress & host, quint16 port)
01236 {
01237 if (len == 0)
01238 return 0;
01239
01240 if (t != Datagram)
01241 {
01242 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01243 qWarning("MSocketDevice::sendBlock: Not datagram");
01244 #endif
01245 return -1;
01246 }
01247
01248 if (data == 0)
01249 {
01250 #if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
01251 qWarning("MSocketDevice::sendBlock: Null pointer error");
01252 #endif
01253 return -1;
01254 }
01255
01256 if (!isValid())
01257 {
01258 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01259 qWarning("MSocketDevice::sendBlock: Invalid socket");
01260 #endif
01261 return -1;
01262 }
01263
01264 if (!isOpen())
01265 {
01266 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01267 qWarning("MSocketDevice::sendBlock: Device is not open");
01268 #endif
01269 return -1;
01270 }
01271
01272 if (!isWritable())
01273 {
01274 #if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
01275 qWarning("MSocketDevice::sendBlock: Write operation not permitted");
01276 #endif
01277 return -1;
01278 }
01279
01280 struct sockaddr_in a4;
01281
01282 struct sockaddr *aa;
01283
01284 SOCKLEN_T slen;
01285
01286 #if !defined(QT_NO_IPV6)
01287 qt_sockaddr_in6 a6;
01288
01289 if (initialized >= 0x20 && host.protocol() == QAbstractSocket::IPv6Protocol)
01290 {
01291 memset(&a6, 0, sizeof(a6));
01292 a6.sin6_family = AF_INET6;
01293 a6.sin6_port = htons(port);
01294
01295 Q_IPV6ADDR tmp = host.toIPv6Address();
01296 memcpy(&a6.sin6_addr.qt_s6_addr, &tmp, sizeof(tmp));
01297 slen = sizeof(a6);
01298 aa = (struct sockaddr *) & a6;
01299 }
01300 else
01301 #endif
01302 if (host.protocol() == QAbstractSocket::IPv4Protocol)
01303 {
01304
01305 memset(&a4, 0, sizeof(a4));
01306 a4.sin_family = AF_INET;
01307 a4.sin_port = htons(port);
01308 a4.sin_addr.s_addr = htonl(host.toIPv4Address());
01309 slen = sizeof(a4);
01310 aa = (struct sockaddr *) & a4;
01311 }
01312 else
01313 {
01314 e = Impossible;
01315 return -1;
01316 }
01317
01318
01319
01320 bool done = false;
01321
01322 qint64 r = 0;
01323
01324 while (!done)
01325 {
01326 r = ::sendto(fd, data, len, 0, aa, slen);
01327 done = true;
01328
01329 if (r == SOCKET_ERROR && e == NoError)
01330 {
01331 switch (WSAGetLastError())
01332 {
01333
01334 case WSANOTINITIALISED:
01335 e = Impossible;
01336 break;
01337
01338 case WSAENETDOWN:
01339
01340 case WSAEACCES:
01341
01342 case WSAENETRESET:
01343
01344 case WSAESHUTDOWN:
01345
01346 case WSAEHOSTUNREACH:
01347
01348 case WSAECONNABORTED:
01349
01350 case WSAECONNRESET:
01351
01352 case WSAEADDRNOTAVAIL:
01353
01354 case WSAENETUNREACH:
01355
01356 case WSAETIMEDOUT:
01357 e = NetworkFailure;
01358 break;
01359
01360 case WSAEINTR:
01361 done = false;
01362 break;
01363
01364 case WSAEINPROGRESS:
01365 e = NoResources;
01366
01367 break;
01368
01369 case WSAEFAULT:
01370
01371 case WSAEOPNOTSUPP:
01372
01373 case WSAEAFNOSUPPORT:
01374 e = InternalError;
01375 break;
01376
01377 case WSAENOBUFS:
01378
01379 case WSAEMSGSIZE:
01380 e = NoResources;
01381 break;
01382
01383 case WSAENOTCONN:
01384
01385 case WSAENOTSOCK:
01386
01387 case WSAEINVAL:
01388
01389 case WSAEDESTADDRREQ:
01390 e = Impossible;
01391 break;
01392
01393 case WSAEWOULDBLOCK:
01394 r = 0;
01395 break;
01396
01397 default:
01398 e = UnknownError;
01399 break;
01400 }
01401 }
01402 }
01403
01404 return r;
01405 }
01406
01407
01408 void MSocketDevice::fetchConnectionParameters()
01409 {
01410 if (!isValid())
01411 {
01412 p = 0;
01413 a = QHostAddress();
01414 pp = 0;
01415 pa = QHostAddress();
01416 return;
01417 }
01418
01419 #if !defined (QT_NO_IPV6)
01420
01421 struct qt_sockaddr_storage sa;
01422
01423 #else
01424
01425 struct sockaddr_in sa;
01426
01427 #endif
01428 memset(&sa, 0, sizeof(sa));
01429
01430 SOCKLEN_T sz;
01431
01432 sz = sizeof(sa);
01433
01434 if (!::getsockname(fd, (struct sockaddr *)(&sa), &sz))
01435 qt_socket_getportaddr((struct sockaddr *)(&sa), &p, &a);
01436
01437 pp = 0;
01438
01439 pa = QHostAddress();
01440 }
01441
01442
01443 void MSocketDevice::fetchPeerConnectionParameters()
01444 {
01445
01446
01447 #if !defined (QT_NO_IPV6)
01448
01449 struct qt_sockaddr_storage sa;
01450 #else
01451
01452 struct sockaddr_in sa;
01453 #endif
01454 memset(&sa, 0, sizeof(sa));
01455 SOCKLEN_T sz;
01456 sz = sizeof(sa);
01457
01458 if (!::getpeername(fd, (struct sockaddr *)(&sa), &sz))
01459 qt_socket_getportaddr((struct sockaddr *)(&sa), &pp, &pa);
01460 }
01461
01462 quint16 MSocketDevice::peerPort() const
01463 {
01464 if (pp == 0 && isValid())
01465 {
01466 MSocketDevice *that = (MSocketDevice*)this;
01467 that->fetchPeerConnectionParameters();
01468 }
01469
01470 return pp;
01471 }
01472
01473
01474 QHostAddress MSocketDevice::peerAddress() const
01475 {
01476 if (pp == 0 && isValid())
01477 {
01478 MSocketDevice *that = (MSocketDevice*)this;
01479 that->fetchPeerConnectionParameters();
01480 }
01481
01482 return pa;
01483 }
01484