Search in sources :

Example 71 with LogEvent

use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.

the class TRTrackerBTAnnouncerImpl method constructUrl.

public URL constructUrl(String evt, URL _url) throws Exception {
    String url = _url.toString();
    StringBuffer request = new StringBuffer(url);
    // if url already has a query component then just append our parameters on the end
    if (url.indexOf('?') != -1) {
        request.append('&');
    } else {
        request.append('?');
    }
    // the client-id stuff RELIES on info_hash being the FIRST parameter added by
    // us to the URL, so don't change it!
    request.append(info_hash);
    request.append(tracker_peer_id_str);
    String port_details = announce_data_provider.getCryptoLevel() == NetworkManager.CRYPTO_OVERRIDE_REQUIRED ? TRTrackerUtils.getPortsForURLFullCrypto() : TRTrackerUtils.getPortsForURL();
    request.append(port_details);
    request.append("&uploaded=").append(announce_data_provider.getTotalSent());
    request.append("&downloaded=").append(announce_data_provider.getTotalReceived());
    if (Constants.DOWNLOAD_SOURCES_PRETEND_COMPLETE) {
        request.append("&left=0");
    } else {
        request.append("&left=").append(announce_data_provider.getRemaining());
    }
    // 3017: added at request of tracker admins who want to be able to monitor swarm poisoning
    request.append("&corrupt=").append(announce_data_provider.getFailedHashCheck());
    // TrackerID extension
    if (tracker_id.length() > 0) {
        request.append("&trackerid=").append(tracker_id);
    }
    if (evt.length() != 0) {
        request.append("&event=").append(evt);
    }
    boolean stopped = evt.equals("stopped");
    if (stopped) {
        request.append("&numwant=0");
        if (stopped_for_queue) {
            request.append("&azq=1");
        }
    } else {
        // calculate how many peers we should ask for
        int numwant = Math.min(calculateNumWant(), userMaxNumwant);
        request.append("&numwant=").append(numwant);
    // no_peer_id has been made obsolete by 'compact'
    }
    // actually, leave this in, ask PARG why!
    request.append("&no_peer_id=1");
    String tracker_network = AENetworkClassifier.categoriseAddress(_url.getHost());
    // latest space saving measure, a compact return type where peers are returned
    // as 6 byte entries in a single byte[] (4 bytes ip, 2 byte port)
    // leave this as always supplied, ask PARG why
    request.append("&compact=1");
    // any explicit override takes precedence over any implicit override added
    // when hosting torrents
    String explicit_ips = COConfigurationManager.getStringParameter("Override Ip", "");
    String ip = null;
    // make sure this tracker network is enabled
    boolean network_ok = false;
    boolean normal_network_ok = false;
    if (peer_networks == null) {
        network_ok = true;
        normal_network_ok = true;
    } else {
        for (int i = 0; i < peer_networks.length; i++) {
            if (peer_networks[i] == AENetworkClassifier.AT_PUBLIC) {
                normal_network_ok = true;
            }
            if (peer_networks[i] == tracker_network) {
                network_ok = true;
            }
        }
    }
    if (!network_ok) {
        throw (new Exception("Network not enabled for url '" + _url + "'"));
    }
    String normal_explicit = null;
    if (explicit_ips.length() > 0) {
        // gotta select an appropriate override based on network type
        StringTokenizer tok = new StringTokenizer(explicit_ips, ";");
        while (tok.hasMoreTokens()) {
            String this_address = tok.nextToken().trim();
            if (this_address.length() > 0) {
                String cat = AENetworkClassifier.categoriseAddress(this_address);
                if (cat == AENetworkClassifier.AT_PUBLIC) {
                    normal_explicit = this_address;
                }
                if (tracker_network == cat) {
                    ip = this_address;
                    break;
                }
            }
        }
    }
    if (ip == null) {
        if (normal_network_ok && normal_explicit != null) {
            ip = normal_explicit;
        } else {
            if (ip_override != null && !TorrentUtils.isDecentralised(ip_override)) {
                ip = ip_override;
            }
        }
    }
    if (ip != null) {
        if (tracker_network == AENetworkClassifier.AT_PUBLIC) {
            try {
                ip = PRHelpers.DNSToIPAddress(ip);
            } catch (UnknownHostException e) {
                if (Logger.isEnabled())
                    Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "IP Override host resolution of '" + ip + "' fails, using unresolved address"));
            }
        }
        request.append("&ip=").append(ip);
    }
    if (COConfigurationManager.getBooleanParameter("Tracker Key Enable Client", true)) {
        request.append("&key=").append(helper.getTrackerKey());
    }
    String ext = announce_data_provider.getExtensions();
    if (ext != null) {
        while (ext.startsWith("&")) {
            ext = ext.substring(1);
        }
        request.append("&");
        request.append(ext);
    }
    request.append("&azver=" + TRTrackerAnnouncer.AZ_TRACKER_VERSION_CURRENT);
    if (az_tracker && !stopped) {
        int up = announce_data_provider.getUploadSpeedKBSec(evt.equals("started"));
        if (up > 0) {
            request.append("&azup=").append(up);
        }
        String as = NetworkAdmin.getSingleton().getCurrentASN().getAS();
        if (as.length() > 0) {
            request.append("&azas=").append(URLEncoder.encode(as, "UTF8"));
        }
        DHTNetworkPosition best_position = DHTNetworkPositionManager.getBestLocalPosition();
        if (best_position != null) {
            try {
                byte[] bytes = DHTNetworkPositionManager.serialisePosition(best_position);
                request.append("&aznp=").append(Base32.encode(bytes));
            } catch (Throwable e) {
                Debug.printStackTrace(e);
            }
        }
    }
    if (tracker_network == AENetworkClassifier.AT_I2P) {
        String temp = request.toString();
        int pos = temp.indexOf('?');
        String head = temp.substring(0, pos);
        String tail = temp.substring(pos + 1);
        String[] bits = tail.split("&");
        Map<String, String> map = new HashMap<>();
        for (String bit : bits) {
            String[] arg = bit.split("=");
            map.put(arg[0], arg[1]);
        }
        tail = "";
        for (String str : new String[] { "info_hash", "peer_id", "port", "ip", "uploaded", "downloaded", "left", "compact", "event", "numwant" }) {
            String val = map.get(str);
            if (val != null) {
                tail += (tail.length() == 0 ? "" : "&") + str + "=" + map.get(str);
            }
        }
        request = new StringBuffer(head + "?" + tail);
    }
    return new URL(request.toString());
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) ClientIDException(com.biglybt.pif.clientid.ClientIDException) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) DHTNetworkPosition(com.biglybt.core.dht.netcoords.DHTNetworkPosition)

Example 72 with LogEvent

use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.

the class TRTrackerBTAnnouncerImpl method announceHTTPSupport.

private String announceHTTPSupport(// overwritten if redirected
URL[] tracker_url, URL original_reqUrl, Proxy proxy, boolean first_effort, ByteArrayOutputStream message) throws IOException {
    TRTrackerUtils.checkForBlacklistedURLs(original_reqUrl);
    URL reqUrl = TRTrackerUtils.adjustURLForHosting(original_reqUrl);
    reqUrl = AddressUtils.adjustURL(reqUrl);
    if (reqUrl != original_reqUrl) {
        if (Logger.isEnabled()) {
            Logger.log(new LogEvent(torrent, LOGID, "    HTTP: url adjusted to " + reqUrl));
        }
    }
    String failure_reason = null;
    HttpURLConnection con;
    Properties http_properties = new Properties();
    http_properties.put(ClientIDGenerator.PR_URL, reqUrl);
    if (proxy != null) {
        http_properties.put(ClientIDGenerator.PR_PROXY, proxy);
    }
    if (enable_sni_hack) {
        http_properties.put(ClientIDGenerator.PR_SNI_HACK, true);
    }
    try {
        ClientIDManagerImpl.getSingleton().generateHTTPProperties(torrent_hash.getBytes(), http_properties);
    } catch (ClientIDException e) {
        throw (new IOException(e.getMessage()));
    }
    reqUrl = (URL) http_properties.get(ClientIDGenerator.PR_URL);
    boolean is_https = reqUrl.getProtocol().equalsIgnoreCase("https");
    if (is_https) {
        // see ConfigurationChecker for SSL client defaults
        HttpsURLConnection ssl_con;
        if (proxy == null) {
            ssl_con = (HttpsURLConnection) reqUrl.openConnection();
        } else {
            ssl_con = (HttpsURLConnection) reqUrl.openConnection(proxy);
        }
        if (!internal_error_hack) {
            ssl_con.setHostnameVerifier(new HostnameVerifier() {

                @Override
                public boolean verify(String host, SSLSession session) {
                    return (true);
                }
            });
        }
        if (dh_hack) {
            UrlUtils.DHHackIt(ssl_con);
        }
        if (!first_effort) {
            // meh, some https trackers are just screwed
            TrustManager[] trustAllCerts = SESecurityManager.getAllTrustingTrustManager();
            try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, RandomUtils.SECURE_RANDOM);
                SSLSocketFactory factory = sc.getSocketFactory();
                ssl_con.setSSLSocketFactory(factory);
            } catch (Throwable e) {
            }
        }
        con = ssl_con;
    } else {
        if (proxy == null) {
            con = (HttpURLConnection) reqUrl.openConnection();
        } else {
            con = (HttpURLConnection) reqUrl.openConnection(proxy);
        }
    }
    // we want this true but some plugins (grrr) set the global default not to follow
    // redirects
    con.setInstanceFollowRedirects(true);
    String user_agent = (String) http_properties.get(ClientIDGenerator.PR_USER_AGENT);
    if (user_agent != null) {
        con.setRequestProperty("User-Agent", user_agent);
    }
    con.setRequestProperty("Connection", "close");
    // some trackers support gzip encoding of replies
    con.addRequestProperty("Accept-Encoding", "gzip");
    try {
        try {
            con.connect();
        } catch (AEProxyFactory.UnknownHostException e) {
            throw (new UnknownHostException(e.getMessage()));
        } catch (IOException e) {
            if (is_https) {
                String msg = Debug.getNestedExceptionMessage(e);
                if (msg.contains("unrecognized_name")) {
                    // SNI borkage - used to fix by globally disabling SNI but this screws too many other things
                    enable_sni_hack = true;
                } else if (msg.contains("internal_error") || msg.contains("handshake_failure")) {
                    internal_error_hack = true;
                } else if (msg.contains("DH keypair")) {
                    dh_hack = true;
                }
            }
            throw (e);
        }
        InputStream is = null;
        try {
            is = con.getInputStream();
            String resulting_url_str = con.getURL().toString();
            if (!reqUrl.toString().equals(resulting_url_str)) {
                // some kind of redirect has occurred. Unfortunately we can't get at the underlying
                // redirection reason (temp, perm etc) so we support the use of an explicit indicator
                // in the resulting url
                String marker = "permredirect=1";
                int pos = resulting_url_str.indexOf(marker);
                if (pos != -1) {
                    // include the '&' or '?'
                    pos = pos - 1;
                    try {
                        URL redirect_url = new URL(resulting_url_str.substring(0, pos));
                        tracker_url[0] = redirect_url;
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
            String encoding = con.getHeaderField("content-encoding");
            boolean gzip = encoding != null && encoding.equalsIgnoreCase("gzip");
            if (gzip) {
                is = new GZIPInputStream(is);
            }
            // there are some trackers out there that don't set content length correctly
            // so we can't reliably use it :(
            // con.getContentLength();
            int content_length = -1;
            // System.out.println(length);
            byte[] data = new byte[1024];
            int num_read = 0;
            while (content_length <= 0 || num_read < content_length) {
                try {
                    int len = is.read(data);
                    if (len > 0) {
                        message.write(data, 0, len);
                        num_read += len;
                        if (num_read > 128 * 1024) {
                            // someone's sending us junk, bail out
                            message.reset();
                            throw (new Exception("Tracker response invalid (too large)"));
                        }
                    } else if (len == 0) {
                        Thread.sleep(20);
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    if (Logger.isEnabled()) {
                        Logger.log(new LogEvent(torrent, LOGID, "Exception while Requesting Tracker", e));
                        Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Message Received was : " + message));
                    }
                    failure_reason = exceptionToString(e);
                    break;
                }
            }
            if (Logger.isEnabled())
                Logger.log(new LogEvent(torrent, LOGID, "Tracker Announcer [" + lastUsedUrl + "] has received : " + message));
        } catch (SSLException e) {
            throw (e);
        } catch (Exception e) {
            // e.printStackTrace();
            failure_reason = exceptionToString(e);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (Exception e) {
                }
                is = null;
            }
        }
    } finally {
        con.disconnect();
    }
    return (failure_reason);
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) LogEvent(com.biglybt.core.logging.LogEvent) GZIPInputStream(java.util.zip.GZIPInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) AEProxyFactory(com.biglybt.core.proxy.AEProxyFactory)

Example 73 with LogEvent

use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.

the class TRTrackerBTAnnouncerImpl method updateOld.

private byte[] updateOld(URL[] tracker_url, URL reqUrl) throws Exception {
    // set context in case authentication dialog is required
    boolean errorLevel = true;
    try {
        TorrentUtils.setTLSTorrentHash(torrent_hash);
        for (int i = 0; i < 2; i++) {
            String failure_reason = null;
            String protocol = reqUrl.getProtocol();
            try {
                if (Logger.isEnabled()) {
                    Logger.log(new LogEvent(torrent, LOGID, "Tracker Announcer is Requesting: " + reqUrl));
                }
                ByteArrayOutputStream message = new ByteArrayOutputStream();
                URL udpAnnounceURL = null;
                boolean udp_probe = false;
                if (protocol.equalsIgnoreCase("udp")) {
                    if (udpAnnounceEnabled) {
                        udpAnnounceURL = reqUrl;
                    } else {
                        throw (new IOException("UDP Tracker protocol disabled"));
                    }
                } else if (protocol.equalsIgnoreCase("http") && (!az_tracker) && (!TorrentUtils.isReallyPrivate(torrent)) && announceCount % autoUDPprobeEvery == 0 && udpProbeEnabled && udpAnnounceEnabled) {
                    if ((stopped || announceCount == 0 || (announceCount < trackerUrlLists.size() && announceFailCount == announceCount)) && !TRTrackerUtils.isUDPProbeOK(reqUrl)) {
                    // skip probe
                    } else {
                        String tracker_network = AENetworkClassifier.categoriseAddress(reqUrl.getHost());
                        if (tracker_network == AENetworkClassifier.AT_PUBLIC) {
                            udpAnnounceURL = new URL(reqUrl.toString().replaceFirst("^http", "udp"));
                            udp_probe = true;
                        }
                    }
                }
                if (udpAnnounceURL != null) {
                    failure_reason = announceUDP(reqUrl, message, udp_probe);
                    if ((failure_reason != null || message.size() == 0) && udp_probe) {
                        // automatic UDP probe failed, use HTTP again
                        udpAnnounceURL = null;
                        if (autoUDPprobeEvery < 16) {
                            autoUDPprobeEvery <<= 1;
                        } else {
                            // unregister in case the tracker somehow changed its capabilities
                            TRTrackerUtils.setUDPProbeResult(reqUrl, false);
                        }
                        if (Logger.isEnabled()) {
                            Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "redirection of http announce [" + tracker_url[0] + "] to udp failed, will retry in " + autoUDPprobeEvery + " announces"));
                        }
                    } else if (failure_reason == null && udp_probe) {
                        TRTrackerUtils.setUDPProbeResult(reqUrl, true);
                        if (Logger.isEnabled()) {
                            Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "redirection of http announce [" + tracker_url[0] + "] to udp successful"));
                        }
                        autoUDPprobeEvery = 1;
                        autoUDPProbeSuccessCount++;
                    }
                }
                announceCount++;
                if (udpAnnounceURL == null) {
                    boolean failed = false;
                    if (!az_tracker && !tcpAnnounceEnabled) {
                        String tracker_network = AENetworkClassifier.categoriseAddress(reqUrl.getHost());
                        if (tracker_network == AENetworkClassifier.AT_PUBLIC) {
                            failure_reason = "HTTP Tracker protocol disabled";
                            failed = true;
                        }
                    }
                    if (!failed) {
                        failure_reason = announceHTTP(tracker_url, reqUrl, message, i == 0);
                    }
                }
                if (message.size() > 0) {
                    return (message.toByteArray());
                }
                if (failure_reason == null) {
                    failure_reason = "No data received from tracker";
                    if (reqUrl.getProtocol().equalsIgnoreCase("udp")) {
                        errorLevel = false;
                    }
                }
            } catch (SSLException e) {
                if (i == 0) {
                    if (SESecurityManager.installServerCertificates(reqUrl) != null) {
                        // retry with new certificate
                        continue;
                    }
                    failure_reason = exceptionToString(e);
                } else {
                    failure_reason = exceptionToString(e);
                }
            } catch (IOException e) {
                if (e instanceof UnknownHostException || e instanceof ConnectException) {
                    errorLevel = false;
                }
                if (i == 0 && protocol.toLowerCase().startsWith("http")) {
                    URL retry_url = UrlUtils.getIPV4Fallback(reqUrl);
                    if (retry_url != null) {
                        reqUrl = retry_url;
                        continue;
                    }
                }
                failure_reason = exceptionToString(e);
            } catch (Exception e) {
                // e.printStackTrace();
                failure_reason = exceptionToString(e);
            }
            if (failure_reason != null && failure_reason.contains("401")) {
                failure_reason = "Tracker authentication failed";
                errorLevel = false;
            }
            if (Logger.isEnabled())
                Logger.log(new LogEvent(torrent, LOGID, errorLevel ? LogEvent.LT_ERROR : LogEvent.LT_WARNING, "Exception while processing the Tracker Request for " + reqUrl + ": " + failure_reason));
            throw (new Exception(failure_reason));
        }
        throw (new Exception("Internal Error: should never get here"));
    } finally {
        TorrentUtils.setTLSTorrentHash(null);
    }
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ClientIDException(com.biglybt.pif.clientid.ClientIDException) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 74 with LogEvent

use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.

the class TRTrackerBTAnnouncerImpl method decodeTrackerResponse.

protected TRTrackerAnnouncerResponseImpl decodeTrackerResponse(URL url, byte[] data) {
    String failure_reason;
    if (data == null) {
        failure_reason = "no response";
    } else {
        try {
            // parse the metadata
            Map metaData = null;
            try {
                metaData = BDecoder.decode(data);
                // obey any peers source restrictions
                Object o = metaData.get("az_ps");
                if (o instanceof List) {
                    List peer_sources = (List) o;
                    List x = new ArrayList();
                    for (int i = 0; i < peer_sources.size(); i++) {
                        Object o1 = peer_sources.get(i);
                        if (o1 instanceof byte[]) {
                            x.add(new String((byte[]) o1));
                        }
                    }
                    String[] y = new String[x.size()];
                    x.toArray(y);
                    announce_data_provider.setPeerSources(y);
                }
                try {
                    byte[] b_warning_message = (byte[]) metaData.get("warning message");
                    if (b_warning_message != null && COConfigurationManager.getBooleanParameter("Tracker Client Show Warnings")) {
                        String warning_message = new String(b_warning_message);
                        if (!warning_message.equals(last_tracker_message)) {
                            last_tracker_message = warning_message;
                            boolean log_it = false;
                            try {
                                class_mon.enter();
                                String last_warning_message = (String) tracker_report_map.get(url.getHost());
                                if (last_warning_message == null || !warning_message.equals(last_warning_message)) {
                                    log_it = true;
                                    tracker_report_map.put(url.getHost(), warning_message);
                                }
                            } finally {
                                class_mon.exit();
                            }
                            if (log_it) {
                                Logger.logTextResource(new LogAlert(torrent, LogAlert.UNREPEATABLE, LogAlert.AT_WARNING, "TrackerClient.announce.warningmessage"), new String[] { announce_data_provider.getName(), warning_message });
                            }
                        }
                    }
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                }
                long time_to_wait;
                try {
                    if (!metaData.containsKey("interval")) {
                        throw (new Exception("interval missing"));
                    }
                    tracker_interval = time_to_wait = ((Long) metaData.get("interval")).longValue();
                    Long raw_min_interval = (Long) metaData.get("min interval");
                    if (Logger.isEnabled()) {
                        Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "Received from announce: 'interval' = " + time_to_wait + "; 'min interval' = " + raw_min_interval));
                    }
                    // guard against crazy return values
                    if (time_to_wait < 0 || time_to_wait > 0xffffffffL) {
                        time_to_wait = 0xffffffffL;
                    }
                    if (raw_min_interval != null) {
                        tracker_min_interval = min_interval = raw_min_interval.longValue();
                        // Note: Many trackers set min_interval and interval the same.
                        if (min_interval < 1) {
                            if (Logger.isEnabled()) {
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "Tracker being silly and " + "returning a 'min interval' of less than 1 second (" + min_interval + ")"));
                            }
                            min_interval = 0;
                        } else if (min_interval > time_to_wait) {
                            if (Logger.isEnabled()) {
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "Tracker being silly and " + "returning a 'min interval' (" + min_interval + ") greater than recommended announce 'interval'" + " (" + time_to_wait + ")"));
                            }
                            min_interval = 0;
                        }
                    } else {
                        // tracker owners complain we announce too much but then never
                        // implement "min interval".  So take it into our own hands
                        // and enforce a min_interval of interval when there is no
                        // "min interval"
                        min_interval = time_to_wait > 30 ? time_to_wait - 10 : time_to_wait;
                    }
                    if (userMinInterval != 0) {
                        time_to_wait = Math.max(userMinInterval, time_to_wait);
                        min_interval = Math.max(min_interval, userMinInterval);
                        if (Logger.isEnabled()) {
                            Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_INFORMATION, "Overriding with user settings: 'interval' = " + time_to_wait + "; 'min interval' = " + min_interval));
                        }
                    }
                    // mess up the "ignore useless values"
                    if (time_to_wait > 30) {
                        time_to_wait -= 10;
                    }
                    if (metaData.containsKey("failure reason")) {
                        throw (new Exception("Tracker reported 'failure reason'"));
                    }
                } catch (Exception e) {
                    byte[] failure_reason_bytes = (byte[]) metaData.get("failure reason");
                    if (failure_reason_bytes == null) {
                        if (Logger.isEnabled())
                            Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_WARNING, "Problems with Tracker, will retry in " + getErrorRetryInterval() + "ms"));
                        return (new TRTrackerAnnouncerResponseImpl(url, torrent_hash, TRTrackerAnnouncerResponse.ST_OFFLINE, getErrorRetryInterval(), "Unknown cause"));
                    }
                    // explicit failure from the tracker
                    failure_reason = new String(failure_reason_bytes, Constants.DEFAULT_ENCODING);
                    return (new TRTrackerAnnouncerResponseImpl(url, torrent_hash, TRTrackerAnnouncerResponse.ST_REPORTED_ERROR, getErrorRetryInterval(), failure_reason));
                }
                // System.out.println("Response from Announce: " + new String(data));
                Long incomplete_l = getLong(metaData, "incomplete");
                Long complete_l = getLong(metaData, "complete");
                Long downloaded_l = getLong(metaData, "downloaded");
                if (incomplete_l != null || complete_l != null) {
                    if (Logger.isEnabled())
                        Logger.log(new LogEvent(torrent, LOGID, "ANNOUNCE SCRAPE1: seeds=" + complete_l + " peers=" + incomplete_l));
                }
                // TrackerID extension, used by phpbt trackers.
                // We reply with '&trackerid=1234' when we receive
                // '10:tracker id4:1234e' on announce reply.
                // NOTE: we receive as 'tracker id' but reply as 'trackerid'
                byte[] trackerid = (byte[]) metaData.get("tracker id");
                if (trackerid != null) {
                    tracker_id = new String(trackerid);
                }
                byte[] crypto_flags = (byte[]) metaData.get("crypto_flags");
                // build the list of peers
                List valid_meta_peers = new ArrayList();
                Object meta_peers_peek = metaData.get("peers");
                Long az_compact_l = (Long) metaData.get("azcompact");
                long az_compact = az_compact_l == null ? 0 : az_compact_l.longValue();
                boolean this_is_az_tracker = az_compact == 2;
                if (az_tracker != this_is_az_tracker || lastUsedUrl != lastAZTrackerCheckedURL) {
                    lastAZTrackerCheckedURL = lastUsedUrl;
                    az_tracker = this_is_az_tracker;
                    TRTrackerUtils.setAZTracker(url, az_tracker);
                }
                if (az_compact == 2) {
                    // latest return to dictionary based data
                    List meta_peers = (List) meta_peers_peek;
                    int peers_length = meta_peers.size();
                    if (Logger.isEnabled()) {
                        Logger.log(new LogEvent(torrent, LOGID, "ANNOUNCE CompactPeers2: num=" + peers_length));
                    }
                    if (peers_length > 1) {
                        // calculate average rtt to use for those with no rtt
                        long total_rtt = 0;
                        int rtt_count = 0;
                        for (int i = 0; i < peers_length; i++) {
                            Map peer = (Map) meta_peers.get(i);
                            Long l_rtt = (Long) peer.get("r");
                            if (l_rtt != null) {
                                long rtt = l_rtt.longValue();
                                if (rtt <= 0) {
                                    // invalid, remove
                                    peer.remove("r");
                                } else {
                                    total_rtt += rtt;
                                }
                                rtt_count++;
                            }
                        }
                        final int average_rtt = (int) (rtt_count == 0 ? 0 : (total_rtt / rtt_count));
                        // sort into smallest rtt order with biased at front
                        Collections.sort(meta_peers, new Comparator() {

                            @Override
                            public int compare(Object o1, Object o2) {
                                Map map1 = (Map) o1;
                                Map map2 = (Map) o2;
                                Long l_rtt1 = (Long) map1.get("r");
                                Long l_rtt2 = (Long) map2.get("r");
                                boolean biased_1 = map1.containsKey("b");
                                boolean biased_2 = map2.containsKey("b");
                                if (biased_1 == biased_2) {
                                    int rtt1 = l_rtt1 == null ? average_rtt : l_rtt1.intValue();
                                    int rtt2 = l_rtt2 == null ? average_rtt : l_rtt2.intValue();
                                    return (rtt1 - rtt2);
                                } else if (biased_1) {
                                    return (-1);
                                } else {
                                    return (+1);
                                }
                            }
                        });
                        // interleave non-biased peers with good rtt
                        int biased_pos = peers_length;
                        int non_biased_pos = peers_length;
                        for (int i = 0; i < peers_length; i++) {
                            Map peer = (Map) meta_peers.get(i);
                            if (peer.containsKey("b")) {
                                if (i == 0) {
                                    biased_pos = i;
                                }
                            } else {
                                non_biased_pos = i;
                                break;
                            }
                        }
                        List new_peers = new ArrayList(peers_length);
                        int non_biased_start = non_biased_pos;
                        boolean last_biased = true;
                        while (biased_pos < non_biased_start || non_biased_pos < peers_length) {
                            if (biased_pos < non_biased_start) {
                                if (non_biased_pos < peers_length) {
                                    Map biased = (Map) meta_peers.get(biased_pos);
                                    Map non_biased = (Map) meta_peers.get(non_biased_pos);
                                    boolean use_biased;
                                    if (!last_biased) {
                                        use_biased = true;
                                    } else {
                                        Long l_rtt_biased = (Long) biased.get("r");
                                        Long l_rtt_non_biased = (Long) non_biased.get("r");
                                        int biased_rtt = l_rtt_biased == null ? average_rtt : l_rtt_biased.intValue();
                                        int non_biased_rtt = l_rtt_non_biased == null ? average_rtt : l_rtt_non_biased.intValue();
                                        use_biased = non_biased_rtt >= biased_rtt;
                                    }
                                    if (use_biased) {
                                        new_peers.add(biased);
                                        biased_pos++;
                                    } else {
                                        new_peers.add(non_biased);
                                        non_biased_pos++;
                                    }
                                    last_biased = use_biased;
                                } else {
                                    new_peers.add(meta_peers.get(biased_pos++));
                                }
                            } else {
                                new_peers.add(meta_peers.get(non_biased_pos++));
                            }
                        }
                        meta_peers = new_peers;
                    }
                    for (int i = 0; i < peers_length; i++) {
                        Map peer = (Map) meta_peers.get(i);
                        try {
                            byte[] ip_bytes = (byte[]) peer.get("i");
                            String ip;
                            if (ip_bytes.length == 4) {
                                int ip1 = 0xff & ip_bytes[0];
                                int ip2 = 0xff & ip_bytes[1];
                                int ip3 = 0xff & ip_bytes[2];
                                int ip4 = 0xff & ip_bytes[3];
                                ip = ip1 + "." + ip2 + "." + ip3 + "." + ip4;
                            } else {
                                StringBuilder sb = new StringBuilder(39);
                                for (int j = 0; j < 16; j += 2) {
                                    sb.append(Integer.toHexString(((ip_bytes[j] << 8) & 0xff00) | (ip_bytes[j + 1] & 0x00ff)));
                                    if (j < 14) {
                                        sb.append(":");
                                    }
                                }
                                ip = sb.toString();
                            }
                            byte[] tcp_bytes = (byte[]) peer.get("t");
                            int tcp_port = ((tcp_bytes[0] & 0xff) << 8) + (tcp_bytes[1] & 0xff);
                            byte[] peer_peer_id = TRTrackerAnnouncerFactoryImpl.getAnonymousPeerId(ip, tcp_port);
                            int udp_port = 0;
                            byte[] udp_bytes = (byte[]) peer.get("u");
                            if (udp_bytes != null) {
                                if (udp_bytes.length == 0) {
                                    udp_port = tcp_port;
                                } else {
                                    udp_port = ((udp_bytes[0] & 0xff) << 8) + (udp_bytes[1] & 0xff);
                                }
                            }
                            int http_port = 0;
                            byte[] http_bytes = (byte[]) peer.get("h");
                            if (http_bytes != null) {
                                http_port = ((http_bytes[0] & 0xff) << 8) + (http_bytes[1] & 0xff);
                            }
                            short protocol = DownloadAnnounceResultPeer.PROTOCOL_NORMAL;
                            byte[] protocol_bytes = (byte[]) peer.get("c");
                            if (protocol_bytes != null) {
                                protocol = (protocol_bytes[0] & 0x01) == 0 ? DownloadAnnounceResultPeer.PROTOCOL_NORMAL : DownloadAnnounceResultPeer.PROTOCOL_CRYPT;
                            }
                            Long l_azver = (Long) peer.get("v");
                            byte az_ver = l_azver == null ? TRTrackerAnnouncer.AZ_TRACKER_VERSION_1 : l_azver.byteValue();
                            Long l_up_speed = (Long) peer.get("s");
                            boolean biased = peer.containsKey("b");
                            if (biased) {
                                PeerClassifier.setAzureusIP(ip);
                            }
                            TRTrackerAnnouncerResponsePeerImpl new_peer = new TRTrackerAnnouncerResponsePeerImpl(PEPeerSource.PS_BT_TRACKER, peer_peer_id, ip, tcp_port, udp_port, http_port, protocol, az_ver, l_up_speed == null ? 0 : l_up_speed.shortValue());
                            if (Logger.isEnabled()) {
                                String extra = "";
                                Long l_rtt = (Long) peer.get("r");
                                if (l_rtt != null) {
                                    extra = ",rtt=" + l_rtt;
                                }
                                if (biased) {
                                    extra += ",biased";
                                }
                                Logger.log(new LogEvent(torrent, LOGID, "AZ2-COMPACT PEER: " + new_peer.getString() + extra));
                            }
                            valid_meta_peers.add(new_peer);
                        } catch (Throwable e) {
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid az2 peer received: " + peer));
                        }
                    }
                } else if (meta_peers_peek instanceof List) {
                    // old style non-compact
                    List meta_peers = (List) meta_peers_peek;
                    // for every peer
                    int peers_length = meta_peers.size();
                    if (Logger.isEnabled()) {
                        Logger.log(new LogEvent(torrent, LOGID, "ANNOUNCE old style non-compact: num=" + peers_length));
                    }
                    if (crypto_flags != null && peers_length != crypto_flags.length) {
                        crypto_flags = null;
                        if (Logger.isEnabled())
                            Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid crypto_flags returned: length mismatch"));
                    }
                    for (int i = 0; i < peers_length; i++) {
                        Map peer = (Map) meta_peers.get(i);
                        Object s_peerid = peer.get("peer id");
                        Object s_ip = peer.get("ip");
                        Object s_port = peer.get("port");
                        if (s_ip != null && s_port != null) {
                            // get the peer ip address
                            String base_ip = new String((byte[]) s_ip, Constants.DEFAULT_ENCODING);
                            String ip = AddressUtils.convertToShortForm(base_ip);
                            if (ip == null) {
                                // corrupt address, skip
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Skipping invalid address: " + base_ip));
                                continue;
                            }
                            // get the peer port number - should be Long but have seen byte[] on occasion
                            int peer_port = s_port instanceof byte[] ? Integer.parseInt(new String((byte[]) s_port)) : ((Long) s_port).intValue();
                            // still can't make outgoing connections that we already can't make
                            if (peer_port > 65535)
                                peer_port -= 65536;
                            if (peer_port < 0)
                                peer_port += 65536;
                            if (peer_port < 0 || peer_port > 65535) {
                                if (Logger.isEnabled())
                                    Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid peer port given: " + ip + ": " + peer_port));
                                continue;
                            }
                            byte[] peer_peer_id;
                            if (s_peerid == null) {
                                // Debug.out(ip + ": tracker did not give peerID in reply");
                                peer_peer_id = TRTrackerAnnouncerFactoryImpl.getAnonymousPeerId(ip, peer_port);
                            // System.out.println("generated peer id" + new String(peerId) + "/" + ByteFormatter.nicePrint( peerId, true ));
                            } else {
                                peer_peer_id = (byte[]) s_peerid;
                            }
                            short protocol;
                            if (crypto_flags == null) {
                                protocol = DownloadAnnounceResultPeer.PROTOCOL_NORMAL;
                            } else {
                                protocol = crypto_flags[i] == 0 ? DownloadAnnounceResultPeer.PROTOCOL_NORMAL : DownloadAnnounceResultPeer.PROTOCOL_CRYPT;
                            }
                            int udp_port = 0;
                            int http_port = 0;
                            TRTrackerAnnouncerResponsePeerImpl new_peer = new TRTrackerAnnouncerResponsePeerImpl(PEPeerSource.PS_BT_TRACKER, peer_peer_id, ip, peer_port, udp_port, http_port, protocol, TRTrackerAnnouncer.AZ_TRACKER_VERSION_1, (short) 0);
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(torrent, LOGID, "NON-COMPACT PEER: " + new_peer.getString()));
                            valid_meta_peers.add(new_peer);
                        }
                    }
                } else if (meta_peers_peek instanceof byte[]) {
                    // byte[] for compact returns
                    byte[] meta_peers = (byte[]) meta_peers_peek;
                    String tracker_network = AENetworkClassifier.categoriseAddress(url.getHost());
                    if (tracker_network == AENetworkClassifier.AT_I2P && (meta_peers.length % 32 == 0)) {
                        for (int i = 0; i < meta_peers.length; i += 32) {
                            byte[] i2p_id = new byte[32];
                            byte[] peer_peer_id = new byte[20];
                            System.arraycopy(meta_peers, i, i2p_id, 0, 32);
                            System.arraycopy(meta_peers, i, peer_peer_id, 0, 20);
                            String hostname = Base32.encode(i2p_id).toLowerCase(Locale.US) + ".b32.i2p";
                            TRTrackerAnnouncerResponsePeerImpl peer = new TRTrackerAnnouncerResponsePeerImpl(PEPeerSource.PS_BT_TRACKER, peer_peer_id, hostname, 6881, 0, 0, DownloadAnnounceResultPeer.PROTOCOL_NORMAL, TRTrackerAnnouncer.AZ_TRACKER_VERSION_1, (short) 0);
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(torrent, LOGID, "COMPACT PEER: " + peer.getString()));
                            valid_meta_peers.add(peer);
                        }
                    } else {
                        int entry_size = az_compact == 1 ? 9 : 6;
                        if (crypto_flags != null && meta_peers.length / entry_size != crypto_flags.length) {
                            crypto_flags = null;
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid crypto_flags returned: length mismatch"));
                        }
                        int peer_number = 0;
                        if (Logger.isEnabled()) {
                            Logger.log(new LogEvent(torrent, LOGID, "ANNOUNCE CompactPeers: num=" + (meta_peers.length / entry_size)));
                        }
                        int peers_length = meta_peers.length;
                        for (int i = 0; i < (peers_length / entry_size) * entry_size; i += entry_size) {
                            peer_number++;
                            int ip1 = 0xFF & meta_peers[i];
                            int ip2 = 0xFF & meta_peers[i + 1];
                            int ip3 = 0xFF & meta_peers[i + 2];
                            int ip4 = 0xFF & meta_peers[i + 3];
                            int po1 = 0xFF & meta_peers[i + 4];
                            int po2 = 0xFF & meta_peers[i + 5];
                            String ip = "" + ip1 + "." + ip2 + "." + ip3 + "." + ip4;
                            int tcp_port = po1 * 256 + po2;
                            if (tcp_port < 0 || tcp_port > 65535) {
                                if (Logger.isEnabled())
                                    Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid compact peer port given: " + ip + ": " + tcp_port));
                                continue;
                            }
                            byte[] peer_peer_id = TRTrackerAnnouncerFactoryImpl.getAnonymousPeerId(ip, tcp_port);
                            short protocol;
                            int udp_port;
                            if (az_compact == 1) {
                                int upo1 = 0xFF & meta_peers[i + 6];
                                int upo2 = 0xFF & meta_peers[i + 7];
                                udp_port = upo1 * 256 + upo2;
                                byte flags = meta_peers[i + 8];
                                protocol = (flags & 0x01) == 0 ? DownloadAnnounceResultPeer.PROTOCOL_NORMAL : DownloadAnnounceResultPeer.PROTOCOL_CRYPT;
                            } else {
                                if (crypto_flags == null) {
                                    protocol = DownloadAnnounceResultPeer.PROTOCOL_NORMAL;
                                } else {
                                    protocol = crypto_flags[peer_number - 1] == 0 ? DownloadAnnounceResultPeer.PROTOCOL_NORMAL : DownloadAnnounceResultPeer.PROTOCOL_CRYPT;
                                }
                                udp_port = 0;
                            }
                            int http_port = 0;
                            TRTrackerAnnouncerResponsePeerImpl peer = new TRTrackerAnnouncerResponsePeerImpl(PEPeerSource.PS_BT_TRACKER, peer_peer_id, ip, tcp_port, udp_port, http_port, protocol, TRTrackerAnnouncer.AZ_TRACKER_VERSION_1, (short) 0);
                            if (Logger.isEnabled())
                                Logger.log(new LogEvent(torrent, LOGID, "COMPACT PEER: " + peer.getString()));
                            valid_meta_peers.add(peer);
                        }
                    }
                } else if (meta_peers_peek instanceof Map) {
                    if (((Map) meta_peers_peek).size() != 0) {
                        throw (new IOException("peers missing from response"));
                    }
                } else if (!metaData.containsKey("peers6")) {
                // we got nothing useful under peers and no peers6 either
                // meh, seen a tracker that doesn't return anything when it has nothing
                // throw( new IOException( "peers missing from response" ));
                }
                final byte[] v6peers = (byte[]) metaData.get("peers6");
                if (v6peers != null) {
                    // 16 bytes for v6 + 2 bytes for port
                    final int entry_size = 18;
                    final byte[] rawAddr = new byte[16];
                    for (int i = 0; i < v6peers.length; i += entry_size) {
                        System.arraycopy(v6peers, i, rawAddr, 0, 16);
                        String ip = InetAddress.getByAddress(rawAddr).getHostAddress();
                        int po1 = 0xFF & v6peers[i + 16];
                        int po2 = 0xFF & v6peers[i + 17];
                        int tcp_port = po1 * 256 + po2;
                        if (tcp_port < 0 || tcp_port > 65535) {
                            if (Logger.isEnabled()) {
                                Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "Invalid compactv6 peer port given: " + ip + ": " + tcp_port));
                            }
                            continue;
                        }
                        byte[] peer_peer_id = TRTrackerAnnouncerFactoryImpl.getAnonymousPeerId(ip, tcp_port);
                        short protocol = DownloadAnnounceResultPeer.PROTOCOL_NORMAL;
                        TRTrackerAnnouncerResponsePeerImpl peer = new TRTrackerAnnouncerResponsePeerImpl(PEPeerSource.PS_BT_TRACKER, peer_peer_id, ip, tcp_port, 0, 0, protocol, TRTrackerAnnouncer.AZ_TRACKER_VERSION_1, (short) 0);
                        if (Logger.isEnabled()) {
                            Logger.log(new LogEvent(torrent, LOGID, "COMPACTv6 PEER: " + peer.getString()));
                        }
                        valid_meta_peers.add(peer);
                    }
                }
                TRTrackerAnnouncerResponsePeerImpl[] peers = new TRTrackerAnnouncerResponsePeerImpl[valid_meta_peers.size()];
                valid_meta_peers.toArray(peers);
                helper.addToTrackerCache(peers);
                TRTrackerAnnouncerResponseImpl resp = new TRTrackerAnnouncerResponseImpl(url, torrent_hash, TRTrackerAnnouncerResponse.ST_ONLINE, time_to_wait, peers);
                // reset failure retry interval on successful connect
                failure_added_time = 0;
                Map extensions = (Map) metaData.get("extensions");
                resp.setExtensions(extensions);
                if (extensions != null) {
                    if (complete_l == null) {
                        complete_l = (Long) extensions.get("complete");
                    }
                    if (incomplete_l == null) {
                        incomplete_l = (Long) extensions.get("incomplete");
                    }
                    if (Logger.isEnabled())
                        Logger.log(new LogEvent(torrent, LOGID, "ANNOUNCE SCRAPE2: seeds=" + complete_l + " peers=" + incomplete_l));
                    Object override = extensions.get("min interval override");
                    if (override != null && override instanceof Long) {
                        // this is to allow specific torrents to be refreshed more quickly
                        // if the tracker permits. Parg
                        min_interval_override = ((Long) override).longValue();
                    }
                }
                if (complete_l != null || incomplete_l != null || downloaded_l != null) {
                    int complete = complete_l == null ? 0 : complete_l.intValue();
                    int incomplete = incomplete_l == null ? 0 : incomplete_l.intValue();
                    int downloaded = downloaded_l == null ? -1 : downloaded_l.intValue();
                    if (complete < 0 || incomplete < 0) {
                        resp.setFailureReason(MessageText.getString("Tracker.announce.ignorePeerSeed", new String[] { (complete < 0 ? MessageText.getString("MyTorrentsView.seeds") + " == " + complete + ". " : "") + (incomplete < 0 ? MessageText.getString("MyTorrentsView.peers") + " == " + incomplete + ". " : "") }));
                    } else {
                        resp.setScrapeResult(complete, incomplete, downloaded);
                        TRTrackerScraper scraper = TRTrackerScraperFactory.getSingleton();
                        if (scraper != null) {
                            TRTrackerScraperResponse scrapeResponse = scraper.scrape(torrent, getTrackerURL());
                            if (scrapeResponse != null) {
                                long lNextScrapeTime = scrapeResponse.getNextScrapeStartTime();
                                long now = SystemTime.getCurrentTime();
                                long lNewNextScrapeTime = now + TRTrackerScraperResponseImpl.calcScrapeIntervalSecs(0, complete) * 1000L;
                                // make it look as if the scrape has just run. Important
                                // as seeding rules may make calculations on when the
                                // scrape value were set
                                scrapeResponse.setScrapeStartTime(now);
                                if (lNextScrapeTime < lNewNextScrapeTime) {
                                    scrapeResponse.setNextScrapeStartTime(lNewNextScrapeTime);
                                }
                                scrapeResponse.setSeedsPeers(complete, incomplete);
                                if (downloaded >= 0) {
                                    scrapeResponse.setCompleted(downloaded);
                                }
                            }
                        }
                    }
                }
                return (resp);
            } catch (IOException e) {
                if (metaData != null) {
                    byte[] failure_reason_bytes = (byte[]) metaData.get("failure reason");
                    if (failure_reason_bytes == null) {
                        Debug.printStackTrace(e);
                        failure_reason = "error: " + e.getMessage();
                    } else {
                        failure_reason = new String(failure_reason_bytes, Constants.DEFAULT_ENCODING);
                    }
                    return (new TRTrackerAnnouncerResponseImpl(url, torrent_hash, TRTrackerAnnouncerResponse.ST_REPORTED_ERROR, Math.max(tracker_interval, getErrorRetryInterval()), failure_reason));
                }
                // decode could fail if the tracker's returned, say, an HTTP response
                // indicating server overload
                String trace_data;
                if (data.length <= 150) {
                    trace_data = new String(data);
                } else {
                    trace_data = new String(data, 0, 150) + "...";
                }
                if (Logger.isEnabled())
                    Logger.log(new LogEvent(torrent, LOGID, LogEvent.LT_ERROR, "TRTrackerAnnouncer::invalid reply: " + trace_data));
                failure_reason = "invalid reply: " + trace_data;
            }
        } catch (Throwable e) {
            Debug.printStackTrace(e);
            failure_reason = "error: " + e.getMessage();
        }
    }
    return (new TRTrackerAnnouncerResponseImpl(url, torrent_hash, TRTrackerAnnouncerResponse.ST_OFFLINE, getErrorRetryInterval(), failure_reason));
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) IOException(java.io.IOException) LogAlert(com.biglybt.core.logging.LogAlert) ClientIDException(com.biglybt.pif.clientid.ClientIDException) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException)

Example 75 with LogEvent

use of com.biglybt.core.logging.LogEvent in project BiglyBT by BiglySoftware.

the class TrackerChecker method runScrapes.

private void runScrapes() {
    TRTrackerBTScraperResponseImpl nextResponseScraping = checkForNextScrape();
    if (Logger.isEnabled() && nextResponseScraping != oldResponse && nextResponseScraping != null) {
        Logger.log(new LogEvent(TorrentUtils.getDownloadManager(nextResponseScraping.getHash()), LOGID, LogEvent.LT_INFORMATION, "Next scrape will be " + nextResponseScraping.getURL() + " in " + ((nextResponseScraping.getNextScrapeStartTime() - SystemTime.getCurrentTime()) / 1000) + " sec,type=" + (nextResponseScraping.getTrackerStatus().getSupportsMultipeHashScrapes() ? "multi" : "single") + ",active=" + nextResponseScraping.getTrackerStatus().getNumActiveScrapes()));
    }
    long delay;
    if (nextResponseScraping == null) {
        // nothing going on, recheck in a min
        delay = 60000;
    } else {
        long scrape_time = nextResponseScraping.getNextScrapeStartTime();
        long time_to_scrape = scrape_time - SystemTime.getCurrentTime() + SystemTime.TIME_GRANULARITY_MILLIS;
        if (time_to_scrape <= 0) {
            if (nextResponseScraping.getTrackerStatus().getNumActiveScrapes() > 0) {
                // check if done scraping every 2 seconds, if no other
                // scrapes are scheduled.  If other scrapes are sceduled,
                // we would have got them from checkForNextScrape()
                delay = 2000;
            } else {
                try {
                    nextResponseScraping.getTrackerStatus().updateSingleHash(nextResponseScraping.getHash(), false);
                    // pick up next scrape fairly quickly
                    delay = 0;
                } catch (Throwable e) {
                    Debug.printStackTrace(e);
                    delay = 30000;
                }
            }
        } else {
            delay = time_to_scrape;
            if (delay > 30000) {
                // don't sleep too long in case new hashes are added etc.
                delay = 30000;
            }
        }
    }
    nextScrapeCheckOn = SystemTime.getCurrentTime() + delay;
    oldResponse = nextResponseScraping;
    // use tracker timer/thread pool
    TRTrackerBTAnnouncerImpl.tracker_timer.addEvent(nextScrapeCheckOn, this);
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent)

Aggregations

LogEvent (com.biglybt.core.logging.LogEvent)172 LogAlert (com.biglybt.core.logging.LogAlert)20 IOException (java.io.IOException)14 File (java.io.File)11 URL (java.net.URL)11 ArrayList (java.util.ArrayList)9 InetSocketAddress (java.net.InetSocketAddress)8 InputStream (java.io.InputStream)7 UnsupportedEncodingException (java.io.UnsupportedEncodingException)7 ZipInputStream (java.util.zip.ZipInputStream)7 CacheFileManagerException (com.biglybt.core.diskmanager.cache.CacheFileManagerException)6 TOTorrent (com.biglybt.core.torrent.TOTorrent)6 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)6 ResourceDownloader (com.biglybt.pif.utils.resourcedownloader.ResourceDownloader)6 UIFunctions (com.biglybt.ui.UIFunctions)6 SocketChannel (java.nio.channels.SocketChannel)6 Iterator (java.util.Iterator)6 ConnectionEndpoint (com.biglybt.core.networkmanager.ConnectionEndpoint)5 ClientIDException (com.biglybt.pif.clientid.ClientIDException)5 ParameterListener (com.biglybt.core.config.ParameterListener)4