From 006f4e94e78d8fea4e96daaa14fe99742ec6b5e5 Mon Sep 17 00:00:00 2001 From: Rowdy Mitchell Chotkan Date: Mon, 19 Aug 2024 17:39:11 +0200 Subject: [PATCH 1/2] Make `createIntroductionRequest` public --- ipv8/src/main/java/nl/tudelft/ipv8/Community.kt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ipv8/src/main/java/nl/tudelft/ipv8/Community.kt b/ipv8/src/main/java/nl/tudelft/ipv8/Community.kt index 8629351a..ad972e2e 100644 --- a/ipv8/src/main/java/nl/tudelft/ipv8/Community.kt +++ b/ipv8/src/main/java/nl/tudelft/ipv8/Community.kt @@ -1,6 +1,9 @@ package nl.tudelft.ipv8 -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.SupervisorJob import mu.KotlinLogging import nl.tudelft.ipv8.exception.PacketDecodingException import nl.tudelft.ipv8.keyvault.PrivateKey @@ -182,7 +185,7 @@ abstract class Community : Overlay { /** * Introduction and puncturing requests creation */ - internal fun createIntroductionRequest( + fun createIntroductionRequest( socketAddress: IPv4Address, extraBytes: ByteArray = byteArrayOf() ): ByteArray { From d790e0d505fe351d24663d22d35e08eabf098a28 Mon Sep 17 00:00:00 2001 From: Rowdy Mitchell Chotkan Date: Mon, 19 Aug 2024 17:39:23 +0200 Subject: [PATCH 2/2] Add force walk example --- .../force_walk/ConnectionCommunity.kt | 15 +++ .../jvm/demo/examples/force_walk/ForceWalk.kt | 102 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ConnectionCommunity.kt create mode 100644 demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ForceWalk.kt diff --git a/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ConnectionCommunity.kt b/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ConnectionCommunity.kt new file mode 100644 index 00000000..f8abbf14 --- /dev/null +++ b/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ConnectionCommunity.kt @@ -0,0 +1,15 @@ +package nl.tudelft.ipv8.jvm.demo.examples.force_walk + +import nl.tudelft.ipv8.Community +import nl.tudelft.ipv8.IPv4Address + +class ConnectionCommunity : Community() { + override val serviceId = "02313685c1912a141279f8248fc8db5899c5df5b" + + override fun walkTo(address: IPv4Address) { + val packet = createIntroductionRequest(address) + this.endpoint.send(address, packet) + } + +} + diff --git a/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ForceWalk.kt b/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ForceWalk.kt new file mode 100644 index 00000000..c8dcd670 --- /dev/null +++ b/demo-jvm/src/main/java/nl/tudelft/ipv8/jvm/demo/examples/force_walk/ForceWalk.kt @@ -0,0 +1,102 @@ +package nl.tudelft.ipv8.jvm.demo.examples.force_walk + +import kotlinx.coroutines.* +import mu.KotlinLogging +import nl.tudelft.ipv8.* +import nl.tudelft.ipv8.keyvault.JavaCryptoProvider +import nl.tudelft.ipv8.messaging.EndpointAggregator +import nl.tudelft.ipv8.messaging.udp.UdpEndpoint +import java.net.InetAddress +import java.util.* +import kotlin.math.roundToInt + +class Application { + + private val scope = CoroutineScope(Dispatchers.Default) + private val logger = KotlinLogging.logger {} + lateinit var ipv8: IPv8 + + fun run() { + startIpv8() + } + + private fun createConnectionCommunity(): OverlayConfiguration { + // Add no walkers on purpose. + return OverlayConfiguration( + Overlay.Factory(ConnectionCommunity::class.java), listOf() + ) + } + + private fun startIpv8() { + val myKey = JavaCryptoProvider.generateKey() + val myPeer = Peer(myKey) + val udpEndpoint = UdpEndpoint(8090, InetAddress.getByName("0.0.0.0")) + val endpoint = EndpointAggregator(udpEndpoint, null) + + val config = IPv8Configuration( + overlays = listOf( + createConnectionCommunity() + ), walkerInterval = 1.0 + ) + + this.ipv8 = IPv8(endpoint, config, myPeer) + this.ipv8.start() + + scope.launch { + while (true) { + for ((_, overlay) in ipv8.overlays) { + printPeersInfo(overlay) + } + logger.info("===") + delay(5000) + } + } + + while (ipv8.isStarted()) { + Thread.sleep(1000) + } + } + + private fun printPeersInfo(overlay: Overlay) { + val peers = overlay.getPeers() + logger.info(overlay::class.simpleName + ": ${peers.size} peers") + for (peer in peers) { + val avgPing = peer.getAveragePing() + val lastRequest = peer.lastRequest + val lastResponse = peer.lastResponse + + val lastRequestStr = + if (lastRequest != null) "" + ((Date().time - lastRequest.time) / 1000.0).roundToInt() + " s" else "?" + + val lastResponseStr = + if (lastResponse != null) "" + ((Date().time - lastResponse.time) / 1000.0).roundToInt() + " s" else "?" + + val avgPingStr = if (!avgPing.isNaN()) "" + (avgPing * 1000).roundToInt() + " ms" else "? ms" + logger.info("${peer.mid} (S: ${lastRequestStr}, R: ${lastResponseStr}, ${avgPingStr})") + } + } +} + +fun main(): Unit = runBlocking { + // Start two peers + val peer0 = Application() + val peer1 = Application() + + val scope = CoroutineScope(Dispatchers.Default) + + scope.launch { peer0.run() } + scope.launch { peer1.run() } + + // Wait for the peers to start + delay(1000) + + // Walk to each other + val peer0Address = peer0.ipv8.getOverlay()!!.myEstimatedLan + val peer1Address = peer1.ipv8.getOverlay()!!.myEstimatedLan + + peer0.ipv8.getOverlay()!!.walkTo(peer1Address) + peer1.ipv8.getOverlay()!!.walkTo(peer0Address) + + // Wait forever + delay(Long.MAX_VALUE) +}