go-stun icon indicating copy to clipboard operation
go-stun copied to clipboard

Examples?

Open isaachess opened this issue 8 years ago • 4 comments

I'm struggling to use this effectively and am wondering if you could provide some examples.

The actually communication with the STUN server works fine: it returns the public addr observed by the STUN server.

But USING this information isn't working for me, and it has me wondering if I'm just misunderstanding how the package works (thus the request for examples).

For example, when calling stun.Discover it returns a conn and addr. I'm attempting, after performing the discover, to receive UDP packets sent to addr. So I'm trying to read from the return conn (while sending UDP messages to addr from another machine), but nothing ever comes through.

The purpose of STUN in my understanding is to hole-punch so peers can send UDP traffic to the public addr, which is then forwarded to the correct host. Can I see an example of how this package gets that done?

isaachess avatar Jun 20 '17 21:06 isaachess

@isaachess Yes, It should work exactly you described, but currently stun.Discover uses net.Dial instead of Listen (so, the socket is associated with a STUN-server's address) and hole-punching does not work. I'll fix it, thanks.

pixelbender avatar Jun 21 '17 07:06 pixelbender

I just spent the better part of a day tearing my hair out over this, so I wanted to make sure that I documented exactly what's happening here, in the hopes that someone else won't have to.

Although @pixelbender fixed the issue with the fact that net.Listen* wasn't being used, the net.PacketConn returned by Discover() isn't actually relinquished in a way that allows it to be repurposed! When the Conn is created, an Agent is set up to handle it. Upon start, the Agent calls this method, which calls ReadFrom on the net.PacketConn to loop over/handle received messages. Turns out, when the net.PacketConn is handed back to you from Discover(), that loop is never actually stopped.

I guess that's what @pixelbender meant by the TODO: hijack comment 😜 Anyway, long story short, it turns out that this issue hasn't really been addressed.

kenkeiter avatar Sep 25 '17 03:09 kenkeiter

@isaachess That PR (#8) should allow you to use this library for hole-punching. The net.PacketConn you get back is now usable, so if you know the public address (host/port) of your peer, you can get them to try to send packets to one another at the same time.

For what it's worth, you'll do something like this for both clients (although you still need an external service to help them exchange addresses):

conn, externalAddr, err := stun.Discover(STUNServer)
if err != nil {
	return nil, errors.Wrap(err, "failed to set up public UDP socket")
}
peerExternalAddr := &net.UDPAddr{
	IP: net.ParseIP("<peer addr>"),
	Port: 1234,
}
conn.WriteTo([]byte("hello"), peerExternalAddr)

kenkeiter avatar Sep 25 '17 05:09 kenkeiter

Could you please point me to the example on how to setup a TCP connection between 2 nodes both behind NAT? Something like node1_code.go, node2_code.go, external_server_code.go Thanks!

mennanov avatar Sep 28 '18 01:09 mennanov