Пример #1
0
        /// <summary>
        /// Creates a new tracker group.
        /// </summary>
        /// <param name="torrent">The parent torrent.</param>
        public TrackerGroup(Torrent torrent)
        {
            this.torrent = torrent;

            int listenPort = PeerListener.Port;

            announceRequest = new AnnounceRequest(torrent.InfoHash, torrent.PeerID, listenPort);
        }
Пример #2
0
        /// <summary>
        /// Makes an announce request to this tracker.
        /// </summary>
        /// <param name="request">The announce request object.</param>
        /// <returns>The announce response.</returns>
        public override async Task <AnnounceResponse> Announce(AnnounceRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            // Check if announces are allowed
            if (announceUri == null)
            {
                return(null);
            }

            try
            {
                Uri    uri           = request.GetUri(announceUri, key, trackerID);
                byte[] responseBytes = await client.GetByteArrayAsync(uri).ConfigureAwait(false);

                Stats.IncreaseDownloadedBytes(responseBytes.Length);
                var info = BEncoding.Decode(responseBytes) as BEncoding.Dictionary;
                if (info == null)
                {
                    status         = TrackerStatus.InvalidResponse;
                    failureMessage = "The tracker returned an invalid announce response.";
                    return(null);
                }

                var announceResponse = HandleAnnounceResponse(info);
                if (announceResponse == null)
                {
                    status         = TrackerStatus.InvalidResponse;
                    failureMessage = "The tracker returned an invalid announce response.";
                    return(null);
                }

                failureMessage = announceResponse.FailureReason;
                warningMessage = announceResponse.WarningMessage;
                status         = TrackerStatus.OK;
                return(announceResponse);
            }
            catch (HttpRequestException ex)
            {
                status         = TrackerStatus.Offline;
                failureMessage = string.Format("Failed to perform announce request: {0}", ex.Message);
                return(null);
            }
            catch (Exception ex)
            {
                status         = TrackerStatus.InvalidResponse;
                failureMessage = string.Format("Exception performing announce request: {0}", ex.Message);
                return(null);
            }
        }
Пример #3
0
        private async Task <AnnounceResponse> DoAnnounceRequest(AnnounceRequest request, bool isIPv6)
        {
            if ((!isIPv6 && trackerEndpointV4 == null) || (isIPv6 && trackerEndpointV6 == null))
            {
                return(null);
            }

            UdpExtensions extensions    = UdpExtensions.None;
            int           extensionSize = 0;

            if (!string.IsNullOrEmpty(authUser))
            {
                extensions    |= UdpExtensions.Authentication;
                extensionSize += 1 + authUser.Length + 8;
            }
            if (!string.IsNullOrEmpty(requestString))
            {
                extensions    |= UdpExtensions.RequestString;
                extensionSize += 1 + requestString.Length;
            }

            int ipInteger       = (!isIPv6 ? GetIPAsInteger(request.IP) : 0);
            var announceRequest = CreateRequest(TrackerUdpAction.Announce, 100 + extensionSize, isIPv6);

            announceRequest.Write(request.InfoHash.Hash, 0, 20);
            announceRequest.Write(request.PeerID.ID, 0, 20);
            announceRequest.WriteInt64(request.BytesDownloaded);
            announceRequest.WriteInt64(request.BytesLeft);
            announceRequest.WriteInt64(request.BytesUploaded);
            announceRequest.WriteInt32((int)request.TrackerEvent);
            announceRequest.WriteInt32(ipInteger);
            announceRequest.WriteInt32(key);
            announceRequest.WriteInt32((request.DesiredPeerCount > 0 ? request.DesiredPeerCount : -1));
            announceRequest.WriteUInt16((ushort)request.Port);
            announceRequest.WriteUInt16((ushort)extensions);

            if ((extensions & UdpExtensions.Authentication) != 0)
            {
                announceRequest.WriteByte((byte)authUser.Length);
                announceRequest.WriteString(authUser);

                byte[] passwordHash = GenerateAuthPasswordHash(announceRequest, authPassHash);
                announceRequest.Write(passwordHash, 0, 8);
            }

            if ((extensions & UdpExtensions.RequestString) != 0)
            {
                announceRequest.WriteByte((byte)requestString.Length);
                announceRequest.WriteString(requestString);
            }

            await SendRequest(announceRequest);

            var responsePacket = await WaitForResponse(announceRequest, 20);

            if (responsePacket == null)
            {
                status         = TrackerStatus.Offline;
                failureMessage = "Timed out making announce request.";
                return(null);
            }

            AnnounceResponse announceResponse;

            if (isIPv6)
            {
                announceResponse = HandleAnnounceResponseV6(responsePacket);
            }
            else
            {
                announceResponse = HandleAnnounceResponseV4(responsePacket);
            }

            return(announceResponse);
        }
Пример #4
0
        /// <summary>
        /// Makes an announce request to this tracker.
        /// </summary>
        /// <param name="request">The announce request object.</param>
        /// <returns>The announce response.</returns>
        public override async Task <AnnounceResponse> Announce(AnnounceRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            try
            {
                failureMessage = null;
                warningMessage = null;
                if (!await WaitForConnection().ConfigureAwait(false))
                {
                    status = TrackerStatus.Offline;
                    if (failureMessage == null)
                    {
                        failureMessage = "Failed to connect with tracker.";
                    }
                    return(null);
                }

                var responseV4 = DoAnnounceRequest(request, false);
                var responseV6 = DoAnnounceRequest(request, true);

                var responses = await Task.WhenAll(responseV4, responseV6).ConfigureAwait(false);

                var announceResponse = JoinResponses(responses);
                if (announceResponse == null)
                {
                    if (failureMessage == null)
                    {
                        status         = TrackerStatus.InvalidResponse;
                        failureMessage = "The tracker returned an invalid announce response.";
                    }
                    return(null);
                }

                failureMessage = announceResponse.FailureReason;
                warningMessage = announceResponse.WarningMessage;
                status         = TrackerStatus.OK;
                return(announceResponse);
            }
            catch (TrackerException ex)
            {
                status         = ex.Status;
                failureMessage = string.Format("Failed to perform announce request: {0}", ex.Message);
                return(null);
            }
            catch (SocketException ex)
            {
                status         = TrackerStatus.Offline;
                failureMessage = string.Format("Failed to perform announce request: {0}", ex.Message);
                return(null);
            }
            catch (Exception ex)
            {
                status         = TrackerStatus.InvalidResponse;
                failureMessage = string.Format("Exception performing announce request: {0}", ex.Message);
                return(null);
            }
        }
Пример #5
0
 /// <summary>
 /// Makes an announce request to this tracker.
 /// </summary>
 /// <param name="request">The announce request object.</param>
 /// <returns>The announce response.</returns>
 public abstract Task<AnnounceResponse> Announce(AnnounceRequest request);