Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions internal/client/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
errFailedToGetLifetime = errors.New("failed to get lifetime from refresh response")
errInvalidTURNAddress = errors.New("invalid TURN server address")
errUnexpectedSTUNRequestMessage = errors.New("unexpected STUN request message")
errCannotBindChannel = errors.New("cannot bind channel")
)

type timeoutError struct {
Expand Down
5 changes: 4 additions & 1 deletion internal/client/udp_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,11 @@ func (c *UDPConn) bind(bound *binding) error {

return errTryAgain
}

return fmt.Errorf("%w: received error %d", errCannotBindChannel, code.Code) // nolint:err113
}
return fmt.Errorf("unexpected response type %s", res.Type) //nolint // dynamic errors

return fmt.Errorf("%w: unexpected response type %s", errCannotBindChannel, res.Type) // nolint:err113
}

c.log.Debugf("Channel binding successful: %s %d", bound.addr, bound.number)
Expand Down
29 changes: 29 additions & 0 deletions internal/client/udp_conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func TestUDPConn(t *testing.T) { // nolint:maintidx
name string
transactionFn func(*stun.Message, net.Addr, bool) (TransactionResult, error)
expectErr error
expectErrContains string
expectBindingDeleted bool
expectNonceChanged bool
}{
Expand All @@ -114,6 +115,31 @@ func TestUDPConn(t *testing.T) { // nolint:maintidx
expectErr: errTryAgain,
expectNonceChanged: true,
},
{
name: "ErrorResponse with error code returns cannot bind channel error",
transactionFn: func(*stun.Message, net.Addr, bool) (TransactionResult, error) {
res := stun.MustBuild(
stun.NewType(stun.MethodChannelBind, stun.ClassErrorResponse),
stun.ErrorCodeAttribute{Code: stun.CodeForbidden, Reason: []byte("Forbidden")},
)

return TransactionResult{Msg: res}, nil
},
expectErr: errCannotBindChannel,
expectErrContains: "received error",
},
{
name: "ErrorResponse without error code returns unexpected response type error",
transactionFn: func(*stun.Message, net.Addr, bool) (TransactionResult, error) {
res := stun.MustBuild(
stun.NewType(stun.MethodChannelBind, stun.ClassErrorResponse),
)

return TransactionResult{Msg: res}, nil
},
expectErr: errCannotBindChannel,
expectErrContains: "unexpected response type",
},
}

for _, tt := range tests {
Expand All @@ -130,6 +156,9 @@ func TestUDPConn(t *testing.T) { // nolint:maintidx
} else {
assert.ErrorIs(t, err, tt.expectErr)
}
if tt.expectErrContains != "" {
assert.ErrorContains(t, err, tt.expectErrContains)
}

if tt.expectBindingDeleted {
assert.Empty(t, bm.chanMap)
Expand Down
Loading