use of com.biglybt.core.dht.DHTOperationAdapter in project BiglyBT by BiglySoftware.
the class DHTNATPuncherImpl method getRendezvous.
protected DHTTransportContact getRendezvous(String reason, DHTTransportContact target) {
DHTTransportContact explicit = (DHTTransportContact) explicit_rendezvous_map.get(target.getAddress());
if (explicit != null) {
return (explicit);
}
String target_key = target.getAddress().toString();
DHTTransportValue[] result_value = null;
AESemaphore sem = null;
long now = SystemTime.getMonotonousTime();
synchronized (rendezvous_lookup_cache) {
if (rendezvous_lookup_cache_tidy_time == -1) {
rendezvous_lookup_cache_tidy_time = now;
} else if (now - rendezvous_lookup_cache_tidy_time >= 2 * 60 * 1000) {
rendezvous_lookup_cache_tidy_time = now;
Iterator<Object[]> it = rendezvous_lookup_cache.values().iterator();
while (it.hasNext()) {
Object[] entry = it.next();
long time = (Long) entry[0];
if (time != -1 && now - time > 2 * 60 * 1000) {
it.remove();
}
}
}
Object[] existing = rendezvous_lookup_cache.get(target_key);
boolean do_lookup;
if (existing != null) {
long time = (Long) existing[0];
if (time == -1 || now - time < 2 * 60 * 1000) {
sem = (AESemaphore) existing[1];
result_value = (DHTTransportValue[]) existing[2];
do_lookup = false;
} else {
do_lookup = true;
}
} else {
do_lookup = true;
}
if (do_lookup) {
result_value = new DHTTransportValue[1];
sem = new AESemaphore("getRend");
final Object[] entry = new Object[] { -1L, sem, result_value };
byte[] key = getPublishKey(target);
dht.get(key, reason + ": lookup for '" + target.getString() + "'", (byte) 0, 1, RENDEZVOUS_LOOKUP_TIMEOUT, false, true, new DHTOperationAdapter() {
@Override
public void read(DHTTransportContact contact, DHTTransportValue value) {
synchronized (rendezvous_lookup_cache) {
entry[0] = SystemTime.getMonotonousTime();
((DHTTransportValue[]) entry[2])[0] = value;
((AESemaphore) entry[1]).releaseForever();
}
}
@Override
public void complete(boolean timeout) {
synchronized (rendezvous_lookup_cache) {
AESemaphore sem = (AESemaphore) entry[1];
if (!sem.isReleasedForever()) {
entry[0] = SystemTime.getMonotonousTime();
sem.releaseForever();
}
}
}
});
rendezvous_lookup_cache.put(target_key, entry);
}
}
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, false);
} catch (Throwable e) {
log(e);
}
}
log("Lookup of rendezvous for " + target.getString() + " -> " + (result == null ? "None" : result.getString()));
return (result);
}
use of com.biglybt.core.dht.DHTOperationAdapter in project BiglyBT by BiglySoftware.
the class DHTNATPuncherImpl method destroy.
@Override
public void destroy() {
try {
server_mon.enter();
Iterator<BindingData> it = rendezvous_bindings.values().iterator();
while (it.hasNext()) {
BindingData entry = it.next();
final DHTTransportUDPContact contact = entry.getContact();
new AEThread2("DHTNATPuncher:destroy", true) {
@Override
public void run() {
sendClose(contact);
}
}.start();
}
byte[] lpk = last_publish_key;
List<DHTTransportContact> lws = last_write_set;
if (lpk != null && lws != null) {
log("Removing publish on closedown");
DHTTransportContact[] contacts = lws.toArray(new DHTTransportContact[lws.size()]);
dht.remove(contacts, lpk, "NAT Puncher destroy", new DHTOperationAdapter());
}
} catch (Throwable e) {
log(e);
} finally {
server_mon.exit();
}
}
Aggregations