Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improved origins filtering #123

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
61 changes: 53 additions & 8 deletions api/basic/helper/multiaddr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,43 @@ import { Multiaddr } from 'multiaddr'
* Convert a comma-separated list of origins into an array of
* multiaddr strings that we could possibly connect to.
*
* Filters out:
* - malformed multiaddrs and ones with transports we don't recognise
* - private or reserved ip address that we wouldn't be able to connect to.
*/
* Picks the first 10 non-ip based multiaddr,
* or ip based multiaddrs with a public (non-bogon) IP address
* or a /p2p/:peerId addr from a bogon ip based multiaddr.
**/
export function findUsableMultiaddrs (input = ''): string[] {
if (input === '' || input === null) return []
return input
.split(',')
.filter(isMultiaddr)
.filter(hasPublicIpAddress)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more usage of this function. Looks like we can remove it

const specificAddrs: Set<string> = new Set()
const p2pAddrs: Set<string> = new Set()
for (const str of input.split(',')) {
const input = str.trim()
const ma = asMultiaddr(input)
if (ma === undefined) continue
// where we've got a ma with an ip we can't connect to,
// try to extract the /p2p/:peerId addr where available
if (hasBogonIpAddress(input)) {
const addr = getP2pAddr(input)
if (addr !== undefined) {
p2pAddrs.add(addr)
}
} else {
// either an ip based multiaddr with public ip, or a non-ip based multiaddr
specificAddrs.add(input)
}
}
return Array
.from(specificAddrs)
.concat(Array.from(p2pAddrs))
.slice(1, 10) // don't return an unbounded number of multiaddrs.
}

export function asMultiaddr (input = ''): Multiaddr | undefined {
if (input === '' || input === null) return undefined
try {
return new Multiaddr(input) // eslint-disable-line no-new
} catch (e) {
return undefined
}
}

export function isMultiaddr (input = ''): boolean {
Expand All @@ -37,3 +64,21 @@ export function hasPublicIpAddress (input = ''): boolean {
// not a IP based multiaddr, so we allow it.
return true
}

export function hasBogonIpAddress (input = ''): boolean {
if (input === '' || input === null) return false
if (input.startsWith('/ip6/') || input.startsWith('/ip4/')) {
const ip = input.split('/').at(2)
if (ip === undefined) return false
return bogon(ip)
}
return false
}

export function getP2pAddr (input = ''): string | undefined {
if (input === '' || input === null) return undefined
const match = input.match(/\/p2p\/\w+$/)
if (match != null) {
return match.at(0)
}
}
42 changes: 42 additions & 0 deletions api/test/multiaddrs.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import test from 'ava'
import { findUsableMultiaddrs } from '../basic/helper/multiaddr.js'

const fixture = [
'/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a dns4 address just to make sure everything is working as expected for non hasBogonIpAddress?

'/ip4/127.0.0.1/udp/4001/quic-v1/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/127.0.0.1/udp/4001/quic-v1/webtransport/certhash/uEiAcyORkzbKPHpd2Rq8px1APBfdnTJ1jzH10u92mYJAOMA/certhash/uEiBFkYB7Q0cp49VFSMY9ae8ffHaRJf7N0WXCGBkGp4KCIQ/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/127.0.0.1/udp/4001/quic/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/192.168.1.113/tcp/4001/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/192.168.1.113/udp/4001/quic-v1/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/192.168.1.113/udp/4001/quic-v1/webtransport/certhash/uEiAcyORkzbKPHpd2Rq8px1APBfdnTJ1jzH10u92mYJAOMA/certhash/uEiBFkYB7Q0cp49VFSMY9ae8ffHaRJf7N0WXCGBkGp4KCIQ/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/192.168.1.113/udp/4001/quic/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/45.76.79.40/udp/4001/quic-v1/p2p/12D3KooWGFLFZ9uYAqD8WschDcPDT4PgmsGzgvwrTdDmV4LD5kSe/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/45.76.79.40/udp/4001/quic/p2p/12D3KooWGFLFZ9uYAqD8WschDcPDT4PgmsGzgvwrTdDmV4LD5kSe/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/5.161.44.89/tcp/4001/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/5.161.44.89/udp/4001/quic/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/2a01:4ff:f0:ab6::1/tcp/4001/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/2a01:4ff:f0:ab6::1/udp/4001/quic/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/::1/tcp/4001/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/::1/udp/4001/quic-v1/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/::1/udp/4001/quic-v1/webtransport/certhash/uEiAcyORkzbKPHpd2Rq8px1APBfdnTJ1jzH10u92mYJAOMA/certhash/uEiBFkYB7Q0cp49VFSMY9ae8ffHaRJf7N0WXCGBkGp4KCIQ/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/::1/udp/4001/quic/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN'
]

const expected = [
'/ip4/5.161.44.89/tcp/4001/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip4/5.161.44.89/udp/4001/quic/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/2a01:4ff:f0:ab6::1/tcp/4001/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/ip6/2a01:4ff:f0:ab6::1/udp/4001/quic/p2p/12D3KooWSvYbdaYZmZucbkEHKDDoHNqCtkEMWdSm1z4udww6fyUM/p2p-circuit/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN',
'/p2p/12D3KooWADjHf2kyANQodg9z5sSdX4bGEMbWg7ojwu6SCyDAMtzN'
]

test('findUsableMultiaddrs', t => {
const input = fixture.join(',')
const res = findUsableMultiaddrs(input)
t.is(res.length, 5)
let i = 0
for (const ma of expected) {
t.is(res[i], ma)
i++
}
})