// Sends a test message to a specified friend static public bool sendTestMessage(TestFriend friend) { // Search for the relay ip string relayip = friend.searchForRelay(); if (relayip == null) { Logging.error("No relay ip found."); return(false); } Logging.info(String.Format("Relay: {0}", relayip)); // Check if we're connected to the relay node TestStreamClient stream_client = TestStreamClientManager.isConnectedTo(relayip); if (stream_client == null) { // In a normal client, this should be done in a different thread and wait for the // connection to be established stream_client = TestStreamClientManager.connectTo(relayip); if (stream_client == null) { Logging.error(string.Format("Error sending message. Could not connect to stream node: {0}", relayip)); } } // Generate encryption keys byte[] keys_data = friend.generateKeys(); // Generate the transaction Transaction transaction = new Transaction((int)Transaction.Type.Normal); transaction.amount = CoreConfig.relayPriceInitial; transaction.toList.Add(friend.relayWallet, transaction.amount); transaction.fee = CoreConfig.transactionPrice; transaction.fromList.Add(new byte[1] { 0 }, transaction.amount + transaction.fee); transaction.blockHeight = Node.blockHeight; transaction.pubKey = Node.walletStorage.getPrimaryPublicKey(); // TODO: check if it's in the walletstate already transaction.checksum = Transaction.calculateChecksum(transaction); // Prepare the stream message StreamMessage message = new StreamMessage(); message.recipient = friend.walletAddress; message.sender = Node.walletStorage.getPrimaryAddress(); message.transaction = transaction.getBytes(); // Encrypt the message byte[] text_message = Encoding.UTF8.GetBytes("Hello Ixian World!"); message.encryptMessage(text_message, friend.aesPassword, friend.chachaKey); // Encrypt the transaction signature byte[] tx_signature = transaction.getSignature(transaction.checksum); message.encryptSignature(tx_signature, friend.aesPassword, friend.chachaKey); stream_client.sendData(ProtocolMessageCode.s2data, message.getBytes()); return(true); }
// Connects to a specified node, with the syntax host:port // Returns the connected stream client // Returns null if connection failed public static TestStreamClient connectTo(string host) { Logging.info(String.Format("Connecting to S2 node: {0}", host)); if (host == null || host.Length < 3) { Logging.error(String.Format("Invalid host address {0}", host)); return(null); } string[] server = host.Split(':'); if (server.Count() < 2) { Logging.warn(string.Format("Cannot connect to invalid hostname: {0}", host)); return(null); } // Resolve the hostname first string resolved_server_name = NetworkUtils.resolveHostname(server[0]); // Skip hostnames we can't resolve if (resolved_server_name.Length < 1) { Logging.warn(string.Format("Cannot resolve IP for {0}, skipping connection.", server[0])); return(null); } string resolved_host = string.Format("{0}:{1}", resolved_server_name, server[1]); // Verify against the publicly disclosed ip // Don't connect to self if (resolved_server_name.Equals(IxianHandler.publicIP, StringComparison.Ordinal)) { if (server[1].Equals(string.Format("{0}", IxianHandler.publicPort), StringComparison.Ordinal)) { Logging.info(string.Format("Skipping connection to public self seed node {0}", host)); return(null); } } // Get all self addresses and run through them List <string> self_addresses = CoreNetworkUtils.GetAllLocalIPAddresses(); foreach (string self_address in self_addresses) { // Don't connect to self if (resolved_server_name.Equals(self_address, StringComparison.Ordinal)) { if (server[1].Equals(string.Format("{0}", IxianHandler.publicPort), StringComparison.Ordinal)) { Logging.info(string.Format("Skipping connection to self seed node {0}", host)); return(null); } } } lock (connectingClients) { foreach (string client in connectingClients) { if (resolved_host.Equals(client, StringComparison.Ordinal)) { // We're already connecting to this client return(null); } } // The the client to the connecting clients list connectingClients.Add(resolved_host); } // Check if node is already in the client list lock (streamClients) { foreach (TestStreamClient client in streamClients) { if (client.getFullAddress(true).Equals(resolved_host, StringComparison.Ordinal)) { // Address is already in the client list return(null); } } } // Connect to the specified node TestStreamClient new_client = new TestStreamClient(); // Recompose the connection address from the resolved IP and the original port bool result = new_client.connectToServer(resolved_server_name, Convert.ToInt32(server[1])); // Add this node to the client list if connection was successfull if (result == true) { // Add this node to the client list lock (streamClients) { streamClients.Add(new_client); } } // Remove this node from the connecting clients list lock (connectingClients) { connectingClients.Remove(resolved_host); } return(new_client); }