|
21 | 21 | import java.nio.ByteBuffer; |
22 | 22 | import java.nio.channels.SelectionKey; |
23 | 23 | import java.util.concurrent.ExecutorService; |
24 | | -import java.util.concurrent.Executors; |
| 24 | +import java.util.concurrent.SynchronousQueue; |
| 25 | +import java.util.concurrent.ThreadPoolExecutor; |
| 26 | +import java.util.concurrent.TimeUnit; |
25 | 27 |
|
26 | 28 | import tech.httptoolkit.android.vpn.transport.ip.IPPacketFactory; |
27 | 29 | import tech.httptoolkit.android.vpn.transport.ip.IPv4Header; |
@@ -52,12 +54,21 @@ public class SessionHandler { |
52 | 54 | private final SocketNIODataService nioService; |
53 | 55 | private final ClientPacketWriter writer; |
54 | 56 |
|
55 | | - private final ExecutorService pingThreadpool = Executors.newCachedThreadPool(); |
| 57 | + private final ExecutorService pingThreadpool; |
56 | 58 |
|
57 | 59 | public SessionHandler(SessionManager manager, SocketNIODataService nioService, ClientPacketWriter writer) { |
58 | 60 | this.manager = manager; |
59 | 61 | this.nioService = nioService; |
60 | 62 | this.writer = writer; |
| 63 | + |
| 64 | + // Pool of threads to synchronously proxy ICMP ping requests in the background. We need to |
| 65 | + // carefully limit these, or a ping flood can cause us big big problems. |
| 66 | + this.pingThreadpool = new ThreadPoolExecutor( |
| 67 | + 1, 20, // 1 - 20 parallel pings max |
| 68 | + 60L, TimeUnit.SECONDS, |
| 69 | + new SynchronousQueue<Runnable>(), |
| 70 | + new ThreadPoolExecutor.DiscardPolicy() // Replace running pings if there's too many |
| 71 | + ); |
61 | 72 | } |
62 | 73 |
|
63 | 74 | /** |
|
0 commit comments