Skip to content

Commit

Permalink
feat: dtls connection using mbedtls (#10)
Browse files Browse the repository at this point in the history
* feat: dtls connection using mbedtls

* refactor: change according to the stun protocol rework

* chore: rename init proc into new

* docs: adds object field comments

* chore: split dtls.nim into two files & renaming

* chore: remove useless code

* chore: remove TODOs as they were addressed with a Stun refactorization

* fix: oversight on dtls.new

* feat: add dtls test

* chore: added license & used pragma on testdtls

* fix: remove usage of deprecated TrackerCounter

* fix: trackers counter

* fix:
- add windows linking library
- make stun stop asynchronous (causing issue on macos)
- store private key and certificate

* chore: renaming test

* docs: update DtlsConn comment

* fix: remove code duplicate

* chore: update comment

* chore: remove duplication mbedtls initialization code in accept/connect and un-expose mbedtls context

* feat: add exception management to dtls_transport

* fix: check address family before handshake

* fix: exhaustive case

* fix: do not create dtlsConn if the address family is not IP

* chore: remove entropy from MbedTLSCtx

* chore: remove asyncspawn of cleanupdtlsconn

* chore: ctx is no longer public

* test: add a test with more than 2 nodes

* chore: started is now useful

* chore: update Dtls.stop

* chore: removed unecessary todos

* docs: add comments on DtlsConn.read and getters

* feat: add tracker for dtls connection and transport

* chore: privatize local and remote certificate

* style: use nph

* fix: remove laddr from dtls_conn (not used)

* style: sort imports

* chore: clean Dtls.stop

* fix: remote address is no longer exposed

* fix: raddr change oversight

* chore: change `verify` name

* chore: changed `sendFuture: Future[void]` into `dataToSend: seq[byte]`

* chore: avoid sequence copy

* chore: change assert message

---------

Co-authored-by: diegomrsantos <[email protected]>
  • Loading branch information
lchenut and diegomrsantos committed Aug 13, 2024
1 parent 81b91e3 commit d75e328
Show file tree
Hide file tree
Showing 9 changed files with 612 additions and 14 deletions.
1 change: 1 addition & 0 deletions tests/runalltests.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
{.used.}

import teststun
import testdtls
83 changes: 83 additions & 0 deletions tests/testdtls.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# 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 chronos
import ../webrtc/udp_transport
import ../webrtc/stun/stun_transport
import ../webrtc/dtls/dtls_transport
import ../webrtc/dtls/dtls_connection
import ./asyncunit

suite "DTLS":
teardown:
checkLeaks()

asyncTest "Two DTLS nodes connecting to each other, then sending/receiving data":
let
localAddr1 = initTAddress("127.0.0.1:4444")
localAddr2 = initTAddress("127.0.0.1:5555")
udp1 = UdpTransport.new(localAddr1)
udp2 = UdpTransport.new(localAddr2)
stun1 = Stun.new(udp1)
stun2 = Stun.new(udp2)
dtls1 = Dtls.new(stun1)
dtls2 = Dtls.new(stun2)
conn1Fut = dtls1.accept()
conn2 = await dtls2.connect(localAddr1)
conn1 = await conn1Fut

await conn1.write(@[1'u8, 2, 3, 4])
let seq1 = await conn2.read()
check seq1 == @[1'u8, 2, 3, 4]

await conn2.write(@[5'u8, 6, 7, 8])
let seq2 = await conn1.read()
check seq2 == @[5'u8, 6, 7, 8]
await allFutures(conn1.close(), conn2.close())
await allFutures(dtls1.stop(), dtls2.stop())
await allFutures(stun1.stop(), stun2.stop())
await allFutures(udp1.close(), udp2.close())

asyncTest "Two DTLS nodes connecting to the same DTLS server, sending/receiving data":
let
localAddr1 = initTAddress("127.0.0.1:4444")
localAddr2 = initTAddress("127.0.0.1:5555")
localAddr3 = initTAddress("127.0.0.1:6666")
udp1 = UdpTransport.new(localAddr1)
udp2 = UdpTransport.new(localAddr2)
udp3 = UdpTransport.new(localAddr3)
stun1 = Stun.new(udp1)
stun2 = Stun.new(udp2)
stun3 = Stun.new(udp3)
dtls1 = Dtls.new(stun1)
dtls2 = Dtls.new(stun2)
dtls3 = Dtls.new(stun3)
servConn1Fut = dtls1.accept()
servConn2Fut = dtls1.accept()
clientConn1 = await dtls2.connect(localAddr1)
clientConn2 = await dtls3.connect(localAddr1)
servConn1 = await servConn1Fut
servConn2 = await servConn2Fut

await servConn1.write(@[1'u8, 2, 3, 4])
await servConn2.write(@[5'u8, 6, 7, 8])
await clientConn1.write(@[9'u8, 10, 11, 12])
await clientConn2.write(@[13'u8, 14, 15, 16])
check:
(await clientConn1.read()) == @[1'u8, 2, 3, 4]
(await clientConn2.read()) == @[5'u8, 6, 7, 8]
(await servConn1.read()) == @[9'u8, 10, 11, 12]
(await servConn2.read()) == @[13'u8, 14, 15, 16]
await allFutures(servConn1.close(), servConn2.close())
await allFutures(clientConn1.close(), clientConn2.close())
await allFutures(dtls1.stop(), dtls2.stop(), dtls3.stop())
await allFutures(stun1.stop(), stun2.stop(), stun3.stop())
await allFutures(udp1.close(), udp2.close(), udp3.close())
8 changes: 4 additions & 4 deletions tests/teststun.nim
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ suite "Stun message encoding/decoding":
decoded == msg
messageIntegrity.attributeType == AttrMessageIntegrity.uint16
fingerprint.attributeType == AttrFingerprint.uint16
conn.close()
await conn.close()
await udp.close()

asyncTest "Get BindingResponse from BindingRequest + encode & decode":
Expand All @@ -82,7 +82,7 @@ suite "Stun message encoding/decoding":
bindingResponse == decoded
messageIntegrity.attributeType == AttrMessageIntegrity.uint16
fingerprint.attributeType == AttrFingerprint.uint16
conn.close()
await conn.close()
await udp.close()

suite "Stun checkForError":
Expand Down Expand Up @@ -114,7 +114,7 @@ suite "Stun checkForError":

check:
errorMissUsername.getAttribute(ErrorCode).get().getErrorCode() == ECBadRequest
conn.close()
await conn.close()
await udp.close()

asyncTest "checkForError: UsernameChecker returns false":
Expand All @@ -136,5 +136,5 @@ suite "Stun checkForError":

check:
error.getAttribute(ErrorCode).get().getErrorCode() == ECUnauthorized
conn.close()
await conn.close()
await udp.close()
5 changes: 4 additions & 1 deletion webrtc.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ let lang = getEnv("NIMLANG", "c") # Which backend (c/cpp/js)
let flags = getEnv("NIMFLAGS", "") # Extra flags for the compiler
let verbose = getEnv("V", "") notin ["", "0"]

let cfg =
var cfg =
" --styleCheck:usages --styleCheck:error" &
(if verbose: "" else: " --verbosity:0 --hints:off") &
" --skipParentCfg --skipUserCfg -f" &
" --threads:on --opt:speed"

when defined(windows):
cfg = cfg & " --clib:ws2_32"

import hashes

proc runTest(filename: string) =
Expand Down
Loading

0 comments on commit d75e328

Please sign in to comment.