use of com.biglybt.net.udp.uc.PRUDPPacket in project BiglyBT by BiglySoftware.
the class TRTrackerServerProcessorUDP method handleConnect.
protected PRUDPPacket handleConnect(String client_ip_address, PRUDPPacketRequest request) {
long conn_id = allocateConnectionId(client_ip_address);
PRUDPPacket reply = new PRUDPPacketReplyConnect(request.getTransactionId(), conn_id);
return (reply);
}
use of com.biglybt.net.udp.uc.PRUDPPacket in project BiglyBT by BiglySoftware.
the class TrackerStatus method scrapeUDP.
protected boolean scrapeUDP(URL reqUrl, ByteArrayOutputStream message, List hashes, boolean do_auth_test) throws Exception {
Map rootMap = new HashMap();
Map files = new ByteEncodedKeyHashMap();
rootMap.put("files", files);
/*
* reduce network traffic by only scraping UDP when the torrent isn't
* running as UDP version 2 contains scrape data in the announce
* response
*/
/* removed implementation for the time being
for (Iterator it = hashes.iterator(); it.hasNext();)
{
HashWrapper hash = (HashWrapper) it.next();
if (PRUDPPacketTracker.VERSION == 2 && scraper.isTorrentDownloading(hash))
{
if (Logger.isEnabled())
Logger.log(new LogEvent(TorrentUtils.getDownloadManager(hash), LOGID, LogEvent.LT_WARNING, "Scrape of " + reqUrl + " skipped as torrent running and " + "therefore scrape data available in " + "announce replies"));
// easiest approach here is to brew up a response that looks like the current one
Map file = new HashMap();
byte[] resp_hash = hash.getBytes();
// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
files.put(new String(resp_hash, Constants.BYTE_ENCODING), file);
file.put("complete", new Long(current_response.getSeeds()));
file.put("downloaded", new Long(-1)); // unknown
file.put("incomplete", new Long(current_response.getPeers()));
byte[] data = BEncoder.encode(rootMap);
message.write(data);
return true;
}
}
*/
reqUrl = TRTrackerUtils.adjustURLForHosting(reqUrl);
PasswordAuthentication auth = null;
boolean auth_ok = false;
try {
if (do_auth_test && UrlUtils.queryHasParameter(reqUrl.getQuery(), "auth", false)) {
auth = SESecurityManager.getPasswordAuthentication("UDP Tracker", reqUrl);
}
int port = UDPNetworkManager.getSingleton().getUDPNonDataListeningPortNumber();
PRUDPPacketHandler handler = PRUDPPacketHandlerFactory.getHandler(port);
InetSocketAddress destination = new InetSocketAddress(reqUrl.getHost(), reqUrl.getPort() == -1 ? 80 : reqUrl.getPort());
handler = handler.openSession(destination);
try {
String failure_reason = null;
for (int retry_loop = 0; retry_loop < PRUDPPacketTracker.DEFAULT_RETRY_COUNT; retry_loop++) {
try {
PRUDPPacket connect_request = new PRUDPPacketRequestConnect();
PRUDPPacket reply = handler.sendAndReceive(auth, connect_request, destination);
if (reply.getAction() == PRUDPPacketTracker.ACT_REPLY_CONNECT) {
PRUDPPacketReplyConnect connect_reply = (PRUDPPacketReplyConnect) reply;
long my_connection = connect_reply.getConnectionId();
PRUDPPacketRequestScrape scrape_request = new PRUDPPacketRequestScrape(my_connection, hashes);
reply = handler.sendAndReceive(auth, scrape_request, destination);
if (reply.getAction() == PRUDPPacketTracker.ACT_REPLY_SCRAPE) {
auth_ok = true;
if (PRUDPPacketTracker.VERSION == 1) {
PRUDPPacketReplyScrape scrape_reply = (PRUDPPacketReplyScrape) reply;
/*
int interval = scrape_reply.getInterval();
if ( interval != 0 ){
map.put( "interval", new Long(interval ));
}
*/
byte[][] reply_hashes = scrape_reply.getHashes();
int[] complete = scrape_reply.getComplete();
int[] downloaded = scrape_reply.getDownloaded();
int[] incomplete = scrape_reply.getIncomplete();
for (int i = 0; i < reply_hashes.length; i++) {
Map file = new HashMap();
byte[] resp_hash = reply_hashes[i];
// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
files.put(new String(resp_hash, Constants.BYTE_ENCODING), file);
file.put("complete", new Long(complete[i]));
file.put("downloaded", new Long(downloaded[i]));
file.put("incomplete", new Long(incomplete[i]));
}
byte[] data = BEncoder.encode(rootMap);
message.write(data);
return true;
} else {
PRUDPPacketReplyScrape2 scrape_reply = (PRUDPPacketReplyScrape2) reply;
/*
int interval = scrape_reply.getInterval();
if ( interval != 0 ){
map.put( "interval", new Long(interval ));
}
*/
int[] complete = scrape_reply.getComplete();
int[] downloaded = scrape_reply.getDownloaded();
int[] incomplete = scrape_reply.getIncomplete();
int i = 0;
for (Iterator it = hashes.iterator(); it.hasNext() && i < complete.length; i++) {
HashWrapper hash = (HashWrapper) it.next();
Map file = new HashMap();
file.put("complete", new Long(complete[i]));
file.put("downloaded", new Long(downloaded[i]));
file.put("incomplete", new Long(incomplete[i]));
files.put(new String(hash.getBytes(), Constants.BYTE_ENCODING), file);
}
// System.out.println("got hash:" + ByteFormatter.nicePrint( resp_hash, true ));
byte[] data = BEncoder.encode(rootMap);
message.write(data);
return true;
}
} else {
failure_reason = ((PRUDPPacketReplyError) reply).getMessage();
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Response from scrape interface " + reqUrl + " : " + failure_reason));
break;
}
} else {
failure_reason = ((PRUDPPacketReplyError) reply).getMessage();
if (Logger.isEnabled())
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "Response from scrape interface " + reqUrl + " : " + ((PRUDPPacketReplyError) reply).getMessage()));
break;
}
} catch (PRUDPPacketHandlerException e) {
if (e.getMessage() == null || !e.getMessage().contains("timed out")) {
throw (e);
}
failure_reason = "Timeout";
}
}
if (failure_reason != null) {
rootMap.put("failure reason", failure_reason.getBytes());
rootMap.remove("files");
byte[] data = BEncoder.encode(rootMap);
message.write(data);
}
} finally {
handler.closeSession();
}
return false;
} finally {
if (auth != null) {
SESecurityManager.setPasswordAuthenticationOutcome(TRTrackerBTAnnouncerImpl.UDP_REALM, reqUrl, auth_ok);
}
}
}
use of com.biglybt.net.udp.uc.PRUDPPacket in project BiglyBT by BiglySoftware.
the class TRTrackerServerProcessorUDP method runSupport.
@Override
public void runSupport() {
byte[] input_buffer = new byte[request_dg.getLength()];
System.arraycopy(request_dg.getData(), 0, input_buffer, 0, input_buffer.length);
int packet_data_length = input_buffer.length;
String auth_user = null;
byte[] auth_user_bytes = null;
byte[] auth_hash = null;
if (server.isTrackerPasswordEnabled()) {
if (input_buffer.length < 17) {
Logger.log(new LogEvent(LOGID, LogEvent.LT_WARNING, "TRTrackerServerProcessorUDP: " + "packet received but authorisation missing"));
return;
}
packet_data_length -= 16;
auth_user_bytes = new byte[8];
auth_hash = new byte[8];
System.arraycopy(input_buffer, packet_data_length, auth_user_bytes, 0, 8);
int user_len = 0;
while (user_len < 8 && auth_user_bytes[user_len] != 0) {
user_len++;
}
auth_user = new String(auth_user_bytes, 0, user_len);
System.arraycopy(input_buffer, packet_data_length + 8, auth_hash, 0, 8);
}
DataInputStream is = new DataInputStream(new ByteArrayInputStream(input_buffer, 0, packet_data_length));
try {
String client_ip_address = request_dg.getAddress().getHostAddress();
PRUDPPacketRequest request = PRUDPPacketRequest.deserialiseRequest(null, is);
Logger.log(new LogEvent(LOGID, "TRTrackerServerProcessorUDP: packet received: " + request.getString()));
PRUDPPacket reply = null;
TRTrackerServerTorrentImpl torrent = null;
if (auth_user_bytes != null) {
// user name is irrelevant as we only have one at the moment
// <parg_home> so <new_packet> = <old_packet> + <user_padded_to_8_bytes> + <hash>
// <parg_home> where <hash> = first 8 bytes of sha1(<old_packet> + <user_padded_to_8> + sha1(pass))
// <XTF> Yes
byte[] sha1_pw = null;
if (server.hasExternalAuthorisation()) {
try {
URL resource = new URL("udp://" + server.getHost() + ":" + server.getPort() + "/");
sha1_pw = server.performExternalAuthorisation(resource, auth_user);
} catch (MalformedURLException e) {
Debug.printStackTrace(e);
}
if (sha1_pw == null) {
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));
reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");
}
} else {
sha1_pw = server.getPassword();
}
if (reply == null) {
SHA1Hasher hasher = new SHA1Hasher();
hasher.update(input_buffer, 0, packet_data_length);
hasher.update(auth_user_bytes);
hasher.update(sha1_pw);
byte[] digest = hasher.getDigest();
for (int i = 0; i < auth_hash.length; i++) {
if (auth_hash[i] != digest[i]) {
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR, "TRTrackerServerProcessorUDP: auth fails for user '" + auth_user + "'"));
reply = new PRUDPPacketReplyError(request.getTransactionId(), "Access Denied");
break;
}
}
}
}
int request_type = TRTrackerServerRequest.RT_UNKNOWN;
if (reply == null) {
if (server.isEnabled()) {
try {
int type = request.getAction();
if (type == PRUDPPacketTracker.ACT_REQUEST_CONNECT) {
reply = handleConnect(client_ip_address, request);
} else if (type == PRUDPPacketTracker.ACT_REQUEST_ANNOUNCE) {
Object[] x = handleAnnounceAndScrape(client_ip_address, request, TRTrackerServerRequest.RT_ANNOUNCE);
if (x == null) {
throw (new Exception("Connection ID mismatch"));
}
reply = (PRUDPPacket) x[0];
torrent = (TRTrackerServerTorrentImpl) x[1];
request_type = TRTrackerServerRequest.RT_ANNOUNCE;
} else if (type == PRUDPPacketTracker.ACT_REQUEST_SCRAPE) {
Object[] x = handleAnnounceAndScrape(client_ip_address, request, TRTrackerServerRequest.RT_SCRAPE);
if (x == null) {
throw (new Exception("Connection ID mismatch"));
}
reply = (PRUDPPacket) x[0];
torrent = (TRTrackerServerTorrentImpl) x[1];
request_type = TRTrackerServerRequest.RT_SCRAPE;
} else {
reply = new PRUDPPacketReplyError(request.getTransactionId(), "unsupported action");
}
} catch (Throwable e) {
// e.printStackTrace();
String error = e.getMessage();
if (error == null) {
error = e.toString();
}
reply = new PRUDPPacketReplyError(request.getTransactionId(), error);
}
} else {
System.out.println("UDP Tracker: replying 'disabled' to " + client_ip_address);
reply = new PRUDPPacketReplyError(request.getTransactionId(), "UDP Tracker disabled");
}
}
if (reply != null) {
InetAddress address = request_dg.getAddress();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream os = new DataOutputStream(baos);
reply.serialise(os);
byte[] output_buffer = baos.toByteArray();
DatagramPacket reply_packet = new DatagramPacket(output_buffer, output_buffer.length, address, request_dg.getPort());
socket.send(reply_packet);
server.updateStats(request_type, torrent, input_buffer.length, output_buffer.length);
}
} catch (Throwable e) {
Logger.log(new LogEvent(LOGID, "TRTrackerServerProcessorUDP: processing fails", e));
} finally {
try {
is.close();
} catch (Throwable e) {
}
}
}
Aggregations