package org.playorm.nio.impl.cm.secure;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Logger;
import org.playorm.nio.api.channels.Channel;
import org.playorm.nio.api.handlers.ConnectionListener;
import org.playorm.nio.api.handlers.DataListener;
import org.playorm.nio.api.handlers.NullWriteCallback;
import org.playorm.nio.api.handlers.OperationCallback;
import org.playorm.nio.api.libs.SSLListener;
import org.playorm.nio.impl.util.DataChunkWithBuffer;
import org.playorm.nio.impl.util.PacketChunk;
class SecSSLListener implements SSLListener {
private static final Logger log = Logger.getLogger(SecSSLListener.class.getName());
private SecTCPChannel channel;
private ConnectionListener cb;
private DataListener client;
private boolean isConnected = false;
public SecSSLListener(SecTCPChannel impl) {
this.channel = impl;
}
public void encryptedLinkEstablished() throws IOException {
try {
channel.resetRegisterForReadState();
} catch (InterruptedException e) {
throw new RuntimeException(channel+"Exception occured", e);
}
cb.connected(channel);
isConnected = true;
}
public void packetEncrypted(ByteBuffer toSocket, Object passThrough) throws IOException {
OperationCallback h;
if(passThrough == null){
h = NullWriteCallback.singleton();
} else {
SecProxyWriteHandler handler = (SecProxyWriteHandler)passThrough;
h = handler;
}
channel.getRealChannel().oldWrite(toSocket, h);
}
public void packetUnencrypted(ByteBuffer out, Object passThrough) throws IOException {
DataChunkWithBuffer c = (DataChunkWithBuffer) passThrough;
PacketChunk packet = new PacketChunk(out, c);
client.incomingData(channel, packet);
}
public void setClientHandler(DataListener client) {
this.client = client;
}
public boolean isClientRegistered() {
return client != null;
}
public void setConnectCallback(ConnectionListener cb) {
this.cb = cb;
}
public void farEndClosed() {
if(client != null) //if the client did not register for reads, we can't fire to anyone(thought that would be mighty odd)
client.farEndClosed(channel);
else if(!isConnected) {
log.info("The far end connected and did NOT establish security session and then closed his socket. " +
"This is normal behavior if a telnet socket connects to your secure socket and exits " +
"because the socket was never officially 'connected' as we only fire " +
"connected AFTER the SSL handshake is done. You may want to check if" +
" someone is trying to hack your server though");
} else
log.warning("When we called ConnectionListener.connected on YOUR ConnectionListener, " +
"you forot to call registerForReads so we have not callback handler to call " +
"to tell you this socket is closed from far end");
}
public void runTask(Runnable r) {
r.run();
}
public void closed(boolean clientInitiated) {
// if(fromEncryptedPacket && !closedAlready)
// client.farEndClosed(channel);
//can just drop this...we are using close, not initiateClose
//which is effective immediately.
}
public void feedProblemThrough(Channel c, ByteBuffer b, Exception e) throws IOException {
client.failure(c, b, e);
}
}