nim-eth/eth/utp/utp_protocol.nim

62 lines
2.2 KiB
Nim
Raw Normal View History

# Copyright (c) 2020-2021 Status Research & Development GmbH
# Licensed and distributed under either of
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms.
{.push raises: [Defect].}
import
chronos, chronicles, bearssl,
./packets,
../keys
logScope:
topics = "utp"
type
# For now utp protocol is tied to udp transport, but ultimatly we would like to
# abstract underlying transport to be able to run utp over udp, discoveryv5 or
# maybe some test transport
UtpProtocol* = ref object
transport: DatagramTransport
rng*: ref BrHmacDrbgContext
UtpSocket* = ref object
# TODO not implemented
# for now just log incoming packets
proc processPacket(p: Packet) =
notice "Received packet ", packet = p
# Connect to provided address
# Reference implementation: https://github.com/bittorrent/libutp/blob/master/utp_internal.cpp#L2732
# TODO not implemented
proc connectTo*(p: UtpProtocol, address: TransportAddress): Future[UtpSocket] {.async.} =
let packet = synPacket(p.rng[], randUint16(p.rng[]), 1048576)
notice "Sending packet", packet = packet
let packetEncoded = encodePacket(packet)
await p.transport.sendTo(address, packetEncoded)
return UtpSocket()
proc processDatagram(transp: DatagramTransport, raddr: TransportAddress):
Future[void] {.async.} =
# TODO: should we use `peekMessage()` to avoid allocation?
let buf = try: transp.getMessage()
except TransportOsError as e:
# This is likely to be local network connection issues.
return
let dec = decodePacket(buf)
if (dec.isOk()):
processPacket(dec.get())
else:
warn "failed to decode packet from address", address = raddr
proc new*(T: type UtpProtocol, address: TransportAddress, rng = newRng()): UtpProtocol {.raises: [Defect, CatchableError].} =
let ta = newDatagramTransport(processDatagram, local = address)
UtpProtocol(transport: ta, rng: rng)
proc closeWait*(p: UtpProtocol): Future[void] =
p.transport.closeWait()