protected boolean checkConnectionId(String client_address, long id) { try { random_mon.enter(); Long key = new Long(id); connectionData data = (connectionData) connection_id_map.get(key); if (data == null) { // System.out.println( "TRTrackerServerProcessorUDP: rejected:" + id + ", data not found" ); return (false); } else { if (SystemTime.getMonotonousTime() - data.getTime() > CONNECTION_ID_LIFETIME) { return (false); } } boolean ok = data.getAddress().equals(client_address); // System.out.println( "TRTrackerServerProcessorUDP: tested:" + id + "/" + client_address + " // -> " + ok ); return (ok); } finally { random_mon.exit(); } }
protected Object[] handleAnnounceAndScrape( String client_ip_address, PRUDPPacketRequest request, int request_type) throws Exception { if (!checkConnectionId(client_ip_address, request.getConnectionId())) { return (null); } List hashbytes = new ArrayList(); HashWrapper peer_id = null; int port = 0; String event = null; long uploaded = 0; long downloaded = 0; long left = 0; int num_want = -1; String key = null; if (request_type == TRTrackerServerRequest.RT_ANNOUNCE) { if (PRUDPPacketTracker.VERSION == 1) { PRUDPPacketRequestAnnounce announce = (PRUDPPacketRequestAnnounce) request; hashbytes.add(announce.getHash()); peer_id = new HashWrapper(announce.getPeerId()); port = announce.getPort(); int i_event = announce.getEvent(); switch (i_event) { case PRUDPPacketRequestAnnounce.EV_STARTED: { event = "started"; break; } case PRUDPPacketRequestAnnounce.EV_STOPPED: { event = "stopped"; break; } case PRUDPPacketRequestAnnounce.EV_COMPLETED: { event = "completed"; break; } } uploaded = announce.getUploaded(); downloaded = announce.getDownloaded(); left = announce.getLeft(); num_want = announce.getNumWant(); int i_ip = announce.getIPAddress(); if (i_ip != 0) { client_ip_address = PRHelpers.intToAddress(i_ip); } } else { PRUDPPacketRequestAnnounce2 announce = (PRUDPPacketRequestAnnounce2) request; hashbytes.add(announce.getHash()); peer_id = new HashWrapper(announce.getPeerId()); port = announce.getPort(); int i_event = announce.getEvent(); switch (i_event) { case PRUDPPacketRequestAnnounce.EV_STARTED: { event = "started"; break; } case PRUDPPacketRequestAnnounce.EV_STOPPED: { event = "stopped"; break; } case PRUDPPacketRequestAnnounce.EV_COMPLETED: { event = "completed"; break; } } uploaded = announce.getUploaded(); downloaded = announce.getDownloaded(); left = announce.getLeft(); num_want = announce.getNumWant(); int i_ip = announce.getIPAddress(); if (i_ip != 0) { client_ip_address = PRHelpers.intToAddress(i_ip); } key = "" + announce.getKey(); } } else { PRUDPPacketRequestScrape scrape = (PRUDPPacketRequestScrape) request; hashbytes.addAll(scrape.getHashes()); } Map[] root_out = new Map[1]; TRTrackerServerPeerImpl[] peer_out = new TRTrackerServerPeerImpl[1]; TRTrackerServerTorrentImpl torrent = processTrackerRequest( server, "", root_out, peer_out, request_type, (byte[][]) hashbytes.toArray(new byte[0][0]), null, null, peer_id, false, TRTrackerServerTorrentImpl.COMPACT_MODE_NONE, key, // currently no "no_peer_id" / "compact" in the packet and anyway they aren't // returned / key event, false, port, 0, 0, client_ip_address, client_ip_address, downloaded, uploaded, left, num_want, TRTrackerServerPeer.CRYPTO_NONE, (byte) 1, 0, null); Map root = root_out[0]; if (request_type == TRTrackerServerRequest.RT_ANNOUNCE) { if (PRUDPPacketTracker.VERSION == 1) { PRUDPPacketReplyAnnounce reply = new PRUDPPacketReplyAnnounce(request.getTransactionId()); reply.setInterval(((Long) root.get("interval")).intValue()); List peers = (List) root.get("peers"); int[] addresses = new int[peers.size()]; short[] ports = new short[addresses.length]; for (int i = 0; i < addresses.length; i++) { Map peer = (Map) peers.get(i); addresses[i] = PRHelpers.addressToInt(new String((byte[]) peer.get("ip"))); ports[i] = (short) ((Long) peer.get("port")).shortValue(); } reply.setPeers(addresses, ports); return (new Object[] {reply, torrent}); } else { PRUDPPacketReplyAnnounce2 reply = new PRUDPPacketReplyAnnounce2(request.getTransactionId()); reply.setInterval(((Long) root.get("interval")).intValue()); boolean local_scrape = client_ip_address.equals("127.0.0.1"); Map scrape_details = torrent.exportScrapeToMap("", client_ip_address, !local_scrape); int seeders = ((Long) scrape_details.get("complete")).intValue(); int leechers = ((Long) scrape_details.get("incomplete")).intValue(); reply.setLeechersSeeders(leechers, seeders); List peers = (List) root.get("peers"); int[] addresses = new int[peers.size()]; short[] ports = new short[addresses.length]; for (int i = 0; i < addresses.length; i++) { Map peer = (Map) peers.get(i); addresses[i] = PRHelpers.addressToInt(new String((byte[]) peer.get("ip"))); ports[i] = (short) ((Long) peer.get("port")).shortValue(); } reply.setPeers(addresses, ports); return (new Object[] {reply, torrent}); } } else { if (PRUDPPacketTracker.VERSION == 1) { PRUDPPacketReplyScrape reply = new PRUDPPacketReplyScrape(request.getTransactionId()); /* Long interval = (Long)root.get("interval"); if ( interval != null ){ reply.setInterval(interval.intValue()); } */ Map files = (Map) root.get("files"); byte[][] hashes = new byte[files.size()][]; int[] s_complete = new int[hashes.length]; int[] s_downloaded = new int[hashes.length]; int[] s_incomplete = new int[hashes.length]; Iterator it = files.keySet().iterator(); int pos = 0; while (it.hasNext()) { String hash_str = (String) it.next(); hashes[pos] = hash_str.getBytes(Constants.BYTE_ENCODING); Map details = (Map) files.get(hash_str); s_complete[pos] = ((Long) details.get("complete")).intValue(); s_incomplete[pos] = ((Long) details.get("incomplete")).intValue(); s_downloaded[pos] = ((Long) details.get("downloaded")).intValue(); pos++; } reply.setDetails(hashes, s_complete, s_downloaded, s_incomplete); return (new Object[] {reply, torrent}); } else { PRUDPPacketReplyScrape2 reply = new PRUDPPacketReplyScrape2(request.getTransactionId()); /* Long interval = (Long)root.get("interval"); if ( interval != null ){ reply.setInterval(interval.intValue()); } */ Map files = (Map) root.get("files"); int[] s_complete = new int[files.size()]; int[] s_downloaded = new int[s_complete.length]; int[] s_incomplete = new int[s_complete.length]; Iterator it = files.keySet().iterator(); int pos = 0; while (it.hasNext()) { String hash_str = (String) it.next(); Map details = (Map) files.get(hash_str); s_complete[pos] = ((Long) details.get("complete")).intValue(); s_incomplete[pos] = ((Long) details.get("incomplete")).intValue(); s_downloaded[pos] = ((Long) details.get("downloaded")).intValue(); pos++; } reply.setDetails(s_complete, s_downloaded, s_incomplete); return (new Object[] {reply, torrent}); } } }
protected long allocateConnectionId(String client_address) { try { random_mon.enter(); long id = random.nextLong(); Long new_key = new Long(id); connectionData new_data = new connectionData(client_address, id); // check for timeouts if (new_data.getTime() - last_timeout_check > 500) { last_timeout_check = new_data.getTime(); Iterator<Long> it = connection_id_map.keySet().iterator(); while (it.hasNext()) { Long key = it.next(); connectionData data = connection_id_map.get(key); if (new_data.getTime() - data.getTime() > CONNECTION_ID_LIFETIME) { // System.out.println( "TRTrackerServerProcessorUDP: connection id timeout" ); it.remove(); List<connectionData> cds = connection_ip_map.get(client_address); if (cds != null) { Iterator<connectionData> it2 = cds.iterator(); while (it2.hasNext()) { if (it2.next().getID() == key) { it2.remove(); break; } } if (cds.size() == 0) { connection_ip_map.remove(client_address); } } } else { // insertion order into map is time based - LinkedHashMap returns keys in same order break; } } } List<connectionData> cds = connection_ip_map.get(client_address); if (cds == null) { cds = new ArrayList<connectionData>(); connection_ip_map.put(client_address, cds); } cds.add(new_data); if (cds.size() > 512) { connectionData dead = cds.remove(0); connection_id_map.remove(dead.getID()); } connection_id_map.put(new_key, new_data); // System.out.println( "TRTrackerServerProcessorUDP: allocated:" + id + ", connection id map // size = " + connection_id_map.size()); return (id); } finally { random_mon.exit(); } }