Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gov.nist.javax.sip.stack.NioTlsWebSocketMessageChannel Maven / Gradle / Ivy
package android.gov.nist.javax.sip.stack;
import android.gov.nist.core.CommonLogger;
import android.gov.nist.core.LogLevels;
import android.gov.nist.core.LogWriter;
import android.gov.nist.core.ServerLogger;
import android.gov.nist.core.StackLogger;
import android.gov.nist.javax.sip.SipStackImpl;
import android.gov.nist.javax.sip.message.SIPMessage;
import android.gov.nist.javax.sip.message.SIPRequest;
import android.gov.nist.javax.sip.stack.SSLStateMachine.MessageSendCallback;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLContext;
import android.javax.sip.address.SipURI;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.security.cert.CertificateException;
import java.util.Timer;
import java.util.TimerTask;
public class NioTlsWebSocketMessageChannel extends NioWebSocketMessageChannel implements NioTlsChannelInterface {
private static StackLogger logger = CommonLogger
.getLogger(NioTlsWebSocketMessageChannel.class);
SSLStateMachine sslStateMachine;
private int appBufferMax;
private int netBufferMax;
public static NioTlsWebSocketMessageChannel create (SIPTransactionStack stack,
NioTlsWebSocketMessageProcessor nioTcpMessageProcessor,
SocketChannel socketChannel) throws IOException {
NioTlsWebSocketMessageChannel retval = (NioTlsWebSocketMessageChannel) channelMap.get(socketChannel);
if (retval == null ) {
retval = new NioTlsWebSocketMessageChannel(stack, nioTcpMessageProcessor,
socketChannel);
channelMap.put(socketChannel, retval);
}
return retval;
}
protected NioTlsWebSocketMessageChannel (SIPTransactionStack stack, NioTcpMessageProcessor nioTcpMessageProcessor,
SocketChannel socketChannel) throws IOException {
super (stack, nioTcpMessageProcessor, socketChannel);
messageProcessor = nioTcpMessageProcessor;
myClientInputStream = socketChannel.socket().getInputStream();
try {
this .init(false );
createBuffers();
}catch (Exception e) {
throw new IOException("Can't do TLS init" , e);
}
}
public void init (boolean clientMode) throws Exception, CertificateException, FileNotFoundException, IOException {
SSLContext ctx = clientMode ?
((NioTlsWebSocketMessageProcessor)messageProcessor).sslClientCtx:
((NioTlsWebSocketMessageProcessor)messageProcessor).sslServerCtx;
sslStateMachine = new SSLStateMachine(ctx.createSSLEngine(), this );
sslStateMachine.sslEngine.setUseClientMode(clientMode);
String auth = ((SipStackImpl)super .sipStack).
getConfigurationProperties().getProperty("android.gov.nist.javax.sip.TLS_CLIENT_AUTH_TYPE" );
sslStateMachine.sslEngine.setNeedClientAuth(false );
sslStateMachine.sslEngine.setWantClientAuth(false );
String clientProtocols = ((SipStackImpl)super .sipStack)
.getConfigurationProperties().getProperty("android.gov.nist.javax.sip.TLS_CLIENT_PROTOCOLS" );
if (clientProtocols != null ) {
sslStateMachine.sslEngine.setEnabledProtocols(clientProtocols.split("," ));
}
}
public ByteBuffer prepareEncryptedDataBuffer () {
return ByteBufferFactory.getInstance().allocateDirect(netBufferMax);
}
public ByteBuffer prepareAppDataBuffer () {
return ByteBufferFactory.getInstance().allocateDirect(appBufferMax);
}
public ByteBuffer prepareAppDataBuffer (int capacity) {
return ByteBufferFactory.getInstance().allocateDirect(capacity);
}
public static class SSLReconnectedException extends IOException {
private static final long serialVersionUID = 1L ;}
@Override
protected void sendMessage (final byte [] msg, final boolean isClient) throws IOException {
checkSocketState();
if (client && readingHttp && httpClientRequestSent.compareAndSet(false , true )) {
final String http = "null null HTTP/1.1\r\n" +
"Host: null\r\n" +
"Upgrade: websocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
"Sec-WebSocket-Protocol: sip\r\n" +
"Sec-WebSocket-Version: 13\r\n\r\n" ;
final ByteBuffer b1 = ByteBuffer.wrap(NioWebSocketMessageChannel.wrapBufferIntoWebSocketFrame(msg, client));
ByteBuffer b = ByteBuffer.wrap(http.getBytes());
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendTCPMessage(bytes,
NioTlsWebSocketMessageChannel.super .peerAddress, NioTlsWebSocketMessageChannel.super .peerPort, false );
final Boolean sent=false ;
try {
sslStateMachine.wrap(b1, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendNonWebSocketMessage(bytes, isClient);
}
});
} catch (Exception e) {
throw new IOException("Can't send message" , e);
}
}
});
} catch (IOException e) {
throw e;
}
} else {
ByteBuffer b = ByteBuffer.wrap(NioWebSocketMessageChannel.wrapBufferIntoWebSocketFrame(msg, client));
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendNonWebSocketMessage(bytes, isClient);
}
});
} catch (Exception e) {
throw new IOException("Can't send message" , e);
}
}
}
public void sendEncryptedData (byte [] msg) throws IOException {
if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
logger.logDebug("sendEncryptedData " + " this = " + this + " peerPort = " + peerPort + " addr = " + peerAddress);
}
lastActivityTimeStamp = System.currentTimeMillis();
NIOHandler nioHandler = ((NioTcpMessageProcessor) messageProcessor).nioHandler;
if (this .socketChannel != null && this .socketChannel.isConnected() && this .socketChannel.isOpen()) {
nioHandler.putSocket(NIOHandler.makeKey(this .peerAddress, this .peerPort), this .socketChannel);
}
super .sendNonWebSocketMessage(msg, false );
}
@Override
public void sendMessage (final byte message[], final InetAddress receiverAddress,
final int receiverPort, final boolean retry) throws IOException {
checkSocketState();
if (client && readingHttp && httpClientRequestSent.compareAndSet(false , true )) {
final String http = "null null HTTP/1.1\r\n" +
"Host: null\r\n" +
"Upgrade: websocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" +
"Sec-WebSocket-Protocol: sip\r\n" +
"Sec-WebSocket-Version: 13\r\n\r\n" ;
final ByteBuffer b1 = ByteBuffer.wrap(NioWebSocketMessageChannel.wrapBufferIntoWebSocketFrame(message, client));
ByteBuffer b = ByteBuffer.wrap(http.getBytes());
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendTCPMessage(bytes,
receiverAddress, receiverPort, false );
try {
sslStateMachine.wrap(b1, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendTCPMessage(bytes,
receiverAddress, receiverPort, retry);
}
});
} catch (IOException e) {
throw e;
}
}
});
} catch (IOException e) {
throw e;
}
} else {
ByteBuffer b = ByteBuffer.wrap(NioWebSocketMessageChannel.wrapBufferIntoWebSocketFrame(message, client));
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendTCPMessage(bytes,
receiverAddress, receiverPort, retry);
}
});
} catch (IOException e) {
throw e;
}
}
}
@Override
public void sendMessage (final SIPMessage sipMessage, final InetAddress receiverAddress, final int receiverPort)
throws IOException {
final byte [] msg = sipMessage.encodeAsBytes(this .getTransport());
sendMessage(msg, receiverAddress, receiverPort, this .client);
if (logger.isLoggingEnabled(ServerLogger.TRACE_MESSAGES))
logMessage(sipMessage, receiverAddress, receiverPort, System.currentTimeMillis());
}
public void sendHttpMessage (final byte message[], final InetAddress receiverAddress,
final int receiverPort, final boolean retry) throws IOException {
checkSocketState();
ByteBuffer b = ByteBuffer.wrap(message);
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendMessage(bytes,
receiverAddress, receiverPort, retry);
}
});
} catch (IOException e) {
throw e;
}
}
private void createBuffers () {
SSLSession session = sslStateMachine.sslEngine.getSession();
appBufferMax = session.getApplicationBufferSize();
netBufferMax = session.getPacketBufferSize();
if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
logger.logDebug("appBufferMax=" + appBufferMax + " netBufferMax=" + netBufferMax);
}
}
public NioTlsWebSocketMessageChannel (InetAddress inetAddress, int port,
SIPTransactionStack sipStack,
NioTcpMessageProcessor nioTcpMessageProcessor) throws IOException {
super (inetAddress, port, sipStack, nioTcpMessageProcessor);
try {
init(true );
createBuffers();
} catch (Exception e) {
throw new IOException("Can't init the TLS channel" , e);
}
}
@Override
protected void addBytes (byte [] bytes) throws Exception {
if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
logger.logDebug("Adding WSS bytes for decryption " + bytes.length);
}
if (bytes.length <= 0 ) return ;
ByteBuffer buffer = ByteBuffer.wrap(bytes);
sslStateMachine.unwrap(buffer);
}
@Override
protected void sendNonWebSocketMessage (byte [] msg, final boolean isClient) throws IOException {
if (logger.isLoggingEnabled(LogWriter.TRACE_DEBUG)) {
logger.logDebug("sendMessage isClient = " + isClient + " this = " + this );
}
lastActivityTimeStamp = System.currentTimeMillis();
NIOHandler nioHandler = ((NioTcpMessageProcessor) messageProcessor).nioHandler;
if (this .socketChannel != null && this .socketChannel.isConnected() && this .socketChannel.isOpen()) {
nioHandler.putSocket(NIOHandler.makeKey(this .peerAddress, this .peerPort), this .socketChannel);
}
checkSocketState();
ByteBuffer b = ByteBuffer.wrap(msg);
try {
sslStateMachine.wrap(b, ByteBufferFactory.getInstance().allocateDirect(netBufferMax), new MessageSendCallback() {
@Override
public void doSend (byte [] bytes) throws IOException {
NioTlsWebSocketMessageChannel.super .sendTCPMessage(bytes,
peerAddress, peerPort, isClient);
}
});
} catch (IOException e) {
throw e;
}
}
@Override
public String getTransport () {
return this .messageProcessor.transport;
}
@Override
public void onNewSocket (byte [] message) {
super .onNewSocket(message);
try {
if (logger.isLoggingEnabled(LogLevels.TRACE_DEBUG)) {
String last = null ;
if (message != null ) {
last = new String(message, "UTF-8" );
}
logger.logDebug("New socket for " + this + " last message = " + last);
}
init(true );
createBuffers();
sendMessage(message, false );
} catch (Exception e) {
logger.logError("Cant reinit" , e);
}
}
private void checkSocketState () throws IOException {
if (socketChannel != null && (!socketChannel.isConnected() || !socketChannel.isOpen())) {
if (logger.isLoggingEnabled(LogLevels.TRACE_DEBUG))
logger.logDebug("Need to reset SSL engine for socket " + socketChannel);
try {
init(sslStateMachine.sslEngine.getUseClientMode());
} catch (Exception ex) {
logger.logError("Cannot reset SSL engine" , ex);
throw new IOException(ex);
}
}
}
@Override
public boolean isSecure () {
return true ;
}
@Override
public void addPlaintextBytes (byte [] bytes) throws Exception {
super .addBytes(bytes);
}
@Override
public SipStackImpl getSIPStack () {
return (SipStackImpl) super .getSIPStack();
}
}