44 #include "private/qnet_unix_p.h" 53 #ifndef QT_NO_IPV6IFNAME 56 #ifndef QT_NO_IPV6IFNAME 60 #include <arpa/inet.h> 63 #if defined QNATIVESOCKETENGINE_DEBUG 68 #include <netinet/tcp.h> 72 #if defined QNATIVESOCKETENGINE_DEBUG 78 static QByteArray qt_prettyDebug(
const char *
data,
int len,
int maxSize)
80 if (!data)
return "(null)";
82 for (
int i = 0; i < len; ++i) {
87 case '\n': out +=
"\\n";
break;
88 case '\r': out +=
"\\r";
break;
89 case '\t': out +=
"\\t";
break;
110 #if !defined(QT_NO_IPV6) 118 #ifndef QT_NO_IPV6IFNAME 119 char scopeid[IFNAMSIZ];
132 *port = ntohs(s->
a4.sin_port);
155 int protocol = AF_INET;
163 case EPROTONOSUPPORT:
198 int level = SOL_SOCKET;
229 level = IPPROTO_IPV6;
230 n = IPV6_MULTICAST_HOPS;
235 n = IP_MULTICAST_TTL;
241 level = IPPROTO_IPV6;
242 n = IPV6_MULTICAST_LOOP;
247 n = IP_MULTICAST_LOOP;
271 int level = SOL_SOCKET;
285 #if !defined(Q_OS_VXWORKS) 288 #ifdef QNATIVESOCKETENGINE_DEBUG 289 perror(
"QNativeSocketEnginePrivate::setOption(): fcntl(F_GETFL) failed");
294 #ifdef QNATIVESOCKETENGINE_DEBUG 295 perror(
"QNativeSocketEnginePrivate::setOption(): fcntl(F_SETFL) failed");
299 #else // Q_OS_VXWORKS 304 #ifdef QNATIVESOCKETENGINE_DEBUG 305 perror(
"QNativeSocketEnginePrivate::setOption(): ioctl(FIONBIO, 1) failed");
309 #endif // Q_OS_VXWORKS 313 #if defined(SO_REUSEPORT) 340 level = IPPROTO_IPV6;
341 n = IPV6_MULTICAST_HOPS;
346 n = IP_MULTICAST_TTL;
352 level = IPPROTO_IPV6;
353 n = IPV6_MULTICAST_LOOP;
358 n = IP_MULTICAST_LOOP;
363 return ::setsockopt(
socketDescriptor, level, n, (
char *) &v,
sizeof(v)) == 0;
368 #ifdef QNATIVESOCKETENGINE_DEBUG 372 struct sockaddr_in sockAddrIPv4;
373 struct sockaddr *sockAddrPtr = 0;
376 #if !defined(QT_NO_IPV6) 377 struct sockaddr_in6 sockAddrIPv6;
380 memset(&sockAddrIPv6, 0,
sizeof(sockAddrIPv6));
381 sockAddrIPv6.sin6_family =
AF_INET6;
382 sockAddrIPv6.sin6_port = htons(port);
386 sockAddrIPv6.sin6_scope_id = scopeid.
toInt(&ok);
387 #ifndef QT_NO_IPV6IFNAME 389 sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.
toLatin1());
392 memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &ip6,
sizeof(ip6));
394 sockAddrSize =
sizeof(sockAddrIPv6);
395 sockAddrPtr = (
struct sockaddr *) &sockAddrIPv6;
402 memset(&sockAddrIPv4, 0,
sizeof(sockAddrIPv4));
403 sockAddrIPv4.sin_family = AF_INET;
404 sockAddrIPv4.sin_port = htons(port);
407 sockAddrSize =
sizeof(sockAddrIPv4);
408 sockAddrPtr = (
struct sockaddr *) &sockAddrIPv4;
414 if (connectResult == -1) {
462 #if defined (QNATIVESOCKETENGINE_DEBUG) 463 qDebug(
"QNativeSocketEnginePrivate::nativeConnect(%s, %i) == false (%s)",
472 #if defined (QNATIVESOCKETENGINE_DEBUG) 473 qDebug(
"QNativeSocketEnginePrivate::nativeConnect(%s, %i) == true",
483 struct sockaddr_in sockAddrIPv4;
484 struct sockaddr *sockAddrPtr = 0;
487 #if !defined(QT_NO_IPV6) 488 struct sockaddr_in6 sockAddrIPv6;
491 memset(&sockAddrIPv6, 0,
sizeof(sockAddrIPv6));
492 sockAddrIPv6.sin6_family =
AF_INET6;
493 sockAddrIPv6.sin6_port = htons(port);
494 #ifndef QT_NO_IPV6IFNAME 500 memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp,
sizeof(tmp));
501 sockAddrSize =
sizeof(sockAddrIPv6);
502 sockAddrPtr = (
struct sockaddr *) &sockAddrIPv6;
506 memset(&sockAddrIPv4, 0,
sizeof(sockAddrIPv4));
507 sockAddrIPv4.sin_family = AF_INET;
508 sockAddrIPv4.sin_port = htons(port);
509 sockAddrIPv4.sin_addr.s_addr = htonl(address.
toIPv4Address());
510 sockAddrSize =
sizeof(sockAddrIPv4);
511 sockAddrPtr = (
struct sockaddr *) &sockAddrIPv4;
516 int bindResult = QT_SOCKET_BIND(
socketDescriptor, sockAddrPtr, sockAddrSize);
518 if (bindResult < 0) {
536 #if defined (QNATIVESOCKETENGINE_DEBUG) 537 qDebug(
"QNativeSocketEnginePrivate::nativeBind(%s, %i) == false (%s)",
544 #if defined (QNATIVESOCKETENGINE_DEBUG) 545 qDebug(
"QNativeSocketEnginePrivate::nativeBind(%s, %i) == true",
564 #if defined (QNATIVESOCKETENGINE_DEBUG) 565 qDebug(
"QNativeSocketEnginePrivate::nativeListen(%i) == false (%s)",
571 #if defined (QNATIVESOCKETENGINE_DEBUG) 572 qDebug(
"QNativeSocketEnginePrivate::nativeListen(%i) == true", backlog);
583 return acceptedDescriptor;
586 #ifndef QT_NO_NETWORKINTERFACE 604 level = IPPROTO_IPV6;
607 sockArgSize =
sizeof(mreq6);
608 memset(&mreq6, 0,
sizeof(mreq6));
610 memcpy(&mreq6.ipv6mr_multiaddr, &ip6,
sizeof(ip6));
611 mreq6.ipv6mr_interface = interface.
index();
618 sockArgSize =
sizeof(mreq4);
619 memset(&mreq4, 0,
sizeof(mreq4));
620 mreq4.imr_multiaddr.s_addr = htonl(groupAddress.
toIPv4Address());
624 if (!addressEntries.
isEmpty()) {
633 mreq4.imr_interface.s_addr = INADDR_ANY;
642 int res = setsockopt(d->
socketDescriptor, level, sockOpt, sockArg, sockArgSize);
697 if (::getsockopt(
socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v, &sizeofv) == -1)
703 struct in_addr v = { 0 };
705 if (::getsockopt(
socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v, &sizeofv) == -1)
707 if (v.s_addr != 0 && sizeofv >=
sizeof(v)) {
710 for (
int i = 0; i < ifaces.
count(); ++i) {
713 for (
int j = 0; j < entries.
count(); ++j) {
715 if (entry.
ip() == ipv4)
728 return (::setsockopt(
socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, &v,
sizeof(v)) != -1);
735 for (
int i = 0; i < entries.
count(); ++i) {
740 int r = ::setsockopt(
socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v,
sizeof(v));
748 v.s_addr = INADDR_ANY;
749 return (::setsockopt(
socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, &v,
sizeof(v)) != -1);
752 #endif // QT_NO_NETWORKINTERFACE 760 available = (
qint64) nbytes;
762 #if defined (QNATIVESOCKETENGINE_DEBUG) 763 qDebug(
"QNativeSocketEnginePrivate::nativeBytesAvailable() == %lli", available);
773 memset(&storage, 0, storageSize);
780 readBytes = ::recvfrom(
socketDescriptor, &c, 1, MSG_PEEK, &storage.
a, &storageSize);
781 }
while (readBytes == -1 &&
errno == EINTR);
785 bool result = (readBytes != -1) ||
errno == EMSGSIZE;
787 #if defined (QNATIVESOCKETENGINE_DEBUG) 788 qDebug(
"QNativeSocketEnginePrivate::nativeHasPendingDatagrams() == %s",
789 result ?
"true" :
"false");
797 ssize_t recvResult = -1;
804 udpMessagePeekBuffer.
size(), MSG_PEEK);
805 if (recvResult == -1 &&
errno == EINTR)
808 if (recvResult != (ssize_t) udpMessagePeekBuffer.
size())
811 udpMessagePeekBuffer.
resize(udpMessagePeekBuffer.
size() * 2);
814 #if defined (QNATIVESOCKETENGINE_DEBUG) 815 qDebug(
"QNativeSocketEnginePrivate::nativePendingDatagramSize() == %i", recvResult);
818 return qint64(recvResult);
825 memset(&aa, 0,
sizeof(aa));
829 ssize_t recvFromResult = 0;
832 recvFromResult = ::recvfrom(
socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1,
834 }
while (recvFromResult == -1 &&
errno == EINTR);
836 if (recvFromResult == -1) {
838 }
else if (port || address) {
842 #if defined (QNATIVESOCKETENGINE_DEBUG) 843 qDebug(
"QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",
844 data, qt_prettyDebug(data,
qMin(recvFromResult, ssize_t(16)), recvFromResult).
data(), maxSize,
846 port ? *port : 0, (
qint64) recvFromResult);
849 return qint64(maxSize ? recvFromResult : recvFromResult == -1 ? -1 : 0);
855 struct sockaddr_in sockAddrIPv4;
856 struct sockaddr *sockAddrPtr = 0;
859 #if !defined(QT_NO_IPV6) 860 struct sockaddr_in6 sockAddrIPv6;
862 memset(&sockAddrIPv6, 0,
sizeof(sockAddrIPv6));
863 sockAddrIPv6.sin6_family =
AF_INET6;
864 sockAddrIPv6.sin6_port = htons(port);
867 memcpy(&sockAddrIPv6.sin6_addr.s6_addr, &tmp,
sizeof(tmp));
870 sockAddrIPv6.sin6_scope_id = scopeid.
toInt(&ok);
871 #ifndef QT_NO_IPV6IFNAME 873 sockAddrIPv6.sin6_scope_id = ::if_nametoindex(scopeid.
toLatin1());
875 sockAddrSize =
sizeof(sockAddrIPv6);
876 sockAddrPtr = (
struct sockaddr *)&sockAddrIPv6;
880 memset(&sockAddrIPv4, 0,
sizeof(sockAddrIPv4));
881 sockAddrIPv4.sin_family = AF_INET;
882 sockAddrIPv4.sin_port = htons(port);
884 sockAddrSize =
sizeof(sockAddrIPv4);
885 sockAddrPtr = (
struct sockaddr *)&sockAddrIPv4;
889 0, sockAddrPtr, sockAddrSize);
901 #if defined (QNATIVESOCKETENGINE_DEBUG) 902 qDebug(
"QNativeSocketEngine::sendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
904 port, (
qint64) sentBytes);
924 memset(&sa, 0,
sizeof(sa));
929 switch (sa.
a.sa_family) {
933 #if !defined (QT_NO_IPV6) 943 }
else if (
errno == EBADF) {
955 if (::getsockopt(
socketDescriptor, SOL_SOCKET, SO_TYPE, &value, &valueSize) == 0) {
956 if (value == SOCK_STREAM)
958 else if (value == SOCK_DGRAM)
963 #if defined (QNATIVESOCKETENGINE_DEBUG) 964 QString socketProtocolStr =
"UnknownProtocol";
968 QString socketTypeStr =
"UnknownSocketType";
972 qDebug(
"QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i," 973 " peer == %s:%i, socket == %s - %s",
983 #if defined (QNATIVESOCKETENGINE_DEBUG) 984 qDebug(
"QNativeSocketEngine::nativeClose()");
994 ssize_t writtenBytes;
997 if (writtenBytes < 0) {
1016 #if defined (QNATIVESOCKETENGINE_DEBUG) 1017 qDebug(
"QNativeSocketEnginePrivate::nativeWrite(%p \"%s\", %llu) == %i",
1018 data, qt_prettyDebug(data,
qMin((
int) len, 16),
1019 (
int) len).
data(), len, (
int) writtenBytes);
1022 return qint64(writtenBytes);
1029 if (!q->isValid()) {
1030 qWarning(
"QNativeSocketEngine::nativeRead: Invalid socket");
1040 #if EWOULDBLOCK-0 && EWOULDBLOCK != EAGAIN 1053 #if defined(Q_OS_VXWORKS) 1063 #if defined (QNATIVESOCKETENGINE_DEBUG) 1064 qDebug(
"QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %i",
1065 data, qt_prettyDebug(data,
qMin(r, ssize_t(16)), r).
data(),
1079 tv.tv_sec = timeout / 1000;
1080 tv.tv_usec = (timeout % 1000) * 1000;
1092 bool *selectForRead,
bool *selectForWrite)
const 1105 tv.tv_sec = timeout / 1000;
1106 tv.tv_usec = (timeout % 1000) * 1000;
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void setScopeId(const QString &id)
Sets the IPv6 scope ID of the address to id.
static void qt_socket_getPortAndAddress(const qt_sockaddr *s, quint16 *port, QHostAddress *addr)
QString scopeId() const
Returns the scope ID of an IPv6 address.
qint64 nativeBytesAvailable() const
int option(QNativeSocketEngine::SocketOption option) const
Returns the value of the socket option opt.
QString & sprintf(const char *format,...)
Safely builds a formatted string from the format string cformat and an arbitrary list of arguments...
Q_IPV6ADDR toIPv6Address() const
Returns the IPv6 address as a Q_IPV6ADDR structure.
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
#define QT_END_NAMESPACE
This macro expands to.
QHostAddress ip() const
This function returns one IPv4 or IPv6 address found, that was found in a network interface...
SocketType
This enum describes the transport layer protocol.
char * data()
Returns a pointer to the data stored in the byte array.
int toInt(bool *ok=0, int base=10) const
Returns the string converted to an int using base base, which is 10 by default and must be between 2 ...
The QByteArray class provides an array of bytes.
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
struct qt_in6_addr sin6_addr
int count(const T &t) const
Returns the number of occurrences of value in the list.
quint32 toIPv4Address() const
Returns the IPv4 address as a number.
NetworkLayerProtocol
This enum describes the network layer protocol values used in Qt.
static int qt_safe_close(int fd)
bool nativeHasPendingDatagrams() const
The QString class provides a Unicode character string.
bool nativeConnect(const QHostAddress &address, quint16 port)
bool setOption(QNativeSocketEngine::SocketOption option, int value)
Sets the socket option opt to v.
static int qt_safe_ioctl(int sockfd, int request, T arg)
qint64 nativeReceiveDatagram(char *data, qint64 maxLength, QHostAddress *address, quint16 *port)
The QNativeSocketEngine class provides low level access to a socket.
bool nativeListen(int backlog)
qint64 nativePendingDatagramSize() const
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Q_CORE_EXPORT void qDebug(const char *,...)
void clear()
Sets the host address to 0.0.0.0.
#define QT_BEGIN_NAMESPACE
This macro expands to.
static int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SOCKLEN_T addrlen)
QString socketErrorString
const T & at(int i) const
Returns the item at index position i in the list.
bool isValid() const
Returns true if this QNetworkInterface object contains valid information about a network interface...
Q_CORE_EXPORT void qWarning(const char *,...)
bool nativeJoinMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
static const char * data(const QByteArray &arr)
QString toString() const
Returns the address as a string.
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
int nativeSelect(int timeout, bool selectForRead) const
static QNetworkInterface interfaceFromIndex(int index)
Returns a QNetworkInterface object for the interface whose internal ID is index.
T & first()
Returns a reference to the first item in the list.
QAbstractSocket::SocketType socketType
const char * constData() const
Returns a pointer to the data stored in the byte array.
static const MacSpecialKey entries[NumEntries]
bool fetchConnectionParameters()
Fetches information about both ends of the connection: whatever is available.
qint64 nativeWrite(const char *data, qint64 length)
QAbstractSocket::NetworkLayerProtocol protocol() const
Returns the network layer protocol of the host address.
void setAddress(quint32 ip4Addr)
Set the IPv4 address specified by ip4Addr.
int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, const struct timeval *orig_timeout)
static int qt_safe_socket(int domain, int type, int protocol, int flags=0)
QHostAddress localAddress
static int qt_safe_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *to, QT_SOCKLEN_T tolen)
static int qt_safe_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen, int flags=0)
static QList< QNetworkInterface > allInterfaces()
Returns a listing of all the network interfaces found on the host machine.
QAbstractSocket::SocketState socketState
void setError(QAbstractSocket::SocketError error, ErrorString errorString) const
Sets the error and error string if not set already.
bool nativeBind(const QHostAddress &address, quint16 port)
int index() const
Returns the interface system index, if known.
static int qt_safe_listen(int s, int backlog)
QNetworkInterface nativeMulticastInterface() const
bool nativeSetMulticastInterface(const QNetworkInterface &iface)
The QNetworkInterface class provides a listing of the host's IP addresses and network interfaces...
The QHostAddress class provides an IP address.
bool nativeLeaveMulticastGroup(const QHostAddress &groupAddress, const QNetworkInterface &iface)
static qint64 qt_safe_write_nosignal(int fd, const void *data, qint64 len)
QList< QNetworkAddressEntry > addressEntries() const
Returns the list of IP addresses that this interface possesses along with their associated netmasks a...
QAbstractSocket::NetworkLayerProtocol socketProtocol
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
The QNetworkAddressEntry class stores one IP address supported by a network interface, along with its associated netmask and broadcast address.
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
qint64 nativeSendDatagram(const char *data, qint64 length, const QHostAddress &host, quint16 port)
bool createNewSocket(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol)
Creates and returns a new socket descriptor of type socketType and socketProtocol.
static bool multicastMembershipHelper(QNativeSocketEnginePrivate *d, int how6, int how4, const QHostAddress &groupAddress, const QNetworkInterface &interface)
qint64 nativeRead(char *data, qint64 maxLength)