-
Notifications
You must be signed in to change notification settings - Fork 3
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
fix: stun and dtls close #22
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ type | |
StunUsernameProvider* = proc(): string {.raises: [], gcsafe.} | ||
StunUsernameChecker* = proc(username: seq[byte]): bool {.raises: [], gcsafe.} | ||
StunPasswordProvider* = proc(username: seq[byte]): seq[byte] {.raises: [], gcsafe.} | ||
StunConnOnClose* = proc() {.raises: [], gcsafe.} | ||
|
||
StunConn* = ref object | ||
udp*: UdpTransport # The wrapper protocol: UDP Transport | ||
|
@@ -37,8 +38,10 @@ type | |
stunMsgs*: AsyncQueue[seq[byte]] # stun messages received and to be | ||
# processed by the stun message handler | ||
handlesFut*: Future[void] # Stun Message handler | ||
closeEvent: AsyncEvent | ||
|
||
# Close connection management | ||
closed*: bool | ||
onClose: seq[StunConnOnClose] | ||
|
||
# Is ice-controlling and iceTiebreaker, not fully implemented yet. | ||
iceControlling: bool | ||
|
@@ -201,7 +204,6 @@ proc new*( | |
laddr: udp.laddr, | ||
raddr: raddr, | ||
closed: false, | ||
closeEvent: newAsyncEvent(), | ||
dataRecv: newAsyncQueue[seq[byte]](StunMaxQueuingMessages), | ||
stunMsgs: newAsyncQueue[seq[byte]](StunMaxQueuingMessages), | ||
iceControlling: iceControlling, | ||
|
@@ -215,10 +217,10 @@ proc new*( | |
trackCounter(StunConnectionTracker) | ||
return self | ||
|
||
proc join*(self: StunConn) {.async: (raises: [CancelledError]).} = | ||
## Wait for the Stun Connection to be closed | ||
proc addOnClose*(self: StunConn, onCloseProc: StunConnOnClose) = | ||
## Adds a proc to be called when StunConn is closed | ||
## | ||
await self.closeEvent.wait() | ||
self.onClose.add(onCloseProc) | ||
|
||
proc close*(self: StunConn) {.async: (raises: []).} = | ||
## Close a Stun Connection | ||
|
@@ -227,7 +229,9 @@ proc close*(self: StunConn) {.async: (raises: []).} = | |
debug "Try to close an already closed StunConn" | ||
return | ||
await self.handlesFut.cancelAndWait() | ||
self.closeEvent.fire() | ||
for onCloseProc in self.onClose: | ||
onCloseProc() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can pass the conn as param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know if it's a good idea, the conn is useless at this point (because it's closed) |
||
self.onClose = @[] | ||
self.closed = true | ||
untrackCounter(StunConnectionTracker) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,12 @@ type | |
|
||
rng: ref HmacDrbgContext | ||
|
||
proc addConnToTable(self: Stun, conn: StunConn) = | ||
proc cleanup() = | ||
self.connections.del(conn.raddr) | ||
self.connections[conn.raddr] = conn | ||
conn.addOnClose(cleanup) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then |
||
|
||
proc accept*(self: Stun): Future[StunConn] {.async: (raises: [CancelledError]).} = | ||
## Accept a Stun Connection | ||
## | ||
|
@@ -53,27 +59,18 @@ proc connect*( | |
do: | ||
let res = StunConn.new(self.udp, raddr, false, self.usernameProvider, | ||
self.usernameChecker, self.passwordProvider, self.rng) | ||
self.connections[raddr] = res | ||
self.addConnToTable(res) | ||
return res | ||
|
||
proc cleanupStunConn(self: Stun, conn: StunConn) {.async: (raises: []).} = | ||
# Waiting for a connection to be closed to remove it from the table | ||
try: | ||
await conn.join() | ||
self.connections.del(conn.raddr) | ||
except CancelledError as exc: | ||
warn "Error cleaning up Stun Connection", error=exc.msg | ||
|
||
proc stunReadLoop(self: Stun) {.async: (raises: [CancelledError]).} = | ||
while true: | ||
let (buf, raddr) = await self.udp.read() | ||
var stunConn: StunConn | ||
if not self.connections.hasKey(raddr): | ||
stunConn = StunConn.new(self.udp, raddr, true, self.usernameProvider, | ||
self.usernameChecker, self.passwordProvider, self.rng) | ||
self.connections[raddr] = stunConn | ||
self.addConnToTable(stunConn) | ||
await self.pendingConn.addLast(stunConn) | ||
asyncSpawn self.cleanupStunConn(stunConn) | ||
else: | ||
try: | ||
stunConn = self.connections[raddr] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be only
OnClose
, it is clear from the context it is related to a Stun conn.