use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.
the class DHTUDPUtils method deserialiseVivaldi.
protected static void deserialiseVivaldi(DHTUDPPacketReply reply, DataInputStream is) throws IOException {
DHTNetworkPosition[] nps;
if (reply.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_GENERIC_NETPOS) {
int entries = is.readByte() & 0xff;
nps = new DHTNetworkPosition[entries];
int skipped = 0;
for (int i = 0; i < entries; i++) {
byte type = is.readByte();
byte size = is.readByte();
DHTNetworkPosition np = DHTNetworkPositionManager.deserialise(reply.getAddress().getAddress(), type, is);
if (np == null) {
skipped++;
for (int j = 0; j < size; j++) {
is.readByte();
}
} else {
nps[i] = np;
}
}
if (skipped > 0) {
DHTNetworkPosition[] x = new DHTNetworkPosition[entries - skipped];
int pos = 0;
for (int i = 0; i < nps.length; i++) {
if (nps[i] != null) {
x[pos++] = nps[i];
}
}
nps = x;
}
} else {
// dead code these days
nps = new DHTNetworkPosition[] { DHTNetworkPositionManager.deserialise(reply.getAddress().getAddress(), DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1, is) };
}
reply.setNetworkPositions(nps);
}
use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.
the class DHTUDPUtils method serialiseVivaldi.
protected static void serialiseVivaldi(DHTUDPPacketReply reply, DataOutputStream os) throws IOException {
DHTNetworkPosition[] nps = reply.getNetworkPositions();
if (reply.getProtocolVersion() >= DHTTransportUDP.PROTOCOL_VERSION_GENERIC_NETPOS) {
boolean v1_found = false;
for (int i = 0; i < nps.length; i++) {
DHTNetworkPosition np = nps[i];
if (np.getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1) {
v1_found = true;
break;
}
}
if (!v1_found) {
if (reply.getProtocolVersion() < DHTTransportUDP.PROTOCOL_VERSION_VIVALDI_OPTIONAL) {
// need to add one in for backward compatability
DHTNetworkPosition np = VivaldiPositionFactory.createPosition(Float.NaN);
DHTNetworkPosition[] new_nps = new DHTNetworkPosition[nps.length + 1];
System.arraycopy(nps, 0, new_nps, 0, nps.length);
new_nps[nps.length] = np;
nps = new_nps;
}
}
os.writeByte((byte) nps.length);
for (int i = 0; i < nps.length; i++) {
DHTNetworkPosition np = nps[i];
os.writeByte(np.getPositionType());
os.writeByte(np.getSerialisedSize());
np.serialise(os);
}
} else {
for (int i = 0; i < nps.length; i++) {
if (nps[i].getPositionType() == DHTNetworkPosition.POSITION_TYPE_VIVALDI_V1) {
nps[i].serialise(os);
return;
}
}
Debug.out("Vivaldi V1 missing");
throw (new IOException("Vivaldi V1 missing"));
}
}
use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.
the class TRTrackerServerProcessorTCP method processRequest.
protected boolean processRequest(String input_header, String lowercase_input_header, String url_path, InetSocketAddress local_address, InetSocketAddress remote_address, boolean announce_and_scrape_only, boolean keep_alive, InputStream is, OutputStream os, AsyncController async) throws IOException {
String str = url_path;
int request_type = TRTrackerServerRequest.RT_UNKNOWN;
boolean compact_enabled = server.isCompactEnabled();
try {
Map root = null;
TRTrackerServerTorrentImpl specific_torrent = null;
boolean gzip_reply = false;
boolean xml_output = false;
try {
List<String> banned = TRTrackerServerImpl.banned_clients;
if (!banned.isEmpty()) {
int ua_pos = lowercase_input_header.indexOf("user-agent");
if (ua_pos != -1) {
String user_agent = lowercase_input_header.substring(ua_pos + 10, lowercase_input_header.indexOf("\n", ua_pos)).trim().substring(1).trim();
for (String b : banned) {
if (user_agent.contains(b)) {
throw (new Exception(MSG_CLIENT_NOT_SUPPORTED));
}
}
}
}
if (str.startsWith("/announce?")) {
request_type = TRTrackerServerRequest.RT_ANNOUNCE;
str = str.substring(10);
} else if (str.startsWith("/scrape?")) {
request_type = TRTrackerServerRequest.RT_SCRAPE;
str = str.substring(8);
} else if (str.equals("/scrape")) {
request_type = TRTrackerServerRequest.RT_FULL_SCRAPE;
str = "";
} else if (str.startsWith("/query?")) {
request_type = TRTrackerServerRequest.RT_QUERY;
str = str.substring(7);
} else {
String redirect = TRTrackerServerImpl.redirect_on_not_found;
if (announce_and_scrape_only) {
if (redirect.length() == 0) {
throw (new Exception("Tracker only supports announce and scrape functions"));
}
} else {
setTaskState("external request");
disable_timeouts = true;
// check non-tracker authentication
String user = doAuthentication(remote_address, url_path, input_header, os, false);
if (user == null) {
return (false);
}
boolean[] ka = new boolean[] { keep_alive };
if (handleExternalRequest(local_address, remote_address, user, str, input_header, is, os, async, ka)) {
return (ka[0]);
}
}
if (redirect.length() > 0) {
os.write(("HTTP/1.1 301 Moved Permanently" + NL + "Location: " + redirect + NL + "Connection: close" + NL + "Content-Length: 0" + NL + NL).getBytes());
} else {
os.write(("HTTP/1.1 404 Not Found" + NL + "Connection: close" + NL + "Content-Length: 0" + NL + NL).getBytes());
}
os.flush();
// throw( new Exception( "Unsupported Request Type"));
return (false);
}
if (doAuthentication(remote_address, url_path, input_header, os, true) == null) {
return (false);
}
int enc_pos = lowercase_input_header.indexOf("accept-encoding:");
if (enc_pos != -1) {
int e_pos = input_header.indexOf(NL, enc_pos);
if (e_pos != -1) {
if (enc_pos > 0) {
char c = lowercase_input_header.charAt(enc_pos - 1);
if (c != FF && c != ' ') {
enc_pos = -1;
}
}
if (enc_pos != -1) {
String accept_encoding = lowercase_input_header.substring(enc_pos + 16, e_pos);
gzip_reply = HTTPUtils.canGZIP(accept_encoding);
}
}
}
setTaskState("decoding announce/scrape");
int pos = 0;
byte[] hash = null;
List hash_list = null;
String link = null;
HashWrapper peer_id = null;
int tcp_port = 0;
String event = null;
long uploaded = 0;
long downloaded = 0;
long left = 0;
int num_want = -1;
boolean no_peer_id = false;
byte compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_NONE;
String key = null;
byte crypto_level = TRTrackerServerPeer.CRYPTO_NONE;
int crypto_port = 0;
int udp_port = 0;
int http_port = 0;
int az_ver = 0;
boolean stop_to_queue = false;
String scrape_flags = null;
int up_speed = 0;
boolean hide = false;
DHTNetworkPosition network_position = null;
String real_ip_address = AddressUtils.getHostAddress(remote_address);
String client_ip_address = real_ip_address;
while (pos < str.length()) {
int p1 = str.indexOf('&', pos);
String token;
if (p1 == -1) {
token = str.substring(pos);
} else {
token = str.substring(pos, p1);
pos = p1 + 1;
}
int p2 = token.indexOf('=');
if (p2 == -1) {
throw (new Exception("format invalid"));
}
String lhs = token.substring(0, p2).toLowerCase();
String rhs = URLDecoder.decode(token.substring(p2 + 1), Constants.BYTE_ENCODING);
if (lhs.equals("info_hash")) {
byte[] b = rhs.getBytes(Constants.BYTE_ENCODING);
if (hash == null) {
hash = b;
} else {
if (hash_list == null) {
hash_list = new ArrayList();
hash_list.add(hash);
}
hash_list.add(b);
}
} else if (lhs.equals("peer_id")) {
peer_id = new HashWrapper(rhs.getBytes(Constants.BYTE_ENCODING));
} else if (lhs.equals("no_peer_id")) {
no_peer_id = rhs.equals("1");
} else if (lhs.equals("compact")) {
if (compact_enabled) {
if (rhs.equals("1") && compact_mode == TRTrackerServerTorrentImpl.COMPACT_MODE_NONE) {
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_NORMAL;
}
}
} else if (lhs.equals("key")) {
if (server.isKeyEnabled()) {
key = rhs;
}
} else if (lhs.equals("port")) {
tcp_port = Integer.parseInt(rhs);
} else if (lhs.equals("event")) {
event = rhs;
} else if (lhs.equals("ip")) {
if (!HostNameToIPResolver.isNonDNSName(rhs)) {
for (int i = 0; i < rhs.length(); i++) {
char c = rhs.charAt(i);
if (c != '.' && c != ':' && !Character.isDigit(c)) {
throw (new Exception("IP override address must be resolved by the client"));
}
}
try {
rhs = HostNameToIPResolver.syncResolve(rhs).getHostAddress();
} catch (UnknownHostException e) {
throw (new Exception("IP override address must be resolved by the client"));
}
} else if (AENetworkClassifier.categoriseAddress(client_ip_address) == AENetworkClassifier.AT_I2P) {
// ignore ip override as it is probably a full destination whereas the real originator is the .b32 equivalent
} else {
client_ip_address = rhs;
}
} else if (lhs.equals("uploaded")) {
uploaded = Long.parseLong(rhs);
} else if (lhs.equals("downloaded")) {
downloaded = Long.parseLong(rhs);
} else if (lhs.equals("left")) {
left = Long.parseLong(rhs);
} else if (lhs.equals("numwant")) {
num_want = Integer.parseInt(rhs);
} else if (lhs.equals("azudp")) {
udp_port = Integer.parseInt(rhs);
if (compact_enabled) {
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_AZ;
}
} else if (lhs.equals("azhttp")) {
http_port = Integer.parseInt(rhs);
} else if (lhs.equals("azver")) {
az_ver = Integer.parseInt(rhs);
} else if (lhs.equals("supportcrypto")) {
if (crypto_level == TRTrackerServerPeer.CRYPTO_NONE) {
crypto_level = TRTrackerServerPeer.CRYPTO_SUPPORTED;
}
} else if (lhs.equals("requirecrypto")) {
crypto_level = TRTrackerServerPeer.CRYPTO_REQUIRED;
} else if (lhs.equals("cryptoport")) {
crypto_port = Integer.parseInt(rhs);
} else if (lhs.equals("azq")) {
stop_to_queue = true;
} else if (lhs.equals("azsf")) {
scrape_flags = rhs;
} else if (lhs.equals("link")) {
link = rhs;
} else if (lhs.equals("outform")) {
if (rhs.equals("xml")) {
xml_output = true;
}
} else if (lhs.equals("hide")) {
hide = Integer.parseInt(rhs) == 1;
} else if (TRTrackerServerImpl.supportsExtensions()) {
if (lhs.equals("aznp")) {
try {
network_position = DHTNetworkPositionManager.deserialisePosition(remote_address.getAddress(), Base32.decode(rhs));
} catch (Throwable e) {
}
} else if (lhs.equals("azup")) {
up_speed = Integer.parseInt(rhs);
}
}
if (p1 == -1) {
break;
}
}
if (hide) {
tcp_port = 0;
crypto_port = 0;
http_port = 0;
udp_port = 0;
}
if (crypto_level == TRTrackerServerPeer.CRYPTO_REQUIRED) {
if (crypto_port != 0) {
tcp_port = crypto_port;
}
}
byte[][] hashes = null;
if (hash_list != null) {
hashes = new byte[hash_list.size()][];
hash_list.toArray(hashes);
} else if (hash != null) {
hashes = new byte[][] { hash };
}
if (compact_enabled) {
if (xml_output) {
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_XML;
} else if (az_ver >= 2) {
compact_mode = TRTrackerServerTorrentImpl.COMPACT_MODE_AZ_2;
}
}
Map[] root_out = new Map[1];
TRTrackerServerPeerImpl[] peer_out = new TRTrackerServerPeerImpl[1];
specific_torrent = processTrackerRequest(server, str, root_out, peer_out, request_type, hashes, link, scrape_flags, peer_id, no_peer_id, compact_mode, key, event, stop_to_queue, tcp_port & 0xffff, udp_port & 0xffff, http_port & 0xffff, real_ip_address, client_ip_address, downloaded, uploaded, left, num_want, crypto_level, (byte) az_ver, up_speed, network_position);
root = root_out[0];
if (request_type == TRTrackerServerRequest.RT_SCRAPE) {
if (lowercase_input_header.contains(lc_azureus_name)) {
root.put("aztracker", new Long(1));
}
}
if (root.get("_data") == null) {
TRTrackerServerPeer post_process_peer = peer_out[0];
if (post_process_peer == null) {
post_process_peer = new lightweightPeer(client_ip_address, tcp_port, peer_id);
}
server.postProcess(post_process_peer, specific_torrent, request_type, str, root);
}
} catch (Exception e) {
String warning_message = null;
Map error_entries = null;
if (e instanceof TRTrackerServerException) {
TRTrackerServerException tr_excep = (TRTrackerServerException) e;
int reason = tr_excep.getResponseCode();
error_entries = tr_excep.getErrorEntries();
if (reason != -1) {
String resp = "HTTP/1.1 " + reason + " " + tr_excep.getResponseText() + NL;
Map headers = tr_excep.getResponseHeaders();
Iterator it = headers.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
if (key.equalsIgnoreCase("connection")) {
if (!value.equalsIgnoreCase("close")) {
Debug.out("Ignoring 'Connection' header");
continue;
}
}
resp += key + ": " + value + NL;
}
resp += "Connection: close" + NL;
byte[] payload = null;
if (error_entries != null) {
payload = BEncoder.encode(error_entries);
resp += "Content-Length: " + payload.length + NL;
} else {
resp += "Content-Length: 0" + NL;
}
resp += NL;
os.write(resp.getBytes());
if (payload != null) {
os.write(payload);
}
os.flush();
return (false);
}
if (tr_excep.isUserMessage()) {
warning_message = tr_excep.getMessage();
}
} else if (e instanceof NullPointerException) {
e.printStackTrace();
}
String message = e.getMessage();
if (message == null || message.length() == 0) {
// e.printStackTrace();
message = e.toString();
}
root = new HashMap();
root.put("failure reason", message);
if (warning_message != null) {
root.put("warning message", warning_message);
}
if (error_entries != null) {
root.putAll(error_entries);
}
}
setTaskState("writing response");
byte[] data;
byte[] header_start;
if (xml_output) {
StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
xml.append("<RESULT>");
if (specific_torrent != null) {
xml.append("<BTIH>");
xml.append(ByteFormatter.encodeString(specific_torrent.getHash().getBytes()));
xml.append("</BTIH>");
xml.append(BEncoder.encodeToXML(root, true));
}
xml.append("</RESULT>");
data = xml.toString().getBytes("UTF-8");
header_start = HTTP_RESPONSE_XML_START;
} else {
// cache both plain and gzip encoded data for possible reuse
data = (byte[]) root.get("_data");
if (data == null) {
data = BEncoder.encode(root);
if (data.length > 1000000) {
File dump = new File("bdecoder.dump");
synchronized (TRTrackerServerProcessorTCP.class) {
try {
Debug.out("Output is too large, saving diagnostics to " + dump.toString());
PrintWriter pw = new PrintWriter(new FileWriter(dump));
BDecoder.print(pw, root);
pw.close();
} catch (Throwable e) {
}
}
}
root.put("_data", data);
}
header_start = HTTP_RESPONSE_START;
}
if (gzip_reply) {
byte[] gzip_data = (byte[]) root.get("_gzipdata");
if (gzip_data == null) {
ByteArrayOutputStream tos = new ByteArrayOutputStream(data.length);
GZIPOutputStream gos = new GZIPOutputStream(tos);
gos.write(data);
gos.close();
gzip_data = tos.toByteArray();
root.put("_gzipdata", gzip_data);
}
data = gzip_data;
}
// System.out.println( "TRTrackerServerProcessor::reply: sending " + new String(data));
// write the response
setTaskState("writing header");
os.write(header_start);
byte[] length_bytes = String.valueOf(data.length).getBytes();
os.write(length_bytes);
int header_len = header_start.length + length_bytes.length;
setTaskState("writing content");
if (gzip_reply) {
os.write(HTTP_RESPONSE_END_GZIP);
header_len += HTTP_RESPONSE_END_GZIP.length;
} else {
os.write(HTTP_RESPONSE_END_NOGZIP);
header_len += HTTP_RESPONSE_END_NOGZIP.length;
}
os.write(data);
server.updateStats(request_type, specific_torrent, input_header.length(), header_len + data.length);
} finally {
setTaskState("final os flush");
os.flush();
}
return (false);
}
use of com.biglybt.core.dht.netcoords.DHTNetworkPosition in project BiglyBT by BiglySoftware.
the class Show method showDHTStats.
protected void showDHTStats(ConsoleInput ci) {
try {
PluginInterface def = ci.core.getPluginManager().getDefaultPluginInterface();
PluginInterface dht_pi = def.getPluginManager().getPluginInterfaceByClass(DHTPlugin.class);
if (dht_pi == null) {
ci.out.println("\tDHT isn't present");
return;
}
DHTPlugin dht_plugin = (DHTPlugin) dht_pi.getPlugin();
if (dht_plugin.getStatus() != DHTPlugin.STATUS_RUNNING) {
ci.out.println("\tDHT isn't running yet (disabled or initialising)");
return;
}
DHT[] dhts = dht_plugin.getDHTs();
for (int i = 0; i < dhts.length; i++) {
if (i > 0) {
ci.out.println("");
}
DHT dht = dhts[i];
DHTTransport transport = dht.getTransport();
DHTTransportStats t_stats = transport.getStats();
DHTDBStats d_stats = dht.getDataBase().getStats();
DHTControlStats c_stats = dht.getControl().getStats();
DHTRouterStats r_stats = dht.getRouter().getStats();
long[] rs = r_stats.getStats();
DHTNetworkPosition[] nps = transport.getLocalContact().getNetworkPositions();
String np_str = "";
for (int j = 0; j < nps.length; j++) {
np_str += (j == 0 ? "" : ",") + nps[j];
}
ci.out.println("DHT:ip=" + transport.getLocalContact().getAddress() + ",net=" + transport.getNetwork() + ",prot=V" + transport.getProtocolVersion() + ",np=" + np_str + ",sleeping=" + dht.isSleeping());
ci.out.println("Router" + ":nodes=" + rs[DHTRouterStats.ST_NODES] + ",leaves=" + rs[DHTRouterStats.ST_LEAVES] + ",contacts=" + rs[DHTRouterStats.ST_CONTACTS] + ",replacement=" + rs[DHTRouterStats.ST_REPLACEMENTS] + ",live=" + rs[DHTRouterStats.ST_CONTACTS_LIVE] + ",unknown=" + rs[DHTRouterStats.ST_CONTACTS_UNKNOWN] + ",failing=" + rs[DHTRouterStats.ST_CONTACTS_DEAD]);
ci.out.println("Transport" + ":" + t_stats.getString());
int[] dbv_details = d_stats.getValueDetails();
ci.out.println("Control:dht=" + c_stats.getEstimatedDHTSize() + ", Database:keys=" + d_stats.getKeyCount() + ",vals=" + dbv_details[DHTDBStats.VD_VALUE_COUNT] + ",loc=" + dbv_details[DHTDBStats.VD_LOCAL_SIZE] + ",dir=" + dbv_details[DHTDBStats.VD_DIRECT_SIZE] + ",ind=" + dbv_details[DHTDBStats.VD_INDIRECT_SIZE] + ",div_f=" + dbv_details[DHTDBStats.VD_DIV_FREQ] + ",div_s=" + dbv_details[DHTDBStats.VD_DIV_SIZE]);
dht.getRouter().print();
}
} catch (Throwable e) {
e.printStackTrace(ci.out);
}
}
use of com.biglybt.core.dht.netcoords.DHTNetworkPosition 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());
}
Aggregations