summaryrefslogtreecommitdiffstats
path: root/src/network/socket/qnativesocketengine_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/socket/qnativesocketengine_win.cpp')
-rw-r--r--src/network/socket/qnativesocketengine_win.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp
index a922b45..2ca1f41 100644
--- a/src/network/socket/qnativesocketengine_win.cpp
+++ b/src/network/socket/qnativesocketengine_win.cpp
@@ -853,6 +853,69 @@ bool QNativeSocketEnginePrivate::nativeLeaveMulticastGroup(const QHostAddress &g
iface);
}
+QNetworkInterface QNativeSocketEnginePrivate::nativeMulticastInterface() const
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v;
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ return QNetworkInterface::interfaceFromIndex(v);
+ }
+#endif
+
+ struct in_addr v = { 0 };
+ QT_SOCKOPTLEN_T sizeofv = sizeof(v);
+ if (::getsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, &sizeofv) == -1)
+ return QNetworkInterface();
+ if (v.s_addr != 0 && sizeofv >= sizeof(v)) {
+ QHostAddress ipv4(ntohl(v.s_addr));
+ QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
+ for (int i = 0; i < ifaces.count(); ++i) {
+ const QNetworkInterface &iface = ifaces.at(i);
+ if (!(iface.flags() & QNetworkInterface::CanMulticast))
+ continue;
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int j = 0; j < entries.count(); ++j) {
+ const QNetworkAddressEntry &entry = entries.at(j);
+ if (entry.ip() == ipv4)
+ return iface;
+ }
+ }
+ }
+ return QNetworkInterface();
+}
+
+bool QNativeSocketEnginePrivate::nativeSetMulticastInterface(const QNetworkInterface &iface)
+{
+#ifndef QT_NO_IPV6
+ if (socketProtocol == QAbstractSocket::IPv6Protocol) {
+ uint v = iface.isValid() ? iface.index() : 0;
+ return (::setsockopt(socketDescriptor, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
+ }
+#endif
+
+ struct in_addr v;
+ if (iface.isValid()) {
+ QList<QNetworkAddressEntry> entries = iface.addressEntries();
+ for (int i = 0; i < entries.count(); ++i) {
+ const QNetworkAddressEntry &entry = entries.at(i);
+ const QHostAddress &ip = entry.ip();
+ if (ip.protocol() == QAbstractSocket::IPv4Protocol) {
+ v.s_addr = htonl(ip.toIPv4Address());
+ int r = ::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v));
+ if (r != -1)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ v.s_addr = INADDR_ANY;
+ return (::setsockopt(socketDescriptor, IPPROTO_IP, IP_MULTICAST_IF, (char *) &v, sizeof(v)) != -1);
+}
+
qint64 QNativeSocketEnginePrivate::nativeBytesAvailable() const
{
unsigned long nbytes = 0;