summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/socket/qnativesocketengine_p.h')
-rw-r--r--src/network/socket/qnativesocketengine_p.h126
1 files changed, 72 insertions, 54 deletions
diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h
index 24909bf310..0fa1d8f96e 100644
--- a/src/network/socket/qnativesocketengine_p.h
+++ b/src/network/socket/qnativesocketengine_p.h
@@ -51,46 +51,51 @@
# include <netinet/in.h>
#else
# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <mswsock.h>
#endif
QT_BEGIN_NAMESPACE
-// Use our own defines and structs which we know are correct
-# define QT_SS_MAXSIZE 128
-# define QT_SS_ALIGNSIZE (sizeof(qint64))
-# define QT_SS_PAD1SIZE (QT_SS_ALIGNSIZE - sizeof (short))
-# define QT_SS_PAD2SIZE (QT_SS_MAXSIZE - (sizeof (short) + QT_SS_PAD1SIZE + QT_SS_ALIGNSIZE))
-struct qt_sockaddr_storage {
- short ss_family;
- char __ss_pad1[QT_SS_PAD1SIZE];
- qint64 __ss_align;
- char __ss_pad2[QT_SS_PAD2SIZE];
-};
-
#ifdef Q_OS_WIN
#define QT_SOCKLEN_T int
#define QT_SOCKOPTLEN_T int
-#endif
-// sockaddr_in6 size changed between old and new SDK
-// Only the new version is the correct one, so always
-// use this structure.
-struct qt_in6_addr {
- quint8 qt_s6_addr[16];
-};
-struct qt_sockaddr_in6 {
- short sin6_family; /* AF_INET6 */
- quint16 sin6_port; /* Transport level port number */
- quint32 sin6_flowinfo; /* IPv6 flow information */
- struct qt_in6_addr sin6_addr; /* IPv6 address */
- quint32 sin6_scope_id; /* set of interfaces for a scope */
-};
+// The following definitions are copied from the MinGW header mswsock.h which
+// was placed in the public domain. The WSASendMsg and WSARecvMsg functions
+// were introduced with Windows Vista, so some Win32 headers are lacking them.
+// There are no known versions of Windows CE or Embedded that contain them.
+#ifndef Q_OS_WINCE
+# ifndef WSAID_WSARECVMSG
+typedef INT (WINAPI *LPFN_WSARECVMSG)(SOCKET s, LPWSAMSG lpMsg,
+ LPDWORD lpdwNumberOfBytesRecvd,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
+# define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}
+# endif
+# ifndef WSAID_WSASENDMSG
+typedef struct {
+ LPWSAMSG lpMsg;
+ DWORD dwFlags;
+ LPDWORD lpNumberOfBytesSent;
+ LPWSAOVERLAPPED lpOverlapped;
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
+} WSASENDMSG, *LPWSASENDMSG;
+
+typedef INT (WSAAPI *LPFN_WSASENDMSG)(SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags,
+ LPDWORD lpNumberOfBytesSent,
+ LPWSAOVERLAPPED lpOverlapped,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
+
+# define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}}
+# endif
+#endif
+#endif
union qt_sockaddr {
sockaddr a;
sockaddr_in a4;
- qt_sockaddr_in6 a6;
- qt_sockaddr_storage storage;
+ sockaddr_in6 a6;
};
class QNativeSocketEnginePrivate;
@@ -133,10 +138,9 @@ public:
qint64 read(char *data, qint64 maxlen) Q_DECL_OVERRIDE;
qint64 write(const char *data, qint64 len) Q_DECL_OVERRIDE;
- qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *addr = 0,
- quint16 *port = 0) Q_DECL_OVERRIDE;
- qint64 writeDatagram(const char *data, qint64 len, const QHostAddress &addr,
- quint16 port) Q_DECL_OVERRIDE;
+ qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = 0,
+ PacketHeaderOptions = WantNone) Q_DECL_OVERRIDE;
+ qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) Q_DECL_OVERRIDE;
bool hasPendingDatagrams() const Q_DECL_OVERRIDE;
qint64 pendingDatagramSize() const Q_DECL_OVERRIDE;
@@ -173,16 +177,6 @@ private:
Q_DISABLE_COPY(QNativeSocketEngine)
};
-#ifdef Q_OS_WIN
-class QWindowsSockInit
-{
-public:
- QWindowsSockInit();
- ~QWindowsSockInit();
- int version;
-};
-#endif
-
class QSocketNotifier;
class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
@@ -196,10 +190,10 @@ public:
QSocketNotifier *readNotifier, *writeNotifier, *exceptNotifier;
-#ifdef Q_OS_WIN
- QWindowsSockInit winSock;
-#endif
-
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+ LPFN_WSASENDMSG sendmsg;
+ LPFN_WSARECVMSG recvmsg;
+# endif
enum ErrorString {
NonBlockingInitFailedErrorString,
BroadcastingInitFailedErrorString,
@@ -256,24 +250,48 @@ public:
bool nativeHasPendingDatagrams() const;
qint64 nativePendingDatagramSize() const;
- qint64 nativeReceiveDatagram(char *data, qint64 maxLength,
- QHostAddress *address, quint16 *port);
- qint64 nativeSendDatagram(const char *data, qint64 length,
- const QHostAddress &host, quint16 port);
+ qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
+ QAbstractSocketEngine::PacketHeaderOptions options);
+ qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header);
qint64 nativeRead(char *data, qint64 maxLength);
qint64 nativeWrite(const char *data, qint64 length);
int nativeSelect(int timeout, bool selectForRead) const;
int nativeSelect(int timeout, bool checkRead, bool checkWrite,
bool *selectForRead, bool *selectForWrite) const;
-#ifdef Q_OS_WIN
- void setPortAndAddress(sockaddr_in * sockAddrIPv4, qt_sockaddr_in6 * sockAddrIPv6,
- quint16 port, const QHostAddress & address, sockaddr ** sockAddrPtr, QT_SOCKLEN_T *sockAddrSize);
-#endif
void nativeClose();
bool checkProxy(const QHostAddress &address);
bool fetchConnectionParameters();
+
+ static uint scopeIdFromString(const QString &scopeid);
+
+ /*! \internal
+ Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
+ The address \a is converted to IPv6 if the current socket protocol is also IPv6.
+ */
+ void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
+ {
+ if (address.protocol() == QAbstractSocket::IPv6Protocol
+ || address.protocol() == QAbstractSocket::AnyIPProtocol
+ || socketProtocol == QAbstractSocket::IPv6Protocol
+ || socketProtocol == QAbstractSocket::AnyIPProtocol) {
+ memset(&aa->a6, 0, sizeof(sockaddr_in6));
+ aa->a6.sin6_family = AF_INET6;
+ aa->a6.sin6_scope_id = scopeIdFromString(address.scopeId());
+ aa->a6.sin6_port = htons(port);
+ Q_IPV6ADDR tmp = address.toIPv6Address();
+ memcpy(&aa->a6.sin6_addr, &tmp, sizeof(tmp));
+ *sockAddrSize = sizeof(sockaddr_in6);
+ } else {
+ memset(&aa->a, 0, sizeof(sockaddr_in));
+ aa->a4.sin_family = AF_INET;
+ aa->a4.sin_port = htons(port);
+ aa->a4.sin_addr.s_addr = htonl(address.toIPv4Address());
+ *sockAddrSize = sizeof(sockaddr_in);
+ }
+ }
+
};
QT_END_NAMESPACE