Search in sources :

Example 1 with PRUDPPacket

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);
}
Also used : PRUDPPacket(com.biglybt.net.udp.uc.PRUDPPacket)

Example 2 with PRUDPPacket

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);
        }
    }
}
Also used : PRUDPPacket(com.biglybt.net.udp.uc.PRUDPPacket) LogEvent(com.biglybt.core.logging.LogEvent) PRUDPPacketHandlerException(com.biglybt.net.udp.uc.PRUDPPacketHandlerException) PRUDPPacketHandler(com.biglybt.net.udp.uc.PRUDPPacketHandler)

Example 3 with PRUDPPacket

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) {
        }
    }
}
Also used : LogEvent(com.biglybt.core.logging.LogEvent) PRUDPPacket(com.biglybt.net.udp.uc.PRUDPPacket) TRTrackerServerTorrentImpl(com.biglybt.core.tracker.server.impl.TRTrackerServerTorrentImpl) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) DataInputStream(java.io.DataInputStream) PRUDPPacketRequest(com.biglybt.net.udp.uc.PRUDPPacketRequest) ByteArrayInputStream(java.io.ByteArrayInputStream)

Aggregations

PRUDPPacket (com.biglybt.net.udp.uc.PRUDPPacket)3 LogEvent (com.biglybt.core.logging.LogEvent)2 TRTrackerServerTorrentImpl (com.biglybt.core.tracker.server.impl.TRTrackerServerTorrentImpl)1 PRUDPPacketHandler (com.biglybt.net.udp.uc.PRUDPPacketHandler)1 PRUDPPacketHandlerException (com.biglybt.net.udp.uc.PRUDPPacketHandlerException)1 PRUDPPacketRequest (com.biglybt.net.udp.uc.PRUDPPacketRequest)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1