/java/org/apache/tomcat/util/net/AprEndpoint.java

https://github.com/enson16855/tomcat · Java · 2410 lines · 1520 code · 283 blank · 607 comment · 409 complexity · df08c18d2ca87283827c555d542e3def MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.tomcat.util.net;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.Map;
  21. import java.util.concurrent.ConcurrentHashMap;
  22. import java.util.concurrent.Executor;
  23. import java.util.concurrent.RejectedExecutionException;
  24. import java.util.concurrent.atomic.AtomicInteger;
  25. import org.apache.juli.logging.Log;
  26. import org.apache.juli.logging.LogFactory;
  27. import org.apache.tomcat.jni.Address;
  28. import org.apache.tomcat.jni.Error;
  29. import org.apache.tomcat.jni.File;
  30. import org.apache.tomcat.jni.Library;
  31. import org.apache.tomcat.jni.OS;
  32. import org.apache.tomcat.jni.Poll;
  33. import org.apache.tomcat.jni.Pool;
  34. import org.apache.tomcat.jni.SSL;
  35. import org.apache.tomcat.jni.SSLContext;
  36. import org.apache.tomcat.jni.SSLSocket;
  37. import org.apache.tomcat.jni.Sockaddr;
  38. import org.apache.tomcat.jni.Socket;
  39. import org.apache.tomcat.jni.Status;
  40. import org.apache.tomcat.util.ExceptionUtils;
  41. import org.apache.tomcat.util.net.AbstractEndpoint.Acceptor.AcceptorState;
  42. import org.apache.tomcat.util.net.AbstractEndpoint.Handler.SocketState;
  43. /**
  44. * APR tailored thread pool, providing the following services:
  45. * <ul>
  46. * <li>Socket acceptor thread</li>
  47. * <li>Socket poller thread</li>
  48. * <li>Sendfile thread</li>
  49. * <li>Worker threads pool</li>
  50. * </ul>
  51. *
  52. * When switching to Java 5, there's an opportunity to use the virtual
  53. * machine's thread pool.
  54. *
  55. * @author Mladen Turk
  56. * @author Remy Maucherat
  57. */
  58. public class AprEndpoint extends AbstractEndpoint<Long> {
  59. // -------------------------------------------------------------- Constants
  60. private static final Log log = LogFactory.getLog(AprEndpoint.class);
  61. // ----------------------------------------------------------------- Fields
  62. /**
  63. * Root APR memory pool.
  64. */
  65. protected long rootPool = 0;
  66. /**
  67. * Server socket "pointer".
  68. */
  69. protected long serverSock = 0;
  70. /**
  71. * APR memory pool for the server socket.
  72. */
  73. protected long serverSockPool = 0;
  74. /**
  75. * SSL context.
  76. */
  77. protected long sslContext = 0;
  78. private final Map<Long,AprSocketWrapper> connections = new ConcurrentHashMap<>();
  79. // ------------------------------------------------------------ Constructor
  80. public AprEndpoint() {
  81. // Need to override the default for maxConnections to align it with what
  82. // was pollerSize (before the two were merged)
  83. setMaxConnections(8 * 1024);
  84. }
  85. // ------------------------------------------------------------- Properties
  86. /**
  87. * Defer accept.
  88. */
  89. protected boolean deferAccept = true;
  90. public void setDeferAccept(boolean deferAccept) { this.deferAccept = deferAccept; }
  91. @Override
  92. public boolean getDeferAccept() { return deferAccept; }
  93. /**
  94. * Size of the sendfile (= concurrent files which can be served).
  95. */
  96. protected int sendfileSize = 1 * 1024;
  97. public void setSendfileSize(int sendfileSize) { this.sendfileSize = sendfileSize; }
  98. public int getSendfileSize() { return sendfileSize; }
  99. /**
  100. * Handling of accepted sockets.
  101. */
  102. protected Handler handler = null;
  103. public void setHandler(Handler handler ) { this.handler = handler; }
  104. public Handler getHandler() { return handler; }
  105. /**
  106. * Poll interval, in microseconds. The smaller the value, the more CPU the poller
  107. * will use, but the more responsive to activity it will be.
  108. */
  109. protected int pollTime = 2000;
  110. public int getPollTime() { return pollTime; }
  111. public void setPollTime(int pollTime) { if (pollTime > 0) { this.pollTime = pollTime; } }
  112. /**
  113. * Use sendfile for sending static files.
  114. */
  115. protected boolean useSendfile = false;
  116. /*
  117. * When the endpoint is created and configured, the APR library will not
  118. * have been initialised. This flag is used to determine if the default
  119. * value of useSendFile should be changed if the APR library indicates it
  120. * supports send file once it has been initialised. If useSendFile is set
  121. * by configuration, that configuration will always take priority.
  122. */
  123. private boolean useSendFileSet = false;
  124. public void setUseSendfile(boolean useSendfile) {
  125. useSendFileSet = true;
  126. this.useSendfile = useSendfile;
  127. }
  128. @Override
  129. public boolean getUseSendfile() { return useSendfile; }
  130. /**
  131. * Allow comet request handling.
  132. */
  133. protected boolean useComet = true;
  134. public void setUseComet(boolean useComet) { this.useComet = useComet; }
  135. @Override
  136. public boolean getUseComet() { return useComet; }
  137. @Override
  138. public boolean getUseCometTimeout() { return false; } // Not supported
  139. @Override
  140. public boolean getUsePolling() { return true; } // Always supported
  141. /**
  142. * Sendfile thread count.
  143. */
  144. protected int sendfileThreadCount = 0;
  145. public void setSendfileThreadCount(int sendfileThreadCount) { this.sendfileThreadCount = sendfileThreadCount; }
  146. public int getSendfileThreadCount() { return sendfileThreadCount; }
  147. /**
  148. * The socket poller.
  149. */
  150. protected Poller poller = null;
  151. public Poller getPoller() {
  152. return poller;
  153. }
  154. /**
  155. * The static file sender.
  156. */
  157. protected Sendfile sendfile = null;
  158. public Sendfile getSendfile() {
  159. return sendfile;
  160. }
  161. /**
  162. * SSL protocols.
  163. */
  164. protected String SSLProtocol = "all";
  165. public String getSSLProtocol() { return SSLProtocol; }
  166. public void setSSLProtocol(String SSLProtocol) { this.SSLProtocol = SSLProtocol; }
  167. /**
  168. * SSL password (if a cert is encrypted, and no password has been provided, a callback
  169. * will ask for a password).
  170. */
  171. protected String SSLPassword = null;
  172. public String getSSLPassword() { return SSLPassword; }
  173. public void setSSLPassword(String SSLPassword) { this.SSLPassword = SSLPassword; }
  174. /**
  175. * SSL cipher suite.
  176. */
  177. protected String SSLCipherSuite = "ALL";
  178. public String getSSLCipherSuite() { return SSLCipherSuite; }
  179. public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
  180. /**
  181. * SSL certificate file.
  182. */
  183. protected String SSLCertificateFile = null;
  184. public String getSSLCertificateFile() { return SSLCertificateFile; }
  185. public void setSSLCertificateFile(String SSLCertificateFile) { this.SSLCertificateFile = SSLCertificateFile; }
  186. /**
  187. * SSL certificate key file.
  188. */
  189. protected String SSLCertificateKeyFile = null;
  190. public String getSSLCertificateKeyFile() { return SSLCertificateKeyFile; }
  191. public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { this.SSLCertificateKeyFile = SSLCertificateKeyFile; }
  192. /**
  193. * SSL certificate chain file.
  194. */
  195. protected String SSLCertificateChainFile = null;
  196. public String getSSLCertificateChainFile() { return SSLCertificateChainFile; }
  197. public void setSSLCertificateChainFile(String SSLCertificateChainFile) { this.SSLCertificateChainFile = SSLCertificateChainFile; }
  198. /**
  199. * SSL CA certificate path.
  200. */
  201. protected String SSLCACertificatePath = null;
  202. public String getSSLCACertificatePath() { return SSLCACertificatePath; }
  203. public void setSSLCACertificatePath(String SSLCACertificatePath) { this.SSLCACertificatePath = SSLCACertificatePath; }
  204. /**
  205. * SSL CA certificate file.
  206. */
  207. protected String SSLCACertificateFile = null;
  208. public String getSSLCACertificateFile() { return SSLCACertificateFile; }
  209. public void setSSLCACertificateFile(String SSLCACertificateFile) { this.SSLCACertificateFile = SSLCACertificateFile; }
  210. /**
  211. * SSL CA revocation path.
  212. */
  213. protected String SSLCARevocationPath = null;
  214. public String getSSLCARevocationPath() { return SSLCARevocationPath; }
  215. public void setSSLCARevocationPath(String SSLCARevocationPath) { this.SSLCARevocationPath = SSLCARevocationPath; }
  216. /**
  217. * SSL CA revocation file.
  218. */
  219. protected String SSLCARevocationFile = null;
  220. public String getSSLCARevocationFile() { return SSLCARevocationFile; }
  221. public void setSSLCARevocationFile(String SSLCARevocationFile) { this.SSLCARevocationFile = SSLCARevocationFile; }
  222. /**
  223. * SSL verify client.
  224. */
  225. protected String SSLVerifyClient = "none";
  226. public String getSSLVerifyClient() { return SSLVerifyClient; }
  227. public void setSSLVerifyClient(String SSLVerifyClient) { this.SSLVerifyClient = SSLVerifyClient; }
  228. /**
  229. * SSL verify depth.
  230. */
  231. protected int SSLVerifyDepth = 10;
  232. public int getSSLVerifyDepth() { return SSLVerifyDepth; }
  233. public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; }
  234. /**
  235. * SSL allow insecure renegotiation for the the client that does not
  236. * support the secure renegotiation.
  237. */
  238. protected boolean SSLInsecureRenegotiation = false;
  239. public void setSSLInsecureRenegotiation(boolean SSLInsecureRenegotiation) { this.SSLInsecureRenegotiation = SSLInsecureRenegotiation; }
  240. public boolean getSSLInsecureRenegotiation() { return SSLInsecureRenegotiation; }
  241. protected boolean SSLHonorCipherOrder = false;
  242. /**
  243. * Set to <code>true</code> to enforce the <i>server's</i> cipher order
  244. * instead of the default which is to allow the client to choose a
  245. * preferred cipher.
  246. */
  247. public void setSSLHonorCipherOrder(boolean SSLHonorCipherOrder) { this.SSLHonorCipherOrder = SSLHonorCipherOrder; }
  248. public boolean getSSLHonorCipherOrder() { return SSLHonorCipherOrder; }
  249. /**
  250. * Disables compression of the SSL stream. This thwarts CRIME attack
  251. * and possibly improves performance by not compressing uncompressible
  252. * content such as JPEG, etc.
  253. */
  254. protected boolean SSLDisableCompression = false;
  255. /**
  256. * Set to <code>true</code> to disable SSL compression. This thwarts CRIME
  257. * attack.
  258. */
  259. public void setSSLDisableCompression(boolean SSLDisableCompression) { this.SSLDisableCompression = SSLDisableCompression; }
  260. public boolean getSSLDisableCompression() { return SSLDisableCompression; }
  261. /**
  262. * Port in use.
  263. */
  264. @Override
  265. public int getLocalPort() {
  266. long s = serverSock;
  267. if (s == 0) {
  268. return -1;
  269. } else {
  270. long sa;
  271. try {
  272. sa = Address.get(Socket.APR_LOCAL, s);
  273. Sockaddr addr = Address.getInfo(sa);
  274. return addr.port;
  275. } catch (Exception e) {
  276. return -1;
  277. }
  278. }
  279. }
  280. @Override
  281. public String[] getCiphersUsed() {
  282. // TODO : Investigate if it is possible to extract the current list of
  283. // available ciphers. Native code changes will be required.
  284. return new String[] { getSSLCipherSuite() };
  285. }
  286. // --------------------------------------------------------- Public Methods
  287. /**
  288. * Number of keepalive sockets.
  289. */
  290. public int getKeepAliveCount() {
  291. if (poller == null) {
  292. return 0;
  293. }
  294. return poller.getConnectionCount();
  295. }
  296. /**
  297. * Number of sendfile sockets.
  298. */
  299. public int getSendfileCount() {
  300. if (sendfile == null) {
  301. return 0;
  302. }
  303. return sendfile.getSendfileCount();
  304. }
  305. // ----------------------------------------------- Public Lifecycle Methods
  306. /**
  307. * Initialize the endpoint.
  308. */
  309. @Override
  310. public void bind() throws Exception {
  311. // Create the root APR memory pool
  312. try {
  313. rootPool = Pool.create(0);
  314. } catch (UnsatisfiedLinkError e) {
  315. throw new Exception(sm.getString("endpoint.init.notavail"));
  316. }
  317. // Create the pool for the server socket
  318. serverSockPool = Pool.create(rootPool);
  319. // Create the APR address that will be bound
  320. String addressStr = null;
  321. if (getAddress() != null) {
  322. addressStr = getAddress().getHostAddress();
  323. }
  324. int family = Socket.APR_INET;
  325. if (Library.APR_HAVE_IPV6) {
  326. if (addressStr == null) {
  327. if (!OS.IS_BSD && !OS.IS_WIN32 && !OS.IS_WIN64)
  328. family = Socket.APR_UNSPEC;
  329. } else if (addressStr.indexOf(':') >= 0) {
  330. family = Socket.APR_UNSPEC;
  331. }
  332. }
  333. long inetAddress = Address.info(addressStr, family,
  334. getPort(), 0, rootPool);
  335. // Create the APR server socket
  336. serverSock = Socket.create(Address.getInfo(inetAddress).family,
  337. Socket.SOCK_STREAM,
  338. Socket.APR_PROTO_TCP, rootPool);
  339. if (OS.IS_UNIX) {
  340. Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
  341. }
  342. // Deal with the firewalls that tend to drop the inactive sockets
  343. Socket.optSet(serverSock, Socket.APR_SO_KEEPALIVE, 1);
  344. // Bind the server socket
  345. int ret = Socket.bind(serverSock, inetAddress);
  346. if (ret != 0) {
  347. throw new Exception(sm.getString("endpoint.init.bind", "" + ret, Error.strerror(ret)));
  348. }
  349. // Start listening on the server socket
  350. ret = Socket.listen(serverSock, getBacklog());
  351. if (ret != 0) {
  352. throw new Exception(sm.getString("endpoint.init.listen", "" + ret, Error.strerror(ret)));
  353. }
  354. if (OS.IS_WIN32 || OS.IS_WIN64) {
  355. // On Windows set the reuseaddr flag after the bind/listen
  356. Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
  357. }
  358. // Enable Sendfile by default if it has not been configured but usage on
  359. // systems which don't support it cause major problems
  360. if (!useSendFileSet) {
  361. useSendfile = Library.APR_HAS_SENDFILE;
  362. } else if (useSendfile && !Library.APR_HAS_SENDFILE) {
  363. useSendfile = false;
  364. }
  365. // Initialize thread count default for acceptor
  366. if (acceptorThreadCount == 0) {
  367. // FIXME: Doesn't seem to work that well with multiple accept threads
  368. acceptorThreadCount = 1;
  369. }
  370. // Delay accepting of new connections until data is available
  371. // Only Linux kernels 2.4 + have that implemented
  372. // on other platforms this call is noop and will return APR_ENOTIMPL.
  373. if (deferAccept) {
  374. if (Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1) == Status.APR_ENOTIMPL) {
  375. deferAccept = false;
  376. }
  377. }
  378. // Initialize SSL if needed
  379. if (isSSLEnabled()) {
  380. if (SSLCertificateFile == null) {
  381. // This is required
  382. throw new Exception(sm.getString("endpoint.apr.noSslCertFile"));
  383. }
  384. // SSL protocol
  385. int value = SSL.SSL_PROTOCOL_NONE;
  386. if (SSLProtocol == null || SSLProtocol.length() == 0) {
  387. value = SSL.SSL_PROTOCOL_ALL;
  388. } else {
  389. for (String protocol : SSLProtocol.split("\\+")) {
  390. protocol = protocol.trim();
  391. if ("SSLv2".equalsIgnoreCase(protocol)) {
  392. value |= SSL.SSL_PROTOCOL_SSLV2;
  393. } else if ("SSLv3".equalsIgnoreCase(protocol)) {
  394. value |= SSL.SSL_PROTOCOL_SSLV3;
  395. } else if ("TLSv1".equalsIgnoreCase(protocol)) {
  396. value |= SSL.SSL_PROTOCOL_TLSV1;
  397. } else if ("all".equalsIgnoreCase(protocol)) {
  398. value |= SSL.SSL_PROTOCOL_ALL;
  399. } else {
  400. // Protocol not recognized, fail to start as it is safer than
  401. // continuing with the default which might enable more than the
  402. // is required
  403. throw new Exception(sm.getString(
  404. "endpoint.apr.invalidSslProtocol", SSLProtocol));
  405. }
  406. }
  407. }
  408. // Create SSL Context
  409. try {
  410. sslContext = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
  411. } catch (Exception e) {
  412. // If the sslEngine is disabled on the AprLifecycleListener
  413. // there will be an Exception here but there is no way to check
  414. // the AprLifecycleListener settings from here
  415. throw new Exception(
  416. sm.getString("endpoint.apr.failSslContextMake"), e);
  417. }
  418. if (SSLInsecureRenegotiation) {
  419. boolean legacyRenegSupported = false;
  420. try {
  421. legacyRenegSupported = SSL.hasOp(SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  422. if (legacyRenegSupported)
  423. SSLContext.setOptions(sslContext, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  424. } catch (UnsatisfiedLinkError e) {
  425. // Ignore
  426. }
  427. if (!legacyRenegSupported) {
  428. // OpenSSL does not support unsafe legacy renegotiation.
  429. log.warn(sm.getString("endpoint.warn.noInsecureReneg",
  430. SSL.versionString()));
  431. }
  432. }
  433. // Set cipher order: client (default) or server
  434. if (SSLHonorCipherOrder) {
  435. boolean orderCiphersSupported = false;
  436. try {
  437. orderCiphersSupported = SSL.hasOp(SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
  438. if (orderCiphersSupported)
  439. SSLContext.setOptions(sslContext, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
  440. } catch (UnsatisfiedLinkError e) {
  441. // Ignore
  442. }
  443. if (!orderCiphersSupported) {
  444. // OpenSSL does not support ciphers ordering.
  445. log.warn(sm.getString("endpoint.warn.noHonorCipherOrder",
  446. SSL.versionString()));
  447. }
  448. }
  449. // Disable compression if requested
  450. if (SSLDisableCompression) {
  451. boolean disableCompressionSupported = false;
  452. try {
  453. disableCompressionSupported = SSL.hasOp(SSL.SSL_OP_NO_COMPRESSION);
  454. if (disableCompressionSupported)
  455. SSLContext.setOptions(sslContext, SSL.SSL_OP_NO_COMPRESSION);
  456. } catch (UnsatisfiedLinkError e) {
  457. // Ignore
  458. }
  459. if (!disableCompressionSupported) {
  460. // OpenSSL does not support ciphers ordering.
  461. log.warn(sm.getString("endpoint.warn.noDisableCompression",
  462. SSL.versionString()));
  463. }
  464. }
  465. // List the ciphers that the client is permitted to negotiate
  466. SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
  467. // Load Server key and certificate
  468. SSLContext.setCertificate(sslContext, SSLCertificateFile, SSLCertificateKeyFile, SSLPassword, SSL.SSL_AIDX_RSA);
  469. // Set certificate chain file
  470. SSLContext.setCertificateChainFile(sslContext, SSLCertificateChainFile, false);
  471. // Support Client Certificates
  472. SSLContext.setCACertificate(sslContext, SSLCACertificateFile, SSLCACertificatePath);
  473. // Set revocation
  474. SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
  475. // Client certificate verification
  476. value = SSL.SSL_CVERIFY_NONE;
  477. if ("optional".equalsIgnoreCase(SSLVerifyClient)) {
  478. value = SSL.SSL_CVERIFY_OPTIONAL;
  479. } else if ("require".equalsIgnoreCase(SSLVerifyClient)) {
  480. value = SSL.SSL_CVERIFY_REQUIRE;
  481. } else if ("optionalNoCA".equalsIgnoreCase(SSLVerifyClient)) {
  482. value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
  483. }
  484. SSLContext.setVerify(sslContext, value, SSLVerifyDepth);
  485. // For now, sendfile is not supported with SSL
  486. if (useSendfile) {
  487. useSendfile = false;
  488. if (useSendFileSet) {
  489. log.warn(sm.getString("endpoint.apr.noSendfileWithSSL"));
  490. }
  491. }
  492. }
  493. }
  494. public long getJniSslContext() {
  495. return sslContext;
  496. }
  497. /**
  498. * Start the APR endpoint, creating acceptor, poller and sendfile threads.
  499. */
  500. @Override
  501. public void startInternal() throws Exception {
  502. if (!running) {
  503. running = true;
  504. paused = false;
  505. // Create worker collection
  506. if (getExecutor() == null) {
  507. createExecutor();
  508. }
  509. initializeConnectionLatch();
  510. // Start poller thread
  511. poller = new Poller();
  512. poller.init();
  513. Thread pollerThread = new Thread(poller, getName() + "-Poller");
  514. pollerThread.setPriority(threadPriority);
  515. pollerThread.setDaemon(true);
  516. pollerThread.start();
  517. // Start sendfile thread
  518. if (useSendfile) {
  519. sendfile = new Sendfile();
  520. sendfile.init();
  521. Thread sendfileThread =
  522. new Thread(sendfile, getName() + "-Sendfile");
  523. sendfileThread.setPriority(threadPriority);
  524. sendfileThread.setDaemon(true);
  525. sendfileThread.start();
  526. }
  527. startAcceptorThreads();
  528. // Start async timeout thread
  529. setAsyncTimeout(new AsyncTimeout());
  530. Thread timeoutThread = new Thread(getAsyncTimeout(), getName() + "-AsyncTimeout");
  531. timeoutThread.setPriority(threadPriority);
  532. timeoutThread.setDaemon(true);
  533. timeoutThread.start();
  534. }
  535. }
  536. /**
  537. * Stop the endpoint. This will cause all processing threads to stop.
  538. */
  539. @Override
  540. public void stopInternal() {
  541. releaseConnectionLatch();
  542. if (!paused) {
  543. pause();
  544. }
  545. if (running) {
  546. running = false;
  547. poller.stop();
  548. getAsyncTimeout().stop();
  549. unlockAccept();
  550. for (AbstractEndpoint.Acceptor acceptor : acceptors) {
  551. long waitLeft = 10000;
  552. while (waitLeft > 0 &&
  553. acceptor.getState() != AcceptorState.ENDED &&
  554. serverSock != 0) {
  555. try {
  556. Thread.sleep(50);
  557. } catch (InterruptedException e) {
  558. // Ignore
  559. }
  560. waitLeft -= 50;
  561. }
  562. if (waitLeft == 0) {
  563. log.warn(sm.getString("endpoint.warn.unlockAcceptorFailed",
  564. acceptor.getThreadName()));
  565. // If the Acceptor is still running force
  566. // the hard socket close.
  567. if (serverSock != 0) {
  568. Socket.shutdown(serverSock, Socket.APR_SHUTDOWN_READ);
  569. serverSock = 0;
  570. }
  571. }
  572. }
  573. try {
  574. poller.destroy();
  575. } catch (Exception e) {
  576. // Ignore
  577. }
  578. poller = null;
  579. connections.clear();
  580. if (useSendfile) {
  581. try {
  582. sendfile.destroy();
  583. } catch (Exception e) {
  584. // Ignore
  585. }
  586. sendfile = null;
  587. }
  588. }
  589. shutdownExecutor();
  590. }
  591. /**
  592. * Deallocate APR memory pools, and close server socket.
  593. */
  594. @Override
  595. public void unbind() throws Exception {
  596. if (running) {
  597. stop();
  598. }
  599. // Destroy pool if it was initialised
  600. if (serverSockPool != 0) {
  601. Pool.destroy(serverSockPool);
  602. serverSockPool = 0;
  603. }
  604. // Close server socket if it was initialised
  605. if (serverSock != 0) {
  606. Socket.close(serverSock);
  607. serverSock = 0;
  608. }
  609. sslContext = 0;
  610. // Close all APR memory pools and resources if initialised
  611. if (rootPool != 0) {
  612. Pool.destroy(rootPool);
  613. rootPool = 0;
  614. }
  615. handler.recycle();
  616. }
  617. // ------------------------------------------------------ Protected Methods
  618. @Override
  619. protected AbstractEndpoint.Acceptor createAcceptor() {
  620. return new Acceptor();
  621. }
  622. /**
  623. * Process the specified connection.
  624. */
  625. protected boolean setSocketOptions(long socket) {
  626. // Process the connection
  627. int step = 1;
  628. try {
  629. // 1: Set socket options: timeout, linger, etc
  630. if (socketProperties.getSoLingerOn() && socketProperties.getSoLingerTime() >= 0)
  631. Socket.optSet(socket, Socket.APR_SO_LINGER, socketProperties.getSoLingerTime());
  632. if (socketProperties.getTcpNoDelay())
  633. Socket.optSet(socket, Socket.APR_TCP_NODELAY, (socketProperties.getTcpNoDelay() ? 1 : 0));
  634. Socket.timeoutSet(socket, socketProperties.getSoTimeout() * 1000);
  635. // 2: SSL handshake
  636. step = 2;
  637. if (sslContext != 0) {
  638. SSLSocket.attach(sslContext, socket);
  639. if (SSLSocket.handshake(socket) != 0) {
  640. if (log.isDebugEnabled()) {
  641. log.debug(sm.getString("endpoint.err.handshake") + ": " + SSL.getLastError());
  642. }
  643. return false;
  644. }
  645. }
  646. } catch (Throwable t) {
  647. ExceptionUtils.handleThrowable(t);
  648. if (log.isDebugEnabled()) {
  649. if (step == 2) {
  650. log.debug(sm.getString("endpoint.err.handshake"), t);
  651. } else {
  652. log.debug(sm.getString("endpoint.err.unexpected"), t);
  653. }
  654. }
  655. // Tell to close the socket
  656. return false;
  657. }
  658. return true;
  659. }
  660. /**
  661. * Allocate a new poller of the specified size.
  662. */
  663. protected long allocatePoller(int size, long pool, int timeout) {
  664. try {
  665. return Poll.create(size, pool, 0, timeout * 1000);
  666. } catch (Error e) {
  667. if (Status.APR_STATUS_IS_EINVAL(e.getError())) {
  668. log.info(sm.getString("endpoint.poll.limitedpollsize", "" + size));
  669. return 0;
  670. } else {
  671. log.error(sm.getString("endpoint.poll.initfail"), e);
  672. return -1;
  673. }
  674. }
  675. }
  676. /**
  677. * Process given socket. This is called when the socket has been
  678. * accepted.
  679. */
  680. protected boolean processSocketWithOptions(long socket) {
  681. try {
  682. // During shutdown, executor may be null - avoid NPE
  683. if (running) {
  684. if (log.isDebugEnabled()) {
  685. log.debug(sm.getString("endpoint.debug.socket",
  686. Long.valueOf(socket)));
  687. }
  688. AprSocketWrapper wrapper =
  689. new AprSocketWrapper(Long.valueOf(socket));
  690. wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
  691. wrapper.setSecure(isSSLEnabled());
  692. connections.put(Long.valueOf(socket), wrapper);
  693. getExecutor().execute(new SocketWithOptionsProcessor(wrapper));
  694. }
  695. } catch (RejectedExecutionException x) {
  696. log.warn("Socket processing request was rejected for:"+socket,x);
  697. return false;
  698. } catch (Throwable t) {
  699. ExceptionUtils.handleThrowable(t);
  700. // This means we got an OOM or similar creating a thread, or that
  701. // the pool and its queue are full
  702. log.error(sm.getString("endpoint.process.fail"), t);
  703. return false;
  704. }
  705. return true;
  706. }
  707. /**
  708. * Process given socket. Called in non-comet mode, typically keep alive
  709. * or upgraded protocol.
  710. */
  711. public boolean processSocket(long socket, SocketStatus status) {
  712. try {
  713. Executor executor = getExecutor();
  714. if (executor == null) {
  715. log.warn(sm.getString("endpoint.warn.noExector",
  716. Long.valueOf(socket), null));
  717. } else {
  718. SocketWrapper<Long> wrapper =
  719. connections.get(Long.valueOf(socket));
  720. // Make sure connection hasn't been closed
  721. if (wrapper != null) {
  722. executor.execute(new SocketProcessor(wrapper, status));
  723. }
  724. }
  725. } catch (RejectedExecutionException x) {
  726. log.warn("Socket processing request was rejected for:"+socket,x);
  727. return false;
  728. } catch (Throwable t) {
  729. ExceptionUtils.handleThrowable(t);
  730. // This means we got an OOM or similar creating a thread, or that
  731. // the pool and its queue are full
  732. log.error(sm.getString("endpoint.process.fail"), t);
  733. return false;
  734. }
  735. return true;
  736. }
  737. @Override
  738. public void processSocket(SocketWrapper<Long> socket, SocketStatus status,
  739. boolean dispatch) {
  740. try {
  741. // Synchronisation is required here as this code may be called as a
  742. // result of calling AsyncContext.dispatch() from a non-container
  743. // thread
  744. synchronized (socket) {
  745. if (waitingRequests.remove(socket)) {
  746. SocketProcessor proc = new SocketProcessor(socket, status);
  747. Executor executor = getExecutor();
  748. if (dispatch && executor != null) {
  749. executor.execute(proc);
  750. } else {
  751. proc.run();
  752. }
  753. }
  754. }
  755. } catch (RejectedExecutionException ree) {
  756. log.warn(sm.getString("endpoint.executor.fail", socket) , ree);
  757. } catch (Throwable t) {
  758. ExceptionUtils.handleThrowable(t);
  759. // This means we got an OOM or similar creating a thread, or that
  760. // the pool and its queue are full
  761. log.error(sm.getString("endpoint.process.fail"), t);
  762. }
  763. }
  764. private void closeSocket(long socket) {
  765. // If not running the socket will be destroyed by
  766. // parent pool or acceptor socket.
  767. // In any case disable double free which would cause JVM core.
  768. connections.remove(Long.valueOf(socket));
  769. // While the connector is running, destroySocket() will call
  770. // countDownConnection(). Once the connector is stopped, the latch is
  771. // removed so it does not matter that destroySocket() does not call
  772. // countDownConnection() in that case
  773. Poller poller = this.poller;
  774. if (poller != null) {
  775. if (!poller.close(socket)) {
  776. destroySocket(socket);
  777. }
  778. }
  779. }
  780. /*
  781. * This method should only be called if there is no chance that the socket
  782. * is currently being used by the Poller. It is generally a bad idea to call
  783. * this directly from a known error condition.
  784. */
  785. private void destroySocket(long socket) {
  786. connections.remove(Long.valueOf(socket));
  787. if (log.isDebugEnabled()) {
  788. String msg = sm.getString("endpoint.debug.destroySocket",
  789. Long.valueOf(socket));
  790. if (log.isTraceEnabled()) {
  791. log.trace(msg, new Exception());
  792. } else {
  793. log.debug(msg);
  794. }
  795. }
  796. // Be VERY careful if you call this method directly. If it is called
  797. // twice for the same socket the JVM will core. Currently this is only
  798. // called from Poller.closePollset() to ensure kept alive connections
  799. // are closed when calling stop() followed by start().
  800. if (socket != 0) {
  801. Socket.destroy(socket);
  802. countDownConnection();
  803. }
  804. }
  805. @Override
  806. protected Log getLog() {
  807. return log;
  808. }
  809. // --------------------------------------------------- Acceptor Inner Class
  810. /**
  811. * The background thread that listens for incoming TCP/IP connections and
  812. * hands them off to an appropriate processor.
  813. */
  814. protected class Acceptor extends AbstractEndpoint.Acceptor {
  815. private final Log log = LogFactory.getLog(AprEndpoint.Acceptor.class);
  816. @Override
  817. public void run() {
  818. int errorDelay = 0;
  819. // Loop until we receive a shutdown command
  820. while (running) {
  821. // Loop if endpoint is paused
  822. while (paused && running) {
  823. state = AcceptorState.PAUSED;
  824. try {
  825. Thread.sleep(50);
  826. } catch (InterruptedException e) {
  827. // Ignore
  828. }
  829. }
  830. if (!running) {
  831. break;
  832. }
  833. state = AcceptorState.RUNNING;
  834. try {
  835. //if we have reached max connections, wait
  836. countUpOrAwaitConnection();
  837. long socket = 0;
  838. try {
  839. // Accept the next incoming connection from the server
  840. // socket
  841. socket = Socket.accept(serverSock);
  842. if (log.isDebugEnabled()) {
  843. long sa = Address.get(Socket.APR_REMOTE, socket);
  844. Sockaddr addr = Address.getInfo(sa);
  845. log.debug(sm.getString("endpoint.apr.remoteport",
  846. Long.valueOf(socket),
  847. Long.valueOf(addr.port)));
  848. }
  849. } catch (Exception e) {
  850. //we didn't get a socket
  851. countDownConnection();
  852. // Introduce delay if necessary
  853. errorDelay = handleExceptionWithDelay(errorDelay);
  854. // re-throw
  855. throw e;
  856. }
  857. // Successful accept, reset the error delay
  858. errorDelay = 0;
  859. if (running && !paused) {
  860. // Hand this socket off to an appropriate processor
  861. if (!processSocketWithOptions(socket)) {
  862. // Close socket right away
  863. closeSocket(socket);
  864. }
  865. } else {
  866. // Close socket right away
  867. // No code path could have added the socket to the
  868. // Poller so use destroySocket()
  869. destroySocket(socket);
  870. }
  871. } catch (Throwable t) {
  872. ExceptionUtils.handleThrowable(t);
  873. if (running) {
  874. String msg = sm.getString("endpoint.accept.fail");
  875. if (t instanceof Error) {
  876. Error e = (Error) t;
  877. if (e.getError() == 233) {
  878. // Not an error on HP-UX so log as a warning
  879. // so it can be filtered out on that platform
  880. // See bug 50273
  881. log.warn(msg, t);
  882. } else {
  883. log.error(msg, t);
  884. }
  885. } else {
  886. log.error(msg, t);
  887. }
  888. }
  889. }
  890. // The processor will recycle itself when it finishes
  891. }
  892. state = AcceptorState.ENDED;
  893. }
  894. }
  895. // -------------------------------------------------- SocketInfo Inner Class
  896. public static class SocketInfo {
  897. public long socket;
  898. public int timeout;
  899. public int flags;
  900. public boolean read() {
  901. return (flags & Poll.APR_POLLIN) == Poll.APR_POLLIN;
  902. }
  903. public boolean write() {
  904. return (flags & Poll.APR_POLLOUT) == Poll.APR_POLLOUT;
  905. }
  906. public static int merge(int flag1, int flag2) {
  907. return ((flag1 & Poll.APR_POLLIN) | (flag2 & Poll.APR_POLLIN))
  908. | ((flag1 & Poll.APR_POLLOUT) | (flag2 & Poll.APR_POLLOUT));
  909. }
  910. @Override
  911. public String toString() {
  912. StringBuilder sb = new StringBuilder();
  913. sb.append("Socket: [");
  914. sb.append(socket);
  915. sb.append("], timeout: [");
  916. sb.append(timeout);
  917. sb.append("], flags: [");
  918. sb.append(flags);
  919. return sb.toString();
  920. }
  921. }
  922. // ---------------------------------------------- SocketTimeouts Inner Class
  923. public class SocketTimeouts {
  924. protected int size;
  925. protected long[] sockets;
  926. protected long[] timeouts;
  927. protected int pos = 0;
  928. public SocketTimeouts(int size) {
  929. this.size = 0;
  930. sockets = new long[size];
  931. timeouts = new long[size];
  932. }
  933. public void add(long socket, long timeout) {
  934. sockets[size] = socket;
  935. timeouts[size] = timeout;
  936. size++;
  937. }
  938. /**
  939. * Removes the specified socket from the poller.
  940. *
  941. * @return The configured timeout for the socket or zero if the socket
  942. * was not in the list of socket timeouts
  943. */
  944. public long remove(long socket) {
  945. long result = 0;
  946. for (int i = 0; i < size; i++) {
  947. if (sockets[i] == socket) {
  948. result = timeouts[i];
  949. sockets[i] = sockets[size - 1];
  950. timeouts[i] = timeouts[size - 1];
  951. size--;
  952. break;
  953. }
  954. }
  955. return result;
  956. }
  957. public long check(long date) {
  958. while (pos < size) {
  959. if (date >= timeouts[pos]) {
  960. long result = sockets[pos];
  961. sockets[pos] = sockets[size - 1];
  962. timeouts[pos] = timeouts[size - 1];
  963. size--;
  964. return result;
  965. }
  966. pos++;
  967. }
  968. pos = 0;
  969. return 0;
  970. }
  971. }
  972. // -------------------------------------------------- SocketList Inner Class
  973. public class SocketList {
  974. protected int size;
  975. protected int pos;
  976. protected long[] sockets;
  977. protected int[] timeouts;
  978. protected int[] flags;
  979. protected SocketInfo info = new SocketInfo();
  980. public SocketList(int size) {
  981. this.size = 0;
  982. pos = 0;
  983. sockets = new long[size];
  984. timeouts = new int[size];
  985. flags = new int[size];
  986. }
  987. public int size() {
  988. return this.size;
  989. }
  990. public SocketInfo get() {
  991. if (pos == size) {
  992. return null;
  993. } else {
  994. info.socket = sockets[pos];
  995. info.timeout = timeouts[pos];
  996. info.flags = flags[pos];
  997. pos++;
  998. return info;
  999. }
  1000. }
  1001. public void clear() {
  1002. size = 0;
  1003. pos = 0;
  1004. }
  1005. public boolean add(long socket, int timeout, int flag) {
  1006. if (size == sockets.length) {
  1007. return false;
  1008. } else {
  1009. for (int i = 0; i < size; i++) {
  1010. if (sockets[i] == socket) {
  1011. flags[i] = SocketInfo.merge(flags[i], flag);
  1012. return true;
  1013. }
  1014. }
  1015. sockets[size] = socket;
  1016. timeouts[size] = timeout;
  1017. flags[size] = flag;
  1018. size++;
  1019. return true;
  1020. }
  1021. }
  1022. public boolean remove(long socket) {
  1023. for (int i = 0; i < size; i++) {
  1024. if (sockets[i] == socket) {
  1025. sockets[i] = sockets[size - 1];
  1026. timeouts[i] = timeouts[size - 1];
  1027. flags[size] = flags[size -1];
  1028. size--;
  1029. return true;
  1030. }
  1031. }
  1032. return false;
  1033. }
  1034. public void duplicate(SocketList copy) {
  1035. copy.size = size;
  1036. copy.pos = pos;
  1037. System.arraycopy(sockets, 0, copy.sockets, 0, size);
  1038. System.arraycopy(timeouts, 0, copy.timeouts, 0, size);
  1039. System.arraycopy(flags, 0, copy.flags, 0, size);
  1040. }
  1041. }
  1042. // ------------------------------------------------------ Poller Inner Class
  1043. public class Poller implements Runnable {
  1044. /**
  1045. * Pointers to the pollers.
  1046. */
  1047. private long[] pollers = null;
  1048. /**
  1049. * Actual poller size.
  1050. */
  1051. private int actualPollerSize = 0;
  1052. /**
  1053. * Amount of spots left in the poller.
  1054. */
  1055. private int[] pollerSpace = null;
  1056. /**
  1057. * Amount of low level pollers in use by this poller.
  1058. */
  1059. private int pollerCount;
  1060. /**
  1061. * Timeout value for the poll call.
  1062. */
  1063. private int pollerTime;
  1064. /**
  1065. * Variable poller timeout that adjusts depending on how many poll sets
  1066. * are in use so that the total poll time across all poll sets remains
  1067. * equal to pollTime.
  1068. */
  1069. private int nextPollerTime;
  1070. /**
  1071. * Root pool.
  1072. */
  1073. private long pool = 0;
  1074. /**
  1075. * Socket descriptors.
  1076. */
  1077. private long[] desc;
  1078. /**
  1079. * List of sockets to be added to the poller.
  1080. */
  1081. private SocketList addList = null;
  1082. /**
  1083. * List of sockets to be closed.
  1084. */
  1085. private SocketList closeList = null;
  1086. /**
  1087. * Structure used for storing timeouts.
  1088. */
  1089. private SocketTimeouts timeouts = null;
  1090. /**
  1091. * Last run of maintain. Maintain will run usually every 5s.
  1092. */
  1093. private long lastMaintain = System.currentTimeMillis();
  1094. /**
  1095. * The number of connections currently inside this Poller. The correct
  1096. * operation of the Poller depends on this figure being correct. If it
  1097. * is not, it is possible that the Poller will enter a wait loop where
  1098. * it waits for the next connection to be added to the Poller before it
  1099. * calls poll when it should still be polling existing connections.
  1100. * Although not necessary at the time of writing this comment, it has
  1101. * been implemented as an AtomicInteger to ensure that it remains
  1102. * thread-safe.
  1103. */
  1104. private AtomicInteger connectionCount = new AtomicInteger(0);
  1105. public int getConnectionCount() { return connectionCount.get(); }
  1106. private volatile boolean pollerRunning = true;
  1107. /**
  1108. * Create the poller. With some versions of APR, the maximum poller size
  1109. * will be 62 (recompiling APR is necessary to remove this limitation).
  1110. */
  1111. protected void init() {
  1112. pool = Pool.create(serverSockPool);
  1113. // Single poller by default
  1114. int defaultPollerSize = getMaxConnections();
  1115. if ((OS.IS_WIN32 || OS.IS_WIN64) && (defaultPollerSize > 1024)) {
  1116. // The maximum per poller to get reasonable performance is 1024
  1117. // Adjust poller size so that it won't reach the limit. This is
  1118. // a limitation of XP / Server 2003 that has been fixed in
  1119. // Vista / Server 2008 onwards.
  1120. actualPollerSize = 1024;
  1121. } else {
  1122. actualPollerSize = defaultPollerSize;
  1123. }
  1124. timeouts = new SocketTimeouts(defaultPollerSize);
  1125. // At the moment, setting the timeout is useless, but it could get
  1126. // used again as the normal poller could be faster using maintain.
  1127. // It might not be worth bothering though.
  1128. long pollset = allocatePoller(actualPollerSize, pool, -1);
  1129. if (pollset == 0 && actualPollerSize > 1024) {
  1130. actualPollerSize = 1024;
  1131. pollset = allocatePoller(actualPollerSize, pool, -1);
  1132. }
  1133. if (pollset == 0) {
  1134. actualPollerSize = 62;
  1135. pollset = allocatePoller(actualPollerSize, pool, -1);
  1136. }
  1137. pollerCount = defaultPollerSize / actualPollerSize;
  1138. pollerTime = pollTime / pollerCount;
  1139. nextPollerTime = pollerTime;
  1140. pollers = new long[pollerCount];
  1141. pollers[0] = pollset;
  1142. for (int i = 1; i < pollerCount; i++) {
  1143. pollers[i] = allocatePoller(actualPollerSize, pool, -1);
  1144. }
  1145. pollerSpace = new int[pollerCount];
  1146. for (int i = 0; i < pollerCount; i++) {
  1147. pollerSpace[i] = actualPollerSize;
  1148. }
  1149. desc = new long[actualPollerSize * 2];
  1150. connectionCount.set(0);
  1151. addList = new SocketList(defaultPollerSize);
  1152. closeList = new SocketList(defaultPollerSize);
  1153. }
  1154. /*
  1155. * This method is synchronized so that it is not possible for a socket
  1156. * to be added to the Poller's addList once this method has completed.
  1157. */
  1158. protected synchronized void stop() {
  1159. pollerRunning = false;
  1160. }
  1161. /**
  1162. * Destroy the poller.
  1163. */
  1164. protected void destroy() {
  1165. // Wait for pollerTime before doing anything, so that the poller
  1166. // threads exit, otherwise parallel destruction of sockets which are
  1167. // still in the poller can cause problems
  1168. try {
  1169. synchronized (this) {
  1170. this.notify();
  1171. this.wait(pollTime / 1000);
  1172. }
  1173. } catch (InterruptedException e) {
  1174. // Ignore
  1175. }
  1176. // Close all sockets in the add queue
  1177. SocketInfo info = addList.get();
  1178. while (info != null) {
  1179. boolean comet =
  1180. connections.get(Long.valueOf(info.socket)).isComet();
  1181. if (!comet || (comet && !processSocket(
  1182. info.socket, SocketStatus.STOP))) {
  1183. // Poller isn't running at this point so use destroySocket()
  1184. // directly
  1185. destroySocket(info.socket);
  1186. }
  1187. info = addList.get();
  1188. }
  1189. addList.clear();
  1190. // Close all sockets still in the poller
  1191. for (int i = 0; i < pollerCount; i++) {
  1192. int rv = Poll.pollset(pollers[i], desc);
  1193. if (rv > 0) {
  1194. for (int n = 0; n < rv; n++) {
  1195. boolean comet = connections.get(
  1196. Long.valueOf(desc[n*2+1])).isComet();
  1197. if (!comet || (comet && !processSocket(
  1198. desc[n*2+1], SocketStatus.STOP))) {
  1199. destroySocket(desc[n*2+1]);
  1200. }
  1201. }
  1202. }
  1203. }
  1204. Pool.destroy(pool);
  1205. connectionCount.set(0);
  1206. }
  1207. /**
  1208. * Add specified socket and associated pool to the poller. The socket
  1209. * will be added to a temporary array, and polled first after a maximum
  1210. * amount of time equal to pollTime (in most cases, latency will be much
  1211. * lower, however). Note: If both read and write are false, the socket
  1212. * will only be checked for timeout; if the socket was already present
  1213. * in the poller, a callback event will be generated and the socket will
  1214. * be removed from the poller.
  1215. *
  1216. * @param socket to add to the poller
  1217. * @param timeout to use for this connection
  1218. * @param read to do read polling
  1219. * @param write to do write polling
  1220. */
  1221. public void add(long socket, int timeout, boolean read, boolean write) {
  1222. add(socket, timeout,
  1223. (read ? Poll.APR_POLLIN : 0) |
  1224. (wri