libp2p / go-libp2p

libp2p implementation in Go
MIT License
6.11k stars 1.08k forks source link

failed to open hole-punching stream: failed to negotiate protocol: protocols not supported: [/libp2p/dcutr] #3024

Closed NanoRed closed 3 days ago

NanoRed commented 1 month ago

Hello, I found that if the relay node is physically close enough to the nodes that under the NAT device, an error "failed to open hole-punching stream: failed to negotiate protocol: protocols not supported: [/libp2p/dcutr]" will occur in hole punching.

After some testing, it seems that when one of my NAT nodes has not yet obtained a public address and set stream handler for the protocol ID /libp2p/dcutr, another NAT node has already sent a request for /libp2p/dcutr.

This caused the hole punching to not work. Is there any solution? Or is there something wrong with my usage?

Here are some logs about my problem,

Node A:

2024-10-28T17:50:47.555+0800    DEBUG  p2p-holepunch   holepunch/svc.go:117    Host now has a public address. Starting holepunch protocol.
2024/10/28 17:50:57.039000 main.go:86: [INFO] new stream: 12D3KooWQ22CtKEBcPQjjACFooT9WrxovRTZCLzZSAvpW8vkSkHY
2024/10/28 17:50:57.039000 main.go:96: [DEBUG] received data: hello
2024-10-28T17:50:57.039+0800    DEBUG  p2p-holepunch   holepunch/holepuncher.go:130    got inbound proxy conn  {"peer": "12D3KooWQ22CtKEBcPQjjACFooT9WrxovRTZCLzZSAvpW8vkSkHY"}
2024-10-28T17:50:57.053+0800    DEBUG  p2p-holepunch   holepunch/holepuncher.go:136    hole punching failed    {"peer": "12D3KooWQ22CtKEBcPQjjACFooT9WrxovRTZCLzZSAvpW8vkSkHY", "error": "failed to open hole-punching stream: failed to negotiate protocol: protocols not supported: [/libp2p/dcutr]"}
2024/10/28 17:51:00.040231 main.go:96: [DEBUG] received data: hello
2024/10/28 17:51:03.039502 main.go:96: [DEBUG] received data: hello

Node B:

2024/10/28 17:50:57.034364 main.go:126: [INFO] connected to peer successfully
2024/10/28 17:50:57.034364 main.go:143: [DEBUG] write message
2024-10-28T17:50:57.151+0800    DEBUG  p2p-holepunch   holepunch/svc.go:117    Host now has a public address. Starting holepunch protocol.
2024/10/28 17:51:00.035302 main.go:143: [DEBUG] write message
2024/10/28 17:51:03.034581 main.go:143: [DEBUG] write message

These two nodes were both running on my PC under the same home NAT network.

NanoRed commented 1 month ago

@MarcoPolo Hi~sorry to border, can i get any information?

sukunrt commented 2 weeks ago

After some testing, it seems that when one of my NAT nodes has not yet obtained a public address

You'll need a public address for hole punching. Why is this device unable to get a public address?

NanoRed commented 2 weeks ago

After some testing, it seems that when one of my NAT nodes has not yet obtained a public address

You'll need a public address for hole punching. Why is this device unable to get a public address?

hi thanks for responding! this two device is under the NAT device, when i enable the holepunch service, it will run a goroutine called "waitForPublicAddr" it looks like a public address is needed to set the "/libp2p/dcutr" protocol stream handler

when Node B connected to Node A through p2p-circuit protocol(Node B is waiting the its public address from other nodes at the same time), Node A immediately send dcutr request to Node B although the Node B has not yet got its public address to set its protocol handler, that cause the error "failed to open hole-punching stream: failed to negotiate protocol: protocols not supported: [/libp2p/dcutr]"

i have another question: how is the public address obtained?

NanoRed commented 3 days ago

i think i figured it out by myself, thanks