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));
}
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));
}
}
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"));
}
}
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));
}
}
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;
}
}
Aggregations