Support resolution of IPv6 STUN/TURN addresses
https://bugs.webkit.org/show_bug.cgi?id=209808
Reviewed by Eric Carlson.
Source/WebCore:
Add family access to IPAddress to support both IPv4 and IPv6.
Store IPAddress internal value as IPv6 and cast them to IPv4 on demand.
* platform/network/DNS.h:
* platform/network/soup/DNSResolveQueueSoup.cpp:
(WebCore::resolvedWithObserverCallback):
Source/WebKit:
Update code to support IPv6 addresses when doing DNS resolution of TURN/STUN servers.
Refactor code to share more code between Cocoa ports and non Cocoa ports.
Manually tested with external IPv6 TURN servers.
* NetworkProcess/webrtc/NetworkRTCProvider.cpp:
(WebKit::NetworkRTCProvider::createResolver):
* NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp:
(WebKit::resolvedName):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259338 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6276b96..001be76 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,17 @@
+2020-04-01 youenn fablet <youenn@apple.com>
+
+ Support resolution of IPv6 STUN/TURN addresses
+ https://bugs.webkit.org/show_bug.cgi?id=209808
+
+ Reviewed by Eric Carlson.
+
+ Add family access to IPAddress to support both IPv4 and IPv6.
+ Store IPAddress internal value as IPv6 and cast them to IPv4 on demand.
+
+ * platform/network/DNS.h:
+ * platform/network/soup/DNSResolveQueueSoup.cpp:
+ (WebCore::resolvedWithObserverCallback):
+
2020-03-31 Simon Fraser <simon.fraser@apple.com>
Make FrameView and Frame TextStream-loggable
diff --git a/Source/WebCore/platform/network/DNS.h b/Source/WebCore/platform/network/DNS.h
index bae4a2d..e63a7b0 100644
--- a/Source/WebCore/platform/network/DNS.h
+++ b/Source/WebCore/platform/network/DNS.h
@@ -27,35 +27,56 @@
#if OS(WINDOWS)
#include <winsock2.h>
+#include <ws2tcpip.h>
#else
#include <netinet/in.h>
#endif
#include <wtf/Forward.h>
+#include <wtf/Optional.h>
+#include <wtf/Variant.h>
namespace WebCore {
-class WEBCORE_EXPORT IPAddress {
+class IPAddress {
public:
- explicit IPAddress(const struct sockaddr_in& address)
+ static Optional<IPAddress> fromSockAddrIn6(const struct sockaddr_in6&);
+ explicit IPAddress(const struct in_addr& address)
+ : m_address(address)
{
- memset(&m_address, 0, sizeof(struct sockaddr_in));
- m_address = address;
}
- const struct in_addr& getSinAddr() { return m_address.sin_addr; };
+ explicit IPAddress(const struct in6_addr& address)
+ : m_address(address)
+ {
+ }
+
+ bool isIPv4() const { return WTF::holds_alternative<struct in_addr>(m_address); }
+ bool isIPv6() const { return WTF::holds_alternative<struct in6_addr>(m_address); }
+
+ const struct in_addr& ipv4Address() const { return WTF::get<struct in_addr>(m_address); }
+ const struct in6_addr& ipv6Address() const { return WTF::get<struct in6_addr>(m_address); }
private:
- struct sockaddr_in m_address;
+ Variant<struct in_addr, struct in6_addr> m_address;
};
enum class DNSError { Unknown, CannotResolve, Cancelled };
-using DNSAddressesOrError = Expected<Vector<WebCore::IPAddress>, DNSError>;
-using DNSCompletionHandler = WTF::CompletionHandler<void(DNSAddressesOrError&&)>;
+using DNSAddressesOrError = Expected<Vector<IPAddress>, DNSError>;
+using DNSCompletionHandler = CompletionHandler<void(DNSAddressesOrError&&)>;
WEBCORE_EXPORT void prefetchDNS(const String& hostname);
WEBCORE_EXPORT void resolveDNS(const String& hostname, uint64_t identifier, DNSCompletionHandler&&);
WEBCORE_EXPORT void stopResolveDNS(uint64_t identifier);
+inline Optional<IPAddress> IPAddress::fromSockAddrIn6(const struct sockaddr_in6& address)
+{
+ if (address.sin6_family == AF_INET6)
+ return IPAddress { address.sin6_addr };
+ if (address.sin6_family == AF_INET)
+ return IPAddress {reinterpret_cast<const struct sockaddr_in&>(address).sin_addr };
+ return { };
+}
+
}
diff --git a/Source/WebCore/platform/network/soup/DNSResolveQueueSoup.cpp b/Source/WebCore/platform/network/soup/DNSResolveQueueSoup.cpp
index d4ba4e9..9f696e7 100644
--- a/Source/WebCore/platform/network/soup/DNSResolveQueueSoup.cpp
+++ b/Source/WebCore/platform/network/soup/DNSResolveQueueSoup.cpp
@@ -143,9 +143,16 @@
Vector<WebCore::IPAddress> addresses;
addresses.reserveInitialCapacity(1);
int len;
- auto* ipAddress = reinterpret_cast<const struct sockaddr_in*>(soup_address_get_sockaddr(address, &len));
- for (unsigned i = 0; i < sizeof(*ipAddress) / len; i++)
- addresses.uncheckedAppend(WebCore::IPAddress(ipAddress[i]));
+ // FIXME: Support multiple addresses, IPv6 and IPv4.
+ auto* ipAddress = soup_address_get_sockaddr(address, &len);
+ if (ipAddress) {
+ if (auto address = IPAddress::fromSockAddrIn6(reinterpret_cast<const struct sockaddr_in6&>(*ipAddress)))
+ addresses.uncheckedAppend(*address);
+ }
+ if (addresses.isEmpty()) {
+ completionHandler(makeUnexpected(WebCore::DNSError::CannotResolve));
+ return;
+ }
completionHandler(addresses);
}
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index bb9fb60..4d5ae6c 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,19 @@
+2020-04-01 youenn fablet <youenn@apple.com>
+
+ Support resolution of IPv6 STUN/TURN addresses
+ https://bugs.webkit.org/show_bug.cgi?id=209808
+
+ Reviewed by Eric Carlson.
+
+ Update code to support IPv6 addresses when doing DNS resolution of TURN/STUN servers.
+ Refactor code to share more code between Cocoa ports and non Cocoa ports.
+ Manually tested with external IPv6 TURN servers.
+
+ * NetworkProcess/webrtc/NetworkRTCProvider.cpp:
+ (WebKit::NetworkRTCProvider::createResolver):
+ * NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp:
+ (WebKit::resolvedName):
+
2020-03-31 Megan Gardner <megan_gardner@apple.com>
Dismiss color picker on color selection on MacCatalyst
diff --git a/Source/WebKit/NetworkProcess/webrtc/NetworkRTCProvider.cpp b/Source/WebKit/NetworkProcess/webrtc/NetworkRTCProvider.cpp
index 4a12f69..48411d1 100644
--- a/Source/WebKit/NetworkProcess/webrtc/NetworkRTCProvider.cpp
+++ b/Source/WebKit/NetworkProcess/webrtc/NetworkRTCProvider.cpp
@@ -201,60 +201,46 @@
NetworkRTCSocket(makeObjectIdentifier<LibWebRTCSocketIdentifierType>(decoder.destinationID()), *this).didReceiveMessage(connection, decoder);
}
-#if PLATFORM(COCOA)
void NetworkRTCProvider::createResolver(LibWebRTCResolverIdentifier identifier, const String& address)
{
- auto resolver = NetworkRTCResolver::create(identifier, [this, identifier](WebCore::DNSAddressesOrError&& result) mutable {
+ WebCore::DNSCompletionHandler completionHandler = [this, identifier](auto&& result) {
if (!result.has_value()) {
if (result.error() != WebCore::DNSError::Cancelled)
m_connection->connection().send(Messages::WebRTCResolver::ResolvedAddressError(1), identifier);
return;
}
- auto addresses = WTF::map(result.value(), [] (auto& address) {
- return RTCNetwork::IPAddress { rtc::IPAddress { address.getSinAddr() } };
- });
-
- m_connection->connection().send(Messages::WebRTCResolver::SetResolvedAddress(addresses), identifier);
- });
- resolver->start(address);
- m_resolvers.add(identifier, WTFMove(resolver));
-}
-
-void NetworkRTCProvider::stopResolver(LibWebRTCResolverIdentifier identifier)
-{
- if (auto resolver = m_resolvers.take(identifier))
- resolver->stop();
-}
-
-#else
-
-void NetworkRTCProvider::createResolver(LibWebRTCResolverIdentifier identifier, const String& address)
-{
- auto completionHandler = [this, identifier](WebCore::DNSAddressesOrError&& result) mutable {
- if (!result.has_value()) {
- if (result.error() != WebCore::DNSError::Cancelled)
- m_connection->connection().send(Messages::WebRTCResolver::ResolvedAddressError(1), identifier);
- return;
+ Vector<RTCNetwork::IPAddress> ipAddresses;
+ ipAddresses.reserveInitialCapacity(result.value().size());
+ for (auto& address : result.value()) {
+ if (address.isIPv4())
+ ipAddresses.uncheckedAppend(rtc::IPAddress { address.ipv4Address() });
+ else if (address.isIPv6())
+ ipAddresses.uncheckedAppend(rtc::IPAddress { address.ipv6Address() });
}
- auto addresses = WTF::map(result.value(), [] (auto& address) {
- return RTCNetwork::IPAddress { rtc::IPAddress { address.getSinAddr() } };
- });
-
- m_connection->connection().send(Messages::WebRTCResolver::SetResolvedAddress(addresses), identifier);
+ m_connection->connection().send(Messages::WebRTCResolver::SetResolvedAddress(ipAddresses), identifier);
};
+#if PLATFORM(COCOA)
+ auto resolver = NetworkRTCResolver::create(identifier, WTFMove(completionHandler));
+ resolver->start(address);
+ m_resolvers.add(identifier, WTFMove(resolver));
+#else
WebCore::resolveDNS(address, identifier.toUInt64(), WTFMove(completionHandler));
+#endif
}
void NetworkRTCProvider::stopResolver(LibWebRTCResolverIdentifier identifier)
{
+#if PLATFORM(COCOA)
+ if (auto resolver = m_resolvers.take(identifier))
+ resolver->stop();
+#else
WebCore::stopResolveDNS(identifier.toUInt64());
-}
-
#endif
+}
void NetworkRTCProvider::closeListeningSockets(Function<void()>&& completionHandler)
{
diff --git a/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp b/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp
index 9c4e041..3080343 100644
--- a/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp
+++ b/Source/WebKit/NetworkProcess/webrtc/NetworkRTCResolverCocoa.cpp
@@ -55,10 +55,8 @@
for (size_t index = 0; index < count; ++index) {
CFDataRef data = (CFDataRef)CFArrayGetValueAtIndex(resolvedAddresses, index);
- auto* address = reinterpret_cast<const struct sockaddr_in*>(CFDataGetBytePtr(data));
- if (address->sin_family == AF_INET)
- addresses.uncheckedAppend(WebCore::IPAddress(*address));
- // FIXME: We should probably return AF_INET6 addresses as well.
+ if (auto address = IPAddress::fromSockAddrIn6(*reinterpret_cast<const struct sockaddr_in6*>(CFDataGetBytePtr(data))))
+ addresses.uncheckedAppend(*address);
}
if (addresses.isEmpty()) {
resolver->completed(makeUnexpected(WebCore::DNSError::CannotResolve));