📄 dhttransportudpimpl.java
字号:
log.log( " External IP address obtained from test data: " + new_external_address );
}
if ( ip_override != null ){
new_external_address = ip_override;
log.log( " External IP address explicitly overridden: " + new_external_address );
}
if ( new_external_address == null ){
// First attempt is via other contacts we know about. Select three
List contacts;
try{
this_mon.enter();
contacts = new ArrayList( contact_history.values());
}finally{
this_mon.exit();
}
// randomly select a number of entries to ping until we
// get three replies
String returned_address = null;
int returned_matches = 0;
int search_lim = Math.min( CONTACT_HISTORY_PING_SIZE, contacts.size());
log.log( " Contacts to search = " + search_lim );
for (int i=0;i<search_lim;i++){
DHTTransportUDPContactImpl contact = (DHTTransportUDPContactImpl)contacts.remove((int)(contacts.size()*Math.random()));
InetSocketAddress a = askContactForExternalAddress( contact );
if ( a != null && a.getAddress() != null ){
String ip = a.getAddress().getHostAddress();
if ( returned_address == null ){
returned_address = ip;
log.log( " : contact " + contact.getString() + " reported external address as '" + ip + "'" );
returned_matches++;
}else if ( returned_address.equals( ip )){
returned_matches++;
log.log( " : contact " + contact.getString() + " also reported external address as '" + ip + "'" );
if ( returned_matches == 3 ){
new_external_address = returned_address;
log.log( " External IP address obtained from contacts: " + returned_address );
break;
}
}else{
log.log( " : contact " + contact.getString() + " reported external address as '" + ip + "', abandoning due to mismatch" );
// mismatch - give up
break;
}
}else{
log.log( " : contact " + contact.getString() + " didn't reply" );
}
}
}
if ( new_external_address == null ){
InetAddress public_address = logger.getPluginInterface().getUtilities().getPublicAddress();
if ( public_address != null ){
new_external_address = public_address.getHostAddress();
log.log( " External IP address obtained: " + new_external_address );
}
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
if ( new_external_address == null ){
new_external_address = default_address;
log.log( " External IP address defaulted: " + new_external_address );
}
if ( external_address == null || !external_address.equals( new_external_address )){
informLocalAddress( new_external_address );
}
external_address = new_external_address;
}finally{
class_mon.exit();
}
}
protected void
informLocalAddress(
String address )
{
for (int i=0;i<listeners.size();i++){
try{
((DHTTransportListener)listeners.get(i)).currentAddress( address );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
protected void
externalAddressChange(
DHTTransportUDPContactImpl reporter,
InetSocketAddress new_address )
throws DHTTransportException
{
/*
* A node has reported that our external address and the one he's seen a
* message coming from differ. Natural explanations are along the lines of
* 1) my address is dynamically allocated by my ISP and it has changed
* 2) I have multiple network interfaces
* 3) there's some kind of proxy going on
* 4) this is a DOS attempting to stuff me up
*
* We assume that our address won't change more frequently than once every
* 5 minutes
* We assume that if we can successfully obtain an external address by
* using the above explicit check then this is accurate
* Only in the case where the above check fails do we believe the address
* that we've been told about
*/
InetAddress ia = new_address.getAddress();
if ( ia == null ){
Debug.out( "reported new external address '" + new_address + "' is unresolved" );
throw( new DHTTransportException( "Address '" + new_address + "' is unresolved" ));
}
final String new_ip = ia.getHostAddress();
if ( new_ip.equals( external_address )){
// probably just be a second notification of an address change, return
// "ok to retry" as it should now work
return;
}
try{
this_mon.enter();
long now = SystemTime.getCurrentTime();
if ( now - last_address_change < 5*60*1000 ){
return;
}
logger.log( "Node " + reporter.getString() + " has reported that the external IP address is '" + new_address + "'" );
// check for dodgy addresses that shouldn't appear as an external address!
if ( invalidExternalAddress( ia )){
logger.log( " This is invalid as it is a private address." );
return;
}
// another situation to ignore is where the reported address is the same as
// the reporter (they must be seeing it via, say, socks connection on a local
// interface
if ( reporter.getExternalAddress().getAddress().getHostAddress().equals( new_ip )){
logger.log( " This is invalid as it is the same as the reporter's address." );
return;
}
last_address_change = now;
}finally{
this_mon.exit();
}
final String old_external_address = external_address;
// we need to perform this test on a separate thread otherwise we'll block in the UDP handling
// code because we're already running on the "process" callback from the UDP handler
// (the test attempts to ping contacts)
new AEThread( "DHTTransportUDP:getAddress", true )
{
public void
runSupport()
{
getExternalAddress( new_ip, logger );
if ( old_external_address.equals( external_address )){
// address hasn't changed, notifier must be perceiving different address
// due to proxy or something
return;
}
setLocalContact();
}
}.start();
}
protected void
contactAlive(
DHTTransportUDPContactImpl contact )
{
try{
this_mon.enter();
contact_history.put( contact.getTransportAddress(), contact );
}finally{
this_mon.exit();
}
}
public DHTTransportContact[]
getReachableContacts()
{
try{
this_mon.enter();
Collection vals = routable_contact_history.values();
DHTTransportContact[] res = new DHTTransportContact[vals.size()];
vals.toArray( res );
return( res );
}finally{
this_mon.exit();
}
}
protected void
updateContactStatus(
DHTTransportUDPContactImpl contact,
int status )
{
try{
this_mon.enter();
contact.setNodeStatus( status );
if ( contact.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_XFER_STATUS ){
if ( status != DHTTransportUDPContactImpl.NODE_STATUS_UNKNOWN ){
boolean other_routable = (status & DHTTransportUDPContactImpl.NODE_STATUS_ROUTABLE) != 0;
if ( other_routable ){
other_routable_total++;
routable_contact_history.put( contact.getTransportAddress(), contact );
}else{
other_non_routable_total++;
}
}
}
}finally{
this_mon.exit();
}
}
protected boolean
invalidExternalAddress(
InetAddress ia )
{
return( ia.isLinkLocalAddress() ||
ia.isLoopbackAddress() ||
ia.isSiteLocalAddress());
}
protected int
getMaxFailForLiveCount()
{
return( max_fails_for_live );
}
protected int
getMaxFailForUnknownCount()
{
return( max_fails_for_unknown );
}
public DHTTransportContact
getLocalContact()
{
return( local_contact );
}
protected void
setLocalContact()
{
InetSocketAddress s_address = new InetSocketAddress( external_address, port );
try{
local_contact = new DHTTransportUDPContactImpl( true, DHTTransportUDPImpl.this, s_address, s_address, protocol_version, random.nextInt(), 0);
logger.log( "External address changed: " + s_address );
for (int i=0;i<listeners.size();i++){
try{
((DHTTransportListener)listeners.get(i)).localContactChanged( local_contact );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
public DHTTransportContact
importContact(
DataInputStream is )
throws IOException, DHTTransportException
{
DHTTransportUDPContactImpl contact = DHTUDPUtils.deserialiseContact( this, is );
importContact( contact );
return( contact );
}
public DHTTransportUDPContact
importContact(
InetSocketAddress _address,
byte _protocol_version )
throws DHTTransportException
{
// instance id of 0 means "unknown"
DHTTransportUDPContactImpl contact = new DHTTransportUDPContactImpl( false, this, _address, _address, _protocol_version, 0, 0 );
importContact( contact );
return( contact );
}
protected void
importContact(
DHTTransportUDPContactImpl contact )
{
try{
this_mon.enter();
// consider newly imported contacts as potential contacts for IP address queries if we've
// got space (in particular, at start of day we may be able to get an address off these if
// they're still alive )
if ( contact_history.size() < CONTACT_HISTORY_MAX ){
contact_history.put( contact.getTransportAddress(), contact );
}
}finally{
this_mon.exit();
}
request_handler.contactImported( contact );
// logger.log( "Imported contact " + contact.getString());
}
public void
exportContact(
DHTTransportContact contact,
DataOutputStream os )
throws IOException, DHTTransportException
{
DHTUDPUtils.serialiseContact( os, contact );
}
public void
removeContact(
DHTTransportContact contact )
{
request_handler.contactRemoved( contact );
}
public void
setRequestHandler(
DHTTransportRequestHandler _request_handler )
{
request_handler = new DHTTransportRequestCounter( _request_handler, stats );
}
public DHTTransportStats
getStats()
{
return( stats );
}
//protected HashMap port_map = new HashMap();
//protected long last_portmap_dump = SystemTime.getCurrentTime();
protected void
checkAddress(
DHTTransportUDPContactImpl contact )
throws DHTUDPPacketHandlerException
{
/*
int port = contact.getExternalAddress().getPort();
try{
this_mon.enter();
int count;
Integer i = (Integer)port_map.get(new Integer(port));
if ( i != null ){
count = i.intValue() + 1;
}else{
count = 1;
}
port_map.put( new Integer(port), new Integer(count));
long now = SystemTime.getCurrentTime();
if ( now - last_portmap_dump > 60000 ){
last_portmap_dump = now;
Iterator it = port_map.keySet().iterator();
Map rev = new TreeMap();
while( it.hasNext()){
Integer key = (Integer)it.next();
Integer val = (Integer)port_map.get(key);
rev.put( val, key );
}
it = rev.keySet().iterator();
while( it.hasNext()){
Integer val = (Integer)it.next();
Integer key = (Integer)rev.get(val);
System.out.println( "port:" + key + "->" + val );
}
}
}finally{
this_mon.exit();
}
*/
if ( ip_filter.isEnabled()){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -