Repository: pion/turn
Pull request #255 (2022-04-27 03:28:40)

Update CI configs to v0.7.2
Update lint scripts and CI configs.

codecov[bot]: # [Codecov](https://codecov.io/gh/pion/turn/pull/255?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) Report
> Merging [#255](https://codecov.io/gh/pion/turn/pull/255?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) (adaa2d7) into [master](https://codecov.io/gh/pion/turn/commit/a456c99743c3e1d306d882bbc5c4ede7c4b0d6d2?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion) (a456c99) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##           master     #255   +/-   ##
=======================================
  Coverage   67.79%   67.79%           
=======================================
  Files          38       38           
  Lines        2400     2400           
=======================================
  Hits         1627     1627           
  Misses        641      641           
  Partials      132      132           
```

| Flag | Coverage Δ | |
|---|---|---|
| go | `67.79% <ø> (ø)` | |
| wasm | `?` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion#carryforward-flags-in-the-pull-request-comment) to find out more.


------

[Continue to review full report at Codecov](https://codecov.io/gh/pion/turn/pull/255?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pion/turn/pull/255?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion). Last update [a456c99...adaa2d7](https://codecov.io/gh/pion/turn/pull/255?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pion).


Patch:
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
index 438443f..d284b19 100644
--- a/.github/workflows/lint.yaml
+++ b/.github/workflows/lint.yaml
@@ -47,5 +47,5 @@ jobs:
       - name: golangci-lint
         uses: golangci/golangci-lint-action@v3
         with:
-          version: v1.31
+          version: v1.45.2
           args: $GOLANGCI_LINT_EXRA_ARGS
diff --git a/.golangci.yml b/.golangci.yml
index d6162c9..d7a88ec 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -15,14 +15,22 @@ linters-settings:
 linters:
   enable:
     - asciicheck       # Simple linter to check that your code does not contain non-ASCII identifiers
+    - bidichk          # Checks for dangerous unicode character sequences
     - bodyclose        # checks whether HTTP response body is closed successfully
+    - contextcheck     # check the function whether use a non-inherited context
     - deadcode         # Finds unused code
+    - decorder         # check declaration order and count of types, constants, variables and functions
     - depguard         # Go linter that checks if package imports are in a list of acceptable packages
     - dogsled          # Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())
     - dupl             # Tool for code clone detection
+    - durationcheck    # check for two durations multiplied together
     - errcheck         # Errcheck is a program for checking for unchecked errors in go programs. These unchecked errors can be critical bugs in some cases
+    - errchkjson       # Checks types passed to the json encoding functions. Reports unsupported types and optionally reports occations, where the check for the returned error can be omitted.
+    - errname          # Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`.
+    - errorlint        # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
     - exhaustive       # check exhaustiveness of enum switch statements
     - exportloopref    # checks for pointers to enclosing loop variables
+    - forcetypeassert  # finds forced type assertions
     - gci              # Gci control golang package import order and make it always deterministic.
     - gochecknoglobals # Checks that no globals are present in Go code
     - gochecknoinits   # Checks that no init functions are present in Go code
@@ -35,40 +43,62 @@ linters:
     - gofumpt          # Gofumpt checks whether code was gofumpt-ed.
     - goheader         # Checks is file header matches to pattern
     - goimports        # Goimports does everything that gofmt does. Additionally it checks unused imports
-    - golint           # Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes
+    - gomoddirectives  # Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod.
     - gomodguard       # Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations.
     - goprintffuncname # Checks that printf-like functions are named with `f` at the end
     - gosec            # Inspects source code for security problems
     - gosimple         # Linter for Go source code that specializes in simplifying a code
     - govet            # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string
+    - grouper          # An analyzer to analyze expression groups.
+    - importas         # Enforces consistent import aliases
     - ineffassign      # Detects when assignments to existing variables are not used
     - misspell         # Finds commonly misspelled English words in comments
     - nakedret         # Finds naked returns in functions greater than a specified function length
+    - nilerr           # Finds the code that returns nil even if it checks that the error is not nil.
+    - nilnil           # Checks that there is no simultaneous return of `nil` error and an invalid value.
     - noctx            # noctx finds sending http request without context.Context
-    - scopelint        # Scopelint checks for unpinned variables in go programs
+    - predeclared      # find code that shadows one of Go's predeclared identifiers
+    - revive           # golint replacement, finds style mistakes
     - staticcheck      # Staticcheck is a go vet on steroids, applying a ton of static analysis checks
     - structcheck      # Finds unused struct fields
     - stylecheck       # Stylecheck is a replacement for golint
+    - tagliatelle      # Checks the struct tags.
+    - tenv             # tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17
+    - tparallel        # tparallel detects inappropriate usage of t.Parallel() method in your Go test codes
     - typecheck        # Like the front-end of a Go compiler, parses and type-checks Go code
     - unconvert        # Remove unnecessary type conversions
     - unparam          # Reports unused function parameters
     - unused           # Checks Go code for unused constants, variables, functions and types
     - varcheck         # Finds unused global variables and constants
+    - wastedassign     # wastedassign finds wasted assignment statements
     - whitespace       # Tool for detection of leading and trailing whitespace
   disable:
+    - containedctx     # containedctx is a linter that detects struct contained context.Context field
+    - cyclop           # checks function and package cyclomatic complexity
+    - exhaustivestruct # Checks if all struct's fields are initialized
+    - forbidigo        # Forbids identifiers
     - funlen           # Tool for detection of long functions
     - gocyclo          # Computes and checks the cyclomatic complexity of functions
     - godot            # Check if comments end in a period
     - gomnd            # An analyzer to detect magic numbers.
+    - ifshort          # Checks that your code uses short syntax for if-statements whenever possible
+    - ireturn          # Accept Interfaces, Return Concrete Types
     - lll              # Reports long lines
+    - maintidx         # maintidx measures the maintainability index of each function.
+    - makezero         # Finds slice declarations with non-zero initial length
     - maligned         # Tool to detect Go structs that would take less memory if their fields were sorted
     - nestif           # Reports deeply nested if statements
     - nlreturn         # nlreturn checks for a new line before return and branch statements to increase code clarity
     - nolintlint       # Reports ill-formed or insufficient nolint directives
+    - paralleltest     # paralleltest detects missing usage of t.Parallel() method in your Go test
     - prealloc         # Finds slice declarations that could potentially be preallocated
+    - promlinter       # Check Prometheus metrics naming via promlint
     - rowserrcheck     # checks whether Err of rows is checked successfully
     - sqlclosecheck    # Checks that sql.Rows and sql.Stmt are closed.
     - testpackage      # linter that makes you use a separate _test package
+    - thelper          # thelper detects golang test helpers without t.Helper() call and checks the consistency of test helpers
+    - varnamelen       # checks that the length of a variable's name matches its scope
+    - wrapcheck        # Checks that errors returned from external packages are wrapped
     - wsl              # Whitespace Linter - Forces you to use empty lines!
 
 issues:
diff --git a/client.go b/client.go
index 2f2823e..6fba46b 100644
--- a/client.go
+++ b/client.go
@@ -341,7 +341,8 @@ func (c *Client) CreatePermission(addrs ...net.Addr) error {
 
 // PerformTransaction performs STUN transaction
 func (c *Client) PerformTransaction(msg *stun.Message, to net.Addr, ignoreResult bool) (client.TransactionResult,
-	error) {
+	error,
+) {
 	trKey := b64.StdEncoding.EncodeToString(msg.TransactionID[:])
 
 	raw := make([]byte, len(msg.Raw))
diff --git a/internal/allocation/allocation.go b/internal/allocation/allocation.go
index ac696ec..0ba3661 100644
--- a/internal/allocation/allocation.go
+++ b/internal/allocation/allocation.go
@@ -186,8 +186,7 @@ func (a *Allocation) SetResponseCache(transactionID [stun.TransactionIDSize]byte
 
 // GetResponseCache return response cache for retransmit allocation request
 func (a *Allocation) GetResponseCache() (id [stun.TransactionIDSize]byte, attrs []stun.Setter) {
-	if r := a.responseCache.Load(); r != nil {
-		res := r.(*allocationResponse)
+	if res, ok := a.responseCache.Load().(*allocationResponse); ok && res != nil {
 		id, attrs = res.transactionID, res.responseAttrs
 	}
 	return
@@ -267,13 +266,19 @@ func (a *Allocation) packetHandler(m *Manager) {
 				a.log.Errorf("Failed to send ChannelData from allocation %v %v", srcAddr, err)
 			}
 		} else if p := a.GetPermission(srcAddr); p != nil {
-			udpAddr := srcAddr.(*net.UDPAddr)
+			udpAddr, ok := srcAddr.(*net.UDPAddr)
+			if !ok {
+				a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err)
+				return
+			}
+
 			peerAddressAttr := proto.PeerAddress{IP: udpAddr.IP, Port: udpAddr.Port}
 			dataAttr := proto.Data(buffer[:n])
 
 			msg, err := stun.Build(stun.TransactionID, stun.NewType(stun.MethodData, stun.ClassIndication), peerAddressAttr, dataAttr)
 			if err != nil {
 				a.log.Errorf("Failed to send DataIndication from allocation %v %v", srcAddr, err)
+				return
 			}
 			a.log.Debugf("relaying message from %s to client at %s",
 				srcAddr.String(),
diff --git a/internal/client/errors.go b/internal/client/errors.go
index 2d4bd30..7fc816f 100644
--- a/internal/client/errors.go
+++ b/internal/client/errors.go
@@ -5,7 +5,7 @@ import (
 )
 
 var (
-	errFakeErr                             = errors.New("fake error")
+	errFake                                = errors.New("fake error")
 	errTryAgain                            = errors.New("try again")
 	errClosed                              = errors.New("use of closed network connection")
 	errUDPAddrCast                         = errors.New("addr is not a net.UDPAddr")
diff --git a/internal/server/turn.go b/internal/server/turn.go
index ca92f8d..41385ea 100644
--- a/internal/server/turn.go
+++ b/internal/server/turn.go
@@ -97,7 +97,7 @@ func handleAllocateRequest(r Request, m *stun.Message) error {
 	//    error.
 	var evenPort proto.EvenPort
 	if err = evenPort.GetFrom(m); err == nil {
-		randomPort := 0
+		var randomPort int
 		randomPort, err = r.AllocationManager.GetRandomEvenPort()
 		if err != nil {
 			return buildAndSendErr(r.Conn, r.SrcAddr, err, insufficentCapacityMsg...)
diff --git a/internal/server/util.go b/internal/server/util.go
index c6baffb..c9a3392 100644
--- a/internal/server/util.go
+++ b/internal/server/util.go
@@ -95,8 +95,13 @@ func authenticateRequest(r Request, m *stun.Message, callingMethod stun.Method)
 	}
 
 	// Assert Nonce exists and is not expired
-	nonceCreationTime, ok := r.Nonces.Load(string(*nonceAttr))
-	if !ok || time.Since(nonceCreationTime.(time.Time)) >= nonceLifetime {
+	nonceCreationTime, nonceFound := r.Nonces.Load(string(*nonceAttr))
+	if !nonceFound {
+		r.Nonces.Delete(nonceAttr)
+		return respondWithNonce(stun.CodeStaleNonce)
+	}
+
+	if timeValue, ok := nonceCreationTime.(time.Time); !ok || time.Since(timeValue) >= nonceLifetime {
 		r.Nonces.Delete(nonceAttr)
 		return respondWithNonce(stun.CodeStaleNonce)
 	}
diff --git a/relay_address_generator_range.go b/relay_address_generator_range.go
index 9f95429..b136eb1 100644
--- a/relay_address_generator_range.go
+++ b/relay_address_generator_range.go
@@ -66,7 +66,11 @@ func (r *RelayAddressGeneratorPortRange) AllocatePacketConn(network string, requ
 		if err != nil {
 			return nil, nil, err
 		}
-		relayAddr := conn.LocalAddr().(*net.UDPAddr)
+		relayAddr, ok := conn.LocalAddr().(*net.UDPAddr)
+		if !ok {
+			return nil, nil, errNilConn
+		}
+
 		relayAddr.IP = r.RelayAddress
 		return conn, relayAddr, nil
 	}
@@ -78,7 +82,11 @@ func (r *RelayAddressGeneratorPortRange) AllocatePacketConn(network string, requ
 			continue
 		}
 
-		relayAddr := conn.LocalAddr().(*net.UDPAddr)
+		relayAddr, ok := conn.LocalAddr().(*net.UDPAddr)
+		if !ok {
+			return nil, nil, errNilConn
+		}
+
 		relayAddr.IP = r.RelayAddress
 		return conn, relayAddr, nil
 	}
diff --git a/relay_address_generator_static.go b/relay_address_generator_static.go
index ae921e7..b836811 100644
--- a/relay_address_generator_static.go
+++ b/relay_address_generator_static.go
@@ -43,7 +43,11 @@ func (r *RelayAddressGeneratorStatic) AllocatePacketConn(network string, request
 	}
 
 	// Replace actual listening IP with the user requested one of RelayAddressGeneratorStatic
-	relayAddr := conn.LocalAddr().(*net.UDPAddr)
+	relayAddr, ok := conn.LocalAddr().(*net.UDPAddr)
+	if !ok {
+		return nil, nil, errNilConn
+	}
+
 	relayAddr.IP = r.RelayAddress
 
 	return conn, relayAddr, nil
diff --git a/server.go b/server.go
index fc36aef..a2bb45d 100644
--- a/server.go
+++ b/server.go
@@ -152,7 +152,7 @@ func (s *Server) Close() error {
 
 	err := errFailedToClose
 	for _, e := range errors {
-		err = fmt.Errorf("%s; Close error (%v) ", err.Error(), e) //nolint:goerr113
+		err = fmt.Errorf("%s; Close error (%w) ", err.Error(), e)
 	}
 
 	return err


Test patch:
diff --git a/client_test.go b/client_test.go
index 678a378..f7401db 100644
--- a/client_test.go
+++ b/client_test.go
@@ -1,3 +1,4 @@
+//go:build !js
 // +build !js
 
 package turn
diff --git a/internal/allocation/allocation_manager_test.go b/internal/allocation/allocation_manager_test.go
index f6f7f02..fd18773 100644
--- a/internal/allocation/allocation_manager_test.go
+++ b/internal/allocation/allocation_manager_test.go
@@ -1,3 +1,4 @@
+//go:build !js
 // +build !js
 
 package allocation
diff --git a/internal/allocation/allocation_test.go b/internal/allocation/allocation_test.go
index 1f1ba26..494d0ea 100644
--- a/internal/allocation/allocation_test.go
+++ b/internal/allocation/allocation_test.go
@@ -1,3 +1,4 @@
+//go:build !js
 // +build !js
 
 package allocation
diff --git a/internal/client/conn_test.go b/internal/client/conn_test.go
index ef73088..4effccd 100644
--- a/internal/client/conn_test.go
+++ b/internal/client/conn_test.go
@@ -53,7 +53,7 @@ func TestUDPConn(t *testing.T) {
 	t.Run("bind()", func(t *testing.T) {
 		obs := &dummyUDPConnObserver{
 			_performTransaction: func(msg *stun.Message, to net.Addr, dontWait bool) (TransactionResult, error) {
-				return TransactionResult{}, errFakeErr
+				return TransactionResult{}, errFake
 			},
 		}
 
diff --git a/internal/server/turn_test.go b/internal/server/turn_test.go
index f09d826..f054235 100644
--- a/internal/server/turn_test.go
+++ b/internal/server/turn_test.go
@@ -1,3 +1,4 @@
+//go:build !js
 // +build !js
 
 package server
diff --git a/lt_cred_test.go b/lt_cred_test.go
index 93b231e..cfdc4aa 100644
--- a/lt_cred_test.go
+++ b/lt_cred_test.go
@@ -1,3 +1,4 @@
+//go:build !js
 // +build !js
 
 package turn
diff --git a/server_test.go b/server_test.go
index 19ce529..e867b68 100644
--- a/server_test.go
+++ b/server_test.go
@@ -281,7 +281,8 @@ func TestServerVNet(t *testing.T) {
 		reflAddr, err := client.SendBindingRequest()
 		assert.NoError(t, err)
 		log.Debugf("mapped-address: %v", reflAddr.String())
-		udpAddr := reflAddr.(*net.UDPAddr)
+		udpAddr, ok := reflAddr.(*net.UDPAddr)
+		assert.True(t, ok)
 
 		// The mapped-address should have IP address that was assigned
 		// to the LAN router.