PageRenderTime 63ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

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

https://github.com/kanishin/tomcat
Java | 2293 lines | 1464 code | 286 blank | 543 comment | 374 complexity | 37ef9eb7b4ac3790e1788f20421a3290 MD5 | raw file
Possible License(s): Apache-2.0

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

Large files files are truncated, but you can click here to view the full file