mirror of https://github.com/vacp2p/nim-webrtc.git
commit
97cd366402
|
@ -0,0 +1,66 @@
|
|||
name: CI
|
||||
on:
|
||||
push:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- os: linux
|
||||
cpu: amd64
|
||||
- os: linux
|
||||
cpu: i386
|
||||
- os: macos
|
||||
cpu: amd64
|
||||
- os: windows
|
||||
cpu: amd64
|
||||
nim: [1.6.16, devel]
|
||||
include:
|
||||
- target:
|
||||
os: linux
|
||||
builder: ubuntu-20.04
|
||||
shell: bash
|
||||
- target:
|
||||
os: macos
|
||||
builder: macos-12
|
||||
shell: bash
|
||||
- target:
|
||||
os: windows
|
||||
builder: windows-2019
|
||||
shell: msys2 {0}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell }}
|
||||
|
||||
name: '${{ matrix.target.os }}-${{ matrix.target.cpu }} (Nim ${{ matrix.nim }})'
|
||||
runs-on: ${{ matrix.builder }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: iffy/install-nim@v3
|
||||
with:
|
||||
version: ${{ matrix.nim }}
|
||||
|
||||
|
||||
- name: Install deps
|
||||
run: |
|
||||
nimble install -dy
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
nim --version
|
||||
nimble --version
|
||||
nimble test
|
||||
nim c examples/ping.nim
|
||||
nim c examples/pong.nim
|
|
@ -0,0 +1,46 @@
|
|||
import unittest2, chronos
|
||||
|
||||
export unittest2, chronos
|
||||
|
||||
template asyncTeardown*(body: untyped): untyped =
|
||||
teardown:
|
||||
waitFor((
|
||||
proc() {.async, gcsafe.} =
|
||||
body
|
||||
)())
|
||||
|
||||
template asyncSetup*(body: untyped): untyped =
|
||||
setup:
|
||||
waitFor((
|
||||
proc() {.async, gcsafe.} =
|
||||
body
|
||||
)())
|
||||
|
||||
template asyncTest*(name: string, body: untyped): untyped =
|
||||
test name:
|
||||
waitFor((
|
||||
proc() {.async, gcsafe.} =
|
||||
body
|
||||
)())
|
||||
|
||||
template flakyAsyncTest*(name: string, attempts: int, body: untyped): untyped =
|
||||
test name:
|
||||
var attemptNumber = 0
|
||||
while attemptNumber < attempts:
|
||||
let isLastAttempt = attemptNumber == attempts - 1
|
||||
inc attemptNumber
|
||||
try:
|
||||
waitFor((
|
||||
proc() {.async, gcsafe.} =
|
||||
body
|
||||
)())
|
||||
except Exception as e:
|
||||
if isLastAttempt: raise e
|
||||
else: testStatusIMPL = TestStatus.FAILED
|
||||
finally:
|
||||
if not isLastAttempt:
|
||||
if testStatusIMPL == TestStatus.FAILED:
|
||||
# Retry
|
||||
testStatusIMPL = TestStatus.OK
|
||||
else:
|
||||
break
|
|
@ -0,0 +1,48 @@
|
|||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
import chronos
|
||||
import unittest2
|
||||
export unittest2
|
||||
|
||||
const
|
||||
StreamTransportTrackerName = "stream.transport"
|
||||
StreamServerTrackerName = "stream.server"
|
||||
DgramTransportTrackerName = "datagram.transport"
|
||||
|
||||
trackerNames = [
|
||||
StreamTransportTrackerName,
|
||||
StreamServerTrackerName,
|
||||
DgramTransportTrackerName,
|
||||
]
|
||||
|
||||
template asyncTest*(name: string, body: untyped): untyped =
|
||||
test name:
|
||||
waitFor((proc () {.async, gcsafe.} = body)())
|
||||
|
||||
iterator testTrackers*(extras: openArray[string] = []): TrackerBase =
|
||||
for name in trackerNames:
|
||||
let t = getTracker(name)
|
||||
if not isNil(t): yield t
|
||||
for name in extras:
|
||||
let t = getTracker(name)
|
||||
if not isNil(t): yield t
|
||||
|
||||
template checkTracker*(name: string) =
|
||||
var tracker = getTracker(name)
|
||||
if tracker.isLeaked():
|
||||
checkpoint tracker.dump()
|
||||
fail()
|
||||
|
||||
template checkTrackers*() =
|
||||
for tracker in testTrackers():
|
||||
if tracker.isLeaked():
|
||||
checkpoint tracker.dump()
|
||||
fail()
|
||||
# Also test the GC is not fooling with us
|
||||
try:
|
||||
GC_fullCollect()
|
||||
except:
|
||||
discard
|
|
@ -0,0 +1,4 @@
|
|||
{.used.}
|
||||
|
||||
import testdatachannel
|
||||
import teststun
|
|
@ -1,11 +1,33 @@
|
|||
import ../webrtc/stun
|
||||
import options
|
||||
import ../webrtc/stun/stun
|
||||
import ../webrtc/stun/stun_attributes
|
||||
import ./asyncunit
|
||||
import binary_serialization
|
||||
|
||||
suite "Stun suite":
|
||||
test "Stun encoding/decoding with padding":
|
||||
suite "Stun message encoding/decoding":
|
||||
test "Stun decoding":
|
||||
let msg = @[ 0x00'u8, 0x01, 0x00, 0xa4, 0x21, 0x12, 0xa4, 0x42, 0x75, 0x6a, 0x58, 0x46, 0x42, 0x58, 0x4e, 0x72, 0x6a, 0x50, 0x4d, 0x2b, 0x00, 0x06, 0x00, 0x63, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2b, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2b, 0x76, 0x31, 0x2f, 0x62, 0x71, 0x36, 0x67, 0x69, 0x43, 0x75, 0x4a, 0x38, 0x6e, 0x78, 0x59, 0x46, 0x4a, 0x36, 0x43, 0x63, 0x67, 0x45, 0x59, 0x58, 0x58, 0x2f, 0x78, 0x51, 0x58, 0x56, 0x4c, 0x74, 0x39, 0x71, 0x7a, 0x3a, 0x6c, 0x69, 0x62, 0x70, 0x32, 0x70, 0x2b, 0x77, 0x65, 0x62, 0x72, 0x74, 0x63, 0x2b, 0x76, 0x31, 0x2f, 0x62, 0x71, 0x36, 0x67, 0x69, 0x43, 0x75, 0x4a, 0x38, 0x6e, 0x78, 0x59, 0x46, 0x4a, 0x36, 0x43, 0x63, 0x67, 0x45, 0x59, 0x58, 0x58, 0x2f, 0x78, 0x51, 0x58, 0x56, 0x4c, 0x74, 0x39, 0x71, 0x7a, 0x00, 0xc0, 0x57, 0x00, 0x04, 0x00, 0x00, 0x03, 0xe7, 0x80, 0x2a, 0x00, 0x08, 0x86, 0x63, 0xfd, 0x45, 0xa9, 0xe5, 0x4c, 0xdb, 0x00, 0x24, 0x00, 0x04, 0x6e, 0x00, 0x1e, 0xff, 0x00, 0x08, 0x00, 0x14, 0x16, 0xff, 0x70, 0x8d, 0x97, 0x0b, 0xd6, 0xa3, 0x5b, 0xac, 0x8f, 0x4c, 0x85, 0xe6, 0xa6, 0xac, 0xaa, 0x7a, 0x68, 0x27, 0x80, 0x28, 0x00, 0x04, 0x79, 0x5e, 0x03, 0xd8 ]
|
||||
check msg == encode(StunMessage.decode(msg))
|
||||
let stunmsg = StunMessage.decode(msg)
|
||||
check:
|
||||
stunmsg.msgType == 1
|
||||
stunmsg.transactionId.len() == 12
|
||||
stunmsg.attributes.len() == 6
|
||||
stunmsg.attributes[0].attributeType == 6 # AttrUsername
|
||||
stunmsg.attributes[^1].attributeType == 0x8028 # AttrFingerprint
|
||||
|
||||
test "Stun encoding":
|
||||
let transactionId: array[12, byte] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
|
||||
var msg = StunMessage(msgType: 0x0001'u16, transactionId: transactionId)
|
||||
msg.attributes.add(ErrorCode.encode(ECUnknownAttribute))
|
||||
let encoded = msg.encode()
|
||||
let decoded = StunMessage.decode(encoded)
|
||||
# cannot do `check msg == decoded` because encode add a Fingerprint
|
||||
# attribute at the end
|
||||
check:
|
||||
decoded.msgType == 1
|
||||
decoded.transactionId == transactionId
|
||||
decoded.attributes.len() == 2
|
||||
decoded.attributes[0].attributeType == 9 # AttrErrorCode
|
||||
decoded.attributes[^1].attributeType == 0x8028 # AttrFingerprint
|
||||
|
||||
test "Error while decoding":
|
||||
let msgLengthFailed = @[ 0x00'u8, 0x01, 0x00, 0xa4, 0x21, 0x12, 0xa4, 0x42, 0x75, 0x6a, 0x58, 0x46, 0x42, 0x58, 0x4e, 0x72, 0x6a, 0x50, 0x4d ]
|
||||
|
|
|
@ -5,11 +5,32 @@ description = "Webrtc stack"
|
|||
license = "MIT"
|
||||
installDirs = @["usrsctp", "webrtc"]
|
||||
|
||||
requires "nim >= 1.2.0",
|
||||
requires "nim >= 1.6.0",
|
||||
"chronicles >= 0.10.2",
|
||||
"chronos >= 3.0.6",
|
||||
"https://github.com/status-im/nim-binary-serialization.git",
|
||||
"https://github.com/status-im/nim-mbedtls.git"
|
||||
|
||||
let nimc = getEnv("NIMC", "nim") # Which nim compiler to use
|
||||
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 =
|
||||
" --styleCheck:usages --styleCheck:error" &
|
||||
(if verbose: "" else: " --verbosity:0 --hints:off") &
|
||||
" --skipParentCfg --skipUserCfg -f" &
|
||||
" --threads:on --opt:speed"
|
||||
|
||||
import hashes
|
||||
|
||||
proc runTest(filename: string) =
|
||||
discard
|
||||
var excstr = nimc & " " & lang & " -d:debug " & cfg & " " & flags
|
||||
excstr.add(" -d:nimOldCaseObjects") # TODO: fix this in binary-serialization
|
||||
if getEnv("CICOV").len > 0:
|
||||
excstr &= " --nimcache:nimcache/" & filename & "-" & $excstr.hash
|
||||
exec excstr & " -r " & " tests/" & filename
|
||||
rmFile "tests/" & filename.toExe
|
||||
|
||||
task test, "Run test":
|
||||
runTest("runalltests")
|
||||
|
|
|
@ -285,9 +285,7 @@ proc removeConnection(self: Dtls, conn: DtlsConn, raddr: TransportAddress) {.asy
|
|||
self.connections.del(raddr)
|
||||
|
||||
proc accept*(self: Dtls): Future[DtlsConn] {.async.} =
|
||||
var
|
||||
selfvar = self
|
||||
res = DtlsConn()
|
||||
var res = DtlsConn()
|
||||
|
||||
res.init(self.conn, self.laddr)
|
||||
mb_ssl_init(res.ssl)
|
||||
|
@ -334,9 +332,7 @@ proc accept*(self: Dtls): Future[DtlsConn] {.async.} =
|
|||
return res
|
||||
|
||||
proc connect*(self: Dtls, raddr: TransportAddress): Future[DtlsConn] {.async.} =
|
||||
var
|
||||
selfvar = self
|
||||
res = DtlsConn()
|
||||
var res = DtlsConn()
|
||||
|
||||
res.init(self.conn, self.laddr)
|
||||
mb_ssl_init(res.ssl)
|
||||
|
|
|
@ -159,7 +159,7 @@ proc write*(self: SctpConn, buf: seq[byte],
|
|||
self.sctpSocket.usrsctp_sendv(cast[pointer](addr cpy[0]), cpy.len().uint, nil, 0,
|
||||
nil, 0, SCTP_SENDV_NOINFO.cuint, 0)
|
||||
else:
|
||||
let sendInfo = sctp_sndinfo(
|
||||
var sendInfo = sctp_sndinfo(
|
||||
snd_sid: sendParams.streamId,
|
||||
# TODO: swapBytes => htonl?
|
||||
snd_ppid: sendParams.protocolId.swapBytes(),
|
||||
|
|
|
@ -59,10 +59,9 @@ type
|
|||
|
||||
RawStunMessage = object
|
||||
msgType: uint16
|
||||
# it.conten.len() + 8 Because the Fingerprint is added after the encoding
|
||||
length* {.bin_value: it.content.len().}: uint16
|
||||
magicCookie: uint32
|
||||
transactionId: array[12, byte]
|
||||
transactionId: array[12, byte] # Down from 16 to 12 bytes in RFC5389
|
||||
content* {.bin_len: it.length.}: seq[byte]
|
||||
|
||||
StunMessage* = object
|
||||
|
@ -98,11 +97,11 @@ proc decode*(T: typedesc[StunMessage], msg: seq[byte]): StunMessage =
|
|||
transactionId: smi.transactionId,
|
||||
attributes: RawStunAttribute.decode(smi.content))
|
||||
|
||||
proc encode*(msg: StunMessage, userOpt: Option[seq[byte]]): seq[byte] =
|
||||
proc encode*(msg: StunMessage, userOpt: Option[seq[byte]] = none(seq[byte])): seq[byte] =
|
||||
const pad = @[0, 3, 2, 1]
|
||||
var smi = RawStunMessage(msgType: msg.msgType,
|
||||
magicCookie: magicCookie,
|
||||
transactionId: msg.transactionId)
|
||||
magicCookie: magicCookie,
|
||||
transactionId: msg.transactionId)
|
||||
for attr in msg.attributes:
|
||||
smi.content.add(Binary.encode(attr))
|
||||
smi.content.add(newSeq[byte](pad[smi.content.len() mod 4]))
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
# This file may not be copied, modified, or distributed except according to
|
||||
# those terms.
|
||||
|
||||
import sequtils
|
||||
import chronos, chronicles
|
||||
|
||||
logScope:
|
||||
|
|
Loading…
Reference in New Issue