public PeerInfo(IPEndPoint peerEP, BinaryID networkID)
            {
                _peerEP    = peerEP;
                _networkID = networkID;

                _dateCreated = DateTime.UtcNow;
            }
        private TcpRelayService(BinaryID networkID, int servicePort, DhtClient dhtClient)
        {
            _trackerManager = new TrackerManager(networkID, servicePort, dhtClient, BIT_CHAT_TRACKER_UPDATE_INTERVAL);

            //start keep alive timer
            _tcpRelayConnectionKeepAliveTimer = new Timer(RelayConnectionKeepAliveTimerCallback, null, TCP_RELAY_KEEP_ALIVE_INTERVAL, Timeout.Infinite);
        }
        public static TcpRelayService StartTcpRelay(BinaryID networkID, Connection connection, int servicePort, DhtClient dhtClient, Uri[] tracketURIs)
        {
            TcpRelayService relay;

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

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

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

            return(relay);
        }
 public void StopAnnouncement(BinaryID networkID)
 {
     lock (_announceNetworkIDs)
     {
         _announceNetworkIDs.Remove(networkID);
     }
 }
 public void StopTracking(BinaryID networkID)
 {
     lock (_trackedNetworkIDs)
     {
         _trackedNetworkIDs.Remove(networkID);
     }
 }
        public static List <IPEndPoint> GetPeerEPs(BinaryID channelName, Connection requestingConnection)
        {
            BinaryID localPeerID  = requestingConnection.LocalPeerID;
            BinaryID remotePeerID = requestingConnection.RemotePeerID;

            lock (_relays)
            {
                foreach (KeyValuePair <BinaryID, TcpRelayService> itemRelay in _relays)
                {
                    BinaryID computedChannelName = Connection.GetChannelName(localPeerID, remotePeerID, itemRelay.Key);

                    if (computedChannelName.Equals(channelName))
                    {
                        Dictionary <BinaryID, Connection> relayConnections = itemRelay.Value._relayConnections;
                        List <IPEndPoint> peerEPs = new List <IPEndPoint>(relayConnections.Count);

                        lock (relayConnections)
                        {
                            foreach (KeyValuePair <BinaryID, Connection> itemProxyConnection in relayConnections)
                            {
                                peerEPs.Add(itemProxyConnection.Value.RemotePeerEP);
                            }
                        }

                        return(peerEPs);
                    }
                }
            }

            return(null);
        }
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_tcpRelayConnectionKeepAliveTimer != null)
                {
                    _tcpRelayConnectionKeepAliveTimer.Dispose();
                    _tcpRelayConnectionKeepAliveTimer = null;

                    //remove all networks from all tcp relay connections
                    BinaryID[] networkIDs;

                    lock (_networks)
                    {
                        networkIDs = new BinaryID[_networks.Keys.Count];
                        _networks.Keys.CopyTo(networkIDs, 0);
                    }

                    lock (_tcpRelayConnections)
                    {
                        foreach (Connection relayConnection in _tcpRelayConnections.Values)
                        {
                            ThreadPool.QueueUserWorkItem(RemoveTcpRelayFromConnectionAsync, new object[] { relayConnection, networkIDs });
                        }

                        _tcpRelayConnections.Clear();
                    }
                }

                _disposed = true;
            }
        }
            public bool IsResponseValid(BinaryID networkID, IPAddress remotePeerIP)
            {
                if (!_isResponse)
                {
                    throw new Exception("Packet is not a response.");
                }

                byte[]   servicePort = BitConverter.GetBytes(_servicePort);
                BinaryID computedHmac;

                using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                {
                    using (MemoryStream mS2 = new MemoryStream(50))
                    {
                        mS2.Write(_challenge.ID, 0, 32); //query_challenge

                        byte[] ipAddr = remotePeerIP.GetAddressBytes();
                        mS2.Write(ipAddr, 0, ipAddr.Length); //peer_ip_address

                        mS2.Write(servicePort, 0, 2);        //service_port

                        mS2.Position = 0;
                        computedHmac = new BinaryID(hmacSHA256.ComputeHash(mS2)); //computed hmac
                    }
                }

                return(_hmac.Equals(computedHmac));
            }
            private DiscoveryPacket(bool isResponse, ushort servicePort, BinaryID challenge)
            {
                _isResponse  = isResponse;
                _servicePort = servicePort;
                _challenge   = challenge;

                _dateCreated = DateTime.UtcNow;
            }
Beispiel #10
0
 public TrackerManager(BinaryID networkID, int servicePort, DhtClient dhtClient, int customUpdateInterval, bool lookupOnly = false)
 {
     _networkID            = networkID;
     _servicePort          = servicePort;
     _dhtClient            = dhtClient;
     _customUpdateInterval = customUpdateInterval;
     _lookupOnly           = lookupOnly;
 }
        private void SendResponse(DiscoveryPacket receivedQueryPacket, BinaryID networkID, IPAddress remotePeerIP)
        {
            NetworkInfo network = NetUtilities.GetNetworkInfo(remotePeerIP);

            DiscoveryPacket responsePacket = DiscoveryPacket.CreateResponsePacket(_announcePort, receivedQueryPacket.Challenge);

            byte[] packet = responsePacket.ToArray(networkID, network.LocalIP);

            _listener.SendTo(packet, 0, packet.Length, remotePeerIP);
        }
 public void StartTracking(BinaryID networkID)
 {
     lock (_trackedNetworkIDs)
     {
         if (!_trackedNetworkIDs.Contains(networkID))
         {
             _trackedNetworkIDs.Add(networkID);
         }
     }
 }
        public void StartAnnouncement(BinaryID networkID)
        {
            lock (_announceNetworkIDs)
            {
                if (!_announceNetworkIDs.Contains(networkID))
                {
                    _announceNetworkIDs.Add(networkID);

                    AnnounceAsync(new BinaryID[] { networkID }, null, ANNOUNCEMENT_RETRY_COUNT);
                }
            }
        }
            public bool IsThisNetwork(BinaryID networkID)
            {
                if (_isResponse)
                {
                    throw new Exception("Packet is not a query.");
                }

                BinaryID computedHmac;

                using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                {
                    computedHmac = new BinaryID(hmacSHA256.ComputeHash(_challenge.ID)); //computed hmac
                }

                return(_hmac.Equals(computedHmac));
            }
        public void RemoveNetwork(BinaryID networkID)
        {
            lock (_networks)
            {
                bool removed = _networks.Remove(networkID);
                if (!removed)
                {
                    return;
                }
            }

            lock (_tcpRelayConnections)
            {
                foreach (Connection relayConnection in _tcpRelayConnections.Values)
                {
                    ThreadPool.QueueUserWorkItem(RemoveTcpRelayFromConnectionAsync, new object[] { relayConnection, new BinaryID[] { networkID } });
                }
            }
        }
            public byte[] ToArray(BinaryID networkID, IPAddress senderPeerIP = null)
            {
                using (MemoryStream mS = new MemoryStream(BUFFER_MAX_SIZE))
                {
                    if (_isResponse)
                    {
                        byte[] servicePort = BitConverter.GetBytes(_servicePort);

                        mS.WriteByte(6);                //version
                        mS.Write(servicePort, 0, 2);    //service_port
                        mS.Write(_challenge.ID, 0, 32); //query_challenge

                        using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                        {
                            using (MemoryStream mS2 = new MemoryStream(50))
                            {
                                mS2.Write(_challenge.ID, 0, 32); //query_challenge

                                byte[] ipAddr = senderPeerIP.GetAddressBytes();
                                mS2.Write(ipAddr, 0, ipAddr.Length); //peer_ip_address

                                mS2.Write(servicePort, 0, 2);        //service_port

                                mS2.Position = 0;
                                mS.Write(hmacSHA256.ComputeHash(mS2), 0, 32); //hmac
                            }
                        }
                    }
                    else
                    {
                        mS.WriteByte(5);                //version
                        mS.Write(_challenge.ID, 0, 32); //challenge

                        using (HMACSHA256 hmacSHA256 = new HMACSHA256(networkID.ID))
                        {
                            mS.Write(hmacSHA256.ComputeHash(_challenge.ID), 0, 32); //hmac
                        }
                    }

                    return(mS.ToArray());
                }
            }
        public void AddNetwork(BinaryID networkID, Uri[] trackerURIs)
        {
            lock (_networks)
            {
                if (_networks.ContainsKey(networkID))
                {
                    return;
                }

                _networks.Add(networkID, trackerURIs);
            }

            lock (_tcpRelayConnections)
            {
                foreach (Connection relayConnection in _tcpRelayConnections.Values)
                {
                    ThreadPool.QueueUserWorkItem(SetupTcpRelayOnConnectionAsync, new object[] { relayConnection, networkID, trackerURIs });
                }
            }
        }
            public DiscoveryPacket(Stream s)
            {
                switch (s.ReadByte())
                {
                case 5:     //query
                {
                    byte[] bufferChallenge = new byte[32];
                    byte[] bufferHmac      = new byte[32];

                    s.Read(bufferChallenge, 0, 32);
                    s.Read(bufferHmac, 0, 32);

                    _isResponse = false;
                    _challenge  = new BinaryID(bufferChallenge);
                    _hmac       = new BinaryID(bufferHmac);
                }
                break;

                case 6:     //response
                {
                    byte[] bufferServicePort = new byte[2];
                    byte[] bufferChallenge   = new byte[32];
                    byte[] bufferHmac        = new byte[32];

                    s.Read(bufferServicePort, 0, 2);
                    s.Read(bufferChallenge, 0, 32);
                    s.Read(bufferHmac, 0, 32);

                    _isResponse  = true;
                    _servicePort = BitConverter.ToUInt16(bufferServicePort, 0);
                    _challenge   = new BinaryID(bufferChallenge);
                    _hmac        = new BinaryID(bufferHmac);
                }
                break;

                default:
                    throw new IOException("Invalid local discovery packet.");
                }
            }
        private void SetupTcpRelayOnConnectionAsync(object state)
        {
            try
            {
                object[] parameters = state as object[];

                Connection relayConnection = parameters[0] as Connection;
                BinaryID   networkID       = parameters[1] as BinaryID;
                Uri[]      trackerURIs     = parameters[2] as Uri[];

                bool success = relayConnection.RequestStartTcpRelay(new BinaryID[] { networkID }, trackerURIs, TCP_RELAY_REQUEST_TIMEOUT);
                if (!success)
                {
                    //remove failed relay
                    lock (_tcpRelayConnections)
                    {
                        _tcpRelayConnections.Remove(relayConnection.RemotePeerEP);
                    }
                }
            }
            catch
            { }
        }
 public static DiscoveryPacket CreateResponsePacket(ushort servicePort, BinaryID challenge)
 {
     return(new DiscoveryPacket(true, servicePort, challenge));
 }
 public static DiscoveryPacket CreateQueryPacket()
 {
     return(new DiscoveryPacket(false, 0, BinaryID.GenerateRandomID256()));
 }
        private void listener_ReceivedPacket(DiscoveryPacket packet, IPAddress remotePeerIP)
        {
            if (packet.IsResponse)
            {
                #region response process

                lock (_queryPacketCache)
                {
                    int i = _queryPacketCache.IndexOf(packet);
                    if (i < 0)
                    {
                        return;
                    }

                    DiscoveryPacket queryPacket = _queryPacketCache[i];
                    if (queryPacket.IsExpired())
                    {
                        return;
                    }
                }

                BinaryID foundNetworkID = null;

                lock (_announceNetworkIDs)
                {
                    foreach (BinaryID networkID in _announceNetworkIDs)
                    {
                        if (packet.IsResponseValid(networkID, remotePeerIP))
                        {
                            foundNetworkID = networkID;
                            break;
                        }
                    }
                }

                if (foundNetworkID != null)
                {
                    IPEndPoint peerEP   = new IPEndPoint(remotePeerIP, packet.ServicePort);
                    PeerInfo   peerInfo = new PeerInfo(peerEP, foundNetworkID);

                    bool peerInCache;

                    lock (_peerInfoCache)
                    {
                        if (_peerInfoCache.Contains(peerInfo))
                        {
                            PeerInfo existingPeerInfo = _peerInfoCache[_peerInfoCache.IndexOf(peerInfo)];

                            if (existingPeerInfo.IsExpired())
                            {
                                peerInCache = false;
                                _peerInfoCache.Remove(existingPeerInfo);
                            }
                            else
                            {
                                peerInCache = true;
                            }
                        }
                        else
                        {
                            peerInCache = false;
                        }
                    }

                    if (!peerInCache)
                    {
                        lock (_peerInfoCache)
                        {
                            _peerInfoCache.Add(peerInfo);
                        }

                        PeerDiscovered(this, peerEP, foundNetworkID);
                    }
                }

                #endregion
            }
            else
            {
                #region query process

                BinaryID foundNetworkID = null;

                lock (_trackedNetworkIDs)
                {
                    foreach (BinaryID networkID in _trackedNetworkIDs)
                    {
                        if (packet.IsThisNetwork(networkID))
                        {
                            foundNetworkID = networkID;
                            break;
                        }
                    }
                }

                if (foundNetworkID != null)
                {
                    SendResponse(packet, foundNetworkID, remotePeerIP);
                }

                #endregion
            }
        }