Fast RFC 5389 STUN implementation in go
Go to file
Aleksandr Razumov 5958aeb5e3
Merge pull request #70 from gortc/dependabot/github_actions/jandelgado/gcov2lcov-action-v1.0.8
build(deps): bump jandelgado/gcov2lcov-action from v1.0.7 to v1.0.8
2020-11-23 19:45:36 +03:00
.github build(deps): bump jandelgado/gcov2lcov-action from v1.0.7 to v1.0.8 2020-11-23 06:57:44 +00:00
api all: use gortc.io import 2019-07-22 14:22:38 +03:00
cmd all: fix golangci-lint warnings 2020-11-01 18:48:51 +03:00
e2e all: use gortc.io import 2019-07-22 14:22:38 +03:00
fuzz fuzz: use "fuzz" directory instead of "examples" 2018-08-01 19:32:17 +03:00
internal hmac: update vendored version to go1.15 2020-11-01 20:17:55 +03:00
testdata attributes: add RFC 8489 constants 2020-11-01 19:45:39 +03:00
.codecov.yml codecov: increase coverage target to 98% 2018-08-17 11:27:12 +03:00
.editorconfig add .editorconfig 2019-08-08 23:19:25 +03:00
.gitignore ci: try coveralls github action 2020-11-01 19:01:01 +03:00
.golangci.yml hmac: update vendored version to go1.15 2020-11-01 20:17:55 +03:00
addr_test.go a:addr: add UnexpectedEOF test 2017-06-25 15:26:38 +02:00
addr.go all: update godoc references to RFC 2018-06-29 12:03:22 +03:00
agent_test.go {agent,client: add NoopHandler 2018-08-11 20:22:21 +03:00
agent.go {agent,client: add NoopHandler 2018-08-11 20:22:21 +03:00
attributes_debug_test.go attrs: add CheckOverflow and IsAttrSizeOverflow 2018-08-02 18:06:32 +03:00
attributes_debug.go attrs: add CheckOverflow and IsAttrSizeOverflow 2018-08-02 18:06:32 +03:00
attributes_test.go attributes: implement Setter for RawAttribute 2018-11-16 04:46:28 +03:00
attributes.go attributes: add RFC 8489 constants 2020-11-01 19:45:39 +03:00
AUTHORS all: add backkem to AUTHORS 2018-06-22 17:51:23 +03:00
checks_debug.go all: use gortc.io import 2019-07-22 14:22:38 +03:00
checks.go all: use gortc.io import 2019-07-22 14:22:38 +03:00
client_test.go all: fix golangci-lint warnings 2020-11-01 18:48:51 +03:00
client.go Fix Client crash on ARM 2019-07-16 20:14:45 +03:00
CONTRIBUTORS A+C: add CONTRIBUTORS 2019-07-18 19:38:57 +03:00
Dockerfile all: use gortc.io import 2019-07-22 14:22:38 +03:00
errorcode_test.go a:errorcode: fix code of StaleNonce 2018-08-15 00:52:44 +03:00
errorcode.go iana: add test for error codes and fix Code{RoleConflict,Unauthorized} 2018-11-16 21:53:47 +03:00
errors_test.go errors: improve coverage 2017-02-26 13:11:44 +03:00
errors.go errors: remove ErrAttributeSizeInvalid 2018-08-09 02:56:56 +03:00
fingerprint_debug.go all: report detailed fingerprint mismatch only in debug mode 2018-08-01 23:25:52 +03:00
fingerprint_test.go all: improve linters config and fix some warnings 2019-02-18 23:49:56 +03:00
fingerprint.go all: fix lint issues 2020-01-01 21:22:13 +03:00
fuzz_test.go fuzz: use "fuzz" directory instead of "examples" 2018-08-01 19:32:17 +03:00
fuzz.go all: fix golangci-lint warnings 2020-11-01 18:48:51 +03:00
go.coverage.sh ci: move coverage to separate pipeline 2020-11-01 19:06:41 +03:00
go.mod all: use gortc.io import 2019-07-22 14:22:38 +03:00
go.test.sh ci: move coverage to separate pipeline 2020-11-01 19:06:41 +03:00
helpers_test.go all: use gortc.io import 2019-07-22 14:22:38 +03:00
helpers.go message: add ForEach helper 2018-08-02 10:51:10 +03:00
iana_test.go iana: add test for error codes and fix Code{RoleConflict,Unauthorized} 2018-11-16 21:53:47 +03:00
integrity_debug.go all: report detailed integrity mismatch only in debug mode 2018-08-01 23:19:00 +03:00
integrity_test.go all: fix golangci-lint warnings 2020-11-01 18:48:51 +03:00
integrity.go all: use gortc.io import 2019-07-22 14:22:38 +03:00
LICENSE license: use more uniformal BSD-3-Clause 2018-07-19 08:01:57 +03:00
Makefile ci: move coverage to separate pipeline 2020-11-01 19:06:41 +03:00
message_test.go message: add GobDecode test 2020-11-01 20:44:28 +03:00
message.go message: implement binary and gob encoding 2020-11-01 20:36:59 +03:00
README.md readme: fix coverage badge 2020-11-01 19:27:58 +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 message: improve docs 2020-01-02 16:36:56 +03:00
textattrs_test.go attrs: add CheckOverflow and IsAttrSizeOverflow 2018-08-02 18:06:32 +03:00
textattrs.go Optimize text attributes 2019-07-16 20:15:13 +03:00
uattrs_test.go all: improve coverage (fix #26) 2017-02-26 13:03:30 +03:00
uattrs.go all: reduce newline overuse 2019-03-08 22:12:06 +03:00
uri_test.go uri: mitigate breaking change 2019-08-14 14:01:21 +03:00
uri.go uri: fix port set 2020-01-03 03:28:12 +03:00
xor_test.go all: fix linters warnings; update makefile 2016-04-29 21:37:10 +03:00
xor.go all: fix lint issues 2020-01-01 21:22:13 +03:00
xoraddr_test.go attrs: add CheckOverflow and IsAttrSizeOverflow 2018-08-02 18:06:32 +03:00
xoraddr.go attrs: add CheckOverflow and IsAttrSizeOverflow 2018-08-02 18:06:32 +03:00

CI GoDev Coverage Status

STUN

Package stun implements Session Traversal Utilities for NAT (STUN) [RFC5389] protocol and client with no external dependencies and zero allocations in hot paths. Client supports automatic request retransmissions. Complies to gortc principles as core package.

See example and stun server for simple usage. Also see gortc/turn for TURN [RFC5766] implementation and gortcd for TURN and STUN server. This repo was merged to pion/stun at version v1.19.0.

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"

	"gortc.io/stun"
)

func main() {
	// Creating a "connection" to STUN server.
	c, err := stun.Dial("udp", "stun.l.google.com:19302")
	if err != nil {
		panic(err)
	}
	// Building 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, 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)
	}
}

Supported RFCs

Stability stability-mature GitHub tag

Package is currently stable, no backward incompatible changes are expected with exception of critical bugs or security fixes.

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.14 is currently supported and tested in CI. Should work on 1.13.

Testing

Client behavior is tested and verified in many ways:

  • End-To-End with long-term credentials
    • coturn: The coturn server (linux)
  • Bunch of code static checkers (linters)
  • Standard unit-tests with coverage reporting (linux {amd64, arm64}, windows and darwin)
  • Explicit API backward compatibility check, see api directory

See TeamCity project and e2e directory for more information. Also the Wireshark .pcap files are available for e2e test in artifacts for build.

Benchmarks

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

version: 1.22.2
goos: linux
goarch: amd64
pkg: github.com/gortc/stun
PASS
benchmark                                         iter       time/iter      throughput   bytes alloc        allocs
---------                                         ----       ---------      ----------   -----------        ------
BenchmarkMappedAddress_AddTo-12               32489450     38.30 ns/op                        0 B/op   0 allocs/op
BenchmarkAlternateServer_AddTo-12             31230991     39.00 ns/op                        0 B/op   0 allocs/op
BenchmarkAgent_GC-12                            431390   2918.00 ns/op                        0 B/op   0 allocs/op
BenchmarkAgent_Process-12                     35901940     36.20 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_GetNotFound-12              242004358      5.19 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_Get-12                      230520343      5.21 ns/op                        0 B/op   0 allocs/op
BenchmarkClient_Do-12                          1282231    943.00 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCode_AddTo-12                   16318916     75.50 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCodeAttribute_AddTo-12          21584140     54.80 ns/op                        0 B/op   0 allocs/op
BenchmarkErrorCodeAttribute_GetFrom-12       100000000     11.10 ns/op                        0 B/op   0 allocs/op
BenchmarkFingerprint_AddTo-12                 19368768     64.00 ns/op     687.81 MB/s        0 B/op   0 allocs/op
BenchmarkFingerprint_Check-12                 24167007     49.10 ns/op    1057.99 MB/s        0 B/op   0 allocs/op
BenchmarkBuildOverhead/Build-12                5486252    224.00 ns/op                        0 B/op   0 allocs/op
BenchmarkBuildOverhead/BuildNonPointer-12      2496544    517.00 ns/op                      100 B/op   4 allocs/op
BenchmarkBuildOverhead/Raw-12                  6652118    181.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_ForEach-12                   28254212     35.90 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageIntegrity_AddTo-12             1000000   1179.00 ns/op      16.96 MB/s        0 B/op   0 allocs/op
BenchmarkMessageIntegrity_Check-12              975954   1219.00 ns/op      26.24 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_Write-12                     41040598     30.40 ns/op     922.13 MB/s        0 B/op   0 allocs/op
BenchmarkMessageType_Value-12               1000000000      0.53 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_WriteTo-12                   94942935     11.30 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_ReadFrom-12                  43437718     29.30 ns/op     682.87 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_ReadBytes-12                 74693397     15.90 ns/op    1257.42 MB/s        0 B/op   0 allocs/op
BenchmarkIsMessage-12                       1000000000      1.20 ns/op   16653.64 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_NewTransactionID-12            521121   2450.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageFull-12                        5389495    221.00 ns/op                        0 B/op   0 allocs/op
BenchmarkMessageFullHardcore-12               12715876     94.40 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_WriteHeader-12              100000000     11.60 ns/op                        0 B/op   0 allocs/op
BenchmarkMessage_CloneTo-12                   30199020     41.80 ns/op    1626.66 MB/s        0 B/op   0 allocs/op
BenchmarkMessage_AddTo-12                    415257625      2.97 ns/op                        0 B/op   0 allocs/op
BenchmarkDecode-12                            49573747     23.60 ns/op                        0 B/op   0 allocs/op
BenchmarkUsername_AddTo-12                    56282674     22.50 ns/op                        0 B/op   0 allocs/op
BenchmarkUsername_GetFrom-12                 100000000     10.10 ns/op                        0 B/op   0 allocs/op
BenchmarkNonce_AddTo-12                       39419097     35.80 ns/op                        0 B/op   0 allocs/op
BenchmarkNonce_AddTo_BadLength-12            196291666      6.04 ns/op                        0 B/op   0 allocs/op
BenchmarkNonce_GetFrom-12                    120857732      9.93 ns/op                        0 B/op   0 allocs/op
BenchmarkUnknownAttributes/AddTo-12           28881430     37.20 ns/op                        0 B/op   0 allocs/op
BenchmarkUnknownAttributes/GetFrom-12         64907534     19.80 ns/op                        0 B/op   0 allocs/op
BenchmarkXOR-12                               32868506     32.20 ns/op   31836.66 MB/s
BenchmarkXORSafe-12                            5185776    234.00 ns/op    4378.74 MB/s
BenchmarkXORFast-12                           30975679     32.50 ns/op   31525.28 MB/s
BenchmarkXORMappedAddress_AddTo-12            21518028     54.50 ns/op                        0 B/op   0 allocs/op
BenchmarkXORMappedAddress_GetFrom-12          35597667     34.40 ns/op                        0 B/op   0 allocs/op
ok      gortc.io/stun   60.973s

License

BSD 3-Clause License