예제 #1
0
        // Retrieve the friend's connected S2 node address. Returns null if not found
        public string searchForRelay()
        {
            string   hostname = null;
            Presence presence = PresenceList.getPresenceByAddress(walletAddress);

            if (presence == null)
            {
                return(hostname);
            }

            byte[] wallet = presence.wallet;

            lock (presence)
            {
                // Go through each presence address searching for C nodes
                foreach (PresenceAddress addr in presence.addresses)
                {
                    // Only check Client nodes
                    if (addr.type == 'C')
                    {
                        // We have a potential candidate here, store it
                        hostname = addr.address;

                        string[] hostname_split = hostname.Split(':');

                        if (hostname_split.Count() == 2 && NetworkUtils.validateIP(hostname_split[0]))
                        {
                            // client is directly connectable
                            break;
                        }

                        // find a relay node
                        Presence s2presence = PresenceList.getPresenceByDeviceId(hostname);
                        if (s2presence != null)
                        {
                            PresenceAddress s2addr = s2presence.addresses.Find(x => x.device == hostname);
                            if (s2addr != null)
                            {
                                // We found the friend's connected s2 node
                                hostname = s2addr.address;
                                wallet   = s2presence.wallet;
                                break;
                            }
                        }
                    }
                }
            }

            // Store the last relay ip and wallet for this friend
            relayIP     = hostname;
            relayWallet = wallet;

            // Finally, return the ip address of the node
            return(relayIP);
        }
예제 #2
0
        public void start(Socket socket = null)
        {
            if (fullyStopped)
            {
                Logging.error("Can't start a fully stopped RemoteEndpoint");
                return;
            }

            if (running)
            {
                return;
            }

            if (socket != null)
            {
                clientSocket = socket;
            }
            if (clientSocket == null)
            {
                Logging.error("Could not start NetworkRemoteEndpoint, socket is null");
                return;
            }

            prepareSocket(clientSocket);

            remoteIP        = (IPEndPoint)clientSocket.RemoteEndPoint;
            address         = remoteIP.Address.ToString();
            fullAddress     = address + ":" + remoteIP.Port;
            presence        = null;
            presenceAddress = null;

            connectionStartTime = Clock.getTimestamp();

            lock (subscribedAddresses)
            {
                subscribedAddresses.Clear();
            }

            lastDataReceivedTime = Clock.getTimestamp();
            lastDataSentTime     = Clock.getTimestamp();

            state = RemoteEndpointState.Established;

            timeDifference   = 0;
            timeSyncComplete = false;
            timeSyncs.Clear();

            running = true;

            // Abort all related threads
            if (recvThread != null)
            {
                recvThread.Abort();
                recvThread = null;
            }
            if (sendThread != null)
            {
                sendThread.Abort();
                sendThread = null;
            }
            if (parseThread != null)
            {
                parseThread.Abort();
                parseThread = null;
            }

            try
            {
                TLC = new ThreadLiveCheck();
                // Start receive thread
                recvThread      = new Thread(new ThreadStart(recvLoop));
                recvThread.Name = "Network_Remote_Endpoint_Receive_Thread";
                recvThread.Start();

                // Start send thread
                sendThread      = new Thread(new ThreadStart(sendLoop));
                sendThread.Name = "Network_Remote_Endpoint_Send_Thread";
                sendThread.Start();

                // Start parse thread
                parseThread      = new Thread(new ThreadStart(parseLoop));
                parseThread.Name = "Network_Remote_Endpoint_Parse_Thread";
                parseThread.Start();
            }
            catch (Exception e)
            {
                Logging.error("Exception start remote endpoint: {0}", e.Message);
            }
        }
예제 #3
0
            public static void handleGetKeepAlives(byte[] data, RemoteEndpoint endpoint)
            {
                using (MemoryStream m = new MemoryStream(data))
                {
                    using (BinaryReader reader = new BinaryReader(m))
                    {
                        int ka_count = (int)reader.ReadIxiVarUInt();

                        int max_ka_per_chunk = CoreConfig.maximumKeepAlivesPerChunk;

                        for (int i = 0; i < ka_count;)
                        {
                            using (MemoryStream mOut = new MemoryStream(max_ka_per_chunk * 570))
                            {
                                using (BinaryWriter writer = new BinaryWriter(mOut))
                                {
                                    int next_ka_count;
                                    if (ka_count - i > max_ka_per_chunk)
                                    {
                                        next_ka_count = max_ka_per_chunk;
                                    }
                                    else
                                    {
                                        next_ka_count = ka_count - i;
                                    }
                                    writer.WriteIxiVarInt(next_ka_count);

                                    for (int j = 0; j < next_ka_count && i < ka_count; j++)
                                    {
                                        i++;

                                        long in_rollback_pos  = reader.BaseStream.Position;
                                        long out_rollback_len = mOut.Length;

                                        if (m.Position == m.Length)
                                        {
                                            break;
                                        }

                                        int    address_len = (int)reader.ReadIxiVarUInt();
                                        byte[] address     = reader.ReadBytes(address_len);

                                        int    device_len = (int)reader.ReadIxiVarUInt();
                                        byte[] device     = reader.ReadBytes(device_len);

                                        Presence p = PresenceList.getPresenceByAddress(address);
                                        if (p == null)
                                        {
                                            Logging.info("I don't have presence: " + Base58Check.Base58CheckEncoding.EncodePlain(address));
                                            continue;
                                        }

                                        PresenceAddress pa = p.addresses.Find(x => x.device.SequenceEqual(device));
                                        if (pa == null)
                                        {
                                            Logging.info("I don't have presence address: " + Base58Check.Base58CheckEncoding.EncodePlain(address));
                                            continue;
                                        }

                                        byte[] ka_bytes = pa.getKeepAliveBytes(address);
                                        byte[] ka_len   = IxiVarInt.GetIxiVarIntBytes(ka_bytes.Length);
                                        writer.Write(ka_len);
                                        writer.Write(ka_bytes);

                                        if (mOut.Length > CoreConfig.maxMessageSize)
                                        {
                                            reader.BaseStream.Position = in_rollback_pos;
                                            mOut.SetLength(out_rollback_len);
                                            i--;
                                            break;
                                        }
                                    }
                                }
                                endpoint.sendData(ProtocolMessageCode.keepAlivesChunk, mOut.ToArray(), null);
                            }
                        }
                    }
                }
            }