// 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); }
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); } }
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); } } } } }