Search in sources :

Example 21 with LogAlert

use of com.biglybt.core.logging.LogAlert 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 22 with LogAlert

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

the class AEJarBuilder method buildFromResources2.

private static long buildFromResources2(OutputStream os, ClassLoader class_loader, String resource_prefix, String[] resource_names, String sign_alias) throws IOException {
    if (sign_alias != null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(65536);
        long tim = buildFromResourcesSupport(new JarOutputStream(baos), class_loader, resource_prefix, resource_names);
        try {
            // leave this check in here as we might as well check for the alias
            SEKeyDetails kd = SESecurityManager.getKeyDetails(sign_alias);
            if (kd == null) {
                Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Certificate alias '" + sign_alias + "' not found, jar signing fails"));
                throw (new Exception("Certificate alias '" + sign_alias + "' not found "));
            }
            // WUJarSigner signer = new WUJarSigner(sign_alias, (PrivateKey)kd.getKey(), kd.getCertificateChain());
            AEJarSigner2 signer = new AEJarSigner2(sign_alias, SESecurityManager.getKeystoreName(), SESecurityManager.getKeystorePassword());
            signer.signJarStream(new ByteArrayInputStream(baos.toByteArray()), os);
            return (tim);
        } catch (Throwable e) {
            Debug.printStackTrace(e);
            throw (new IOException(e.getMessage()));
        }
    } else {
        JarOutputStream jos;
        if (os instanceof JarOutputStream) {
            jos = (JarOutputStream) os;
        } else {
            jos = new JarOutputStream(os);
        }
        return (buildFromResourcesSupport(jos, class_loader, resource_prefix, resource_names));
    }
}
Also used : SEKeyDetails(com.biglybt.core.security.SEKeyDetails) JarOutputStream(java.util.jar.JarOutputStream) LogAlert(com.biglybt.core.logging.LogAlert)

Example 23 with LogAlert

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

the class AEJarSigner2 method loadJarSigner.

protected void loadJarSigner() throws IOException {
    File tools_dir;
    String manual_tools_dir = COConfigurationManager.getStringParameter("Security.JAR.tools.dir");
    if (manual_tools_dir.length() == 0) {
        String java_home = System.getProperty("java.home");
        // if it ends in "jre" then go up one dir
        // then look for lib/tools.jar
        File jh = new File(java_home);
        if (jh.getName().equalsIgnoreCase("jre")) {
            jh = jh.getParentFile();
        } else {
            // otherwise, for 1.5, see if the JDK is also installed in default position
            String dir_name = jh.getName();
            if (dir_name.startsWith("jre")) {
                dir_name = "jdk" + dir_name.substring(3);
                jh = new File(jh.getParentFile(), dir_name);
            }
        }
        tools_dir = new File(jh, "lib");
    } else {
        tools_dir = new File(manual_tools_dir);
    }
    File tools_jar = new File(tools_dir, "tools.jar");
    if (tools_jar.exists()) {
        try {
            ClassLoader cl = new URLClassLoader(new URL[] { tools_jar.toURL() }, AEJarSigner2.class.getClassLoader());
            JarSigner_class = cl.loadClass("sun.security.tools.JarSigner");
        } catch (Throwable e) {
            Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.signfail"), new String[] { e.getMessage() });
            Debug.printStackTrace(e);
            throw (new IOException("JAR signing fails: " + e.getMessage()));
        }
    } else {
        Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.tools_not_found"), new String[] { tools_dir.toString() });
        throw (new IOException("JAR signing fails: tools.jar not found"));
    }
}
Also used : URLClassLoader(java.net.URLClassLoader) URLClassLoader(java.net.URLClassLoader) LogAlert(com.biglybt.core.logging.LogAlert)

Example 24 with LogAlert

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

the class AEJarSigner2 method signJarFile.

protected void signJarFile(File input_file) throws IOException {
    if (JarSigner_class == null) {
        loadJarSigner();
    }
    PrintStream old_err = null;
    PrintStream old_out = null;
    String failure_msg = null;
    try {
        Object jar_signer = JarSigner_class.newInstance();
        String[] args = { "-keystore", keystore_name, "-storepass", keystore_password, input_file.toString(), alias };
        old_err = System.err;
        old_out = System.out;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos);
        System.setErr(ps);
        System.setOut(ps);
        try {
            JarSigner_class.getMethod("run", new Class[] { String[].class }).invoke(jar_signer, new Object[] { args });
        } catch (Throwable e) {
            ps.close();
            String err_msg = baos.toString();
            if (err_msg.length() > 0) {
                failure_msg = err_msg;
            } else {
                Debug.printStackTrace(e);
                failure_msg = e.getMessage();
            }
        }
    } catch (Throwable e) {
        Debug.printStackTrace(e);
        failure_msg = e.getMessage();
    } finally {
        if (old_err != null) {
            System.setErr(old_err);
            System.setOut(old_out);
        }
    }
    if (failure_msg != null) {
        Debug.out("JAR signing fails '" + failure_msg + "'");
        Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.signfail"), new String[] { failure_msg });
        throw (new IOException("JAR signing fails: " + failure_msg));
    }
}
Also used : LogAlert(com.biglybt.core.logging.LogAlert)

Example 25 with LogAlert

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

the class AEThreadMonitor method monitor15.

private static void monitor15() {
    AEDiagnosticsLogger log = AEDiagnostics.getLogger("thread");
    int num_processors = Runtime.getRuntime().availableProcessors();
    if (num_processors < 1) {
        num_processors = 1;
    }
    ThreadMXBean bean = ManagementFactory.getThreadMXBean();
    log.log("Monitoring starts (processors =" + num_processors + ")");
    if (!bean.isThreadCpuTimeSupported()) {
        log.log("ThreadCpuTime not supported");
        return;
    }
    if (!bean.isThreadCpuTimeEnabled()) {
        log.log("Enabling ThreadCpuTime");
        bean.setThreadCpuTimeEnabled(true);
    }
    Map<Long, Long> last_times = new HashMap<>();
    final int time_available = 10 * 1000;
    long start_mono = SystemTime.getMonotonousTime();
    MovingAverage high_usage_history = AverageFactory.MovingAverage(2 * 60 * 1000 / time_available);
    boolean huh_mon_active = false;
    while (true) {
        long start = System.currentTimeMillis();
        try {
            Thread.sleep(time_available);
        } catch (Throwable e) {
            log.log(e);
        }
        long end = System.currentTimeMillis();
        long elapsed = end - start;
        long[] ids = bean.getAllThreadIds();
        long[] diffs = new long[ids.length];
        long total_diffs = 0;
        long biggest_diff = 0;
        int biggest_index = 0;
        Map<Long, Long> new_times = new HashMap<>();
        for (int i = 0; i < ids.length; i++) {
            long id = ids[i];
            // nanos -> millis
            long time = bean.getThreadCpuTime(id) / 1000000;
            Long old_time = last_times.get(id);
            if (old_time != null) {
                long diff = time - old_time.longValue();
                if (diff > biggest_diff) {
                    biggest_diff = diff;
                    biggest_index = i;
                }
                diffs[i] = diff;
                total_diffs += diff;
            }
            new_times.put(id, time);
        }
        ThreadInfo info = bean.getThreadInfo(ids[biggest_index]);
        String thread_name = info == null ? "<dead>" : info.getThreadName();
        int percent = (int) (100 * biggest_diff / time_available);
        Runtime rt = Runtime.getRuntime();
        log.log("Thread state: elapsed=" + elapsed + ",cpu=" + total_diffs + ",max=" + thread_name + "(" + biggest_diff + "/" + percent + "%),mem:max=" + (rt.maxMemory() / 1024) + ",tot=" + (rt.totalMemory() / 1024) + ",free=" + (rt.freeMemory() / 1024));
        if (huh_mon_active) {
            // ESET version 8 seems to be triggering high CPU in this thread
            boolean interesting = percent > 5 && thread_name.equals("PRUDPPacketHandler:sender");
            double temp = high_usage_history.update(interesting ? 1 : 0);
            if (temp >= 0.5) {
                Logger.log(new LogAlert(false, LogAlert.AT_WARNING, "High CPU usage detected in networking code - see <a href=\"" + Constants.URL_WIKI + "/w/High_CPU_Usage\">The Wiki</a> for possible solutions"));
            }
        } else {
            huh_mon_active = SystemTime.getMonotonousTime() - start_mono > 2 * 60 * 1000;
        }
        if (biggest_diff > time_available / 4) {
            info = bean.getThreadInfo(ids[biggest_index], 255);
            if (info == null) {
                log.log("    no info for max thread");
            } else {
                StackTraceElement[] elts = info.getStackTrace();
                StringBuilder str = new StringBuilder(elts.length * 20);
                str.append("    ");
                for (int i = 0; i < elts.length; i++) {
                    if (i != 0)
                        str.append(", ");
                    str.append(elts[i]);
                }
                log.log(str.toString());
            }
        }
        last_times = new_times;
    }
}
Also used : MovingAverage(com.biglybt.core.util.average.MovingAverage) ThreadMXBean(java.lang.management.ThreadMXBean) LogAlert(com.biglybt.core.logging.LogAlert) ThreadInfo(java.lang.management.ThreadInfo)

Aggregations

LogAlert (com.biglybt.core.logging.LogAlert)72 File (java.io.File)21 LogEvent (com.biglybt.core.logging.LogEvent)20 URL (java.net.URL)7 Core (com.biglybt.core.Core)5 ParameterListener (com.biglybt.core.config.ParameterListener)5 DownloadManager (com.biglybt.core.download.DownloadManager)5 TOTorrent (com.biglybt.core.torrent.TOTorrent)5 UIFunctions (com.biglybt.ui.UIFunctions)5 IOException (java.io.IOException)5 ArrayList (java.util.ArrayList)5 VuzeFile (com.biglybt.core.vuzefile.VuzeFile)4 PlatformManagerException (com.biglybt.pif.platform.PlatformManagerException)4 Method (java.lang.reflect.Method)4 CoreRunningListener (com.biglybt.core.CoreRunningListener)3 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)3 URLClassLoader (java.net.URLClassLoader)3 CoreException (com.biglybt.core.CoreException)2 CacheFile (com.biglybt.core.diskmanager.cache.CacheFile)2 DownloadManagerInitialisationAdapter (com.biglybt.core.download.DownloadManagerInitialisationAdapter)2