Search in sources :

Example 6 with DHTNetworkPosition

use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.

the class TRTrackerServerTorrentImpl method exportPeer.

private void exportPeer(LinkedList rep_peers, TRTrackerServerSimplePeer peer, boolean send_peer_ids, byte compact_mode, byte crypto_level, DHTNetworkPosition network_position) {
    Map rep_peer = new HashMap(3);
    if (send_peer_ids) {
        rep_peer.put("peer id", peer.getPeerId().getHash());
    }
    if (compact_mode != COMPACT_MODE_NONE) {
        byte[] peer_bytes = peer.getIPAddressBytes();
        if (peer_bytes == null) {
            return;
        }
        rep_peer.put("ip", peer_bytes);
        if (compact_mode >= COMPACT_MODE_AZ) {
            rep_peer.put("azver", new Long(peer.getAZVer()));
            rep_peer.put("azudp", new Long(peer.getUDPPort()));
            if (peer.isSeed()) {
                rep_peer.put("azhttp", new Long(peer.getHTTPPort()));
            }
            if (compact_mode >= COMPACT_MODE_XML) {
                rep_peer.put("ip", peer.getIPAsRead());
            } else {
                rep_peer.put("azup", new Long(peer.getUpSpeed()));
                if (peer.isBiased()) {
                    rep_peer.put("azbiased", "");
                }
                if (network_position != null) {
                    DHTNetworkPosition peer_pos = peer.getNetworkPosition();
                    if (peer_pos != null && network_position.getPositionType() == peer_pos.getPositionType()) {
                        rep_peer.put("azrtt", new Long((long) peer_pos.estimateRTT(network_position)));
                    }
                }
            }
        }
    } else {
        rep_peer.put("ip", peer.getIPAsRead());
    }
    rep_peer.put("port", new Long(peer.getTCPPort()));
    if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
        rep_peer.put("crypto_flag", new Long(peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ? 1 : 0));
    }
    if (peer.isBiased()) {
        rep_peers.addFirst(rep_peer);
    } else {
        rep_peers.addLast(rep_peer);
    }
}
Also used : DHTNetworkPosition(com.biglybt.core.dht.netcoords.DHTNetworkPosition)

Example 7 with DHTNetworkPosition

use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.

the class TRTrackerServerTorrentImpl method exportAnnounceToMap.

public Map exportAnnounceToMap(String ip_address, HashMap preprocess_map, // maybe null for an initial announce from a stopped peer
TRTrackerServerPeerImpl requesting_peer, boolean include_seeds, int num_want, long interval, long min_interval, boolean no_peer_id, byte compact_mode, byte crypto_level, DHTNetworkPosition network_position) {
    try {
        this_mon.enter();
        long now = SystemTime.getCurrentTime();
        // we have to force non-caching for nat_warnings responses as they include
        // peer-specific data
        boolean nat_warning = requesting_peer != null && requesting_peer.getNATStatus() == TRTrackerServerPeerImpl.NAT_CHECK_FAILED;
        int total_peers = peer_map.size();
        int cache_millis = TRTrackerServerImpl.getAnnounceCachePeriod();
        boolean send_peer_ids = TRTrackerServerImpl.getSendPeerIds();
        if (no_peer_id || compact_mode != COMPACT_MODE_NONE) {
            send_peer_ids = false;
        }
        boolean add_to_cache = false;
        int max_peers = TRTrackerServerImpl.getMaxPeersToSend();
        if (num_want < 0) {
            num_want = total_peers;
        }
        if (max_peers > 0 && num_want > max_peers) {
            num_want = max_peers;
        }
        // if set this list contains the only peers that are to be returned. It allows a manual
        // external peer selection algorithm
        List<TRTrackerServerSimplePeer> explicit_limited_peers = null;
        List<TRTrackerServerSimplePeer> explicit_biased_peers = null;
        Set remove_ips = null;
        if (requesting_peer != null) {
            if (peer_listeners != null) {
                for (int i = 0; i < peer_listeners.size(); i++) {
                    try {
                        Map reply = ((TRTrackerServerTorrentPeerListener) peer_listeners.get(i)).eventOccurred(this, requesting_peer, TRTrackerServerTorrentPeerListener.ET_ANNOUNCE, null);
                        if (reply != null) {
                            List limited_peers = (List) reply.get("limited_peers");
                            if (limited_peers != null) {
                                if (explicit_limited_peers == null) {
                                    explicit_limited_peers = new ArrayList<>();
                                }
                                for (int j = 0; j < limited_peers.size(); j++) {
                                    Map peer_map = (Map) limited_peers.get(j);
                                    String ip = (String) peer_map.get("ip");
                                    int port = ((Long) peer_map.get("port")).intValue();
                                    String reuse_key = ip + ":" + port;
                                    TRTrackerServerPeerImpl peer = (TRTrackerServerPeerImpl) peer_reuse_map.get(reuse_key);
                                    if (peer != null && !explicit_limited_peers.contains(peer)) {
                                        explicit_limited_peers.add(peer);
                                    }
                                }
                            }
                            List biased_peers = (List) reply.get("biased_peers");
                            if (biased_peers != null) {
                                if (explicit_biased_peers == null) {
                                    explicit_biased_peers = new ArrayList<>();
                                }
                                for (int j = 0; j < biased_peers.size(); j++) {
                                    Map peer_map = (Map) biased_peers.get(j);
                                    String ip = (String) peer_map.get("ip");
                                    int port = ((Long) peer_map.get("port")).intValue();
                                    String reuse_key = ip + ":" + port;
                                    TRTrackerServerSimplePeer peer = peer_reuse_map.get(reuse_key);
                                    if (peer == null) {
                                        peer = new temporaryBiasedSeed(ip, port);
                                    }
                                    if (!explicit_biased_peers.contains(peer)) {
                                        explicit_biased_peers.add(peer);
                                    }
                                }
                            }
                            remove_ips = (Set) reply.get("remove_ips");
                        }
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
        }
        boolean requester_is_biased;
        if (requesting_peer == null) {
            Set bp = server.getBiasedPeers();
            if (bp == null) {
                requester_is_biased = false;
            } else {
                requester_is_biased = bp.contains(ip_address);
            }
        } else {
            requester_is_biased = requesting_peer.isBiased();
        }
        if (caching_enabled && explicit_limited_peers == null && explicit_biased_peers == null && !requester_is_biased && remove_ips == null && (!nat_warning) && // don't cache if we've got pre-process stuff to add
        preprocess_map.size() == 0 && cache_millis > 0 && num_want >= MIN_CACHE_ENTRY_SIZE && total_peers >= TRTrackerServerImpl.getAnnounceCachePeerThreshold() && crypto_level != TRTrackerServerPeer.CRYPTO_REQUIRED) {
            // no cache for crypto required peers
            // too busy to bother with network position stuff
            network_position = null;
            // note that we've got to select a cache entry that is somewhat
            // relevant to the num_want param (but NOT greater than it)
            // remove stuff that's too old
            Iterator it = announce_cache.keySet().iterator();
            while (it.hasNext()) {
                Integer key = (Integer) it.next();
                announceCacheEntry entry = (announceCacheEntry) announce_cache.get(key);
                if (now - entry.getTime() > cache_millis) {
                    it.remove();
                }
            }
            for (int i = num_want / 10; i > num_want / 20; i--) {
                announceCacheEntry entry = (announceCacheEntry) announce_cache.get(new Integer(i));
                if (entry != null) {
                    if (now - entry.getTime() > cache_millis) {
                        announce_cache.remove(new Integer(i));
                    } else {
                        if (entry.getSendPeerIds() == send_peer_ids && entry.getCompactMode() == compact_mode) {
                            return (entry.getData());
                        }
                    }
                }
            }
            add_to_cache = true;
        }
        LinkedList rep_peers = new LinkedList();
        if (num_want > 0 && explicit_limited_peers == null) {
            if (num_want >= total_peers) {
                for (int i = 0; i < peer_list.size(); i++) {
                    TRTrackerServerPeerImpl peer = (TRTrackerServerPeerImpl) peer_list.get(i);
                    if (peer == null || peer == requesting_peer) {
                    } else if (now > peer.getTimeout()) {
                        // System.out.println( "removing timed out client '" + peer.getString());
                        removePeer(peer, i, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null);
                    } else if (peer.getTCPPort() == 0) {
                    // a port of 0 means that the peer definitely can't accept incoming connections
                    } else if (crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED) {
                    // don't return "crypto required" peers to those that can't correctly connect to them
                    /* change this to make the explicit ones additional, not replacing
						}else if ( 	explicit_biased_peers != null &&
									peer.isBiased()){
							*/
                    // if we have an explicit biased peer list and this peer is biased
                    // skip here as we add them later
                    } else if (remove_ips != null && remove_ips.contains(new String(peer.getIP()))) {
                    // skippy skippy
                    } else if (include_seeds || !peer.isSeed()) {
                        Map rep_peer = new HashMap(3);
                        if (send_peer_ids) {
                            rep_peer.put("peer id", peer.getPeerId().getHash());
                        }
                        if (compact_mode != COMPACT_MODE_NONE) {
                            byte[] peer_bytes = peer.getIPAddressBytes();
                            if (peer_bytes == null) {
                                continue;
                            }
                            rep_peer.put("ip", peer_bytes);
                            if (compact_mode >= COMPACT_MODE_AZ) {
                                rep_peer.put("azver", new Long(peer.getAZVer()));
                                rep_peer.put("azudp", new Long(peer.getUDPPort()));
                                if (peer.isSeed()) {
                                    rep_peer.put("azhttp", new Long(peer.getHTTPPort()));
                                }
                                if (compact_mode >= COMPACT_MODE_XML) {
                                    rep_peer.put("ip", peer.getIPAsRead());
                                } else {
                                    rep_peer.put("azup", new Long(peer.getUpSpeed()));
                                    if (peer.isBiased()) {
                                        rep_peer.put("azbiased", "");
                                    }
                                    if (network_position != null) {
                                        DHTNetworkPosition peer_pos = peer.getNetworkPosition();
                                        if (peer_pos != null && network_position.getPositionType() == peer_pos.getPositionType()) {
                                            rep_peer.put("azrtt", new Long((long) peer_pos.estimateRTT(network_position)));
                                        }
                                    }
                                }
                            }
                        } else {
                            rep_peer.put("ip", peer.getIPAsRead());
                        }
                        rep_peer.put("port", new Long(peer.getTCPPort()));
                        if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
                            rep_peer.put("crypto_flag", new Long(peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ? 1 : 0));
                        }
                        if (peer.isBiased()) {
                            rep_peers.addFirst(rep_peer);
                        } else {
                            rep_peers.addLast(rep_peer);
                        }
                    }
                }
            } else {
                int peer_list_size = peer_list.size();
                if (duplicate_peer_checker.length < peer_list_size) {
                    duplicate_peer_checker = new byte[peer_list_size * 2];
                    duplicate_peer_checker_index = 1;
                } else if (duplicate_peer_checker.length > (peer_list_size * 2)) {
                    duplicate_peer_checker = new byte[(3 * peer_list_size) / 2];
                    duplicate_peer_checker_index = 1;
                } else {
                    duplicate_peer_checker_index++;
                    if (duplicate_peer_checker_index == 0) {
                        Arrays.fill(duplicate_peer_checker, (byte) 0);
                        duplicate_peer_checker_index = 1;
                    }
                }
                boolean peer_removed = false;
                try {
                    // got to suspend peer list compaction as we rely on the
                    // list staying the same size during processing below
                    peer_list_compaction_suspended = true;
                    // too costly to randomise as below. use more efficient but slightly less accurate
                    // approach
                    // two pass process if bad nat detection enabled
                    int added = 0;
                    for (int bad_nat_loop = TRTrackerServerNATChecker.getSingleton().isEnabled() ? 0 : 1; bad_nat_loop < 2; bad_nat_loop++) {
                        // some entries we find might not be usable
                        int limit = num_want * 2;
                        if (num_want * 3 > total_peers) {
                            limit++;
                        }
                        int biased_peers_count = 0;
                        if (biased_peers != null) {
                            if (biased_peers.size() > 1) {
                                // juggle things a bit
                                Object x = biased_peers.remove(0);
                                biased_peers.add(random.nextInt(biased_peers.size() + 1), x);
                            }
                            biased_peers_count = Math.min(min_biased_peers, biased_peers.size());
                        }
                        for (int i = 0; i < limit && added < num_want; i++) {
                            int peer_index;
                            TRTrackerServerPeerImpl peer;
                            if (bad_nat_loop == 1 && i < biased_peers_count) {
                                peer = (TRTrackerServerPeerImpl) biased_peers.get(i);
                                // don't know actual index and don't need to as biased peers processed separately
                                peer_index = -1;
                            } else {
                                peer_index = random.nextInt(peer_list_size);
                                peer = (TRTrackerServerPeerImpl) peer_list.get(peer_index);
                                if (peer == null || peer.isBiased()) {
                                    continue;
                                }
                            }
                            if (now > peer.getTimeout()) {
                                removePeer(peer, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null);
                                peer_removed = true;
                            } else if (requesting_peer == peer || peer.getTCPPort() == 0) {
                            // a port of 0 means that the peer definitely can't accept incoming connections
                            } else if (crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED) {
                            // don't return "crypto required" peers to those that can't correctly connect to them
                            } else if (remove_ips != null && remove_ips.contains(new String(peer.getIP()))) {
                            // skippy skippy
                            } else if (include_seeds || !peer.isSeed()) {
                                boolean bad_nat = peer.isNATStatusBad();
                                if ((bad_nat_loop == 0 && !bad_nat) || (bad_nat_loop == 1)) {
                                    if (peer_index == -1 || duplicate_peer_checker[peer_index] != duplicate_peer_checker_index) {
                                        if (peer_index != -1) {
                                            duplicate_peer_checker[peer_index] = duplicate_peer_checker_index;
                                        }
                                        // if ( bad_nat ){
                                        // 
                                        // bad_nat_added++;
                                        // }
                                        added++;
                                        Map rep_peer = new HashMap(3);
                                        if (send_peer_ids) {
                                            rep_peer.put("peer id", peer.getPeerId().getHash());
                                        }
                                        if (compact_mode != COMPACT_MODE_NONE) {
                                            byte[] peer_bytes = peer.getIPAddressBytes();
                                            if (peer_bytes == null) {
                                                continue;
                                            }
                                            rep_peer.put("ip", peer_bytes);
                                            if (compact_mode >= COMPACT_MODE_AZ) {
                                                rep_peer.put("azver", new Long(peer.getAZVer()));
                                                rep_peer.put("azudp", new Long(peer.getUDPPort()));
                                                if (peer.isSeed()) {
                                                    rep_peer.put("azhttp", new Long(peer.getHTTPPort()));
                                                }
                                                if (compact_mode >= COMPACT_MODE_XML) {
                                                    rep_peer.put("ip", peer.getIPAsRead());
                                                } else {
                                                    rep_peer.put("azup", new Long(peer.getUpSpeed()));
                                                    if (peer.isBiased()) {
                                                        rep_peer.put("azbiased", "");
                                                    }
                                                    if (network_position != null) {
                                                        DHTNetworkPosition peer_pos = peer.getNetworkPosition();
                                                        if (peer_pos != null && network_position.getPositionType() == peer_pos.getPositionType()) {
                                                            rep_peer.put("azrtt", new Long((long) peer_pos.estimateRTT(network_position)));
                                                        }
                                                    }
                                                }
                                            }
                                        } else {
                                            rep_peer.put("ip", peer.getIPAsRead());
                                        }
                                        rep_peer.put("port", new Long(peer.getTCPPort()));
                                        if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
                                            rep_peer.put("crypto_flag", new Long(peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ? 1 : 0));
                                        }
                                        if (peer.isBiased()) {
                                            rep_peers.addFirst(rep_peer);
                                        } else {
                                            rep_peers.addLast(rep_peer);
                                        }
                                    }
                                }
                            }
                        }
                    }
                // System.out.println( "num_want = " + num_want + ", added = " + added + ", bad_nat = " + bad_nat_added );
                } finally {
                    peer_list_compaction_suspended = false;
                    if (peer_removed) {
                        checkForPeerListCompaction(false);
                    }
                }
            /*
				}else{
						// given up on this approach for the moment as too costly

						// randomly select the peers to return

					LinkedList	peers = new LinkedList( peer_map.keySet());

					int	added = 0;

					while( added < num_want && peers.size() > 0 ){

						String	key = (String)peers.remove(random.nextInt(peers.size()));

						TRTrackerServerPeerImpl	peer = (TRTrackerServerPeerImpl)peer_map.get(key);

						if ( now > peer.getTimeout()){

							removePeer( peer, TRTrackerServerTorrentPeerListener.ET_TIMEOUT, null );

						}else if ( peer.getTCPPort() == 0 ){

								// a port of 0 means that the peer definitely can't accept incoming connections

						}else if ( crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ){

							// don't return "crypto required" peers to those that can't correctly connect to them

						}else if ( include_seeds || !peer.isSeed()){

							added++;

							Map rep_peer = new HashMap(3);	// don't use TreeMap as default is "compact"
															// so we never actually encode anyway

							if ( send_peer_ids ){

								rep_peer.put( "peer id", peer.getPeerId().getHash());
							}

							if ( compact_mode != COMPACT_MODE_NONE ){

								byte[]	peer_bytes = peer.getIPBytes();

								if ( peer_bytes == null ){

									continue;
								}

								rep_peer.put( "ip", peer_bytes );

								if ( compact_mode >= COMPACT_MODE_AZ ){

									rep_peer.put( "azver", new Long( peer.getAZVer()));

									rep_peer.put( "azudp", new Long( peer.getUDPPort()));

									if ( peer.isSeed()){

										rep_peer.put( "azhttp", new Long( peer.getHTTPPort()));
									}
								}
							}else{
								rep_peer.put( "ip", peer.getIPAsRead() );
							}

							rep_peer.put( "port", new Long( peer.getTCPPort()));

							if ( crypto_level != TRTrackerServerPeer.CRYPTO_NONE ){

								rep_peer.put( "crypto_flag", new Long( peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED?1:0));
							}

							rep_peers.add( rep_peer );

						}
					}*/
            }
        }
        if (include_seeds && explicit_limited_peers == null && !send_peer_ids && seed_count < 3 && queued_peers != null) {
            Iterator it = queued_peers.iterator();
            List added = new ArrayList(QUEUED_PEERS_ADD_MAX);
            while (it.hasNext() && num_want > rep_peers.size() && added.size() < QUEUED_PEERS_ADD_MAX) {
                QueuedPeer peer = (QueuedPeer) it.next();
                if (peer.isTimedOut(now)) {
                    it.remove();
                } else if (crypto_level == TRTrackerServerPeer.CRYPTO_NONE && peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED) {
                // don't return "crypto required" peers to those that can't correctly connect to them
                } else if (remove_ips != null && remove_ips.contains(peer.getIP())) {
                // skippy skippy
                } else {
                    Map rep_peer = new HashMap(3);
                    if (compact_mode != COMPACT_MODE_NONE) {
                        byte[] peer_bytes = peer.getIPAddressBytes();
                        if (peer_bytes == null) {
                            continue;
                        }
                        rep_peer.put("ip", peer_bytes);
                        if (compact_mode >= COMPACT_MODE_AZ) {
                            rep_peer.put("azver", new Long(peer.getAZVer()));
                            rep_peer.put("azudp", new Long(peer.getUDPPort()));
                            if (peer.isSeed()) {
                                rep_peer.put("azhttp", new Long(peer.getHTTPPort()));
                            }
                            if (compact_mode >= COMPACT_MODE_XML) {
                                rep_peer.put("ip", peer.getIPAsRead());
                            }
                        }
                    } else {
                        rep_peer.put("ip", peer.getIPAsRead());
                    }
                    rep_peer.put("port", new Long(peer.getTCPPort()));
                    if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
                        rep_peer.put("crypto_flag", new Long(peer.getCryptoLevel() == TRTrackerServerPeer.CRYPTO_REQUIRED ? 1 : 0));
                    }
                    // System.out.println( "added queued peer " + peer.getString());
                    rep_peers.addLast(rep_peer);
                    added.add(peer);
                    // it'll be added back in below, don't worry!
                    it.remove();
                }
            }
            for (int i = 0; i < added.size(); i++) {
                queued_peers.add(added.get(i));
            }
        }
        // user TreeMap to pre-sort so encoding quicker
        Map root = new TreeMap();
        if (preprocess_map.size() > 0) {
            root.putAll(preprocess_map);
        }
        if (explicit_limited_peers != null) {
            for (int i = 0; i < explicit_limited_peers.size(); i++) {
                num_want--;
                TRTrackerServerSimplePeer peer = explicit_limited_peers.get(i);
                exportPeer(rep_peers, peer, send_peer_ids, compact_mode, crypto_level, network_position);
            }
        }
        if (explicit_biased_peers != null) {
            for (int i = 0; i < explicit_biased_peers.size(); i++) {
                num_want--;
                TRTrackerServerSimplePeer peer = explicit_biased_peers.get(i);
                exportPeer(rep_peers, peer, send_peer_ids, compact_mode, crypto_level, network_position);
            }
        }
        if (explicit_manual_biased_peers != null) {
            if (requesting_peer != null && !requesting_peer.isSeed()) {
                Object[] explicit_peer = (Object[]) explicit_manual_biased_peers.get(explicit_next_peer++);
                if (explicit_next_peer == explicit_manual_biased_peers.size()) {
                    explicit_next_peer = 0;
                }
                Map rep_peer = new HashMap(3);
                if (send_peer_ids) {
                    byte[] peer_id = new byte[20];
                    random.nextBytes(peer_id);
                    rep_peer.put("peer id", peer_id);
                }
                if (compact_mode != COMPACT_MODE_NONE) {
                    byte[] peer_bytes = (byte[]) explicit_peer[1];
                    rep_peer.put("ip", peer_bytes);
                    if (compact_mode >= COMPACT_MODE_AZ) {
                        // non-az
                        rep_peer.put("azver", new Long(0));
                        rep_peer.put("azudp", new Long(0));
                        rep_peer.put("azup", new Long(0));
                        rep_peer.put("azbiased", "");
                    }
                } else {
                    rep_peer.put("ip", ((String) explicit_peer[0]).getBytes());
                }
                rep_peer.put("port", new Long(((Integer) explicit_peer[2]).intValue()));
                if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
                    rep_peer.put("crypto_flag", new Long(0));
                }
                rep_peers.addFirst(rep_peer);
            }
        }
        int num_peers_returned = rep_peers.size();
        Iterator it = rep_peers.iterator();
        if (compact_mode == COMPACT_MODE_AZ) {
            byte[] compact_peers = new byte[num_peers_returned * 9];
            int index = 0;
            while (it.hasNext()) {
                Map rep_peer = (Map) it.next();
                byte[] ip = (byte[]) rep_peer.get("ip");
                int tcp_port = ((Long) rep_peer.get("port")).intValue();
                int udp_port = ((Long) rep_peer.get("azudp")).intValue();
                Long crypto_flag_l = (Long) rep_peer.get("crypto_flag");
                byte crypto_flag = crypto_flag_l == null ? 0 : crypto_flag_l.byteValue();
                int pos = index * 9;
                System.arraycopy(ip, 0, compact_peers, pos, 4);
                pos += 4;
                compact_peers[pos++] = (byte) (tcp_port >> 8);
                compact_peers[pos++] = (byte) (tcp_port & 0xff);
                compact_peers[pos++] = (byte) (udp_port >> 8);
                compact_peers[pos++] = (byte) (udp_port & 0xff);
                compact_peers[pos++] = crypto_flag;
                index++;
            }
            root.put("peers", compact_peers);
            root.put("azcompact", new Long(1));
        } else if (compact_mode == COMPACT_MODE_AZ_2) {
            List compact_peers = new ArrayList(num_peers_returned);
            while (it.hasNext()) {
                Map rep_peer = (Map) it.next();
                Map peer = new HashMap();
                compact_peers.add(peer);
                byte[] ip = (byte[]) rep_peer.get("ip");
                peer.put("i", ip);
                int tcp_port = ((Long) rep_peer.get("port")).intValue();
                peer.put("t", new byte[] { (byte) (tcp_port >> 8), (byte) (tcp_port & 0xff) });
                int udp_port = ((Long) rep_peer.get("azudp")).intValue();
                if (udp_port != 0) {
                    if (udp_port == tcp_port) {
                        peer.put("u", new byte[0]);
                    } else {
                        peer.put("u", new byte[] { (byte) (udp_port >> 8), (byte) (udp_port & 0xff) });
                    }
                }
                Long http_port_l = (Long) rep_peer.get("azhttp");
                if (http_port_l != null) {
                    int http_port = http_port_l.intValue();
                    if (http_port != 0) {
                        peer.put("h", new byte[] { (byte) (http_port >> 8), (byte) (http_port & 0xff) });
                    }
                }
                Long crypto_flag_l = (Long) rep_peer.get("crypto_flag");
                byte crypto_flag = crypto_flag_l == null ? 0 : crypto_flag_l.byteValue();
                if (crypto_flag != 0) {
                    peer.put("c", new byte[] { crypto_flag });
                }
                Long az_ver_l = (Long) rep_peer.get("azver");
                byte az_ver = az_ver_l == null ? 0 : az_ver_l.byteValue();
                if (az_ver != 0) {
                    peer.put("v", new Long(az_ver));
                }
                Long up_speed = (Long) rep_peer.get("azup");
                if (up_speed != null && up_speed.longValue() != 0) {
                    peer.put("s", up_speed);
                }
                Long rtt = (Long) rep_peer.get("azrtt");
                if (rtt != null) {
                    peer.put("r", rtt);
                }
                if (rep_peer.containsKey("azbiased")) {
                    peer.put("b", new Long(1));
                }
            }
            root.put("peers", compact_peers);
            root.put("azcompact", new Long(2));
        } else if (compact_mode == COMPACT_MODE_XML) {
            List xml_peers = new ArrayList(num_peers_returned);
            while (it.hasNext()) {
                Map rep_peer = (Map) it.next();
                Map peer = new HashMap();
                xml_peers.add(peer);
                peer.put("ip", rep_peer.get("ip"));
                peer.put("tcp", rep_peer.get("port"));
                int udp_port = ((Long) rep_peer.get("azudp")).intValue();
                if (udp_port != 0) {
                    peer.put("udp", new Long(udp_port));
                }
                Long http_port_l = (Long) rep_peer.get("azhttp");
                if (http_port_l != null) {
                    int http_port = http_port_l.intValue();
                    if (http_port != 0) {
                        peer.put("http", new Long(http_port));
                    }
                }
            }
            root.put("peers", xml_peers);
        } else {
            byte[] crypto_flags = null;
            if (crypto_level != TRTrackerServerPeer.CRYPTO_NONE) {
                crypto_flags = new byte[num_peers_returned];
            }
            if (compact_mode == COMPACT_MODE_NORMAL) {
                byte[] compact_peers = new byte[num_peers_returned * 6];
                int index = 0;
                int num_ipv4 = 0;
                int num_ipv6 = 0;
                while (it.hasNext()) {
                    Map rep_peer = (Map) it.next();
                    byte[] ip = (byte[]) rep_peer.get("ip");
                    if (ip.length > 4) {
                        num_ipv6++;
                    // continue and fill in crypto return
                    } else {
                        num_ipv4++;
                        if (num_ipv6 == 0) {
                            int port = ((Long) rep_peer.get("port")).intValue();
                            int pos = index * 6;
                            System.arraycopy(ip, 0, compact_peers, pos, 4);
                            pos += 4;
                            compact_peers[pos++] = (byte) (port >> 8);
                            compact_peers[pos++] = (byte) (port & 0xff);
                        }
                    }
                    if (crypto_flags != null) {
                        Long crypto_flag = (Long) rep_peer.remove("crypto_flag");
                        crypto_flags[index] = crypto_flag.byteValue();
                    }
                    index++;
                }
                if (num_ipv6 > 0) {
                    byte[] compact_peers_v4 = new byte[num_ipv4 * 6];
                    byte[] compact_peers_v6 = new byte[num_ipv6 * 18];
                    it = rep_peers.iterator();
                    int v4_index = 0;
                    int v6_index = 0;
                    while (it.hasNext()) {
                        Map rep_peer = (Map) it.next();
                        byte[] ip = (byte[]) rep_peer.get("ip");
                        int port = ((Long) rep_peer.get("port")).intValue();
                        if (ip.length > 4) {
                            int pos = v6_index * 18;
                            System.arraycopy(ip, 0, compact_peers_v6, pos, 16);
                            pos += 16;
                            compact_peers_v6[pos++] = (byte) (port >> 8);
                            compact_peers_v6[pos++] = (byte) (port & 0xff);
                            v6_index++;
                        } else {
                            int pos = v4_index * 6;
                            System.arraycopy(ip, 0, compact_peers_v4, pos, 4);
                            pos += 4;
                            compact_peers_v4[pos++] = (byte) (port >> 8);
                            compact_peers_v4[pos++] = (byte) (port & 0xff);
                            v4_index++;
                        }
                    }
                    if (compact_peers_v4.length > 0) {
                        root.put("peers", compact_peers_v4);
                    }
                    if (compact_peers_v6.length > 0) {
                        root.put("peers6", compact_peers_v6);
                    }
                } else {
                    root.put("peers", compact_peers);
                }
            } else {
                int index = 0;
                while (it.hasNext()) {
                    Map rep_peer = (Map) it.next();
                    if (crypto_flags != null) {
                        Long crypto_flag = (Long) rep_peer.remove("crypto_flag");
                        crypto_flags[index] = crypto_flag.byteValue();
                    }
                    index++;
                }
                root.put("peers", rep_peers);
            }
            if (crypto_flags != null) {
                root.put("crypto_flags", crypto_flags);
            }
        }
        root.put("interval", new Long(interval));
        root.put("min interval", new Long(min_interval));
        if (nat_warning) {
            requesting_peer.setNATStatus(TRTrackerServerPeerImpl.NAT_CHECK_FAILED_AND_REPORTED);
            root.put("warning message", ("Unable to connect to your incoming data port (" + requesting_peer.getIP() + ":" + requesting_peer.getTCPPort() + "). " + "This will result in slow downloads. Please check your firewall/router settings").getBytes());
        }
        // also include scrape details
        root.put("complete", new Long(getSeedCountForScrape(requester_is_biased)));
        root.put("incomplete", new Long(getLeecherCount()));
        root.put("downloaded", new Long(stats.getCompletedCount()));
        if (add_to_cache) {
            announce_cache.put(new Integer((num_peers_returned + 9) / 10), new announceCacheEntry(root, send_peer_ids, compact_mode));
        }
        return (root);
    } finally {
        this_mon.exit();
    }
}
Also used : DHTNetworkPosition(com.biglybt.core.dht.netcoords.DHTNetworkPosition)

Example 8 with DHTNetworkPosition

use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.

the class VivaldiPanel method refreshContacts.

public void refreshContacts(List<DHTControlContact> contacts, DHTTransportContact self) {
    if (contacts == null || self == null) {
        return;
    }
    lastContacts = contacts;
    lastSelf = self;
    if (canvas.isDisposed())
        return;
    Rectangle size = canvas.getBounds();
    if (size.isEmpty()) {
        return;
    }
    scale.width = size.width;
    scale.height = size.height;
    Color white = ColorCache.getColor(display, 255, 255, 255);
    Color blue = ColorCache.getColor(display, 66, 87, 104);
    if (img != null && !img.isDisposed()) {
        img.dispose();
    }
    img = new Image(display, size);
    GC gc = new GC(img);
    gc.setForeground(white);
    gc.setBackground(white);
    gc.fillRectangle(size);
    if (SWT.getVersion() >= 3138 && antiAliasingAvailable) {
        try {
        // gc.setTextAntialias(SWT.ON);
        // gc.setAntialias(SWT.ON);
        } catch (Exception e) {
            antiAliasingAvailable = false;
        }
    }
    gc.setForeground(blue);
    gc.setBackground(white);
    DHTNetworkPosition _ownPosition = self.getNetworkPosition(DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1);
    if (_ownPosition == null) {
        gc.dispose();
        return;
    }
    currentPositions.clear();
    VivaldiPosition ownPosition = (VivaldiPosition) _ownPosition;
    float ownErrorEstimate = ownPosition.getErrorEstimate();
    HeightCoordinatesImpl ownCoords = (HeightCoordinatesImpl) ownPosition.getCoordinates();
    gc.drawText("Our error: " + ownErrorEstimate, 10, 10);
    Color black = ColorCache.getColor(display, 0, 0, 0);
    // Color of the squares
    gc.setBackground(black);
    // Draw all known positions of other contacts
    long total_distance = 0;
    for (DHTControlContact contact : contacts) {
        DHTNetworkPosition _position = contact.getTransportContact().getNetworkPosition(DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1);
        if (_position == null) {
            continue;
        }
        VivaldiPosition position = (VivaldiPosition) _position;
        HeightCoordinatesImpl coord = (HeightCoordinatesImpl) position.getCoordinates();
        if (coord.isValid()) {
            int distance = (int) ownCoords.distance(coord);
            total_distance += distance;
            draw(gc, coord.getX(), coord.getY(), coord.getH(), contact, distance, position.getErrorEstimate());
        }
    }
    // Mark our own position
    Color red = ColorCache.getColor(display, 255, 0, 0);
    gc.setForeground(red);
    drawSelf(gc, ownCoords.getX(), ownCoords.getY(), ownCoords.getH(), ownErrorEstimate);
    gc.dispose();
    boolean skip_redraw = false;
    if (!disableAutoScale) {
        int num_pos = currentPositions.size();
        if (num_pos > 0) {
            long now = SystemTime.getMonotonousTime();
            if (now - lastAutoScale >= 5 * 1000) {
                lastAutoScale = now;
                float min_x = Float.MAX_VALUE;
                float min_y = Float.MAX_VALUE;
                float max_x = Float.MIN_VALUE;
                float max_y = Float.MIN_VALUE;
                int average_distance = (int) (total_distance / num_pos);
                for (Object[] entry : currentPositions) {
                    if (num_pos > 25) {
                        int distance = (Integer) entry[6];
                        if (distance >= average_distance * 4) {
                            continue;
                        }
                    }
                    float x = (Float) entry[4];
                    float y = (Float) entry[5];
                    min_x = Math.min(min_x, x);
                    min_y = Math.min(min_y, y);
                    max_x = Math.max(max_x, x);
                    max_y = Math.max(max_y, y);
                }
                float new_min_x = min_x - 50;
                float new_max_x = max_x + 50;
                float new_min_y = min_y - 50;
                float new_max_y = max_y + 50;
                if (scale.minX != new_min_x || scale.maxX != new_max_x || scale.minY != new_min_y || scale.maxY != new_max_y) {
                    scale.minX = new_min_x;
                    scale.maxX = new_max_x;
                    scale.minY = new_min_y;
                    scale.maxY = new_max_y;
                }
                // System.out.println(scale.minX+","+ scale.maxX+","+scale.minY+","+scale.maxY+" -> " + new_min_x + "," +new_max_x+","+new_min_y+","+new_max_y);
                refreshContacts(contacts, self);
                skip_redraw = true;
            }
        }
    }
    if (!skip_redraw) {
        canvas.redraw();
    }
}
Also used : Color(org.eclipse.swt.graphics.Color) Rectangle(org.eclipse.swt.graphics.Rectangle) Image(org.eclipse.swt.graphics.Image) DHTNetworkPosition(com.biglybt.core.dht.netcoords.DHTNetworkPosition) DHTControlContact(com.biglybt.core.dht.control.DHTControlContact) GC(org.eclipse.swt.graphics.GC)

Aggregations

DHTNetworkPosition (com.biglybt.core.dht.netcoords.DHTNetworkPosition)8 IOException (java.io.IOException)2 DHT (com.biglybt.core.dht.DHT)1 DHTControlContact (com.biglybt.core.dht.control.DHTControlContact)1 DHTControlStats (com.biglybt.core.dht.control.DHTControlStats)1 DHTDBStats (com.biglybt.core.dht.db.DHTDBStats)1 DHTRouterStats (com.biglybt.core.dht.router.DHTRouterStats)1 LogEvent (com.biglybt.core.logging.LogEvent)1 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)1 TRTrackerServerException (com.biglybt.core.tracker.server.TRTrackerServerException)1 TRTrackerServerPeer (com.biglybt.core.tracker.server.TRTrackerServerPeer)1 TRTrackerServerPeerImpl (com.biglybt.core.tracker.server.impl.TRTrackerServerPeerImpl)1 TRTrackerServerTorrentImpl (com.biglybt.core.tracker.server.impl.TRTrackerServerTorrentImpl)1 PluginInterface (com.biglybt.pif.PluginInterface)1 ClientIDException (com.biglybt.pif.clientid.ClientIDException)1 DHTPlugin (com.biglybt.plugin.dht.DHTPlugin)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 GZIPOutputStream (java.util.zip.GZIPOutputStream)1 Color (org.eclipse.swt.graphics.Color)1 GC (org.eclipse.swt.graphics.GC)1