NatCheckerServerpublic class NatCheckerServer extends AEThread
Fields Summary |
---|
private static final LogIDs | LOGID | private static final String | incoming_handshake | private final InetAddress | bind_ip | private boolean | bind_ip_set | private final String | check | private final boolean | http_test | private ServerSocket | server | private volatile boolean | bContinue | private final boolean | use_incoming_router | private NetworkManager.ByteMatcher | matcher |
Constructors Summary |
---|
public NatCheckerServer(InetAddress _bind_ip, int _port, String _check, boolean _http_test)
super("Nat Checker Server");
bind_ip = _bind_ip;
check = _check;
http_test = _http_test;
if ( http_test ){
HTTPNetworkManager net_man = HTTPNetworkManager.getSingleton();
if ( net_man.isHTTPListenerEnabled()){
use_incoming_router = _port == net_man.getHTTPListeningPortNumber();
}else{
use_incoming_router = false;
}
if ( use_incoming_router ){
if ( !net_man.isEffectiveBindAddress( bind_ip )){
net_man.setExplicitBindAddress( bind_ip );
bind_ip_set = true;
}
}
}else{
TCPNetworkManager net_man = TCPNetworkManager.getSingleton();
if ( net_man.isTCPListenerEnabled()){
use_incoming_router = _port == net_man.getTCPListeningPortNumber();
}else{
use_incoming_router = false;
}
if ( use_incoming_router ) {
if ( !net_man.isEffectiveBindAddress( bind_ip )){
net_man.setExplicitBindAddress( bind_ip );
bind_ip_set = true;
}
//test port and currently-configured listening port are the same,
//so register for incoming connection routing
matcher = new NetworkManager.ByteMatcher() {
public int matchThisSizeOrBigger(){ return( maxSize()); }
public int maxSize() { return incoming_handshake.getBytes().length; }
public int minSize(){ return maxSize(); }
public Object matches( TransportHelper transport, ByteBuffer to_compare, int port ) {
int old_limit = to_compare.limit();
to_compare.limit( to_compare.position() + maxSize() );
boolean matches = to_compare.equals( ByteBuffer.wrap( incoming_handshake.getBytes() ) );
to_compare.limit( old_limit ); //restore buffer structure
return matches?"":null;
}
public Object minMatches( TransportHelper transport, ByteBuffer to_compare, int port ) { return( matches( transport, to_compare, port )); }
public byte[][] getSharedSecrets(){ return( null ); }
public int getSpecificPort(){return( -1 );
}
};
NetworkManager.getSingleton().requestIncomingConnectionRouting(
matcher,
new NetworkManager.RoutingListener() {
public void
connectionRouted(
NetworkConnection connection,
Object routing_data )
{
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "Incoming connection from ["
+ connection + "] successfully routed to NAT CHECKER"));
try{
ByteBuffer msg = getMessage();
Transport transport = connection.getTransport();
long start = SystemTime.getCurrentTime();
while( msg.hasRemaining()){
transport.write( new ByteBuffer[]{ msg }, 0, 1 );
if ( msg.hasRemaining()){
long now = SystemTime.getCurrentTime();
if ( now < start ){
start = now;
}else{
if ( now - start > 30000 ){
throw( new Exception( "Timeout" ));
}
}
Thread.sleep( 50 );
}
}
}catch( Throwable t ) {
Debug.out( "Nat check write failed", t );
}
connection.close();
}
public boolean
autoCryptoFallback()
{
return( true );
}
},
new MessageStreamFactory() {
public MessageStreamEncoder createEncoder() { return new AZMessageEncoder(false); /* unused */}
public MessageStreamDecoder createDecoder() { return new AZMessageDecoder(); /* unused */}
});
}
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, "NAT tester using central routing for "
+ "server socket"));
}
if ( !use_incoming_router ){
//different port than already listening on, start new listen server
try{
server = new ServerSocket(); //unbound
server.setReuseAddress( true ); //set SO_REUSEADDR
InetSocketAddress address;
if( bind_ip != null ) {
address = new InetSocketAddress( bind_ip, _port );
}else {
address = new InetSocketAddress( _port );
}
server.bind( address );
if (Logger.isEnabled()) Logger.log(new LogEvent(LOGID, "NAT tester server socket bound to " +address ));
}catch(Exception e) {
Logger.log(new LogEvent(LOGID, "NAT tester failed to setup listener socket", e ));
throw( e );
}
}
|
Methods Summary |
---|
protected java.nio.ByteBuffer | getMessage()
Map map = new HashMap();
map.put( "check", check );
byte[] map_bytes = BEncoder.encode( map );
ByteBuffer msg = ByteBuffer.allocate( 4 + map_bytes.length );
msg.putInt( map_bytes.length );
msg.put( map_bytes );
msg.flip();
return( msg );
| public void | runSupport()
while(bContinue) {
try {
if (use_incoming_router) {
//just NOOP loop sleep while waiting for routing
Thread.sleep(20);
}
else {
//listen for accept
Socket sck = server.accept();
sck.getOutputStream().write( getMessage().array());
sck.close();
}
} catch(Exception e) {
//Debug.printStackTrace(e);
bContinue = false;
}
}
| public void | stopIt()
bContinue = false;
if( use_incoming_router ) {
if ( http_test ){
if ( bind_ip_set ){
HTTPNetworkManager.getSingleton().clearExplicitBindAddress();
}
}else{
NetworkManager.getSingleton().cancelIncomingConnectionRouting( matcher );
if ( bind_ip_set ){
TCPNetworkManager.getSingleton().clearExplicitBindAddress();
}
}
}
else if( server != null ) {
try {
server.close();
}
catch(Throwable t) { t.printStackTrace(); }
}
|
|