Beispiel #1
0
        public bool RegisterMessage(DhtMessage message, DhtNode node)
        {
            switch (message.CommandType)
            {
            case CommandType.UnKnow:
                return(false);

            case CommandType.Ping:
            case CommandType.Find_Node:
            case CommandType.Announce_Peer:
                message.MessageId = TypeMapTransactionId[message.CommandType];
                return(true);

            case CommandType.Get_Peers:
                break;

            default:
                return(false);
            }
            if (RegisterGetPeersMessage(message.Get <byte[]>("info_hash"), node, out var msgId))
            {
                message.MessageId = msgId;
                return(true);
            }
            return(false);
        }
Beispiel #2
0
        protected override bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash)
        {
            var nodeKey = node.CompactEndPoint();
            var key     = new byte[nodeKey.Length + 2];

            Array.Copy(nodeKey, 0, key, 2, nodeKey.Length);
            key[0] = msgId[0];
            key[1] = msgId[1];
            lock (_syncRoot)
            {
                var old = _table.Find(key);
                if (old == null)
                {
                    infoHash = null;
                    return(false);
                }
                infoHash = old.InfoHash;
                _operateSize++;
                _table.Delete(key);
                if (_operateSize > 5120)
                {
                    _storageEngine.Commit();
                    _operateSize = 0;
                }
                return(true);
            }
        }
Beispiel #3
0
        public async Task <bool> RegisterMessageAsync(DhtMessage message, DhtNode node)
        {
            switch (message.CommandType)
            {
            case CommandType.UnKnow:
                return(false);

            case CommandType.Ping:
            case CommandType.Find_Node:
            case CommandType.Announce_Peer:
                message.MessageId = TypeMapTransactionId[message.CommandType];
                return(true);

            case CommandType.Get_Peers:
                break;

            default:
                return(false);
            }
            var result = await RegisterGetPeersMessageAsync(message.Get <byte[]>("info_hash"), node);

            if (result.IsOk)
            {
                message.MessageId = result.MsgId;
                return(true);
            }
            return(false);
        }
Beispiel #4
0
        protected override bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId)
        {
            var nodeId  = node.CompactEndPoint().ToInt64();
            var srcript = _registerScript[(int)(nodeId % _registerScript.Count)];

            lock (this)
            {
                _index++;
                if (_index >= _bucketArray.Length)
                {
                    _index = 0;
                }
                msgId = _bucketArray[_index];
            }
            var result = srcript.Evaluate(_database, new { point = nodeId, hash = infoHash, msgId = ((byte[])msgId) });

            if (result.IsNull)
            {
                msgId = null;
                return(false);
            }
            var resultInt = (int)result;

            if (resultInt == 1)
            {
                return(true);
            }
            msgId = null;
            return(false);
        }
        private TcpRelayService(BinaryNumber networkID, int servicePort, DhtNode dhtNode)
        {
            _trackerManager = new TrackerManager(networkID, servicePort, dhtNode, null, BIT_CHAT_TRACKER_UPDATE_INTERVAL);

            //start keep alive timer
            _tcpRelayConnectionKeepAliveTimer = new Timer(RelayConnectionKeepAliveTimerCallback, null, TCP_RELAY_KEEP_ALIVE_INTERVAL, Timeout.Infinite);
        }
        private void UpdateDhtAsync(object state)
        {
            object[] parameters = state as object[];

            DhtNode    dhtNode = parameters[0] as DhtNode;
            IPEndPoint localEP = parameters[1] as IPEndPoint;

            try
            {
                IPEndPoint[] peers;

                if (_lookupOnly)
                {
                    peers = dhtNode.FindPeers(_networkID);
                }
                else
                {
                    peers = dhtNode.Announce(_networkID, localEP.Port);
                }

                _dhtLastUpdated   = DateTime.UtcNow;
                _dhtLastException = null; //reset last error

                if ((peers != null) && (peers.Length > 0))
                {
                    _dhtPeers.AddRange(peers);
                    DiscoveredPeers?.Invoke(this, peers);
                }
            }
            catch (Exception ex)
            {
                _dhtLastException = ex;
            }
        }
Beispiel #7
0
        protected override bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash)
        {
            var nodeId = (ulong)node.CompactEndPoint().ToInt64();
            var path   = nodeId << 16 | (uint)(msgId[0] << 8) | msgId[1];

            return(_treeStore.TryGetValue(path, out infoHash));
        }
Beispiel #8
0
        protected override bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId)
        {
            var nodeId = (ulong)node.CompactEndPoint().ToInt64();

            lock (this)
            {
                _index++;
                if (_index >= _bucketArray.Length)
                {
                    _index = 0;
                }
            }
            var nowTick = DateTime.Now.Ticks;

            if (nowTick - _lastClearTime >= _clearDuration)
            {
                lock (this)
                {
                    if (nowTick - _lastClearTime >= _clearDuration)
                    {
                        _treeStore.Clear();
                        _lastClearTime = nowTick;
                    }
                }
            }
            msgId = _bucketArray[_index];
            var path = nodeId << 16 | (uint)(msgId[0] << 8) | msgId[1];

            return(_treeStore.TryAdd(path, infoHash));
        }
 public TrackerManager(BinaryNumber networkID, int servicePort, DhtNode ipv4DhtNode, DhtNode ipv6DhtNode, int customUpdateInterval, bool lookupOnly = false)
 {
     _networkID            = networkID;
     _servicePort          = servicePort;
     _ipv4DhtNode          = ipv4DhtNode;
     _ipv6DhtNode          = ipv6DhtNode;
     _customUpdateInterval = customUpdateInterval;
     _lookupOnly           = lookupOnly;
 }
Beispiel #10
0
 public bool RequireRegisteredInfo(DhtMessage message, DhtNode node)
 {
     if (TransactionIdMapType.ContainsKey(message.MessageId))
     {
         message.CommandType = TransactionIdMapType[message.MessageId];
         return(true);
     }
     message.CommandType = CommandType.Get_Peers;
     if (RequireGetPeersRegisteredInfo(message.MessageId, node, out var infoHash))
     {
         message.Data["info_hash"] = infoHash;
         return(true);
     }
     return(false);
 }
Beispiel #11
0
        protected override bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId)
        {
            var nodeKey = node.CompactEndPoint();
            var key     = new byte[nodeKey.Length + 2];

            Array.Copy(nodeKey, 0, key, 2, nodeKey.Length);
            var tryTimes = 0;

            while (true)
            {
                if (tryTimes > 10)
                {
                    break;
                }
                lock (this)
                {
                    _bucketIndex++;
                    if (_bucketIndex >= _bucketArray.Length)
                    {
                        _bucketIndex = 0;
                    }
                }
                msgId  = _bucketArray[_bucketIndex];
                key[0] = msgId[0];
                key[1] = msgId[1];
                lock (_syncRoot)
                {
                    var old = _table.Find(msgId);
                    if (old == null || old.AddTime.AddMinutes(30) < DateTime.Now)
                    {
                        _operateSize++;
                        _table[key] = new Record()
                        {
                            InfoHash = infoHash, AddTime = DateTime.Now
                        };
                        if (_operateSize > 5120)
                        {
                            _storageEngine.Commit();
                            _operateSize = 0;
                        }
                        return(true);
                    }
                }
                tryTimes++;
            }
            msgId = null;
            return(false);
        }
Beispiel #12
0
        protected override bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash)
        {
            var nodeId  = node.CompactEndPoint().ToInt64();
            var srcript = _unRegisterScript[(int)(nodeId % _registerScript.Count)];
            var result  = srcript.Evaluate(_database, new { point = nodeId, msgId = ((byte[])msgId) });

            if (result.IsNull)
            {
                infoHash = null;
                return(false);
            }
            var hash = (byte[])result;

            infoHash = hash;
            return(true);
        }
Beispiel #13
0
        public async Task <bool> RequireRegisteredInfoAsync(DhtMessage message, DhtNode node)
        {
            if (TransactionIdMapType.ContainsKey(message.MessageId))
            {
                message.CommandType = TransactionIdMapType[message.MessageId];
                return(true);
            }
            message.CommandType = CommandType.Get_Peers;
            var result = await RequireGetPeersRegisteredInfoAsync(message.MessageId, node);

            if (result.IsOk)
            {
                message.Data["info_hash"] = result.InfoHash;
                return(true);
            }
            return(false);
        }
Beispiel #14
0
 protected override bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash)
 {
     if (_mappingInfo.TryGetValue(msgId, out var mapInfo))
     {
         if (_idMappingInfo.TryGetValue(mapInfo.InfoHash, out var idMap))
         {
             lock (idMap)
             {
                 var nodeId = node.CompactEndPoint().ToInt64();
                 var isok   = idMap.Remove(nodeId);
                 if (idMap.Count <= 0)
                 {
                     _idMappingInfo.TryRemove(mapInfo.InfoHash, out var rm);
                     _mappingInfo.TryRemove(msgId, out var obj);
                     _bucket.Add(msgId);
                 }
                 if (!isok)
                 {
                     infoHash = null;
                     return(false);
                 }
             }
         }
         else
         {
             _mappingInfo.TryRemove(msgId, out var obj);
             _bucket.Add(msgId);
         }
     }
     if (mapInfo?.InfoHash == null)
     {
         infoHash = null;
         return(false);
     }
     infoHash = mapInfo.InfoHash;
     return(true);
 }
Beispiel #15
0
        protected override bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash)
        {
            infoHash = null;
            var nodeKey = node.CompactEndPoint().ToInt64();

            if (!NodeMap.TryGetValue(nodeKey, out var nodeMap))
            {
                return(false);
            }
            var result = false;

            nodeMap.LastTime = DateTime.Now.Ticks;
            if (nodeMap.InfoHashMap.TryRemove(msgId, out var infohash))
            {
                if (infohash?.InfoHash == null)
                {
                    return(false);
                }
                infoHash = infohash.InfoHash;
                result   = true;
            }
            if (nodeMap.InfoHashMap.Count <= 0)
            {
                if (NodeMap.TryRemove(nodeKey, out var rm) && rm.InfoHashMap.Count > 0)
                {
                    NodeMap.AddOrUpdate(nodeKey, rm, (key, old) =>
                    {
                        foreach (var item in rm.InfoHashMap)
                        {
                            old.InfoHashMap.TryAdd(item.Key, item.Value);
                        }
                        return(old);
                    });
                }
            }
            return(result);
        }
Beispiel #16
0
        protected virtual Task <(bool IsOk, byte[] InfoHash)> RequireGetPeersRegisteredInfoAsync(TransactionId msgId, DhtNode node)
        {
            var result = RequireGetPeersRegisteredInfo(msgId, node, out var infoHash);

            return(Task.FromResult((result, infoHash)));
        }
        public static TcpRelayService StartTcpRelay(BinaryNumber networkID, Connection connection, int servicePort, DhtNode dhtNode, Uri[] tracketURIs)
        {
            TcpRelayService relay;

            lock (_relays)
            {
                if (_relays.ContainsKey(networkID))
                {
                    relay = _relays[networkID];
                }
                else
                {
                    relay = new TcpRelayService(networkID, servicePort, dhtNode);
                    _relays.Add(networkID, relay);
                }

                lock (relay._relayConnections)
                {
                    relay._relayConnections.Add(connection.RemotePeerID, connection);
                }
            }

            relay._trackerManager.AddTracker(tracketURIs);
            relay._trackerManager.StartTracking();

            return(relay);
        }
Beispiel #18
0
        protected override bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId)
        {
            var nodeId = node.CompactEndPoint().ToInt64();

            if (_filter.Contain(nodeId))
            {
                msgId = null;
                return(false);
            }
            TransactionId messageId;

            if (_idMappingInfo.TryGetValue(infoHash, out var idMap))
            {
                if (!idMap.Add(nodeId))
                {
                    msgId = null;
                    return(false);
                }
                messageId = idMap.TransactionId;
                if (_mappingInfo.TryGetValue(messageId, out var info))
                {
                    info.LastTime = DateTime.Now;
                }
            }
            else
            {
                msgId = null;
                var cleared = false;
                while (!_bucket.TryTake(out messageId, 1000))
                {
                    if (cleared) //清理以后没有过期命令则丢弃该消息
                    {
                        return(false);
                    }
                    ClearExpireMessage();
                    cleared = true;
                }
                if (!_mappingInfo.TryAdd(messageId, new MapInfo()
                {
                    LastTime = DateTime.Now,
                    InfoHash = infoHash
                }))
                {
                    msgId = null;
                    return(false);
                }
                idMap = new IdMapInfo()
                {
                    TransactionId = messageId
                };
                idMap.Add(nodeId);
                if (_idMappingInfo.TryAdd(infoHash, idMap))
                {
                    msgId = messageId;
                    return(true);
                }
                return(false);
            }
            msgId = messageId;
            return(true);
        }
Beispiel #19
0
        protected override Task <(bool IsOk, byte[] InfoHash)> RequireGetPeersRegisteredInfoAsync(TransactionId msgId, DhtNode node)
        {
            var nodeId  = node.CompactEndPoint().ToInt64();
            var srcript = _unRegisterScript[(int)(nodeId % _registerScript.Count)];

            return(srcript.EvaluateAsync(_database, new { point = nodeId, msgId = ((byte[])msgId) }).ContinueWith(
                       t =>
            {
                if (t.IsCanceled || t.IsFaulted)
                {
                    return (false, null);
                }
                var result = t.Result;
                if (result.IsNull)
                {
                    return (false, null);
                }
                var hash = (byte[])result;
                return (true, hash);
            }));
        }
Beispiel #20
0
        protected override Task <(bool IsOk, TransactionId MsgId)> RegisterGetPeersMessageAsync(byte[] infoHash, DhtNode node)
        {
            var nodeId     = node.CompactEndPoint().ToInt64();
            var srcript    = _registerScript[(int)(nodeId % _registerScript.Count)];
            var localIndex = _index;

            localIndex++;
            if (localIndex >= _bucketArray.Length)
            {
                localIndex = 0;
            }
            var msgId = _bucketArray[localIndex];

            return(srcript.EvaluateAsync(_database,
                                         new { point = nodeId, hash = infoHash, msgId = ((byte[])msgId) }).ContinueWith(
                       t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                {
                    return (false, null);
                }
                var result = t.Result;
                if (!result.IsNull)
                {
                    var resultInt = (int)result;
                    if (resultInt == 1)
                    {
                        return (true, msgId);
                    }
                }
                return (false, null);
            }));
        }
Beispiel #21
0
        protected override bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId)
        {
            var sendPeers = InfoHashPeers.GetOrAdd(infoHash, new HashSet <long>());
            var nodeKey   = node.CompactEndPoint().ToInt64();

            lock (sendPeers)
            {
                if (sendPeers.Contains(nodeKey))
                {
                    msgId = null;
                    return(false);
                }
                sendPeers.Add(nodeKey);
            }
            var nodeMapInfo = NodeMap.GetOrAdd(nodeKey, new NodeMapInfo());

            if (nodeMapInfo.IsExpire(_expireTimeSpan))
            {
                NodeMap.TryRemove(nodeKey, out nodeMapInfo);
                msgId = null;
                lock (sendPeers)
                {
                    sendPeers.Remove(nodeKey);
                }
                return(false);
            }
            if (DateTime.Now >= _lastClearTime)
            {
                lock (_syncRoot)
                {
                    if (DateTime.Now >= _lastClearTime)
                    {
                        ClearExpireMessage();
                        _lastClearTime = DateTime.Now.AddTicks(_expireTimeSpan);
                    }
                }
            }
            var mapItem = new NodeMapInfoItem()
            {
                InfoHash = infoHash, LastTime = DateTime.Now.Ticks
            };

            lock (_bucketArray)
            {
                _bucketIndex++;
                if (_bucketIndex >= _bucketArray.Length)
                {
                    _bucketIndex = 0;
                }
                msgId = _bucketArray[_bucketIndex];
            }
            if (nodeMapInfo.InfoHashMap.TryAdd(msgId, mapItem))
            {
                return(true);
            }
            lock (sendPeers)
            {
                sendPeers.Remove(nodeKey);
            }
            msgId = null;
            return(false);
        }
Beispiel #22
0
 protected abstract bool RequireGetPeersRegisteredInfo(TransactionId msgId, DhtNode node, out byte[] infoHash);
Beispiel #23
0
        protected virtual Task <(bool IsOk, TransactionId MsgId)> RegisterGetPeersMessageAsync(byte[] infoHash, DhtNode node)
        {
            var result = RegisterGetPeersMessage(infoHash, node, out var msgId);

            return(Task.FromResult((result, msgId)));
        }
Beispiel #24
0
 protected abstract bool RegisterGetPeersMessage(byte[] infoHash, DhtNode node, out TransactionId msgId);