Skip to content

Commit

Permalink
Expand wildcard addresses in mdns peer info
Browse files Browse the repository at this point in the history
  • Loading branch information
ianopolous committed May 22, 2024
1 parent a0710d5 commit f70b6f2
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 10 deletions.
77 changes: 68 additions & 9 deletions libp2p/src/main/kotlin/io/libp2p/discovery/MDnsDiscovery.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
package io.libp2p.discovery

import io.libp2p.core.Discoverer
import io.libp2p.core.Host
import io.libp2p.core.PeerId
import io.libp2p.core.PeerInfo
import io.libp2p.core.PeerListener
import io.libp2p.core.*
import io.libp2p.core.multiformats.Multiaddr
import io.libp2p.core.multiformats.MultiaddrComponent
import io.libp2p.core.multiformats.Protocol
import io.libp2p.discovery.mdns.AnswerListener
import io.libp2p.discovery.mdns.JmDNS
import io.libp2p.discovery.mdns.ServiceInfo
import io.libp2p.discovery.mdns.impl.DNSRecord
import io.libp2p.discovery.mdns.impl.constants.DNSRecordType
import java.net.Inet4Address
import java.net.Inet6Address
import java.net.InetAddress
import java.net.*
import java.util.*
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.ForkJoinPool
import java.util.stream.Collectors
import java.util.stream.Stream

class MDnsDiscovery(
private val host: Host,
Expand Down Expand Up @@ -91,11 +89,72 @@ class MDnsDiscovery(
return Integer.parseInt(str)
}

/* /ip6/::/tcp/4001 should expand to the following for example:
"/ip6/0:0:0:0:0:0:0:1/udp/4001/quic"
"/ip4/50.116.48.246/tcp/4001"
"/ip4/127.0.0.1/tcp/4001"
"/ip6/2600:3c03:0:0:f03c:92ff:fee7:bc1c/tcp/4001"
"/ip6/0:0:0:0:0:0:0:1/tcp/4001"
"/ip4/50.116.48.246/udp/4001/quic"
"/ip4/127.0.0.1/udp/4001/quic"
"/ip6/2600:3c03:0:0:f03c:92ff:fee7:bc1c/udp/4001/quic"
*/
fun expandWildcardAddresses(addr: Multiaddr): List<Multiaddr> {
// Do not include /p2p or /ipfs components which are superfluous here
if (!isWildcard(addr)) return java.util.List.of(Multiaddr(addr.components
.stream()
.filter { c: MultiaddrComponent ->
(c.protocol !== Protocol.P2P
&& c.protocol !== Protocol.IPFS)
}
.collect(Collectors.toList())))
if (addr.has(Protocol.IP4)) return listNetworkAddresses(false, addr)
return if (addr.has(Protocol.IP6)) listNetworkAddresses(true, addr) else emptyList()
}

fun listNetworkAddresses(includeIp6: Boolean, addr: Multiaddr): List<Multiaddr> {
return try {
Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
.flatMap { net: NetworkInterface ->
net.interfaceAddresses.stream()
.map { obj: InterfaceAddress -> obj.address }
.filter { ip: InetAddress? -> includeIp6 || ip is Inet4Address }
}
.map { ip: InetAddress ->
Multiaddr(
Stream.concat(
Stream.of(
MultiaddrComponent(
if (ip is Inet4Address) Protocol.IP4 else Protocol.IP6,
ip.address
)
),
addr.components.stream()
.filter { c: MultiaddrComponent ->
c.protocol !== Protocol.IP4 && c.protocol !== Protocol.IP6 && c.protocol !== Protocol.P2P && c.protocol !== Protocol.IPFS
}
)
.collect(Collectors.toList())
)
}
.collect(Collectors.toList())
} catch (e: SocketException) {
throw RuntimeException(e)
}
}

fun isWildcard(addr: Multiaddr): Boolean {
val s = addr.toString()
return s.contains("/::/") || s.contains("/0:0:0:0/")
}

private fun ip4Addresses() = ipAddresses(Protocol.IP4, Inet4Address::class.java)
private fun ip6Addresses() = ipAddresses(Protocol.IP6, Inet6Address::class.java)

private fun <R> ipAddresses(protocol: Protocol, klass: Class<R>): List<R> {
return host.listenAddresses().map {
return host.listenAddresses().flatMap {
expandWildcardAddresses(it)
}.map {
it.getFirstComponent(protocol)
}.filterNotNull().map {
InetAddress.getByAddress(localhost.hostName, it.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.libp2p.core.multiformats.Multiaddr
import io.libp2p.crypto.keys.generateEcdsaKeyPair
import io.libp2p.tools.NullHost
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import java.util.concurrent.TimeUnit

Expand Down Expand Up @@ -109,7 +110,7 @@ class MDnsDiscoveryTest {
discoverer.stop().get(5, TimeUnit.SECONDS)

assertEquals(hostIpv6.peerId, peerInfo?.peerId)
assertEquals(hostIpv6.listenAddresses().size, peerInfo?.addresses?.size)
assertTrue(hostIpv6.listenAddresses().size <= peerInfo?.addresses?.size!!)
}

@Test
Expand Down

0 comments on commit f70b6f2

Please sign in to comment.