private void updateStats(int record_type) { long current_d_received = gm_stats.getTotalDataBytesReceived(); long current_p_received = gm_stats.getTotalProtocolBytesReceived(); long current_d_sent = gm_stats.getTotalDataBytesSent(); long current_p_sent = gm_stats.getTotalProtocolBytesSent(); long current_dht_sent = 0; long current_dht_received = 0; DHT[] dhts = getDHTs(); if (dhts != null) { for (DHT dht : dhts) { DHTTransportStats dht_stats = dht.getTransport().getStats(); current_dht_sent += dht_stats.getBytesSent(); current_dht_received += dht_stats.getBytesReceived(); } } write( record_type, new long[] { (current_p_sent - ss_p_sent), (current_d_sent - ss_d_sent), (current_p_received - ss_p_received), (current_d_received - ss_d_received), (current_dht_sent - ss_dht_sent), (current_dht_received - ss_dht_received) }); }
public DHTNATPuncherImpl(DHTNATPuncherAdapter _adapter, DHT _dht) { adapter = _adapter; dht = _dht; logger = dht.getLogger(); plugin_interface = dht.getLogger().getPluginInterface(); formatters = plugin_interface.getUtilities().getFormatters(); pub_mon = plugin_interface.getUtilities().getMonitor(); server_mon = plugin_interface.getUtilities().getMonitor(); punch_mon = plugin_interface.getUtilities().getMonitor(); timer = plugin_interface.getUtilities().createTimer("DHTNATPuncher:refresher", true); }
public DHTSpeedTesterImpl(DHT _dht) { dht = _dht; plugin_interface = dht.getLogger().getPluginInterface(); UTTimer timer = plugin_interface.getUtilities().createTimer("DHTSpeedTester:finder", true); timer.addPeriodicEvent( 5000, new UTTimerEventPerformer() { public void perform(UTTimerEvent event) { findContacts(); } }); timer.addPeriodicEvent( 1000, new UTTimerEventPerformer() { int tick_count; public void perform(UTTimerEvent event) { try { pingContacts(tick_count); } finally { tick_count++; } } }); }
protected boolean sendTunnelMessage(DHTTransportContact target, byte[] data) { try { dht.getTransport() .writeTransfer( new DHTTransportProgressListener() { public void reportSize(long size) {} public void reportActivity(String str) {} public void reportCompleteness(int percent) {} }, target, transfer_handler_key, new byte[0], data, TUNNEL_TIMEOUT); return (true); } catch (DHTTransportException e) { // log(e); timeout most likely 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 void findContacts() { DHTTransportContact[] reachables = dht.getTransport().getReachableContacts(); for (int i = 0; i < reachables.length; i++) { DHTTransportContact contact = reachables[i]; byte[] address = contact.getAddress().getAddress().getAddress(); if (tried_bloom == null || tried_bloom.getEntryCount() > 500) { tried_bloom = BloomFilterFactory.createAddOnly(4096); } if (!tried_bloom.contains(address)) { tried_bloom.add(address); synchronized (pending_contacts) { potentialPing ping = new potentialPing( contact, DHTNetworkPositionManager.estimateRTT( contact.getNetworkPositions(), dht.getTransport().getLocalContact().getNetworkPositions())); pending_contacts.add(0, ping); if (pending_contacts.size() > 60) { pending_contacts.removeLast(); } } } } }
protected DHTTransportUDPContact decodeContact(byte[] bytes) { try { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); DataInputStream dis = new DataInputStream(bais); return ((DHTTransportUDPContact) dht.getTransport().importContact(dis)); } catch (Throwable e) { log(e); return (null); } }
public Map sendMessage(InetSocketAddress rendezvous, InetSocketAddress target, Map message) { try { DHTTransportUDP transport = (DHTTransportUDP) dht.getTransport(); DHTTransportUDPContact rend_contact = transport.importContact(rendezvous, transport.getProtocolVersion()); DHTTransportUDPContact target_contact = transport.importContact(target, transport.getProtocolVersion()); Map result = sendPunch(rend_contact, target_contact, message, true); return (result); } catch (Throwable e) { Debug.printStackTrace(e); return (null); } }
protected byte[] sendRequest(DHTTransportContact target, byte[] data, int timeout) { try { return (dht.getTransport() .writeReadTransfer( new DHTTransportProgressListener() { public void reportSize(long size) {} public void reportActivity(String str) {} public void reportCompleteness(int percent) {} }, target, transfer_handler_key, data, timeout)); } catch (DHTTransportException e) { // log(e); timeout most likely return (null); } }
public Map punch( String reason, InetSocketAddress[] target, DHTTransportContact[] rendezvous_used, Map originator_client_data) { try { DHTTransportUDP transport = (DHTTransportUDP) dht.getTransport(); DHTTransportUDPContact contact = transport.importContact(target[0], transport.getProtocolVersion()); Map result = punch(reason, contact, rendezvous_used, originator_client_data); target[0] = contact.getTransportAddress(); return (result); } catch (Throwable e) { Debug.printStackTrace(e); return (null); } }
private void sessionStart() { OverallStatsImpl stats = (OverallStatsImpl) StatsFactory.getStats(); synchronized (this) { if (closing) { return; } boolean enabled = COConfigurationManager.getBooleanParameter("long.term.stats.enable"); if (active || !enabled) { return; } active = true; long[] snap = stats.getLastSnapshot(); ss_d_received = gm_stats.getTotalDataBytesReceived(); ss_p_received = gm_stats.getTotalProtocolBytesReceived(); ss_d_sent = gm_stats.getTotalDataBytesSent(); ss_p_sent = gm_stats.getTotalProtocolBytesSent(); ss_dht_sent = 0; ss_dht_received = 0; if (core.isStarted()) { DHT[] dhts = getDHTs(); if (dhts != null) { for (DHT dht : dhts) { DHTTransportStats dht_stats = dht.getTransport().getStats(); ss_dht_sent += dht_stats.getBytesSent(); ss_dht_received += dht_stats.getBytesReceived(); } } } st_p_sent = snap[0] + (ss_p_sent - snap[6]); st_d_sent = snap[1] + (ss_d_sent - snap[7]); st_p_received = snap[2] + (ss_p_received - snap[8]); st_d_received = snap[3] + (ss_d_received - snap[9]); st_dht_sent = snap[4] + (ss_dht_sent - snap[10]); st_dht_received = snap[5] + (ss_dht_received - snap[11]); write( RT_SESSION_START, new long[] { st_p_sent, st_d_sent, st_p_received, st_d_received, st_dht_sent, st_dht_received }); if (event == null) { // should always be null but hey ho event = SimpleTimer.addPeriodicEvent( "LongTermStats", MIN_IN_MILLIS, new TimerEventPerformer() { public void perform(TimerEvent event) { updateStats(); } }); } } }
private void start() { synchronized (this) { if (started) { return; } started = true; } N_3072 = fromHex( "FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08" + "8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B" + "302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9" + "A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6" + "49286651 ECE45B3D C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8" + "FD24CF5F 83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" + "670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B E39E772C" + "180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9 DE2BCBF6 95581718" + "3995497C EA956AE5 15D22618 98FA0510 15728E5A 8AAAC42D AD33170D" + "04507A33 A85521AB DF1CBA64 ECFB8504 58DBEF0A 8AEA7157 5D060C7D" + "B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226" + "1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" + "BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC" + "E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"); G_3072 = BigInteger.valueOf(5); try { PluginInterface dht_pi = core.getPluginManager().getPluginInterfaceByClass(DHTPlugin.class); if (dht_pi == null) { throw (new Exception("DHT Plugin not found")); } DHTPlugin dht_plugin = (DHTPlugin) dht_pi.getPlugin(); if (!dht_plugin.isEnabled()) { throw (new Exception("DHT Plugin is disabled")); } DHT[] dhts = dht_plugin.getDHTs(); List<DHTNATPuncher> punchers = new ArrayList<DHTNATPuncher>(); for (DHT dht : dhts) { int net = dht.getTransport().getNetwork(); if (net == DHT.NW_MAIN) { DHTNATPuncher primary_puncher = dht.getNATPuncher(); if (primary_puncher != null) { punchers.add(primary_puncher); nat_punchers_ipv4.add(primary_puncher); for (int i = 1; i <= 2; i++) { DHTNATPuncher puncher = primary_puncher.getSecondaryPuncher(); punchers.add(puncher); nat_punchers_ipv4.add(puncher); } } } else if (net == DHT.NW_MAIN_V6) { /* * no point in this atm as we don't support v6 tunnels DHTNATPuncher puncher = dht.getNATPuncher(); if ( puncher != null ){ punchers.add( puncher ); nat_punchers_ipv6.add( puncher ); puncher = puncher.getSecondaryPuncher(); punchers.add( puncher ); nat_punchers_ipv6.add( puncher ); } */ } } if (punchers.size() == 0) { throw (new Exception("No suitable DHT instances available")); } for (DHTNATPuncher p : punchers) { p.forceActive(true); p.addListener( new DHTNATPuncherListener() { public void rendezvousChanged(DHTTransportContact rendezvous) { System.out.println("active: " + rendezvous.getString()); synchronized (PairingManagerTunnelHandler.this) { if (update_event == null) { update_event = SimpleTimer.addEvent( "PMT:defer", SystemTime.getOffsetTime(15 * 1000), new TimerEventPerformer() { public void perform(TimerEvent event) { synchronized (PairingManagerTunnelHandler.this) { update_event = null; } System.out.println(" updating"); manager.updateNeeded(); }; }); } } } }); } core.getNATTraverser() .registerHandler( new NATTraversalHandler() { private Map<Long, Object[]> server_map = new LinkedHashMap<Long, Object[]>(10, 0.75f, true) { protected boolean removeEldestEntry(Map.Entry<Long, Object[]> eldest) { return size() > 10; } }; public int getType() { return (NATTraverser.TRAVERSE_REASON_PAIR_TUNNEL); } public String getName() { return ("Pairing Tunnel"); } public Map process(InetSocketAddress originator, Map data) { if (SRP_VERIFIER == null || !active) { return (null); } boolean good_request = false; try { Map result = new HashMap(); Long session = (Long) data.get("sid"); if (session == null) { return (null); } InetAddress tunnel_originator; try { tunnel_originator = InetAddress.getByAddress((byte[]) data.get("origin")); } catch (Throwable e) { Debug.out("originator decode failed: " + data); return (null); } System.out.println( "PairManagerTunnelHander: incoming message - session=" + session + ", payload=" + data + " from " + tunnel_originator + " via " + originator); SRP6Server server; BigInteger B; synchronized (server_map) { Object[] entry = server_map.get(session); if (entry == null) { long diff = SystemTime.getMonotonousTime() - last_server_create_time; if (diff < 5000) { try { long sleep = 5000 - diff; System.out.println("Sleeping for " + sleep + " before starting srp"); Thread.sleep(sleep); } catch (Throwable e) { } } server = new SRP6Server(); server.init( N_3072, G_3072, SRP_VERIFIER, new SHA256Digest(), RandomUtils.SECURE_RANDOM); B = server.generateServerCredentials(); server_map.put(session, new Object[] {server, B}); last_server_create_time = SystemTime.getMonotonousTime(); total_servers++; } else { server = (SRP6Server) entry[0]; B = (BigInteger) entry[1]; } } Long op = (Long) data.get("op"); if (op == 1) { result.put("op", 2); result.put("s", SRP_SALT); result.put("b", B.toByteArray()); good_request = true; if (data.containsKey("test")) { manager.recordRequest( "SRP Test", originator.getAddress().getHostAddress(), true); } } else if (op == 3) { boolean log_error = true; try { long diff = SystemTime.getMonotonousTime() - last_server_agree_time; if (diff < 5000) { try { long sleep = 5000 - diff; System.out.println("Sleeping for " + sleep + " before completing srp"); Thread.sleep(sleep); } catch (Throwable e) { } } BigInteger A = new BigInteger((byte[]) data.get("a")); BigInteger serverS = server.calculateSecret(A); byte[] shared_secret = serverS.toByteArray(); Cipher decipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] key = new byte[16]; System.arraycopy(shared_secret, 0, key, 0, 16); SecretKeySpec secret = new SecretKeySpec(key, "AES"); decipher.init( Cipher.DECRYPT_MODE, secret, new IvParameterSpec((byte[]) data.get("enc_iv"))); byte[] dec = decipher.doFinal((byte[]) data.get("enc_data")); String json_str = new String(dec, "UTF-8"); if (!json_str.startsWith("{")) { log_error = false; throw (new Exception("decode failed")); } JSONObject dec_json = (JSONObject) JSONUtils.decodeJSON(json_str); String tunnel_url = (String) dec_json.get("url"); String service_id = new String((byte[]) data.get("service"), "UTF-8"); String endpoint_url = (String) dec_json.get("endpoint"); boolean ok = createTunnel( tunnel_originator, session, service_id, secret, tunnel_url, endpoint_url); result.put("op", 4); result.put("status", ok ? "ok" : "failed"); good_request = true; } catch (Throwable e) { result.put("op", 4); result.put("status", "failed"); // filter usual errors on bad agreement if (e instanceof BadPaddingException || e instanceof IllegalBlockSizeException) { log_error = false; } if (log_error) { e.printStackTrace(); } } finally { last_server_agree_time = SystemTime.getMonotonousTime(); } } return (result); } finally { if (!good_request) { manager.recordRequest("SRP", originator.getAddress().getHostAddress(), false); } } } }); SimpleTimer.addPeriodicEvent( "pm:tunnel:stats", 30 * 1000, new TimerEventPerformer() { public void perform(TimerEvent event) { synchronized (tunnels) { if (tunnels.size() > 0) { System.out.println("PairTunnels: " + tunnels.size()); for (PairManagerTunnel t : tunnels.values()) { System.out.println("\t" + t.getString()); } } } } }); } catch (Throwable e) { Debug.out(e); init_fail = Debug.getNestedExceptionMessage(e); manager.updateSRPState(); } }
protected void publishSupport() { DHTTransport transport = dht.getTransport(); if (TESTING || !transport.isReachable()) { DHTTransportContact local_contact = transport.getLocalContact(); // see if the rendezvous has failed and therefore we are required to find a new one boolean force = rendezvous_target != null && failed_rendezvous.containsKey(rendezvous_target.getAddress()); if (rendezvous_local_contact != null && !force) { if (local_contact.getAddress().equals(rendezvous_local_contact.getAddress())) { // already running for the current local contact return; } } DHTTransportContact explicit = (DHTTransportContact) explicit_rendezvous_map.get(local_contact.getAddress()); if (explicit != null) { try { pub_mon.enter(); rendezvous_local_contact = local_contact; rendezvous_target = explicit; runRendezvous(); } finally { pub_mon.exit(); } } else { final DHTTransportContact[] new_rendezvous_target = {null}; DHTTransportContact[] reachables = dht.getTransport().getReachableContacts(); int reachables_tried = 0; int reachables_skipped = 0; final Semaphore sem = plugin_interface.getUtilities().getSemaphore(); for (int i = 0; i < reachables.length; i++) { DHTTransportContact contact = reachables[i]; try { pub_mon.enter(); // see if we've found a good one yet if (new_rendezvous_target[0] != null) { break; } // skip any known bad ones if (failed_rendezvous.containsKey(contact.getAddress())) { reachables_skipped++; sem.release(); continue; } } finally { pub_mon.exit(); } if (i > 0) { try { Thread.sleep(1000); } catch (Throwable e) { } } reachables_tried++; contact.sendPing( new DHTTransportReplyHandlerAdapter() { public void pingReply(DHTTransportContact ok_contact) { trace("Punch:" + ok_contact.getString() + " OK"); try { pub_mon.enter(); if (new_rendezvous_target[0] == null) { new_rendezvous_target[0] = ok_contact; } } finally { pub_mon.exit(); sem.release(); } } public void failed(DHTTransportContact failed_contact, Throwable e) { try { trace("Punch:" + failed_contact.getString() + " Failed"); } finally { sem.release(); } } }); } for (int i = 0; i < reachables.length; i++) { sem.reserve(); try { pub_mon.enter(); if (new_rendezvous_target[0] != null) { rendezvous_target = new_rendezvous_target[0]; rendezvous_local_contact = local_contact; log( "Rendezvous found: " + rendezvous_local_contact.getString() + " -> " + rendezvous_target.getString()); runRendezvous(); break; } } finally { pub_mon.exit(); } } if (new_rendezvous_target[0] == null) { log( "No rendezvous found: candidates=" + reachables.length + ",tried=" + reachables_tried + ",skipped=" + reachables_skipped); try { pub_mon.enter(); rendezvous_local_contact = null; rendezvous_target = null; } finally { pub_mon.exit(); } } } } else { try { pub_mon.enter(); rendezvous_local_contact = null; rendezvous_target = null; } finally { pub_mon.exit(); } } }
protected DHTTransportContact getRendezvous(String reason, 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, reason + ": lookup for '" + target.getString() + "'", (byte) 0, 1, RENDEZVOUS_LOOKUP_TIMEOUT, false, true, 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); }
public void start() { if (started) { return; } started = true; DHTTransport transport = dht.getTransport(); transport.addListener( new DHTTransportListener() { public void localContactChanged(DHTTransportContact local_contact) { publish(false); } public void currentAddress(String address) {} public void reachabilityChanged(boolean reacheable) { publish(false); } }); transport.registerTransferHandler( transfer_handler_key, new DHTTransportTransferHandler() { public String getName() { return ("NAT Traversal"); } public byte[] handleRead(DHTTransportContact originator, byte[] key) { return (null); } public byte[] handleWrite(DHTTransportContact originator, byte[] key, byte[] value) { return (receiveRequest((DHTTransportUDPContact) originator, value)); } }); timer.addPeriodicEvent( REPUBLISH_TIME_MIN, new UTTimerEventPerformer() { public void perform(UTTimerEvent event) { publish(false); } }); timer.addPeriodicEvent( RENDEZVOUS_SERVER_TIMEOUT / 2, new UTTimerEventPerformer() { public void perform(UTTimerEvent event) { long now = plugin_interface.getUtilities().getCurrentSystemTime(); try { server_mon.enter(); Iterator it = rendezvous_bindings.values().iterator(); while (it.hasNext()) { Object[] entry = (Object[]) it.next(); long time = ((Long) entry[1]).longValue(); boolean removed = false; if (time > now) { // clock change, easiest approach is to remove it it.remove(); removed = true; } else if (now - time > RENDEZVOUS_SERVER_TIMEOUT) { // timeout it.remove(); removed = true; } if (removed) { log( "Rendezvous " + ((DHTTransportContact) entry[0]).getString() + " removed due to inactivity"); } } } finally { server_mon.exit(); } } }); publish(false); }