Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: stun protocol & stun connection #9

Merged
merged 44 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
a53c04f
feat: stun protocol & stun connection
lchenut Mar 8, 2024
6778672
rename getResponse into getPong and test it
lchenut Mar 15, 2024
7be3d0a
add Username attribute
lchenut Mar 15, 2024
f4ca113
genUfrag procedure
lchenut Mar 15, 2024
81a2a51
Add generateRandomSeq to generate a transaction id
lchenut Mar 21, 2024
52296d1
First draft of getPing
lchenut Mar 21, 2024
2b70ad7
Merge remote-tracking branch 'origin/master' into stun-protocol
lchenut Apr 2, 2024
50fde87
Use UdpPacketInfo tuple
lchenut Apr 2, 2024
82203f2
Change closing debug message
lchenut Apr 2, 2024
fa5d674
Add proper exception tracking
lchenut Apr 2, 2024
3d070b5
Change StunConn init behavior
lchenut Apr 2, 2024
762acd8
Add a last UdpPacketInfo
lchenut Apr 2, 2024
5ce6796
Add comments
lchenut Apr 2, 2024
5e9a335
refactor: change connection management
lchenut Apr 5, 2024
832a343
Add a lot of comments/Finish refactor
lchenut Apr 11, 2024
18e302b
Add copyright headers on test files
lchenut Apr 15, 2024
7eb2940
simplify newRng proc for testing
lchenut Apr 15, 2024
f075c40
add exception tracking for stun transport asynchronous proc
lchenut Apr 15, 2024
5100b40
remove ping/pong example building in the ci
lchenut Apr 15, 2024
5c3afe1
rename getPong test
lchenut Apr 15, 2024
4660ac0
remove maximum connections
lchenut Apr 17, 2024
7c36e98
Add ICE stun attributes
lchenut Apr 23, 2024
cf84596
Stun rework
lchenut Apr 26, 2024
b22d6a5
feat: getBindingRequest
lchenut Apr 26, 2024
aada110
fix oversight & add comments
lchenut Apr 26, 2024
9e95f56
Test rework
lchenut Apr 26, 2024
bdf32d9
Adds continue in stunMessageHandler loop
lchenut Apr 29, 2024
6f2dae5
remove `doAssert(false)` from Stun.connect()
lchenut Apr 29, 2024
bccc27f
Update TODO
lchenut Apr 29, 2024
47319e4
fix comment typo
lchenut Apr 29, 2024
9508b79
fix: test lacking precision
lchenut Apr 30, 2024
65bbfba
docs: add StunConn.init() comments
lchenut Apr 30, 2024
d0c4013
chore: make teststun more readable
lchenut Apr 30, 2024
559c857
feat: use withValue instead of getOrDefault in Stun.connect()
lchenut Apr 30, 2024
735cde8
feat: add check if Fingerprint is valid
lchenut Apr 30, 2024
11b4d42
refactor: getAttribute and username/password provider
lchenut May 21, 2024
3a5b206
chore: removes genUfrag, should be in libp2p instead
lchenut May 23, 2024
955b1d2
chore: remove redundant test
lchenut May 24, 2024
285d7fb
chore: change warn log to debug
lchenut May 24, 2024
ea2e56a
docs: update getBindingResponse/Request comments
lchenut May 24, 2024
a1a1acc
chore: renames init into new
lchenut May 24, 2024
0aab612
fix: compilation warnings
lchenut May 24, 2024
f3af915
chore: change closed line to be at the end of the close procedure
lchenut May 24, 2024
96749ab
feat: limit queues size
lchenut May 24, 2024
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
4 changes: 1 addition & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,4 @@ jobs:
run: |
nim --version
nimble --version
# nimble test
# nim c examples/ping.nim
# nim c examples/pong.nim
nimble test
12 changes: 12 additions & 0 deletions tests/runalltests.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Nim-WebRTC
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.

{.used.}

import teststun
130 changes: 130 additions & 0 deletions tests/teststun.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Nim-WebRTC
# Copyright (c) 2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.

{.used.}
diegomrsantos marked this conversation as resolved.
Show resolved Hide resolved

import options, strutils
import bearssl
import ../webrtc/udp_connection
import ../webrtc/stun/stun_connection
import ../webrtc/stun/stun_message
import ../webrtc/stun/stun_attributes
import ../webrtc/stun/stun_utils
import ./asyncunit

proc newRng(): ref HmacDrbgContext =
diegomrsantos marked this conversation as resolved.
Show resolved Hide resolved
HmacDrbgContext.new()

proc usernameProvEmpty(): string = ""
proc usernameProvTest(): string {.raises: [], gcsafe.} = "TestUsername"
proc usernameCheckTrue(username: seq[byte]): bool {.raises: [], gcsafe.} = true
proc usernameCheckFalse(username: seq[byte]): bool {.raises: [], gcsafe.} = false
proc passwordProvEmpty(username: seq[byte]): seq[byte] {.raises: [], gcsafe.} = @[]
proc passwordProvTest(username: seq[byte]): seq[byte] {.raises: [], gcsafe.} = @[1'u8, 2, 3, 4]

suite "Stun message encoding/decoding":
test "Get BindingRequest + encode & decode with a set username":
var
udpConn = UdpConn.init(AnyAddress)
conn = StunConn.init(
udpConn,
TransportAddress(AnyAddress),
iceControlling=true,
usernameProvider=usernameProvTest,
usernameChecker=usernameCheckTrue,
passwordProvider=passwordProvEmpty,
newRng()
)
msg = conn.getBindingRequest()
encoded = msg.encode(@[1'u8, 2, 3, 4])
decoded = StunMessage.decode(encoded)
messageIntegrity = decoded.attributes[^2]
fingerprint = decoded.attributes[^1]

decoded.attributes = decoded.attributes[0 ..< ^2]
check:
decoded == msg
messageIntegrity.attributeType == AttrMessageIntegrity.uint16
fingerprint.attributeType == AttrFingerprint.uint16
conn.close()

test "Get BindingResponse from BindingRequest + encode & decode":
var
udpConn = UdpConn.init(AnyAddress)
conn = StunConn.init(
udpConn,
TransportAddress(AnyAddress),
iceControlling=false,
usernameProvider=usernameProvTest,
usernameChecker=usernameCheckTrue,
passwordProvider=passwordProvEmpty,
newRng()
)
bindingRequest = conn.getBindingRequest()
bindingResponse = conn.getBindingResponse(bindingRequest)
encoded = bindingResponse.encode(@[1'u8, 2, 3, 4])
decoded = StunMessage.decode(encoded)
messageIntegrity = decoded.attributes[^2]
fingerprint = decoded.attributes[^1]

decoded.attributes = decoded.attributes[0 ..< ^2]
check:
bindingResponse == decoded
messageIntegrity.attributeType == AttrMessageIntegrity.uint16
fingerprint.attributeType == AttrFingerprint.uint16

suite "Stun checkForError":
test "checkForError: Missing MessageIntegrity or Username":
var
udpConn = UdpConn.init(AnyAddress)
conn = StunConn.init(
udpConn,
TransportAddress(AnyAddress),
iceControlling=false,
usernameProvider=usernameProvEmpty, # Use of an empty username provider
usernameChecker=usernameCheckTrue,
passwordProvider=passwordProvEmpty,
newRng()
)
bindingRequest = conn.getBindingRequest()
diegomrsantos marked this conversation as resolved.
Show resolved Hide resolved
errorMissMessageIntegrity = conn.checkForError(bindingRequest).get()

check:
errorMissMessageIntegrity.getAttribute(ErrorCode).isSome()
errorMissMessageIntegrity.getAttribute(ErrorCode).get().getErrorCode() == ECBadRequest

let
encoded = bindingRequest.encode(@[1'u8, 2, 3, 4]) # adds MessageIntegrity
decoded = StunMessage.decode(encoded)
errorMissUsername = conn.checkForError(decoded).get()

check:
errorMissUsername.getAttribute(ErrorCode).isSome()
errorMissUsername.getAttribute(ErrorCode).get().getErrorCode() == ECBadRequest

test "checkForError: UsernameChecker returns false":
var
udpConn = UdpConn.init(AnyAddress)
conn = StunConn.init(
udpConn,
TransportAddress(AnyAddress),
iceControlling=false,
usernameProvider=usernameProvTest,
usernameChecker=usernameCheckFalse, # Username provider returns false
passwordProvider=passwordProvEmpty,
newRng()
)
bindingRequest = conn.getBindingRequest()
encoded = bindingRequest.encode(@[0'u8, 1, 2, 3])
decoded = StunMessage.decode(encoded)
error = conn.checkForError(decoded).get()

check:
error.getAttribute(ErrorCode).isSome()
diegomrsantos marked this conversation as resolved.
Show resolved Hide resolved
error.getAttribute(ErrorCode).get().getErrorCode() == ECUnauthorized
4 changes: 2 additions & 2 deletions webrtc.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ proc runTest(filename: string) =
exec excstr & " -r " & " tests/" & filename
diegomrsantos marked this conversation as resolved.
Show resolved Hide resolved
rmFile "tests/" & filename.toExe

# task test, "Run test":
# runTest("runalltests")
task test, "Run test":
runTest("runalltests")
Loading
Loading