From c7cd61c9689d18913619a66bdf9f0b68a4edad45 Mon Sep 17 00:00:00 2001 From: Nate Mortensen Date: Wed, 26 Jul 2017 11:52:48 -0600 Subject: [PATCH] Make usage of the Netty DNS resolver configurable This adds a new configuration value "use_netty_dns_resolver", which defaults to true. This allows users to opt out of Netty's DNS resolver if they encounter any issues with it. --- ...ionally-use-async-Netty-DNS-resolver.patch | 174 ++++++++++++++++++ .../0040-Use-async-Netty-DNS-resolver.patch | 111 ----------- 2 files changed, 174 insertions(+), 111 deletions(-) create mode 100644 BungeeCord-Patches/0040-Optionally-use-async-Netty-DNS-resolver.patch delete mode 100644 BungeeCord-Patches/0040-Use-async-Netty-DNS-resolver.patch diff --git a/BungeeCord-Patches/0040-Optionally-use-async-Netty-DNS-resolver.patch b/BungeeCord-Patches/0040-Optionally-use-async-Netty-DNS-resolver.patch new file mode 100644 index 0000000..08151d5 --- /dev/null +++ b/BungeeCord-Patches/0040-Optionally-use-async-Netty-DNS-resolver.patch @@ -0,0 +1,174 @@ +From 76a25a666157c1d1fa94ddf7a46e7232aee60e56 Mon Sep 17 00:00:00 2001 +From: Tux +Date: Wed, 21 Dec 2016 03:13:03 -0500 +Subject: [PATCH] Optionally use async Netty DNS resolver + +We no longer need to cache the address for the session server now. + +diff --git a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java +index a443614..43519ce 100644 +--- a/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java ++++ b/api/src/main/java/net/md_5/bungee/api/ProxyConfig.java +@@ -173,6 +173,11 @@ public interface ProxyConfig + */ + String getGameVersion(); + ++ /** ++ * Whether Netty's async DNS resolver is used for account authentication. ++ */ ++ boolean isUseNettyDnsResolver(); ++ + // Throttling options + + /** +diff --git a/proxy/pom.xml b/proxy/pom.xml +index 98656fe..ae6ee15 100644 +--- a/proxy/pom.xml ++++ b/proxy/pom.xml +@@ -41,6 +41,14 @@ + ${netty.version} + compile + ++ ++ ++ io.netty ++ netty-resolver-dns ++ ${netty.version} ++ compile ++ ++ + + io.netty + netty-handler +diff --git a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java +index 5983581..7dc3c2d 100644 +--- a/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java ++++ b/proxy/src/main/java/io/github/waterfallmc/waterfall/conf/WaterfallConfiguration.java +@@ -33,6 +33,13 @@ public class WaterfallConfiguration extends Configuration { + @Getter + private String gameVersion; + ++ /** ++ * Whether we use Netty's async DNS resolver for the HttpClient. ++ *

Default is true (use Netty's async DNS resolver)

++ */ ++ @Getter ++ private boolean useNettyDnsResolver = true; ++ + /* + * Throttling options + * Helps prevent players from overloading the servers behind us +@@ -56,6 +63,7 @@ public class WaterfallConfiguration extends Configuration { + // Throttling options + tabThrottle = config.getInt("throttling.tab_complete", tabThrottle); + gameVersion = config.getString("game_version", "").isEmpty() ? Joiner.on(", ").join(ProtocolConstants.SUPPORTED_VERSIONS) : config.getString("game_version", ""); ++ useNettyDnsResolver = config.getBoolean("use_netty_dns_resolver", useNettyDnsResolver); + } + + @Override +diff --git a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java +index 2feb4d6..b265bb4 100644 +--- a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java ++++ b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java +@@ -28,6 +28,10 @@ public class HttpClient + + public static final int TIMEOUT = 5000; + private static final Cache addressCache = CacheBuilder.newBuilder().expireAfterWrite( 1, TimeUnit.MINUTES ).build(); ++ // Waterfall Start - optionally use async resolver from Netty ++ private static final io.netty.resolver.dns.DnsAddressResolverGroup dnsResolverGroup = ++ new io.netty.resolver.dns.DnsAddressResolverGroup(PipelineUtils.getDatagramChannel(), io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.INSTANCE); ++ // Waterfall End + + @SuppressWarnings("UnusedAssignment") + public static void get(String url, EventLoop eventLoop, final Callback callback) +@@ -57,19 +61,21 @@ public class HttpClient + } + } + +- InetAddress inetHost = addressCache.getIfPresent( uri.getHost() ); +- if ( inetHost == null ) +- { +- try +- { +- inetHost = InetAddress.getByName( uri.getHost() ); +- } catch ( UnknownHostException ex ) +- { +- callback.done( null, ex ); +- return; +- } +- addressCache.put( uri.getHost(), inetHost ); +- } ++ // Waterfall Start - Move address creation to implementation method ++ //InetAddress inetHost = addressCache.getIfPresent( uri.getHost() ); ++ //if ( inetHost == null ) ++ //{ ++ // try ++ // { ++ // inetHost = InetAddress.getByName( uri.getHost() ); ++ // } catch ( UnknownHostException ex ) ++ // { ++ // callback.done( null, ex ); ++ // return; ++ // } ++ // addressCache.put( uri.getHost(), inetHost ); ++ //} ++ // Waterfall End + + ChannelFutureListener future = new ChannelFutureListener() + { +@@ -92,7 +98,39 @@ public class HttpClient + } + }; + ++ // Waterfall Start - Optionally use Netty's async DNS Resolver ++ if (net.md_5.bungee.api.ProxyServer.getInstance().getConfig().isUseNettyDnsResolver()) { ++ getWithNettyResolver(eventLoop, uri, port, future, callback, ssl); ++ } else { ++ getWithDefaultResolver(eventLoop, uri, port, future, callback, ssl); ++ } ++ //new Bootstrap().channel( PipelineUtils.getChannel() ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ). ++ // option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).remoteAddress( inetHost, port ).connect().addListener( future ); ++ } ++ ++ private static void getWithNettyResolver(EventLoop eventLoop, URI uri, int port, ChannelFutureListener future, Callback callback, boolean ssl) { ++ java.net.InetSocketAddress address = java.net.InetSocketAddress.createUnresolved(uri.getHost(), port); ++ new Bootstrap().channel( PipelineUtils.getChannel() ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ). ++ option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).resolver(dnsResolverGroup).remoteAddress( address ).connect().addListener( future ); ++ } ++ ++ private static void getWithDefaultResolver(EventLoop eventLoop, URI uri, int port, ChannelFutureListener future, Callback callback, boolean ssl) { ++ // This is identical to the Bungee implementation of #get other than the absence of the ChannelFutureListener creation ++ InetAddress inetHost = addressCache.getIfPresent( uri.getHost() ); ++ if ( inetHost == null ) ++ { ++ try ++ { ++ inetHost = InetAddress.getByName( uri.getHost() ); ++ } catch ( UnknownHostException ex ) ++ { ++ callback.done( null, ex ); ++ return; ++ } ++ addressCache.put( uri.getHost(), inetHost ); ++ } + new Bootstrap().channel( PipelineUtils.getChannel() ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ). + option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).remoteAddress( inetHost, port ).connect().addListener( future ); + } ++ // Waterfall End + } +diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +index 503adfd..ad47dbb 100644 +--- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java ++++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java +@@ -111,7 +111,7 @@ public class PipelineUtils + return epoll ? EpollSocketChannel.class : NioSocketChannel.class; + } + +- public static Class getDatagramChannel() ++ public static Class getDatagramChannel() // Waterfall - change to DatagramChannel + { + return epoll ? EpollDatagramChannel.class : NioDatagramChannel.class; + } +-- +2.7.1.windows.2 + diff --git a/BungeeCord-Patches/0040-Use-async-Netty-DNS-resolver.patch b/BungeeCord-Patches/0040-Use-async-Netty-DNS-resolver.patch deleted file mode 100644 index 27c5b22..0000000 --- a/BungeeCord-Patches/0040-Use-async-Netty-DNS-resolver.patch +++ /dev/null @@ -1,111 +0,0 @@ -From c0d6188b4987814068db056085aa50db72efc1e3 Mon Sep 17 00:00:00 2001 -From: Tux -Date: Wed, 21 Dec 2016 03:13:03 -0500 -Subject: [PATCH] Use async Netty DNS resolver - -We no longer need to cache the address for the session server now. - -diff --git a/proxy/pom.xml b/proxy/pom.xml -index 98656fe..ae6ee15 100644 ---- a/proxy/pom.xml -+++ b/proxy/pom.xml -@@ -41,6 +41,14 @@ - ${netty.version} - compile -
-+ -+ -+ io.netty -+ netty-resolver-dns -+ ${netty.version} -+ compile -+ -+ - - io.netty - netty-handler -diff --git a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java -index 2feb4d6..3db3639 100644 ---- a/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java -+++ b/proxy/src/main/java/net/md_5/bungee/http/HttpClient.java -@@ -27,7 +27,11 @@ public class HttpClient - { - - public static final int TIMEOUT = 5000; -- private static final Cache addressCache = CacheBuilder.newBuilder().expireAfterWrite( 1, TimeUnit.MINUTES ).build(); -+ // Waterfall Start - use async resolver from Netty -+ //private static final Cache addressCache = CacheBuilder.newBuilder().expireAfterWrite( 1, TimeUnit.MINUTES ).build(); // Waterfall - remove cache -+ private static final io.netty.resolver.dns.DnsAddressResolverGroup dnsResolverGroup = -+ new io.netty.resolver.dns.DnsAddressResolverGroup(PipelineUtils.getDatagramChannel(), io.netty.resolver.dns.DefaultDnsServerAddressStreamProvider.INSTANCE); -+ // Waterfall End - - @SuppressWarnings("UnusedAssignment") - public static void get(String url, EventLoop eventLoop, final Callback callback) -@@ -57,19 +61,22 @@ public class HttpClient - } - } - -- InetAddress inetHost = addressCache.getIfPresent( uri.getHost() ); -- if ( inetHost == null ) -- { -- try -- { -- inetHost = InetAddress.getByName( uri.getHost() ); -- } catch ( UnknownHostException ex ) -- { -- callback.done( null, ex ); -- return; -- } -- addressCache.put( uri.getHost(), inetHost ); -- } -+ // Waterfall Start: remove IP address cache -+ //InetAddress inetHost = addressCache.getIfPresent( uri.getHost() ); -+ //if ( inetHost == null ) -+ //{ -+ // try -+ // { -+ // inetHost = InetAddress.getByName( uri.getHost() ); -+ // } catch ( UnknownHostException ex ) -+ // { -+ // callback.done( null, ex ); -+ // return; -+ // } -+ // addressCache.put( uri.getHost(), inetHost ); -+ //} -+ java.net.InetSocketAddress address = java.net.InetSocketAddress.createUnresolved(uri.getHost(), port); -+ // Waterfall End - - ChannelFutureListener future = new ChannelFutureListener() - { -@@ -86,13 +93,13 @@ public class HttpClient - future.channel().writeAndFlush( request ); - } else - { -- addressCache.invalidate( uri.getHost() ); -+ // addressCache.invalidate( uri.getHost() ); // Waterfall - use async DNS resolver - callback.done( null, future.cause() ); - } - } - }; - - new Bootstrap().channel( PipelineUtils.getChannel() ).group( eventLoop ).handler( new HttpInitializer( callback, ssl, uri.getHost(), port ) ). -- option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).remoteAddress( inetHost, port ).connect().addListener( future ); -+ option( ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT ).resolver(dnsResolverGroup).remoteAddress( address ).connect().addListener( future ); // Waterfall - use async DNS resolver - } - } -diff --git a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java -index 503adfd..ad47dbb 100644 ---- a/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java -+++ b/proxy/src/main/java/net/md_5/bungee/netty/PipelineUtils.java -@@ -111,7 +111,7 @@ public class PipelineUtils - return epoll ? EpollSocketChannel.class : NioSocketChannel.class; - } - -- public static Class getDatagramChannel() -+ public static Class getDatagramChannel() // Waterfall - change to DatagramChannel - { - return epoll ? EpollDatagramChannel.class : NioDatagramChannel.class; - } --- -2.7.4 (Apple Git-66) -