1// Copyright (C) 2023 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QNATIVESOCKETENGINE_P_P_H
6#define QNATIVESOCKETENGINE_P_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include "private/qabstractsocketengine_p.h"
20#include "private/qnativesocketengine_p.h"
21
22#ifndef Q_OS_WIN
23# include <netinet/in.h>
24#else
25# include <winsock2.h>
26# include <ws2tcpip.h>
27# include <mswsock.h>
28#endif
29
30QT_BEGIN_NAMESPACE
31
32#ifdef Q_OS_WIN
33
34// The following definitions are copied from the MinGW header mswsock.h which
35// was placed in the public domain. The WSASendMsg and WSARecvMsg functions
36// were introduced with Windows Vista, so some Win32 headers are lacking them.
37// There are no known versions of Windows CE or Embedded that contain them.
38# ifndef WSAID_WSARECVMSG
39typedef INT (WINAPI *LPFN_WSARECVMSG)(SOCKET s, LPWSAMSG lpMsg,
40 LPDWORD lpdwNumberOfBytesRecvd,
41 LPWSAOVERLAPPED lpOverlapped,
42 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
43# define WSAID_WSARECVMSG {0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}
44# endif // !WSAID_WSARECVMSG
45# ifndef WSAID_WSASENDMSG
46typedef struct {
47 LPWSAMSG lpMsg;
48 DWORD dwFlags;
49 LPDWORD lpNumberOfBytesSent;
50 LPWSAOVERLAPPED lpOverlapped;
51 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
52} WSASENDMSG, *LPWSASENDMSG;
53
54typedef INT (WSAAPI *LPFN_WSASENDMSG)(SOCKET s, LPWSAMSG lpMsg, DWORD dwFlags,
55 LPDWORD lpNumberOfBytesSent,
56 LPWSAOVERLAPPED lpOverlapped,
57 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
58
59# define WSAID_WSASENDMSG {0xa441e712,0x754f,0x43ca,{0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d}}
60# endif // !WSAID_WSASENDMSG
61#endif // Q_OS_WIN
62
63union qt_sockaddr {
64 sockaddr a;
65 sockaddr_in a4;
66 sockaddr_in6 a6;
67};
68
69class QSocketNotifier;
70
71class QNativeSocketEnginePrivate : public QAbstractSocketEnginePrivate
72{
73 Q_DECLARE_PUBLIC(QNativeSocketEngine)
74public:
75 QNativeSocketEnginePrivate();
76 ~QNativeSocketEnginePrivate();
77
78 qintptr socketDescriptor;
79
80 QSocketNotifier *readNotifier, *writeNotifier, *exceptNotifier;
81
82#if defined(Q_OS_WIN)
83 LPFN_WSASENDMSG sendmsg;
84 LPFN_WSARECVMSG recvmsg;
85# endif
86 enum ErrorString {
87 NonBlockingInitFailedErrorString,
88 BroadcastingInitFailedErrorString,
89 NoIpV6ErrorString,
90 RemoteHostClosedErrorString,
91 TimeOutErrorString,
92 ResourceErrorString,
93 OperationUnsupportedErrorString,
94 ProtocolUnsupportedErrorString,
95 InvalidSocketErrorString,
96 HostUnreachableErrorString,
97 NetworkUnreachableErrorString,
98 AccessErrorString,
99 ConnectionTimeOutErrorString,
100 ConnectionRefusedErrorString,
101 AddressInuseErrorString,
102 AddressNotAvailableErrorString,
103 AddressProtectedErrorString,
104 DatagramTooLargeErrorString,
105 SendDatagramErrorString,
106 ReceiveDatagramErrorString,
107 WriteErrorString,
108 ReadErrorString,
109 PortInuseErrorString,
110 NotSocketErrorString,
111 InvalidProxyTypeString,
112 TemporaryErrorString,
113 NetworkDroppedConnectionErrorString,
114 ConnectionResetErrorString,
115
116 UnknownSocketErrorString = -1
117 };
118
119 void setError(QAbstractSocket::SocketError error, ErrorString errorString) const;
120 QHostAddress adjustAddressProtocol(const QHostAddress &address) const;
121
122 // native functions
123 int option(QNativeSocketEngine::SocketOption option) const;
124 bool setOption(QNativeSocketEngine::SocketOption option, int value);
125
126 bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol &protocol);
127
128 bool nativeConnect(const QHostAddress &address, quint16 port);
129 bool nativeBind(const QHostAddress &address, quint16 port);
130 bool nativeListen(int backlog);
131 qintptr nativeAccept();
132#ifndef QT_NO_NETWORKINTERFACE
133 bool nativeJoinMulticastGroup(const QHostAddress &groupAddress,
134 const QNetworkInterface &iface);
135 bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress,
136 const QNetworkInterface &iface);
137 QNetworkInterface nativeMulticastInterface() const;
138 bool nativeSetMulticastInterface(const QNetworkInterface &iface);
139#endif
140 qint64 nativeBytesAvailable() const;
141
142 bool nativeHasPendingDatagrams() const;
143 qint64 nativePendingDatagramSize() const;
144 qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QIpPacketHeader *header,
145 QAbstractSocketEngine::PacketHeaderOptions options);
146 qint64 nativeSendDatagram(const char *data, qint64 length, const QIpPacketHeader &header);
147 qint64 nativeRead(char *data, qint64 maxLength);
148 qint64 nativeWrite(const char *data, qint64 length);
149 int nativeSelect(int timeout, bool selectForRead) const;
150 int nativeSelect(int timeout, bool checkRead, bool checkWrite,
151 bool *selectForRead, bool *selectForWrite) const;
152
153 void nativeClose();
154
155 bool checkProxy(const QHostAddress &address);
156 bool fetchConnectionParameters();
157
158 /*! \internal
159 Sets \a address and \a port in the \a aa sockaddr structure and the size in \a sockAddrSize.
160 The address \a is converted to IPv6 if the current socket protocol is also IPv6.
161 */
162 void setPortAndAddress(quint16 port, const QHostAddress &address, qt_sockaddr *aa, QT_SOCKLEN_T *sockAddrSize)
163 {
164 switch (socketProtocol) {
165 case QHostAddress::IPv6Protocol:
166 case QHostAddress::AnyIPProtocol:
167 // force to IPv6
168 setSockaddr(sin6: &aa->a6, addr: address, port);
169 *sockAddrSize = sizeof(sockaddr_in6);
170 return;
171
172 case QHostAddress::IPv4Protocol:
173 // force to IPv4
174 setSockaddr(sin: &aa->a4, addr: address, port);
175 *sockAddrSize = sizeof(sockaddr_in);
176 return;
177
178 case QHostAddress::UnknownNetworkLayerProtocol:
179 // don't force
180 break;
181 }
182 *sockAddrSize = setSockaddr(sa: &aa->a, addr: address, port);
183 }
184
185};
186
187QT_END_NAMESPACE
188
189#endif // QNATIVESOCKETENGINE_P_P_H
190

source code of qtbase/src/network/socket/qnativesocketengine_p_p.h