Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: java/src/org/apache/tomcat/jni/socket/AprSocket.java

Issue 2842333002: Updated netty-tcnative to version 2.0.0.Final (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.jni.socket;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.IOException;
21 import java.security.cert.CertificateException;
22 import java.security.cert.CertificateFactory;
23 import java.security.cert.X509Certificate;
24 import java.util.logging.Level;
25 import java.util.logging.Logger;
26
27 import org.apache.tomcat.jni.Address;
28 import org.apache.tomcat.jni.Error;
29 import org.apache.tomcat.jni.Poll;
30 import org.apache.tomcat.jni.SSL;
31 import org.apache.tomcat.jni.SSLExt;
32 import org.apache.tomcat.jni.SSLSocket;
33 import org.apache.tomcat.jni.Sockaddr;
34 import org.apache.tomcat.jni.Socket;
35 import org.apache.tomcat.jni.Status;
36 import org.apache.tomcat.jni.socket.AprSocketContext.AprPoller;
37 import org.apache.tomcat.jni.socket.AprSocketContext.BlockingPollHandler;
38
39 /**
40 * Native socket, using JNI + APR + openssl.
41 *
42 * The socket is non-blocking - you can register either a blocking or non
43 * blocking callback.
44 *
45 * There is no explicit method to register/unregister poll interest -
46 * it is done automatically, when read/write methods return 0.
47 *
48 * To keep the socket polling you must read all the available data, until
49 * read() returns 0. If you want to pause - don't read all input. To resume -
50 * read again until it returns 0.
51 *
52 * Same for write - when write() returns 0 the socket is registered for
53 * write interest.
54 *
55 * You can also use the blocking read/write methods.
56 */
57 public class AprSocket implements Runnable {
58
59 private static final Logger log =
60 Logger.getLogger("org.apache.tomcat.jni.socket.AprSocket");
61
62 private static final byte[][] NO_CERTS = new byte[0][];
63
64 static final int CONNECTING = 0x1;
65 static final int CONNECTED = 0x2;
66
67 // Current ( real ) poll status
68 static final int POLLIN_ACTIVE = 0x4;
69 static final int POLLOUT_ACTIVE = 0x8;
70
71 static final int POLL = 0x10;
72
73 static final int SSL_ATTACHED = 0x40;
74
75 // Requested poll status. Set by read/write when needed.
76 // Cleared when polled
77 static final int POLLIN = 0x80;
78 static final int POLLOUT = 0x100;
79
80 static final int ACCEPTED = 0x200;
81 static final int ERROR = 0x400;
82 static final int CLOSED = 0x800;
83
84 static final int READING = 0x1000;
85 static final int WRITING = 0x2000;
86
87 // Not null
88 private final AprSocketContext context;
89
90 // only one - to save per/socket memory - context has similar callbacks.
91 BlockingPollHandler handler;
92
93 // Set while it's associated with a poller - it'll stay associated after
94 // connect until close. Destroy will happen in the poller.
95 // POLL bit indicates if the socket is actually polling.
96 AprPoller poller;
97
98 // Bit field indicating the status and socket should only be accessed with
99 // socketLock protection
100 private int status;
101
102 long socket;
103
104 //long to = 10000;
105
106 // Persistent info about the peer ( SSL, etc )
107 private HostInfo hostInfo;
108
109 AprSocket(AprSocketContext context) {
110 this.context = context;
111 }
112
113 public void recycle() {
114 status = 0;
115 hostInfo = null;
116 handler = null;
117 socket = 0;
118 poller = null;
119 }
120
121 @Override
122 public String toString() {
123 return (context.isServer() ? "AprSrv-" : "AprCli-") +
124 Long.toHexString(socket) + " " + Integer.toHexString(status);
125 }
126
127 public void setHandler(BlockingPollHandler l) {
128 handler = l;
129 }
130
131 private void setNonBlocking() {
132 if (socket != 0 && context.running) {
133 Socket.optSet(socket, Socket.APR_SO_NONBLOCK, 1);
134 Socket.timeoutSet(socket, 0);
135 }
136 }
137
138 /**
139 * Check if the socket is currently registered with a poller.
140 */
141 public boolean isPolling() {
142 synchronized (this) {
143 return (status & POLL) != 0;
144 }
145 }
146
147 public BlockingPollHandler getHandler() {
148 return handler;
149 }
150
151 public AprSocketContext getContext() {
152 return context;
153 }
154
155 AprSocket setHost(HostInfo hi) {
156 hostInfo = hi;
157 return this;
158 }
159
160 /**
161 */
162 public void connect() throws IOException {
163 if (isBlocking()) {
164 // will call handleConnected() at the end.
165 context.connectBlocking(this);
166 } else {
167 synchronized(this) {
168 if ((status & CONNECTING) != 0) {
169 return;
170 }
171 status |= CONNECTING;
172 }
173 context.connectExecutor.execute(this);
174 }
175 }
176
177
178 // after connection is done, called from a thread pool ( not IO thread )
179 // may block for handshake.
180 void afterConnect() throws IOException {
181 if (hostInfo.secure) {
182 blockingStartTLS();
183 }
184
185 setNonBlocking(); // call again, to set the bits ( connect was blocking )
186
187 setStatus(CONNECTED);
188 clearStatus(CONNECTING);
189
190 notifyConnected(false);
191 }
192
193 public HostInfo getHost() {
194 return hostInfo;
195 }
196
197 /**
198 * Write as much data as possible to the socket.
199 *
200 * @param data
201 * @param off
202 * @param len
203 * @return For both blocking and non-blocking, returns the number of bytes
204 * written. If no data can be written (e.g. if the buffers are
205 * full) 0 will be returned.
206 * @throws IOException
207 */
208 public int write(byte[] data, int off, int len, long to) throws IOException {
209 long max = System.currentTimeMillis() + to;
210
211 while (true) {
212 int rc = writeInternal(data, off, len);
213 if (rc < 0) {
214 throw new IOException("Write error " + rc);
215 } else if (rc == 0) {
216 // need poll out - do we need to update polling ?
217 context.findPollerAndAdd(this);
218 } else {
219 return rc;
220 }
221
222 try {
223 long waitTime = max - System.currentTimeMillis();
224 if (waitTime <= 0) {
225 return 0;
226 }
227 wait(waitTime);
228 } catch (InterruptedException e) {
229 return 0;
230 }
231 }
232 }
233
234 public int write(byte[] data, int off, int len) throws IOException {
235 // In SSL mode, read/write can't be called at the same time.
236 int rc = writeInternal(data, off, len);
237 if (rc < 0) {
238 throw new IOException("Write error " + rc);
239 } else if (rc == 0) {
240 // need poll out - do we need to update polling ?
241 synchronized (this) {
242 context.findPollerAndAdd(this);
243 }
244 }
245 return rc;
246 }
247
248 private int writeInternal(byte[] data, int off, int len) throws IOException {
249 int rt = 0;
250 int sent = 0;
251 synchronized(this) {
252 if ((status & CLOSED) != 0
253 || socket == 0
254 || !context.running) {
255 throw new IOException("Closed");
256 }
257 if ((status & WRITING) != 0) {
258 throw new IOException("Write from 2 threads not allowed");
259 }
260 status |= WRITING;
261
262 while (len > 0) {
263 sent = Socket.send(socket, data, off, len);
264 if (sent <= 0) {
265 break;
266 }
267 off += sent;
268 len -= sent;
269 }
270
271 status &= ~WRITING;
272 }
273
274 if (context.rawDataHandler != null) {
275 context.rawData(this, false, data, off, sent, len, false);
276 }
277
278 if (sent <= 0) {
279 if (sent == -Status.TIMEUP || sent == -Status.EAGAIN || sent == 0) {
280 setStatus(POLLOUT);
281 updatePolling();
282 return rt;
283 }
284 log.warning("apr.send(): Failed to send, closing " + sent);
285 reset();
286 throw new IOException("Error sending " + sent + " " + Error.strerror (-sent));
287 } else {
288 off += sent;
289 len -= sent;
290 rt += sent;
291 return sent;
292 }
293 }
294
295 public int read(byte[] data, int off, int len, long to) throws IOException {
296 int rd = readNB(data, off, len);
297 if (rd == 0) {
298 synchronized(this) {
299 try {
300 wait(to);
301 } catch (InterruptedException e) {
302 return 0;
303 }
304 }
305 rd = readNB(data, off, len);
306 }
307 return processReadResult(data, off, len, rd);
308 }
309
310 public int read(byte[] data, int off, int len) throws IOException {
311 return readNB(data, off, len);
312 }
313
314 private int processReadResult(byte[] data, int off, int len, int read)
315 throws IOException {
316 if (context.rawDataHandler != null) {
317 context.rawData(this, true, data, off, read, len, false);
318 }
319
320 if (read > 0) {
321 return read;
322 }
323
324 if (read == 0 || read == -Status.TIMEUP || read == -Status.ETIMEDOUT
325 || read == -Status.EAGAIN) {
326 read = 0;
327 setStatus(POLLIN);
328 updatePolling();
329 return 0;
330 }
331
332 if (read == -Status.APR_EOF || read == -1) {
333 close();
334 return -1;
335 }
336 // abrupt close
337 reset();
338 throw new IOException("apr.read(): " + read + " " + Error.strerror(-read ));
339 }
340
341 public int readNB(byte[] data, int off, int len) throws IOException {
342 int read;
343 synchronized(this) {
344 if ((status & CLOSED) != 0
345 || socket == 0
346 || !context.running) {
347 return -1;
348 }
349 if ((status & READING) != 0) {
350 throw new IOException("Read from 2 threads not allowed");
351 }
352 status |= READING;
353
354 read = Socket.recv(socket, data, off, len);
355 status &= ~READING;
356 }
357 return processReadResult(data, off, len, read);
358 }
359
360 /*
361 No support for shutdownOutput: SSL is quite tricky.
362 Use close() instead - no read/write will be allowed after.
363
364 */
365
366 public void close() {
367 synchronized (this) {
368 if ((status & CLOSED) != 0 || socket == 0) {
369 return;
370 }
371 status |= CLOSED;
372 status &= ~POLLIN;
373 status &= ~POLLOUT;
374 }
375 if (context.rawDataHandler != null) {
376 context.rawDataHandler.rawData(this, false, null, 0, 0, 0, true);
377 }
378 Socket.close(socket);
379 if (poller == null) {
380 maybeDestroy();
381 } else {
382 try {
383 poller.requestUpdate(this);
384 } catch (IOException e) {
385 e.printStackTrace();
386 }
387 }
388 }
389
390 void maybeDestroy() {
391 synchronized(this) {
392 if (socket == 0 ||
393 (status & CONNECTING) != 0 || !context.running) {
394 // closed or operation in progress
395 // if context stopped, pool will be destroyed and close
396 // all sockets automatically.
397 return;
398 }
399 if ((status & CLOSED) == 0) {
400 return; // not closed
401 }
402 if ((status & (WRITING | READING)) != 0) {
403 return; // not closed
404 }
405
406 if (context.rawDataHandler != null) {
407 context.rawDataHandler.rawData(this, false, null, -1, -1, -1, tr ue);
408 }
409 if (log.isLoggable(Level.FINE)) {
410 log.info("closing: context.open=" + context.open.get() + " " + t his);
411 }
412
413 context.open.decrementAndGet();
414
415 if (socket != 0 && (status & CLOSED) == 0) {
416 Socket.close(socket);
417 status |= CLOSED;
418 }
419
420 if (handler != null) {
421 if (isBlocking()) {
422 context.getExecutor().execute(this);
423 } else {
424 handler.closed(this);
425 }
426 }
427
428 context.destroySocket(this);
429 }
430 }
431
432
433
434 /**
435 * Close input and output, potentially sending RST, than close the socket.
436 *
437 * The proper way to close when gracefully done is by calling writeEnd() and
438 * reading all remaining input until -1 (EOF) is received.
439 *
440 * If EOF is received, the proper way to close is send whatever is remaining and
441 * call writeEnd();
442 */
443 public void reset() {
444 setStatus(ERROR);
445 close();
446 }
447
448
449 /**
450 */
451 public boolean isClosed() {
452 synchronized(this) {
453 if ((status & CLOSED) != 0 || socket == 0 || !context.running) {
454 return true;
455 }
456 return false;
457 }
458 }
459
460 public long getIOTimeout() throws IOException {
461 if (socket != 0 && context.running) {
462 try {
463 return Socket.timeoutGet(socket) / 1000;
464 } catch (Exception e) {
465 throw new IOException(e);
466 }
467 } else {
468 throw new IOException("Socket is closed");
469 }
470 }
471
472 // Cert is in DER format
473 // Called after handshake
474 public byte[][] getPeerCert(boolean check) throws IOException {
475 getHost();
476 if (hostInfo.certs != null && hostInfo.certs != NO_CERTS && !check) {
477 return hostInfo.certs;
478 }
479 if (!checkBitAndSocket(SSL_ATTACHED)) {
480 return NO_CERTS;
481 }
482 try {
483 int certLength = SSLSocket.getInfoI(socket,
484 SSL.SSL_INFO_CLIENT_CERT_CHAIN);
485 // TODO: if resumed, old certs are good.
486 // If not - warn if certs changed, remember first cert, etc.
487 if (certLength <= 0) {
488 // Can also happen on session resume - keep the old
489 if (hostInfo.certs == null) {
490 hostInfo.certs = NO_CERTS;
491 }
492 return hostInfo.certs;
493 }
494 hostInfo.certs = new byte[certLength + 1][];
495
496 hostInfo.certs[0] = SSLSocket.getInfoB(socket,
497 SSL.SSL_INFO_CLIENT_CERT);
498 for (int i = 0; i < certLength; i++) {
499 hostInfo.certs[i + 1] = SSLSocket.getInfoB(socket,
500 SSL.SSL_INFO_CLIENT_CERT_CHAIN + i);
501 }
502 return hostInfo.certs;
503 } catch (Exception e) {
504 throw new IOException(e);
505 }
506 }
507
508 public X509Certificate[] getPeerX509Cert() throws IOException {
509 byte[][] certs = getPeerCert(false);
510 X509Certificate[] xcerts = new X509Certificate[certs.length];
511 if (certs.length == 0) {
512 return xcerts;
513 }
514 try {
515 CertificateFactory cf = CertificateFactory.getInstance("X.509");
516 for (int i = 0; i < certs.length; i++) {
517 if (certs[i] != null) {
518 ByteArrayInputStream bis = new ByteArrayInputStream(
519 certs[i]);
520 xcerts[i] = (X509Certificate) cf.generateCertificate(bis);
521 bis.close();
522 }
523 }
524 } catch (CertificateException ex) {
525 throw new IOException(ex);
526 }
527 return xcerts;
528 }
529
530 public String getCipherSuite() throws IOException {
531 if (checkBitAndSocket(SSL_ATTACHED)) {
532 return null;
533 }
534 try {
535 return SSLSocket.getInfoS(socket, SSL.SSL_INFO_CIPHER);
536 } catch (Exception e) {
537 throw new IOException(e);
538 }
539 }
540
541 public int getKeySize() throws IOException {
542 if (checkBitAndSocket(SSL_ATTACHED)) {
543 return -1;
544 }
545 try {
546 return SSLSocket.getInfoI(socket, SSL.SSL_INFO_CIPHER_USEKEYSIZE);
547 } catch (Exception e) {
548 throw new IOException(e);
549 }
550 }
551
552 public int getRemotePort() throws IOException {
553 if (socket != 0 && context.running) {
554 try {
555 long sa = Address.get(Socket.APR_REMOTE, socket);
556 Sockaddr addr = Address.getInfo(sa);
557 return addr.port;
558 } catch (Exception ex) {
559 throw new IOException(ex);
560 }
561 }
562 throw new IOException("Socket closed");
563 }
564
565 public String getRemoteAddress() throws IOException {
566 if (socket != 0 && context.running) {
567 try {
568 long sa = Address.get(Socket.APR_REMOTE, socket);
569 return Address.getip(sa);
570 } catch (Exception ex) {
571 throw new IOException(ex);
572 }
573 }
574 throw new IOException("Socket closed");
575 }
576
577 public String getRemoteHostname() throws IOException {
578 if (socket != 0 && context.running) {
579 try {
580 long sa = Address.get(Socket.APR_REMOTE, socket);
581 String remoteHost = Address.getnameinfo(sa, 0);
582 if (remoteHost == null) {
583 remoteHost = Address.getip(sa);
584 }
585 return remoteHost;
586 } catch (Exception ex) {
587 throw new IOException(ex);
588 }
589 }
590 throw new IOException("Socket closed");
591 }
592
593 public int getLocalPort() throws IOException {
594 if (socket != 0 && context.running) {
595 try {
596 long sa = Address.get(Socket.APR_LOCAL, socket);
597 Sockaddr addr = Address.getInfo(sa);
598 return addr.port;
599 } catch (Exception ex) {
600 throw new IOException(ex);
601 }
602 }
603 throw new IOException("Socket closed");
604 }
605
606 public String getLocalAddress() throws IOException {
607 if (socket != 0 && context.running) {
608 try {
609 long sa = Address.get(Socket.APR_LOCAL, socket);
610 return Address.getip(sa);
611 } catch (Exception ex) {
612 throw new IOException(ex);
613 }
614 }
615 throw new IOException("Socket closed");
616 }
617
618 public String getLocalHostname() throws IOException {
619 if (socket != 0 && context.running) {
620 try {
621 long sa = Address.get(Socket.APR_LOCAL, socket);
622 return Address.getnameinfo(sa, 0);
623 } catch (Exception ex) {
624 throw new IOException(ex);
625 }
626 }
627 throw new IOException("Socket closed");
628 }
629
630 public boolean isBlocking() {
631 return ! (handler instanceof AprSocketContext.NonBlockingPollHandler);
632 }
633
634 public boolean isError() {
635 return checkPreConnect(ERROR);
636 }
637
638 void notifyError(Throwable err, boolean needsThread) {
639 if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
640 if (err != null) {
641 ((AprSocketContext.NonBlockingPollHandler) handler).error(this, err);
642 }
643 } else {
644 // poller destroyed, etc
645 if (needsThread) {
646 context.getExecutor().execute(this);
647 } else {
648 try {
649 notifyIO();
650 } catch (IOException e) {
651 log.log(Level.SEVERE, this + " error ", e);
652 }
653 }
654 }
655 }
656
657 // Called after connect and from poller.
658 void notifyIO() throws IOException {
659 long t0 = System.currentTimeMillis();
660 try {
661 if (handler != null) {
662 handler.process(this, true, false, false);
663 }
664 } catch (Throwable t) {
665 throw new IOException(t);
666 } finally {
667 long t1 = System.currentTimeMillis();
668 t1 -= t0;
669 if (t1 > context.maxHandlerTime.get()) {
670 context.maxHandlerTime.set(t1);
671 }
672 context.totalHandlerTime.addAndGet(t1);
673 context.handlerCount.incrementAndGet();
674 }
675 }
676
677 private void notifyConnected(boolean server) throws IOException {
678 // Will set the handler on the channel for accepted
679 context.onSocket(this);
680
681 if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
682 ((AprSocketContext.NonBlockingPollHandler) handler).connected(this);
683
684 ((AprSocketContext.NonBlockingPollHandler) handler).process(this, tr ue, true, false);
685 // Now register for polling - unless process() set suspendRead and
686 // doesn't need out notifications
687 updatePolling();
688 } else {
689 if (server) {
690 // client will block in connect().
691 // Server: call process();
692 notifyIO();
693 }
694 }
695 }
696
697 private void updatePolling() throws IOException {
698 synchronized (this) {
699 if ((status & CLOSED) != 0) {
700 maybeDestroy();
701 return;
702 }
703 }
704 context.findPollerAndAdd(this);
705 }
706
707 @Override
708 public void run() {
709 if (!context.running) {
710 return;
711 }
712 if (checkPreConnect(CLOSED)) {
713 if (handler != null) {
714 handler.closed(this);
715 }
716 return;
717 }
718 if (!checkPreConnect(CONNECTED)) {
719 if (checkBitAndSocket(ACCEPTED)) {
720 try {
721 context.open.incrementAndGet();
722
723 if (log.isLoggable(Level.FINE)) {
724 log.info("Accept: " + context.open.get() + " " + this + " " +
725 getRemotePort());
726 }
727 if (context.tcpNoDelay) {
728 Socket.optSet(socket, Socket.APR_TCP_NODELAY, 1);
729 }
730
731 setStatus(CONNECTED);
732 if (context.sslMode) {
733 Socket.timeoutSet(socket,
734 context.connectTimeout * 1000L);
735 blockingStartTLS();
736 }
737 setNonBlocking(); // call again, to set the bits ( connect w as blocking )
738
739 notifyConnected(true);
740 return;
741 } catch (Throwable t) {
742 t.printStackTrace(); // no error handler yet
743 reset();
744 notifyError(t, false);
745 return;
746 }
747 }
748 if (checkPreConnect(CONNECTING)) {
749 // Non-blocking connect - will call 'afterConnection' at the end .
750 try {
751 context.connectBlocking(this);
752 } catch (IOException t) {
753 reset(); // also sets status ERROR
754 if (handler instanceof AprSocketContext.NonBlockingPollHandl er) {
755 ((AprSocketContext.NonBlockingPollHandler) handler).proc ess(this, false, false, true);
756 }
757 notifyError(t, false);
758 }
759 }
760 } else {
761 if (handler != null) {
762 try {
763 notifyIO();
764 } catch (Throwable e) {
765 log.log(Level.SEVERE, this + " error ", e);
766 reset();
767 // no notifyIO - just did it.
768 }
769 }
770 }
771 }
772
773 /**
774 * This is a blocking call ! ( can be made non-blocking, but too complex )
775 *
776 * Will be called automatically after connect() or accept if 'secure' is
777 * true.
778 *
779 * Can be called manually to upgrade the channel
780 * @throws IOException
781 */
782 public void blockingStartTLS() throws IOException {
783 synchronized(this) {
784 if (socket == 0 || !context.running) {
785 return;
786 }
787 if ((status & SSL_ATTACHED) != 0) {
788 return;
789 }
790 status |= SSL_ATTACHED;
791 }
792
793 try {
794 if (log.isLoggable(Level.FINE)) {
795 log.info(this + " StartSSL");
796 }
797
798 AprSocketContext aprCon = context;
799 SSLSocket.attach(aprCon.getSslCtx(), socket);
800
801 if (context.debugSSL) {
802 SSLExt.debug(socket);
803 }
804 if (!getContext().isServer()) {
805 if (context.USE_TICKETS && hostInfo.ticketLen > 0) {
806 SSLExt.setTicket(socket, hostInfo.ticket,
807 hostInfo.ticketLen);
808 } else if (hostInfo.sessDer != null) {
809 SSLExt.setSessionData(socket, hostInfo.sessDer,
810 hostInfo.sessDer.length);
811 }
812 }
813 SSLExt.sslSetMode(socket, SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
814 SSLExt.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
815
816 int rc = SSLSocket.handshake(socket);
817
818 // At this point we have the session ID, remote certs, etc
819 // we can lookup host info
820 if (hostInfo == null) {
821 hostInfo = new HostInfo();
822 }
823
824 if (rc != Status.APR_SUCCESS) {
825 throw new IOException(this + " Handshake failed " + rc + " "
826 + Error.strerror(rc) + " SSLL "
827 + SSL.getLastError());
828 } else { // SUCCESS
829 handshakeDone();
830 }
831 } catch (IOException e) {
832 throw e;
833 } catch (Exception e) {
834 throw new IOException(e);
835 }
836 }
837
838 private void handshakeDone() throws IOException {
839 getHost();
840 if (socket == 0 || !context.running) {
841 throw new IOException("Socket closed");
842 }
843 if (context.USE_TICKETS && ! context.isServer()) {
844 if (hostInfo.ticket == null) {
845 hostInfo.ticket = new byte[2048];
846 }
847 int ticketLen = SSLExt.getTicket(socket, hostInfo.ticket);
848 if (ticketLen > 0) {
849 hostInfo.ticketLen = ticketLen;
850 if (log.isLoggable(Level.FINE)) {
851 log.info("Received ticket: " + ticketLen);
852 }
853 }
854 }
855
856 // TODO: if the ticket, session id or session changed - callback to
857 // save the session again
858 try {
859 hostInfo.sessDer = SSLExt.getSessionData(socket);
860 getPeerCert(true);
861 hostInfo.sessionId = SSLSocket.getInfoS(socket,
862 SSL.SSL_INFO_SESSION_ID);
863 } catch (Exception e) {
864 throw new IOException(e);
865 }
866
867 hostInfo.npn = new byte[32];
868 hostInfo.npnLen = SSLExt.getNPN(socket, hostInfo.npn);
869
870 // If custom verification is used - should check the certificates
871 if (context.tlsCertVerifier != null) {
872 context.tlsCertVerifier.handshakeDone(this);
873 }
874 }
875
876 int requestedPolling() {
877 synchronized(this) {
878 if (socket == 0 || ((status & CLOSED) != 0)) {
879 return 0;
880 }
881 // Implicit:
882 //Poll.APR_POLLNVAL | Poll.APR_POLLHUP | Poll.APR_POLLERR |
883 int res = 0;
884 if ((status & POLLIN) != 0) {
885 res = Poll.APR_POLLIN;
886 }
887 if ((status & POLLOUT) != 0) {
888 res |= Poll.APR_POLLOUT;
889 }
890 return res;
891 }
892 }
893
894 boolean checkBitAndSocket(int bit) {
895 synchronized (this) {
896 return ((status & bit) != 0 && socket != 0 &&
897 (status & CLOSED) == 0 && context.running);
898 }
899 }
900
901 boolean checkPreConnect(int bit) {
902 synchronized (this) {
903 return ((status & bit) != 0);
904 }
905 }
906
907 void clearStatus(int bit) {
908 synchronized (this) {
909 status &= ~bit;
910 }
911 }
912
913 boolean setStatus(int bit) {
914 synchronized (this) {
915 int old = status & bit;
916 status |= bit;
917 return old != 0;
918 }
919 }
920
921
922 }
OLDNEW
« no previous file with comments | « java/src/org/apache/tomcat/jni/User.java ('k') | java/src/org/apache/tomcat/jni/socket/AprSocketContext.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698