package com.sissi.server.tls.impl;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.ssl.SslHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.SSLEngine;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.sissi.commons.Trace;
import com.sissi.server.tls.SSLContextBuilder;
import com.sissi.server.tls.StartTls;
/**
* 固定Domain的StartTls
*
* @author kim 2013年12月17日
*/
public class FixDomainStartTls implements StartTls, GenericFutureListener<Future<Void>> {
private final static Log log = LogFactory.getLog(FixDomainStartTls.class);
private final AtomicBoolean prepareTls = new AtomicBoolean();
private final AtomicBoolean isTls = new AtomicBoolean();
private final SSLContextBuilder sslContextBuilder;
private final ChannelHandlerContext context;
private SslHandler handler;
public FixDomainStartTls(SSLContextBuilder sslContextBuilder, ChannelHandlerContext context) {
super();
this.context = context;
this.sslContextBuilder = sslContextBuilder;
}
public void operationComplete(Future<Void> future) throws Exception {
if (future.isSuccess() && this.prepareTls.get()) {
this.context.pipeline().addFirst(this.handler);
this.prepareTls.compareAndSet(true, false);
}
}
@Override
public boolean startTls(String domain) {
try {
if (this.isTls.compareAndSet(false, true)) {
SSLEngine engine = this.sslContextBuilder.build().createSSLEngine();
engine.setNeedClientAuth(false);
engine.setUseClientMode(false);
this.handler = new SslHandler(engine);
this.prepareTls.compareAndSet(false, true);
}
return true;
} catch (Exception e) {
log.error(e.toString());
Trace.trace(log, e);
return this.rollbackSSL();
}
}
public boolean isTls(String domain) {
return this.isTls.get();
}
private boolean rollbackSSL() {
this.isTls.set(false);
this.prepareTls.set(false);
return false;
}
}