// Copyright (C) 2016 The Qt Company Ltd. // Copyright (C) 2016 Intel Corporation. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QNATIVESOCKETENGINE_P_H #define QNATIVESOCKETENGINE_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include "QtNetwork/qhostaddress.h" #include "QtNetwork/qnetworkinterface.h" #include "private/qabstractsocketengine_p.h" #include "qplatformdefs.h" #ifndef Q_OS_WIN # include #else # include # include # include #endif QT_BEGIN_NAMESPACE #ifdef Q_OS_WIN # define QT_SOCKLEN_T int # define QT_SOCKOPTLEN_T int #endif namespace { namespace SetSALen { template void set(T *sa, typename std::enable_if<(&T::sa_len, true), QT_SOCKLEN_T>::type len) { sa->sa_len = len; } template void set(T *sa, typename std::enable_if<(&T::sin_len, true), QT_SOCKLEN_T>::type len) { sa->sin_len = len; } template void set(T *sin6, typename std::enable_if<(&T::sin6_len, true), QT_SOCKLEN_T>::type len) { sin6->sin6_len = len; } template void set(T *, ...) {} } inline QT_SOCKLEN_T setSockaddr(sockaddr_in *sin, const QHostAddress &addr, quint16 port = 0) { *sin = {}; SetSALen::set(sin, sizeof(*sin)); sin->sin_family = AF_INET; sin->sin_port = htons(port); sin->sin_addr.s_addr = htonl(addr.toIPv4Address()); return sizeof(*sin); } inline QT_SOCKLEN_T setSockaddr(sockaddr_in6 *sin6, const QHostAddress &addr, quint16 port = 0) { *sin6 = {}; SetSALen::set(sin6, sizeof(*sin6)); sin6->sin6_family = AF_INET6; sin6->sin6_port = htons(port); memcpy(sin6->sin6_addr.s6_addr, addr.toIPv6Address().c, sizeof(sin6->sin6_addr)); #if QT_CONFIG(networkinterface) sin6->sin6_scope_id = QNetworkInterface::interfaceIndexFromName(addr.scopeId()); #else // it had better be a number then, if it is not empty sin6->sin6_scope_id = addr.scopeId().toUInt(); #endif return sizeof(*sin6); } inline QT_SOCKLEN_T setSockaddr(sockaddr *sa, const QHostAddress &addr, quint16 port = 0) { switch (addr.protocol()) { case QHostAddress::IPv4Protocol: return setSockaddr(reinterpret_cast(sa), addr, port); case QHostAddress::IPv6Protocol: case QHostAddress::AnyIPProtocol: return setSockaddr(reinterpret_cast(sa), addr, port); case QHostAddress::UnknownNetworkLayerProtocol: break; } *sa = {}; sa->sa_family = AF_UNSPEC; return 0; } } // unnamed namespace class QNativeSocketEnginePrivate; #ifndef QT_NO_NETWORKINTERFACE class QNetworkInterface; #endif class Q_AUTOTEST_EXPORT QNativeSocketEngine : public QAbstractSocketEngine { Q_OBJECT public: QNativeSocketEngine(QObject *parent = nullptr); ~QNativeSocketEngine(); bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) override; bool initialize(qintptr socketDescriptor, QAbstractSocket::SocketState socketState = QAbstractSocket::ConnectedState) override; qintptr socketDescriptor() const override; bool isValid() const override; bool connectToHost(const QHostAddress &address, quint16 port) override; bool connectToHostByName(const QString &name, quint16 port) override; bool bind(const QHostAddress &address, quint16 port) override; bool listen(int backlog) override; qintptr accept() override; void close() override; qint64 bytesAvailable() const override; qint64 read(char *data, qint64 maxlen) override; qint64 write(const char *data, qint64 len) override; #ifndef QT_NO_UDPSOCKET #ifndef QT_NO_NETWORKINTERFACE bool joinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface) override; bool leaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface) override; QNetworkInterface multicastInterface() const override; bool setMulticastInterface(const QNetworkInterface &iface) override; #endif bool hasPendingDatagrams() const override; qint64 pendingDatagramSize() const override; #endif // QT_NO_UDPSOCKET qint64 readDatagram(char *data, qint64 maxlen, QIpPacketHeader * = nullptr, PacketHeaderOptions = WantNone) override; qint64 writeDatagram(const char *data, qint64 len, const QIpPacketHeader &) override; qint64 bytesToWrite() const override; #if 0 // currently unused qint64 receiveBufferSize() const; void setReceiveBufferSize(qint64 bufferSize); qint64 sendBufferSize() const; void setSendBufferSize(qint64 bufferSize); #endif int option(SocketOption option) const override; bool setOption(SocketOption option, int value) override; bool waitForRead(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout}, bool *timedOut = nullptr) override; bool waitForWrite(QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout}, bool *timedOut = nullptr) override; bool waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, bool checkRead, bool checkWrite, QDeadlineTimer deadline = QDeadlineTimer{DefaultTimeout}, bool *timedOut = nullptr) override; bool isReadNotificationEnabled() const override; void setReadNotificationEnabled(bool enable) override; bool isWriteNotificationEnabled() const override; void setWriteNotificationEnabled(bool enable) override; bool isExceptionNotificationEnabled() const override; void setExceptionNotificationEnabled(bool enable) override; public Q_SLOTS: // non-virtual override; void connectionNotification(); private: Q_DECLARE_PRIVATE(QNativeSocketEngine) Q_DISABLE_COPY_MOVE(QNativeSocketEngine) }; QT_END_NAMESPACE #endif // QNATIVESOCKETENGINE_P_H