📄 dhtnatpuncherimpl.java
字号:
boolean ok = true;
boolean log = true;
try{
server_mon.enter();
Object[] entry = (Object[])rendezvous_bindings.get( originator.getAddress().toString());
if ( entry == null ){
if ( rendezvous_bindings.size() == RENDEZVOUS_SERVER_MAX ){
ok = false;
}
}else{
// already present, no need to log again
log = false;
}
if ( ok ){
long now = plugin_interface.getUtilities().getCurrentSystemTime();
rendezvous_bindings.put( originator.getAddress().toString(), new Object[]{ originator, new Long( now )});
}
}finally{
server_mon.exit();
}
if ( log ){
log( "Rendezvous request from " + originator.getString() + " " + (ok?"accepted":"denied" ));
}
response.put( "ok", new Long(ok?1:0));
}
protected int
sendPunch(
DHTTransportContact rendezvous,
DHTTransportContact target )
{
try{
Map request = new HashMap();
request.put("type", new Long( RT_PUNCH_REQUEST ));
request.put("target", target.getAddress().toString().getBytes());
Map response = sendRequest( rendezvous, request );
if ( response == null ){
return( RESP_FAILED );
}
if (((Long)response.get( "type" )).intValue() == RT_PUNCH_REPLY ){
int result = ((Long)response.get("ok")).intValue();
if ( TRACE ){
System.out.println( "received punch reply: " + (result==0?"failed":"ok" ));
}
if ( result == 1 ){
return( RESP_OK );
}
}
return( RESP_NOT_OK );
}catch( Throwable e ){
log(e);
return( RESP_FAILED );
}
}
protected void
receivePunch(
DHTTransportContact originator,
Map request,
Map response )
{
if ( TRACE ){
System.out.println( "received puch request" );
}
boolean ok = false;
try{
server_mon.enter();
String target_str = new String((byte[])request.get( "target" ));
Object[] entry = (Object[])rendezvous_bindings.get( target_str );
if ( entry != null ){
DHTTransportContact target = (DHTTransportContact)entry[0];
if ( sendConnect( target, originator ) == RESP_OK ){
ok = true;
}
}
log( "Rendezvous punch request from " + originator.getString() + " to " + target_str + " " + (ok?"initiated":"failed"));
}finally{
server_mon.exit();
}
response.put( "ok", new Long(ok?1:0));
}
protected int
sendConnect(
DHTTransportContact target,
DHTTransportContact originator )
{
try{
Map request = new HashMap();
request.put("type", new Long( RT_CONNECT_REQUEST ));
request.put("origin", encodeContact( originator ));
Map response = sendRequest( target, request );
if ( response == null ){
return( RESP_FAILED );
}
if (((Long)response.get( "type" )).intValue() == RT_CONNECT_REPLY ){
int result = ((Long)response.get("ok")).intValue();
if ( TRACE ){
System.out.println( "received connect reply: " + (result==0?"failed":"ok" ));
}
if ( result == 1 ){
return( RESP_OK );
}
}
return( RESP_NOT_OK );
}catch( Throwable e ){
log(e);
return( RESP_FAILED );
}
}
protected void
receiveConnect(
DHTTransportContact rendezvous,
Map request,
Map response )
{
if ( TRACE ){
System.out.println( "received connect request" );
}
boolean ok = false;
// ensure that we've received this from our current rendezvous node
DHTTransportContact rt = rendezvous_target;
if ( rt != null && rt.getAddress().equals( rendezvous.getAddress())){
final DHTTransportContact target = decodeContact( (byte[])request.get( "origin" ));
if ( target != null ){
// ping the origin a few times to try and establish a tunnel
final int[] pings = {1};
timer.addPeriodicEvent(
3000,
new UTTimerEventPerformer()
{
public void
perform(
UTTimerEvent event )
{
try{
pub_mon.enter();
if ( pings[0] > 3 ){
event.cancel();
return;
}else{
pings[0]++;
}
}finally{
pub_mon.exit();
}
target.sendPing(
new DHTTransportReplyHandlerAdapter()
{
public void
pingReply(
DHTTransportContact ok_contact )
{
if ( TRACE ){
System.out.println( "tunnel ping ok" );
}
}
public void
failed(
DHTTransportContact failed_contact,
Throwable e )
{
}
});
}
});
target.sendPing(
new DHTTransportReplyHandlerAdapter()
{
public void
pingReply(
DHTTransportContact ok_contact )
{
try{
pub_mon.enter();
pings[0] = 100; // stop periodic above
if ( TRACE ){
System.out.println( "tunnel ping ok" );
}
}finally{
pub_mon.exit();
}
}
public void
failed(
DHTTransportContact failed_contact,
Throwable e )
{
}
});
ok = true;
}
}
response.put( "ok", new Long(ok?1:0));
}
public boolean
punch(
DHTTransportContact target )
{
try{
DHTTransportContact rendezvous = getRendezvous( target );
if ( rendezvous == null ){
return( false );
}
if ( sendPunch( rendezvous, target ) == RESP_OK ){
log( " punch to " + target.getString() + " succeeded" );
return( true );
}
}catch( Throwable e ){
log( e );
}
log( " punch to " + target.getString() + " failed" );
return( false );
}
public void
setRendezvous(
DHTTransportContact target,
DHTTransportContact rendezvous )
{
explicit_rendezvous_map.put( target.getAddress(), rendezvous );
if ( target.getAddress().equals( dht.getTransport().getLocalContact().getAddress())){
publish( true );
}
}
protected DHTTransportContact
getRendezvous(
DHTTransportContact target )
{
DHTTransportContact explicit = (DHTTransportContact)explicit_rendezvous_map.get( target.getAddress());
if ( explicit != null ){
return( explicit );
}
byte[] key = getPublishKey( target );
final DHTTransportValue[] result_value = {null};
final Semaphore sem = plugin_interface.getUtilities().getSemaphore();
dht.get( key,
"DHTNatPuncher: lookup for '" + target.getString() + "'",
(byte)0,
1,
RENDEZVOUS_LOOKUP_TIMEOUT,
false,
new DHTOperationAdapter()
{
public void
read(
DHTTransportContact contact,
DHTTransportValue value )
{
result_value[0] = value;
sem.release();
}
public void
complete(
boolean timeout )
{
sem.release();
}
});
sem.reserve();
DHTTransportContact result = null;
if ( result_value[0] != null ){
byte[] bytes = result_value[0].getValue();
try{
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
DataInputStream dis = new DataInputStream( bais );
byte version = dis.readByte();
if ( version != 0 ){
throw( new Exception( "Unsupported rendezvous version '" + version + "'" ));
}
result = dht.getTransport().importContact( dis );
}catch( Throwable e ){
log(e);
}
}
log( "Lookup of rendezvous for " + target.getString() + " -> " + ( result==null?"None":result.getString()));
return( result );
}
protected byte[]
getPublishKey(
DHTTransportContact contact )
{
byte[] id = contact.getID();
byte[] suffix = ":DHTNATPuncher".getBytes();
byte[] res = new byte[id.length + suffix.length];
System.arraycopy( id, 0, res, 0, id.length );
System.arraycopy( suffix, 0, res, id.length, suffix.length );
return( res );
}
protected byte[]
encodePublishValue(
DHTTransportContact contact )
{
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeByte( 0 ); // version
contact.exportContact( dos );
dos.close();
return( baos.toByteArray());
}catch( Throwable e ){
log( e );
return( new byte[0]);
}
}
protected byte[]
encodeContact(
DHTTransportContact contact )
{
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
contact.exportContact( dos );
dos.close();
return( baos.toByteArray());
}catch( Throwable e ){
log( e );
return( null );
}
}
protected DHTTransportContact
decodeContact(
byte[] bytes )
{
try{
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
DataInputStream dis = new DataInputStream( bais );
return( dht.getTransport().importContact( dis ));
}catch( Throwable e ){
log(e);
return( null );
}
}
protected void
log(
String str )
{
logger.log( "NATPuncher: " + str );
}
protected void
log(
Throwable e )
{
logger.log( "NATPuncher: error occurred" );
logger.log(e);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -