Giter Site home page Giter Site logo

go-stun's People

Contributors

audriusbutkevicius avatar calmh avatar ccding avatar ckt avatar imsodin avatar kevinlemonra avatar muink avatar nagesh4193 avatar piasy avatar rynorris avatar xlch88 avatar ytghost avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-stun's Issues

Two more bugs

So first of all, I claim there is a bug here:
https://github.com/ccding/go-stun/blob/master/stun/discover.go#L142

I think this line should be removed, as if you look at this, it makes no sense:

[root@acro-syncer /home/jb]# ./foo
2016/08/18 22:05:33 Do Test1
2016/08/18 22:05:33 Send To: 217.10.68.152:3478
2016/08/18 22:05:33 Received: {packet nil: false, local: X.X.X.X:44444, remote: 217.10.68.152:3478, changed: 217.116.122.138:3479, identical: false}
2016/08/18 22:05:33 Do Test2
2016/08/18 22:05:33 Send To: 217.10.68.152:3478
2016/08/18 22:05:43 Received: Nil
2016/08/18 22:05:43 Do Test1
2016/08/18 22:05:43 Send To: 217.116.122.138:3479
2016/08/18 22:05:43 Received: {packet nil: false, local: X.X.X.X:44444, remote: 217.116.122.138:3479, changed: 217.10.68.152:3478, identical: false}
2016/08/18 22:05:43 Do Test3
2016/08/18 22:05:43 Send To: 217.116.122.138:3478
2016/08/18 22:05:43 Received: {packet nil: false, local: X.X.X.X:44444, remote: 217.116.122.138:3479, changed: 217.10.68.152:3478, identical: false}
Restricted NAT X.X.X.X:44444 <nil>

Ignore test 1 and test2, just focus on 2nd instance of Test 1 and Test 3.

We send to 217.116.122.138:3479, asking to bind.
Afterwards we set the port to the changed port (for no reason), and ask via 217.116.122.138:3478 to send us a packet on a changed port, which happens to be 217.116.122.138:3479... an address we already sent bind request to...

If you agree this is a bug let's continue.

I've removed the line at fault on two different configurations.

This one:

2016/08/18 22:11:49 Do Test1
2016/08/18 22:11:49 Send To: 217.10.68.152:3478
2016/08/18 22:11:49 Received: {packet nil: false, local: X.X.X.X:44444, remote: 217.10.68.152:3478, changed: 217.116.122.138:3479, identical: false}
2016/08/18 22:11:49 Do Test2
2016/08/18 22:11:49 Send To: 217.10.68.152:3478
2016/08/18 22:11:58 Received: Nil
2016/08/18 22:11:58 Do Test1
2016/08/18 22:11:58 Send To: 217.116.122.138:3479
2016/08/18 22:11:59 Received: {packet nil: false, local: X.X.X.X:44444, remote: 217.116.122.138:3479, changed: 217.10.68.152:3478, identical: false}
2016/08/18 22:11:59 Do Test3
2016/08/18 22:11:59 Send To: 217.116.122.138:3479
2016/08/18 22:12:08 Received: Nil
Port restricted NAT X.X.X.X:44444 <nil>

Looks ok, as it seems that it is port restricted and all local shows the same ip port pair across all tests, and Test3 which just ask to change the port fails.

Now this one, I think is NOT OK:

jb@syno:~/tmp $ go run foo.go 
2016/08/18 22:15:42 Do Test1
2016/08/18 22:15:42 Send To: 217.10.68.152:3478
2016/08/18 22:15:42 Received: {packet nil: false, local: Y.Y.Y.Y:9237, remote: 217.10.68.152:3478, changed: 217.116.122.136:3479, identical: false}
2016/08/18 22:15:42 Do Test2
2016/08/18 22:15:42 Send To: 217.10.68.152:3478
2016/08/18 22:15:52 Received: Nil
2016/08/18 22:15:52 Do Test1
2016/08/18 22:15:52 Send To: 217.116.122.136:3479
2016/08/18 22:15:52 Received: {packet nil: false, local: Y.Y.Y.Y:21548, remote: 217.116.122.136:3479, changed: 217.10.68.152:3478, identical: false}
2016/08/18 22:15:52 Do Test3
2016/08/18 22:15:52 Send To: 217.116.122.136:3479
2016/08/18 22:16:01 Received: Nil
Port restricted NAT Y.Y.Y.Y:9237 <nil>

local is actually different on both tests, which implies that it's a symetric nat.
The reason this returns Port Restricted NAT, I believe is because we do not check the Port() equality on this line:

https://github.com/ccding/go-stun/blob/master/stun/discover.go#L139

NATUnknown

Despite the comment in the code, I do end up getting NATUnknown, for example on an ec2 instance that doesn't have any incoming udp rules set.

2019/02/20 19:09:26 Do Test1
2019/02/20 19:09:26 Send To: 216.93.246.18:3478
2019/02/20 19:09:26 
00000000  00 01 00 18 21 12 a4 42  89 7c 41 a3 25 31 77 80  |....!..B.|A.%1w.|
00000010  d1 6d 38 a9 80 22 00 0c  53 74 75 6e 43 6c 69 65  |.m8.."..StunClie|
00000020  6e 74 00 00 80 28 00 04  8a 52 09 fd              |nt...(...R..|
2019/02/20 19:09:26 
00000000  01 01 00 48 21 12 a4 42  89 7c 41 a3 25 31 77 80  |...H!..B.|A.%1w.|
00000010  d1 6d 38 a9 00 01 00 08  00 01 38 e1 2d 9d 9b 2a  |.m8.......8.-..*|
00000020  00 04 00 08 00 01 93 f1  59 74 6a 2c 00 05 00 08  |........Ytj,....|
00000030  00 01 74 76 38 03 dc 5e  80 20 00 08 00 01 00 a3  |..tv8..^. ......|
00000040  7a d9 8e 0e 80 22 00 14  56 6f 76 69 64 61 2e 6f  |z...."..Vovida.o|
00000050  72 67 20 30 2e 39 38 2d  43 50 43 00              |rg 0.98-CPC.|
2019/02/20 19:09:26 Received: {packet nil: false, local: 91.203.42.76:8625, remote: 216.93.246.18:3478, changed: 56.3.220.94:29814, other: <nil>, identical: false}
2019/02/20 19:09:26 Do Test2
2019/02/20 19:09:26 Send To: 216.93.246.18:3478
2019/02/20 19:09:26 
00000000  00 01 00 20 21 12 a4 42  cd 28 92 d7 9a 77 a7 5d  |... !..B.(...w.]|
00000010  5c fe b0 ee 80 22 00 0c  53 74 75 6e 43 6c 69 65  |\...."..StunClie|
00000020  6e 74 00 00 00 03 00 04  00 00 00 06 80 28 00 04  |nt...........(..|
00000030  3c 75 37 77                                       |<u7w|
2019/02/20 19:09:36 Received: Nil
2019/02/20 19:09:36 Do Test1
2019/02/20 19:09:36 Send To: 56.3.220.94:29814
2019/02/20 19:09:36 
00000000  00 01 00 18 21 12 a4 42  73 01 e5 40 c9 cb cd 97  |....!..Bs..@....|
00000010  a6 15 79 01 80 22 00 0c  53 74 75 6e 43 6c 69 65  |..y.."..StunClie|
00000020  6e 74 00 00 80 28 00 04  9a 04 5d 35              |nt...(....]5|
2019/02/20 19:09:45 Received: Nil
NAT Type: Unexpected response from the STUN server
External IP Family: 1
External IP: 91.203.42.76
External Port: 8625

go-stun can't support coturn-4.5.0.6

go-stun send binding request to coturn-4.5.0.6 will fail.

The binding request packet will drop for fingerprint. I have debug it in coturn.
packet check will fail in stun_is_command_message_full_check_str.

stun_is_command_message_full_check_str in src/client/ns_turn_msg.c
int stun_is_command_message_full_check_str(const u08bits* buf, size_t blen, int must_check_fingerprint, int *fingerprint_present) {
    if(!stun_is_command_message_str(buf,blen))
        return 0;
    
    stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, blen, STUN_ATTRIBUTE_FINGERPRINT);
    if(!sar) {
        if(fingerprint_present)
            *fingerprint_present = 0; 
        if(stun_get_method_str(buf,blen) == STUN_METHOD_BINDING) {
            return 1;
        }    
        return !must_check_fingerprint;
    }    

    if(stun_attr_get_len(sar) != 4)
        return 0;

    const u32bits* fingerprint = (const u32bits*)stun_attr_get_value(sar);
    if(!fingerprint)
        return !must_check_fingerprint;
    
    u32bits crc32len = (u32bits)((((const u08bits*)fingerprint)-buf)-4);
    int ret = (*fingerprint == nswap32(ns_crc32(buf,crc32len) ^ ((u32bits)0x5354554e)));
    if(ret && fingerprint_present)
        *fingerprint_present = ret;
        
    return ret;
}   

I can use chrome send binding request to coturn-4.5.0.6 。So, this is bug in go-stun?
Thank you for reply.

Am I insane?

Hi,

I am testing this again, and I am hitting a strange issue, where my NAT is reported correctly as a full cone nat, but I believe it hasn't done proper testing.

I've made a small diff just for debugging:

@@ -125,6 +126,7 @@ func (v *packet) xorMappedAddr() *Host {
 // Retransmissions continue with intervals of 1.6s until a response is
 // received, or a total of 9 requests have been sent.
 func (v *packet) send(conn net.PacketConn, addr net.Addr) (*packet, error) {
+       fmt.Println("send to", addr)
        timeout := 100
        for i := 0; i < 9; i++ {
                length, err := conn.WriteTo(v.bytes(), addr)
@@ -142,8 +144,9 @@ func (v *packet) send(conn net.PacketConn, addr net.Addr) (*packet, error) {
                        timeout *= 2
                }
                packetBytes := make([]byte, 1024)
-               length, _, err = conn.ReadFrom(packetBytes)
+               length, raddr, err := conn.ReadFrom(packetBytes)
                if err == nil {
+                       fmt.Println("recv", raddr)
                        return newPacketFromBytes(packetBytes[0:length])
                }
                if !err.(net.Error).Timeout() {

And the verbose output is as follows:

2016/08/05 22:46:58 Do Test1
2016/08/05 22:46:58 Send To: 64.233.165.127:19302
send to 64.233.165.127:19302
recv 64.233.165.127:19302
2016/08/05 22:46:58 Received: {isNil:false}
2016/08/05 22:46:58 Received: {changedAddr:'<nil>', identical:'false', host:'111.189.74.19:55777'}
2016/08/05 22:46:58 Do Test2
2016/08/05 22:46:58 Send To: 64.233.165.127:19302
send to 64.233.165.127:19302
recv 64.233.165.127:19302
2016/08/05 22:46:58 Received: {isNil:false}
Full cone NAT &{1 111.189.74.19 55777} <nil>

Now correct me if I am wrong, but the response in Test2 came from the same address as Test1, hence there is no evidence that it is actually a full cone nat?

I feel that it's the stun server misbehaving, yet perhaps sanity checks should be performed client side too?

Also, I changed my router since I ran the last tests when it actually worked, so perhaps it's my router re-writing the addresses and causing this impression?

As I seem to get the same result with multiple stun servers...

Does it support ipv6?

Does it support ipv6? Although our ipv6 does not have a nat, the superior route has a firewall, and the inbound is completely blocked, and because it is a 4G network, the firewall settings cannot be changed. I am wondering whether stun can be used in ipv6.

Inconsistent results with pystun

package main

import(
    "fmt"

    "github.com/ccding/go-stun/stun"
)

func main(){
    client := stun.NewClient()
    client.SetServerAddr("stun.ekiga.net:3478")
    fmt.Println(client.Discover())
}

returns:

5 &{1 46.XXX.151.XXX 56986} <nil>

5 being symetric

Where as pystun returns:

Audrius@Audrius ~ $ pystun --debug
DEBUG:pystun:Do Test1
DEBUG:pystun:Trying STUN host: stun.ekiga.net
DEBUG:pystun:sendto: ('stun.ekiga.net', 3478)
DEBUG:pystun:recvfrom: ('217.10.68.152', 3478)
DEBUG:pystun:Result: {'ExternalIP': '46.XXX.151.XXX', 'Resp': True, 'ExternalPort': 65465, 'ChangedPort': 3479, 'SourcePort': 3478, 'SourceIP': '217.10.68.152', 'ChangedIP': '217.116.122.138'}
DEBUG:pystun:Do Test2
DEBUG:pystun:sendto: ('stun.ekiga.net', 3478)
DEBUG:pystun:recvfrom: ('217.116.122.138', 3479)
DEBUG:pystun:Result: {'ExternalIP': '46.XXX.151.XXX', 'Resp': True, 'ExternalPort': 65465, 'ChangedPort': 3479, 'SourcePort': 3479, 'SourceIP': '217.116.122.138', 'ChangedIP': '217.116.122.138'}
NAT Type: Full Cone
External IP: 46.XXX.151.XXX
External Port: 65465

Any ideas where to start debugging?

Furthermore, a bit of a noob question.
This seems to only perform NAT type discovery, but does not give you any way to actually perform the punch through, because it does not return the local port used (so that I could reuse that port and advertise the external port returned by the discovery), nor does it allow requesting a specific port.

How do I actually use this to perform the punchthrough with this?

how use passwd and username?

how use passwd and username?
Usage of ./go-stun

{'urls':'turn:turn.bistri.com:80?transport=udp','credential':'homeo','username':'homeo'},
{'urls':'stun:webrtcweb.com:4455?transport=udp','credential':'muazkh','username':'muazkh'},
{'urls':'stun:webrtcweb.com:8877?transport=udp','credential':'muazkh','username':'muazkh'},

Doesn't work with some servers

For example google ones:

stun.l.google.com:19302
stun1.l.google.com:19302
stun2.l.google.com:19302
stun3.l.google.com:19302
stun4.l.google.com:19302

Test1 fails with "No changed address." error. Any idea what could be wrong?

UDP hole punching question

thanks for this repo, just what I was looking for.

Question on UDP hole punching: is this something the big peer networks do reliable to the point they don't have to send people to https://portforward.com or do the majority of peer to peer networks not use UDP hole punching because it isn't 100% reliable and having the user go into their router and make a real open port is always a more reliable solution?

stun punching invalid a few minutes later

if I use the punchd port as a udp server ,a few minutes later, it will fail.
it needs a keep alive method.
the keepalive method can not cooperate with a server connection, because when keep alive called, this method will send and receive packet.
generally , there only one postion for receiving packet!

stun and turn - question

I need a stun & turn server for webrtc system.
This repo is all about stun. Is turn also supported ?

server implementation

Currently this package only contains the Client implementation, would a Server implementation be within the Scope of this package, I certainly would hope it does?

I'm asking as I might be interested to have this working in a P2P network, where a peer would be both a client and server, so having a server implementation ready in Golang, would help a lot with that?

I'm prepared to do the work for this, would just need to know if:

  • this is within the scope of this package;
  • this is actually something feasible;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.