protected void accept(SelectionKey key) { ServerSocketChannel ch = (ServerSocketChannel) key.channel(); SocketChannel s; try { while ((s = ch.accept()) != null) { long t0 = evtAccepts.time(); s.configureBlocking(false); NetCtx atta = ctxFactory.create(s, null,this); s.register(selector, OP_READ, atta); log.traceNio(key, "accept()", "AFTER"); if (sslContext != null) { TlsContext tctx = new TlsContext(); tctx.setSslEngine(sslContext.createSSLEngine()); tctx.getSslEngine().setUseClientMode(false); tctx.getSslEngine().beginHandshake(); tctx.setSslState(HANDSHAKE); atta.setTlsContext(tctx); log.traceNio(key, "accept()", "SSL"); } evtAccepts.call(t0); } } catch (Exception e) { // eg: too many open files. do not quit log.error("accept incoming request", e); evtAccepts.error(); } }
private void saveNetBuf(TlsContext tctx) { int rem = tctx.getSslNetBuf().remaining(); byte[] b = new byte[rem]; tctx.getSslNetBuf().get(b); tctx.setSslReadChunk(b); if (rem == tctx.getSslNetBuf().capacity()) { // Did not consume anything; extend buffer by 1kB tctx.setSslNetBuf(ByteBuffer.allocate(tctx.getSslNetBuf().capacity() + 1024)); } }
if (tctx.getSslNetBuf() == null) { tctx.setSslNetBuf(ByteBuffer.allocate(tctx.getSslEngine().getSession().getPacketBufferSize())); tctx.getSslNetBuf().clear(); // clear for read if (tctx.getSslReadChunk() != null) { tctx.getSslNetBuf().put(tctx.getSslReadChunk()); tctx.setSslReadChunk(null); int read = ch.read(tctx.getSslNetBuf()); if (read > 0) { tctx.getSslNetBuf().flip(); while (tctx.getSslNetBuf().hasRemaining()) { buffer.clear(); log.traceNio(key, "sslDataRead()->unwrap()", "BEFORE"); SSLEngineResult result = tctx.getSslEngine().unwrap(tctx.getSslNetBuf(), buffer); log.traceNio(key, "sslDataRead()->unwrap()", result.getStatus().toString()); switch (result.getStatus()) { log.error("at sslDataRead: BUFFER_OVERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); return; case BUFFER_UNDERFLOW: case CLOSED: clientClose(key); tctx.setSslState(CLOSED); break; default:
SocketChannel ch = (SocketChannel) key.channel(); TlsContext tctx = atta.getTlsContext(); SSLEngine engine = tctx.getSslEngine(); SSLEngineResult.HandshakeStatus handshakeStatus; SSLEngineResult result; if (tctx.getSslAppBuf() == null) { tctx.setSslAppBuf(ByteBuffer.allocate(engine.getSession().getApplicationBufferSize())); tctx.getSslAppBuf().clear(); if (tctx.getSslNetBuf() == null) { tctx.setSslNetBuf(ByteBuffer.allocate(engine.getSession().getPacketBufferSize())); tctx.getSslNetBuf().clear(); case NEED_UNWRAP: try { int rb = ch.read(tctx.getSslNetBuf()); if (rb < 0) { forceClose(key, atta, tctx, engine); return; tctx.getSslNetBuf().flip(); try { log.traceNio(key, "sslHandshake()->unwrap()", "BEFORE"); result = engine.unwrap(tctx.getSslNetBuf(), tctx.getSslAppBuf()); log.traceNio(key, "sslHandshake()->unwrap()", "AFTER"); tctx.getSslNetBuf().compact(); handshakeStatus = result.getHandshakeStatus(); } catch (SSLException e) {
public void traceNio(SelectionKey key, String tag, String action) { if (isTraceEnabled()) { NetCtx atta = (NetCtx)key.attachment(); if (atta != null) { TlsContext tctx = atta.getTlsContext(); if (tctx != null) { trace(keyToString(key) + " " + tag + " " + action + ", state=" + tctx.getSslState() + ", netBuf=" + tctx.getSslNetBuf() + ", appBuf=" + tctx.getSslAppBuf()); } else { trace(keyToString(key) + " " + tag + " " + action + ", (no attachment)"); } } else { trace(keyToString(key) + " " + tag + " " + action + ", (no attachment)"); } } } }
ByteBuffer sslWrite = ByteBuffer.allocate(16384 + 4096); sslWrite.clear(); SSLEngineResult result = tctx.getSslEngine().wrap(ibufs, sslWrite); log.error("at sslEncode(), BUFFER_OVERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); break; case BUFFER_UNDERFLOW: log.error("at sslEncode(), BUFFER_UNDERFLOW should not happen"); clientClose(key); tctx.setSslState(ERROR); break; case CLOSED: clientClose(key); tctx.setSslState(CLOSED); break; default: log.error("at sslEncode(), illegal status:" + result.getStatus()); clientClose(key); tctx.setSslState(ERROR); break; log.error("at sslEncode()", e); clientClose(key); tctx.setSslState(ERROR);
if (tctx != null && tctx.getSslState() == DATA) { LinkedList<ByteBuffer> sbufs = sslEncode(key, bufs); atta.addWrites(sbufs);
doRead(key); } else { switch (tctx.getSslState()) { case HANDSHAKE: sslHandshake(key); doWrite(key); } else { switch (tctx.getSslState()) { case HANDSHAKE: sslHandshake(key);