Example #1
0
        public void AddNode(NodeContact contact)
        {
            if (contact.NodeEP.AddressFamily != _currentNode.NodeEP.AddressFamily)
            {
                return;
            }

            if (_routingTable.AddContact(contact))
            {
                Debug.Write(this.GetType().Name, "node contact added: " + contact.ToString());

                ThreadPool.QueueUserWorkItem(delegate(object state)
                {
                    Query(DhtRpcPacket.CreatePingPacket(_currentNode), contact);
                });
            }
        }
Example #2
0
        internal bool Ping(NodeContact contact)
        {
            DhtRpcPacket response = Query(DhtRpcPacket.CreatePingPacket(_currentNode), contact);

            return(response != null);
        }
Example #3
0
        private DhtRpcPacket ProcessQuery(DhtRpcPacket query, EndPoint remoteNodeEP)
        {
            //in case of remote node querying via Tor, remoteNodeEP.Address will be loopback IP. Use the onion address from the query as remote end point

            if (!_currentNode.NodeEP.Equals(remoteNodeEP))
            {
                switch (remoteNodeEP.AddressFamily)
                {
                case AddressFamily.InterNetwork:
                case AddressFamily.InterNetworkV6:
                    IPAddress remoteNodeAddress = (remoteNodeEP as IPEndPoint).Address;

                    if (IPAddress.IsLoopback(remoteNodeAddress) && (query.SourceNodeEP.AddressFamily == AddressFamily.Unspecified) && (query.SourceNodeEP as DomainEndPoint).Address.EndsWith(".onion", StringComparison.OrdinalIgnoreCase))
                    {
                        AddNode(query.SourceNodeEP);     //use the tor hidden end point claimed by remote node
                    }
                    else
                    {
                        AddNode(new IPEndPoint(remoteNodeAddress, query.SourceNodeEP.GetPort()));     //use remote node end point as seen by connection manager and use port from query
                    }
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            Debug.Write(this.GetType().Name, "query received from: " + remoteNodeEP.ToString() + "; type: " + query.Type.ToString());

            //process query
            switch (query.Type)
            {
            case DhtRpcType.PING:
                return(DhtRpcPacket.CreatePingPacket(_currentNode));

            case DhtRpcType.FIND_NODE:
                return(DhtRpcPacket.CreateFindNodePacketResponse(_currentNode, query.NetworkId, _routingTable.GetKClosestContacts(query.NetworkId, false)));

            case DhtRpcType.FIND_PEERS:
                EndPoint[] peers = _currentNode.GetPeers(query.NetworkId);
                if (peers.Length == 0)
                {
                    return(DhtRpcPacket.CreateFindPeersPacketResponse(_currentNode, query.NetworkId, _routingTable.GetKClosestContacts(query.NetworkId, false), peers));
                }
                else
                {
                    return(DhtRpcPacket.CreateFindPeersPacketResponse(_currentNode, query.NetworkId, new NodeContact[] { }, peers));
                }

            case DhtRpcType.ANNOUNCE_PEER:
                if ((query.Peers != null) && (query.Peers.Length > 0))
                {
                    EndPoint peerEP;

                    if (query.Peers[0].AddressFamily == AddressFamily.Unspecified)
                    {
                        peerEP = query.Peers[0];
                    }
                    else
                    {
                        peerEP = new IPEndPoint((remoteNodeEP as IPEndPoint).Address, query.Peers[0].GetPort());
                    }

                    _currentNode.StorePeer(query.NetworkId, peerEP);
                }

                return(DhtRpcPacket.CreateAnnouncePeerPacketResponse(_currentNode, query.NetworkId, _currentNode.GetPeers(query.NetworkId)));

            default:
                throw new Exception("Invalid DHT-RPC type.");
            }
        }