Fast RFC 5389 STUN implementation in go
Go to file
2018-06-25 12:07:16 +03:00
cmd cmd: added NAT traversal POC. 2018-06-10 15:41:25 +02:00
examples fuzz: fix tests 2018-04-29 17:55:02 +03:00
integration-test ci: run integration tests 2018-06-25 00:46:22 +03:00
testdata all: clear docs, testa and Makefile (fixes #19) 2017-02-18 14:20:21 +03:00
.gitignore stun-bench: add binary to gitignore 2017-02-11 06:04:30 +03:00
.travis.yml ci: add docker 2018-06-25 00:47:58 +03:00
addr_test.go a:addr: add UnexpectedEOF test 2017-06-25 15:26:38 +02:00
addr.go all: fix lint warnings 2017-02-28 00:01:20 +03:00
agent_test.go agent: test double-close error 2017-12-15 20:07:03 +03:00
agent.go {client,agent}: don't alloc on client.Do 2017-12-15 15:07:25 +03:00
appveyor.yml ci: update go to 1.10 2018-02-22 11:30:34 +03:00
attributes_test.go attributes: adjust AttrOverflowErr, AttrLengthErr text 2017-06-25 17:53:12 +02:00
attributes.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
AUTHORS all: add backkem to AUTHORS 2018-06-22 17:51:23 +03:00
client_test.go client: fix linters 2018-04-29 14:36:13 +03:00
client.go client: fix aligncheck 2018-04-29 14:33:19 +03:00
Dockerfile *: rename go-rtc to gortc 2017-10-27 03:23:59 +03:00
errorcode_test.go a:errorcode: add test for ErrUnexpectedEOF 2017-07-01 22:31:25 +02:00
errorcode.go a:errorcode: gofmt 2017-07-01 22:54:59 +02:00
errors_test.go errors: improve coverage 2017-02-26 13:11:44 +03:00
errors.go all: remove usage of constant errors 2017-02-11 06:54:37 +03:00
fingerprint_test.go all: improve coverage (fix #26) 2017-02-26 13:03:30 +03:00
fingerprint.go a:fingerprint: fix Check comment 2017-07-20 02:34:25 +02:00
fuzz_test.go fuzz: fix tests 2018-04-29 17:55:02 +03:00
fuzz.go fuzz: update 2018-04-29 17:47:54 +03:00
helpers_test.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
helpers.go helpers: add missed dot in comment 2017-07-01 08:13:33 +02:00
integrity_test.go all: make TransactionIDSize public 2017-06-26 03:58:21 +02:00
integrity.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
LICENSE all: add The Go Authors to LICENSE 2018-06-22 17:48:33 +03:00
Makefile fuzz: update 2018-04-29 17:47:54 +03:00
message_test.go message: add TestDecode/ZeroAlloc 2018-06-23 21:17:53 +03:00
message.go message: copy on Decode 2018-06-23 12:07:33 +03:00
README.md readme: fix titles, add RFC-style link 2018-06-25 12:07:16 +03:00
rfc5769_test.go a:integrity: rename NewLongtermIntegrity to NewLongTermIntegrity 2017-02-18 20:40:05 +03:00
stun_test.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
stun.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
textattrs_test.go all: fix BenchmarkUsername_GetFrom allocations 2017-12-15 00:46:55 +03:00
textattrs.go all: sasl-prep implementation is out of scope (fix #20) 2017-02-28 00:07:12 +03:00
uattrs_test.go all: improve coverage (fix #26) 2017-02-26 13:03:30 +03:00
uattrs.go a:uattrs: simplify String() 2017-06-26 05:06:15 +02:00
xor_test.go all: fix linters warnings; update makefile 2016-04-29 21:37:10 +03:00
xor.go all: refactor attributes 2017-02-11 05:23:49 +03:00
xoraddr_test.go all: refactor errors, improve coverage, refactor 2017-06-26 03:18:07 +02:00
xoraddr.go all: make TransactionIDSize public 2017-06-26 03:58:21 +02:00

Build Status Build status GoDoc Coverage Status Go Report

STUN

Package stun implements Session Traversal Utilities for NAT (STUN) [RFC 5389] with no external dependencies and focuses on speed. See example or stun server for usage.

RFCs

The package aims to implement the follwing RFCs. Note that the requirement status is based on the WebRTC spec, focusing on data channels for now.

rfc status requirement description
RFC5389 status status Session Traversal Utilities for NAT
IPv6 status status IPv6 support
(TLS-over-)TCP status status Sending over TCP or TLS-over-TCP
ALTERNATE-SERVER status status ALTERNATE-SERVER Mechanism

Example

You can get your current IP address from any STUN server by sending binding request. See more idiomatic example at cmd/stun-client.

package main

import (
	"fmt"
	"time"

	"github.com/gortc/stun"
)

func main() {
	// Creating a "connection" to STUN server.
	c, err := stun.Dial("udp", "stun.l.google.com:19302")
	if err != nil {
		panic(err)
	}
	deadline := time.Now().Add(time.Second * 5)
	// Bulding binding request with random transaction id.
	message := stun.MustBuild(stun.TransactionID, stun.BindingRequest)
	// Sending request to STUN server, waiting for response message.
	if err := c.Do(message, deadline, func(res stun.Event) {
		if res.Error != nil {
			panic(res.Error)
		}
		// Decoding XOR-MAPPED-ADDRESS attribute from message.
		var xorAddr stun.XORMappedAddress
		if err := xorAddr.GetFrom(res.Message); err != nil {
			panic(err)
		}
		fmt.Println("your IP is", xorAddr.IP)
	}); err != nil {
		panic(err)
	}
}

Stability

Package is currently approaching beta stage, API should be fairly stable and implementation is almost complete. Bug reports are welcome.

Additional attributes are unlikely to be implemented in scope of stun package, the only exception is constants for attribute or message types.

RFC 3489 notes

RFC 5389 obsoletes RFC 3489, so implementation was ignored by purpose, however, RFC 3489 can be easily implemented as separate package.

Requirements

Go 1.9.2 is currently supported and tested in CI. Should work on 1.8, 1.7, and tip.

Benchmarks

Intel(R) Core(TM) i7-8700K:

goos: linux
goarch: amd64
pkg: github.com/gortc/stun
PASS
benchmark                                          iter       time/iter      throughput   bytes alloc        allocs
---------                                          ----       ---------      ----------   -----------        ------
BenchmarkMappedAddress_AddTo-12              1000000000     22.90 ns/op                        0 B/op   0 allocs/op
BenchmarkAlternateServer_AddTo-12            1000000000     23.00 ns/op                        0 B/op   0 allocs/op
BenchmarkAgent_GC-12                           10000000   2217.00 ns/op                        0 B/op   0 allocs/op
BenchmarkAgent_Process-12                     300000000     52.80 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_GetNotFound-12              3000000000      4.13 ns/op                        0 B/op   0 allocs/op
BenchmarkClient_Do-12                          30000000    495.00 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCode_AddTo-12                   300000000     41.10 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCodeAttribute_AddTo-12          500000000     30.90 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCodeAttribute_GetFrom-12       2000000000      7.84 ns/op                        0 B/op   0 allocs/op
BenchmarkFingerprint_AddTo-12                 300000000     46.60 ns/op     944.52 MB/s        0 B/op   0 allocs/op
BenchmarkFingerprint_Check-12                 500000000     37.20 ns/op    1397.50 MB/s        0 B/op   0 allocs/op
BenchmarkBuildOverhead/Build-12               100000000    133.00 ns/op                        0 B/op   0 allocs/op
BenchmarkBuildOverhead/BuildNonPointer-12     100000000    262.00 ns/op                      100 B/op   4 allocs/op
BenchmarkBuildOverhead/Raw-12                 100000000    119.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageIntegrity_AddTo-12             20000000   1058.00 ns/op      18.89 MB/s      480 B/op   6 allocs/op
BenchmarkMessageIntegrity_Check-12             20000000   1023.00 ns/op      31.27 MB/s      480 B/op   6 allocs/op
BenchmarkMessage_Write-12                    1000000000     16.10 ns/op    1734.19 MB/s        0 B/op   0 allocs/op
BenchmarkMessageType_Value-12               10000000000      0.23 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_WriteTo-12                  2000000000      8.19 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_ReadFrom-12                 1000000000     18.00 ns/op    1108.32 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_ReadBytes-12                2000000000     10.50 ns/op    1896.39 MB/s        0 B/op   0 allocs/op
BenchmarkIsMessage-12                       10000000000      0.64 ns/op   31241.13 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_NewTransactionID-12           50000000    385.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageFull-12                       100000000    134.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageFullHardcore-12               300000000     52.70 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_WriteHeader-12              3000000000      5.21 ns/op                        0 B/op   0 allocs/op
BenchmarkUsername_AddTo-12                   1000000000     14.60 ns/op                        0 B/op   0 allocs/op
BenchmarkUsername_GetFrom-12                 2000000000     11.70 ns/op                        0 B/op   0 allocs/op
BenchmarkNonce_AddTo-12                      1000000000     20.00 ns/op                        0 B/op   0 allocs/op
BenchmarkNonce_AddTo_BadLength-12             300000000     49.40 ns/op                       32 B/op   1 allocs/op
BenchmarkNonce_GetFrom-12                    2000000000     11.80 ns/op                        0 B/op   0 allocs/op
BenchmarkUnknownAttributes/AddTo-12          1000000000     18.50 ns/op                        0 B/op   0 allocs/op
BenchmarkUnknownAttributes/GetFrom-12        1000000000     13.40 ns/op                        0 B/op   0 allocs/op
BenchmarkXOR-12                              1000000000     14.00 ns/op   73071.52 MB/s        0 B/op   0 allocs/op
BenchmarkXORSafe-12                           100000000    102.00 ns/op    9945.44 MB/s        0 B/op   0 allocs/op
BenchmarkXORFast-12                          1000000000     13.60 ns/op   75332.68 MB/s        0 B/op   0 allocs/op
BenchmarkXORMappedAddress_AddTo-12            500000000     35.20 ns/op                        0 B/op   0 allocs/op
BenchmarkXORMappedAddress_GetFrom-12         1000000000     22.30 ns/op                        0 B/op   0 allocs/op
ok  	github.com/gortc/stun	698.712s

Development goals

stun package is low-level core gortc module, so security, efficiency (both memory and cpu), simplicity, code quality, and low dependencies are paramount goals.