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

add naive detection of public ip address #554

Merged
merged 2 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/components/P2P/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { INDEXER_DDO_EVENT_EMITTER } from '../Indexer/index.js'
import { P2P_LOGGER } from '../../utils/logging/common.js'
import { CoreHandlersRegistry } from '../core/handler/coreHandlersRegistry'
import { multiaddr } from '@multiformats/multiaddr'
import { getIPv4, getIPv6 } from '../../utils/ip.js'

const DEFAULT_OPTIONS = {
pollInterval: 1000
Expand Down Expand Up @@ -84,6 +85,7 @@ export class OceanP2P extends EventEmitter {
private _handleMessage: any
private _interval: NodeJS.Timeout
private _upnp_interval: NodeJS.Timeout
private _ip_discovery_interval: NodeJS.Timeout
private _idx: number
private readonly db: Database
private readonly _config: OceanNodeConfig
Expand Down Expand Up @@ -794,6 +796,73 @@ export class OceanP2P extends EventEmitter {
// we need to wait until we have some peers connected
clearInterval(this._upnp_interval)
const node = <any>this._libp2p
// try autodiscover by using ipify.org. This is a very long shot, but it works if you have a proper port forward
let haveIPv4 = false
let haveIPv6 = false
const addrs = node.components.transportManager.getAddrs()
for (const addr of addrs) {
if (addr.toOptions().family === 4) haveIPv4 = true
if (addr.toOptions().family === 6) haveIPv6 = true
}
P2P_LOGGER.info(`Doing discovery on IPv4: ` + haveIPv4 + ' , IPv6:' + haveIPv6)
if (
node &&
this._config.p2pConfig &&
this._config.p2pConfig.enableIPV4 &&
this._config.p2pConfig.ipV4BindTcpPort > 0 &&
haveIPv4
) {
const ipV4 = await getIPv4()

if (ipV4) {
P2P_LOGGER.info(`Looks like our external IPV4 address is ` + ipV4)
const addressToAdd = multiaddr(
'/ip4/' + ipV4 + '/tcp/' + String(this._config.p2pConfig.ipV4BindTcpPort)
)
const alreadyObserving = await node.components.addressManager.getObservedAddrs()
if (!alreadyObserving.includes(addressToAdd)) {
P2P_LOGGER.info('Adding ' + addressToAdd.toString() + ' to observed addresses')

try {
await node.components.addressManager.addObservedAddr(addressToAdd)
} catch (e) {
P2P_LOGGER.info('Failed to add')
}
}
} else {
P2P_LOGGER.info(`Cannot detect our public IPv4`)
}
}

if (
node &&
this._config.p2pConfig &&
this._config.p2pConfig.enableIPV6 &&
this._config.p2pConfig.ipV6BindTcpPort > 0 &&
haveIPv6
) {
const ipV6 = await getIPv6()

if (ipV6) {
P2P_LOGGER.info(`Looks like our external IPV6 address is ` + ipV6)
const addressToAdd = multiaddr(
'/ip6/' + ipV6 + '/tcp/' + String(this._config.p2pConfig.ipV6BindTcpPort)
)
const alreadyObserving = await node.components.addressManager.getObservedAddrs()
if (!alreadyObserving.includes(addressToAdd)) {
P2P_LOGGER.info('Adding ' + addressToAdd.toString() + ' to observed addresses')

try {
await node.components.addressManager.addObservedAddr(addressToAdd)
} catch (e) {
P2P_LOGGER.info('Failed to add')
}
}
} else {
P2P_LOGGER.info(`Cannot detect our public IPv6`)
}
}

if (node) {
const connManager = node.components.connectionManager
if (connManager) {
Expand Down
23 changes: 23 additions & 0 deletions src/utils/ip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export async function getIPv4() {
return await getIPFromAPI('https://api.ipify.org?format=json')
}

export async function getIPv6() {
return await getIPFromAPI('https://api6.ipify.org?format=json')
}

export async function getIPFromAPI(url: string): Promise<string | null> {
try {
const res = await fetch(url, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
method: 'GET'
})
const data = await res.json()
return data.ip
} catch (e) {
return null
}
}
Loading