View Javadoc
1   /*
2    * Copyright 2019 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package io.netty.util.internal;
18  
19  import io.netty.util.concurrent.FastThreadLocalThread;
20  import reactor.blockhound.BlockHound;
21  import reactor.blockhound.integration.BlockHoundIntegration;
22  
23  import java.util.function.Function;
24  import java.util.function.Predicate;
25  
26  /**
27   * Contains classes that must have public visibility but are not public API.
28   */
29  class Hidden {
30  
31      /**
32       * This class integrates Netty with BlockHound.
33       * <p>
34       * It is public but only because of the ServiceLoader's limitations
35       * and SHOULD NOT be considered a public API.
36       */
37      @UnstableApi
38      public static final class NettyBlockHoundIntegration implements BlockHoundIntegration {
39  
40          @Override
41          public void applyTo(BlockHound.Builder builder) {
42              builder.allowBlockingCallsInside(
43                      "io.netty.channel.nio.NioEventLoop",
44                      "handleLoopException"
45              );
46  
47              builder.allowBlockingCallsInside(
48                      "io.netty.channel.kqueue.KQueueEventLoop",
49                      "handleLoopException"
50              );
51  
52              builder.allowBlockingCallsInside(
53                      "io.netty.channel.epoll.EpollEventLoop",
54                      "handleLoopException"
55              );
56  
57              builder.allowBlockingCallsInside(
58                      "io.netty.util.HashedWheelTimer",
59                      "start"
60              );
61  
62              builder.allowBlockingCallsInside(
63                      "io.netty.util.HashedWheelTimer",
64                      "stop"
65              );
66  
67              builder.allowBlockingCallsInside(
68                      "io.netty.util.HashedWheelTimer$Worker",
69                      "waitForNextTick"
70              );
71  
72              builder.allowBlockingCallsInside(
73                      "io.netty.util.concurrent.SingleThreadEventExecutor",
74                      "confirmShutdown"
75              );
76  
77              builder.allowBlockingCallsInside(
78                      "io.netty.buffer.PoolArena",
79                      "lock"
80              );
81  
82              builder.allowBlockingCallsInside(
83                      "io.netty.buffer.PoolSubpage",
84                      "lock"
85              );
86  
87              builder.allowBlockingCallsInside(
88                      "io.netty.buffer.PoolChunk",
89                      "allocateRun"
90              );
91  
92              builder.allowBlockingCallsInside(
93                      "io.netty.buffer.PoolChunk",
94                      "free"
95              );
96  
97              builder.allowBlockingCallsInside(
98                      "io.netty.buffer.AdaptivePoolingAllocator$1",
99                      "initialValue"
100             );
101 
102             builder.allowBlockingCallsInside(
103                     "io.netty.buffer.AdaptivePoolingAllocator$1",
104                     "onRemoval"
105             );
106 
107             builder.allowBlockingCallsInside(
108                     "io.netty.handler.ssl.SslHandler",
109                     "handshake"
110             );
111 
112             builder.allowBlockingCallsInside(
113                     "io.netty.handler.ssl.SslHandler",
114                     "runAllDelegatedTasks"
115             );
116             builder.allowBlockingCallsInside(
117                     "io.netty.handler.ssl.SslHandler",
118                     "runDelegatedTasks"
119             );
120             builder.allowBlockingCallsInside(
121                     "io.netty.util.concurrent.GlobalEventExecutor",
122                     "takeTask");
123 
124             builder.allowBlockingCallsInside(
125                     "io.netty.util.concurrent.GlobalEventExecutor",
126                     "addTask");
127 
128             builder.allowBlockingCallsInside(
129                     "io.netty.util.concurrent.SingleThreadEventExecutor",
130                     "takeTask");
131 
132             builder.allowBlockingCallsInside(
133                     "io.netty.util.concurrent.SingleThreadEventExecutor",
134                     "addTask");
135 
136             builder.allowBlockingCallsInside(
137                     "io.netty.handler.ssl.ReferenceCountedOpenSslClientContext$ExtendedTrustManagerVerifyCallback",
138                     "verify");
139 
140             builder.allowBlockingCallsInside(
141                     "io.netty.handler.ssl.JdkSslContext$Defaults",
142                     "init");
143 
144             // Let's whitelist SSLEngineImpl.unwrap(...) for now as it may fail otherwise for TLS 1.3.
145             // See https://mail.openjdk.java.net/pipermail/security-dev/2020-August/022271.html
146             builder.allowBlockingCallsInside(
147                     "sun.security.ssl.SSLEngineImpl",
148                     "unwrap");
149 
150             builder.allowBlockingCallsInside(
151                     "sun.security.ssl.SSLEngineImpl",
152                     "wrap");
153 
154             builder.allowBlockingCallsInside(
155                     "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider",
156                     "parse");
157 
158             builder.allowBlockingCallsInside(
159                     "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider",
160                     "parseEtcResolverSearchDomains");
161 
162             builder.allowBlockingCallsInside(
163                     "io.netty.resolver.dns.UnixResolverDnsServerAddressStreamProvider",
164                     "parseEtcResolverOptions");
165 
166             builder.allowBlockingCallsInside(
167                     "io.netty.resolver.HostsFileEntriesProvider$ParserImpl",
168                     "parse");
169 
170             builder.allowBlockingCallsInside(
171                     "io.netty.util.NetUtil$SoMaxConnAction",
172                     "run");
173 
174             builder.allowBlockingCallsInside("io.netty.util.internal.ReferenceCountUpdater",
175                     "retryRelease0");
176 
177             builder.allowBlockingCallsInside("io.netty.util.internal.PlatformDependent", "createTempFile");
178             builder.nonBlockingThreadPredicate(new Function<Predicate<Thread>, Predicate<Thread>>() {
179                 @Override
180                 public Predicate<Thread> apply(final Predicate<Thread> p) {
181                     return new Predicate<Thread>() {
182                         @Override
183                         public boolean test(Thread thread) {
184                             return p.test(thread) ||
185                                     thread instanceof FastThreadLocalThread &&
186                                             !((FastThreadLocalThread) thread).permitBlockingCalls();
187                         }
188                     };
189                 }
190             });
191         }
192 
193         @Override
194         public int compareTo(BlockHoundIntegration o) {
195             return 0;
196         }
197     }
198 }