mirror of https://github.com/status-im/nim-eth.git
bearssl: use split api (#510)
This commit is contained in:
parent
8761ea3222
commit
1b516682bd
24
eth/keys.nim
24
eth/keys.nim
|
@ -16,12 +16,13 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/strformat,
|
std/strformat,
|
||||||
secp256k1, bearssl, stew/[byteutils, objects, results],
|
secp256k1, bearssl/hash as bhash, bearssl/rand,
|
||||||
|
stew/[byteutils, objects, results],
|
||||||
nimcrypto/[hash, keccak]
|
nimcrypto/[hash, keccak]
|
||||||
|
|
||||||
from nimcrypto/utils import burnMem
|
from nimcrypto/utils import burnMem
|
||||||
|
|
||||||
export secp256k1, results, bearssl
|
export secp256k1, results, rand
|
||||||
|
|
||||||
const
|
const
|
||||||
KeyLength* = SkEcdhRawSecretSize - 1
|
KeyLength* = SkEcdhRawSecretSize - 1
|
||||||
|
@ -51,24 +52,15 @@ type
|
||||||
template pubkey*(v: KeyPair): PublicKey = PublicKey(SkKeyPair(v).pubkey)
|
template pubkey*(v: KeyPair): PublicKey = PublicKey(SkKeyPair(v).pubkey)
|
||||||
template seckey*(v: KeyPair): PrivateKey = PrivateKey(SkKeyPair(v).seckey)
|
template seckey*(v: KeyPair): PrivateKey = PrivateKey(SkKeyPair(v).seckey)
|
||||||
|
|
||||||
proc newRng*(): ref BrHmacDrbgContext =
|
proc newRng*(): ref HmacDrbgContext =
|
||||||
# You should only create one instance of the RNG per application / library
|
# You should only create one instance of the RNG per application / library
|
||||||
# Ref is used so that it can be shared between components
|
# Ref is used so that it can be shared between components
|
||||||
# TODO consider moving to bearssl
|
HmacDrbgContext.new()
|
||||||
var seeder = brPrngSeederSystem(nil)
|
|
||||||
if seeder == nil:
|
|
||||||
return nil
|
|
||||||
|
|
||||||
var rng = (ref BrHmacDrbgContext)()
|
proc random*(T: type PrivateKey, rng: var HmacDrbgContext): T =
|
||||||
brHmacDrbgInit(addr rng[], addr sha256Vtable, nil, 0)
|
|
||||||
if seeder(addr rng.vtable) == 0:
|
|
||||||
return nil
|
|
||||||
rng
|
|
||||||
|
|
||||||
proc random*(T: type PrivateKey, rng: var BrHmacDrbgContext): T =
|
|
||||||
let rngPtr = unsafeAddr rng # doesn't escape
|
let rngPtr = unsafeAddr rng # doesn't escape
|
||||||
proc callRng(data: var openArray[byte]) =
|
proc callRng(data: var openArray[byte]) =
|
||||||
brHmacDrbgGenerate(rngPtr[], data)
|
generate(rngPtr[], data)
|
||||||
|
|
||||||
T(SkSecretKey.random(callRng))
|
T(SkSecretKey.random(callRng))
|
||||||
|
|
||||||
|
@ -106,7 +98,7 @@ func toRaw*(pubkey: PublicKey): array[RawPublicKeySize, byte] =
|
||||||
|
|
||||||
func toRawCompressed*(pubkey: PublicKey): array[33, byte] {.borrow.}
|
func toRawCompressed*(pubkey: PublicKey): array[33, byte] {.borrow.}
|
||||||
|
|
||||||
proc random*(T: type KeyPair, rng: var BrHmacDrbgContext): T =
|
proc random*(T: type KeyPair, rng: var HmacDrbgContext): T =
|
||||||
let seckey = SkSecretKey(PrivateKey.random(rng))
|
let seckey = SkSecretKey(PrivateKey.random(rng))
|
||||||
KeyPair(SkKeyPair(
|
KeyPair(SkKeyPair(
|
||||||
seckey: seckey,
|
seckey: seckey,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, algorithm, random],
|
std/[tables, algorithm, random],
|
||||||
bearssl, chronos, chronos/timer, chronicles,
|
chronos, chronos/timer, chronicles,
|
||||||
./keys, ./common/eth_types, ./p2p/private/p2p_types,
|
./keys, ./common/eth_types, ./p2p/private/p2p_types,
|
||||||
./p2p/[kademlia, discovery, enode, peer_pool, rlpx]
|
./p2p/[kademlia, discovery, enode, peer_pool, rlpx]
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
nimcrypto/[rijndael, keccak, utils], bearssl,
|
nimcrypto/[rijndael, keccak, utils],
|
||||||
stew/[byteutils, endians2, objects, results],
|
stew/[arrayops, byteutils, endians2, objects, results],
|
||||||
".."/[keys, rlp],
|
".."/[keys, rlp],
|
||||||
./ecies
|
./ecies
|
||||||
|
|
||||||
|
@ -88,15 +88,11 @@ type
|
||||||
template toa(a, b, c: untyped): untyped =
|
template toa(a, b, c: untyped): untyped =
|
||||||
toOpenArray((a), (b), (b) + (c) - 1)
|
toOpenArray((a), (b), (b) + (c) - 1)
|
||||||
|
|
||||||
proc `xor`[N: static int](a, b: array[N, byte]): array[N, byte] =
|
|
||||||
for i in 0 ..< len(a):
|
|
||||||
result[i] = a[i] xor b[i]
|
|
||||||
|
|
||||||
proc mapErrTo[T, E](r: Result[T, E], v: static AuthError): AuthResult[T] =
|
proc mapErrTo[T, E](r: Result[T, E], v: static AuthError): AuthResult[T] =
|
||||||
r.mapErr(proc (e: E): AuthError = v)
|
r.mapErr(proc (e: E): AuthError = v)
|
||||||
|
|
||||||
proc init*(
|
proc init*(
|
||||||
T: type Handshake, rng: var BrHmacDrbgContext, host: KeyPair,
|
T: type Handshake, rng: var HmacDrbgContext, host: KeyPair,
|
||||||
flags: set[HandshakeFlag] = {Initiator},
|
flags: set[HandshakeFlag] = {Initiator},
|
||||||
version: uint8 = SupportedRlpxVersion): T =
|
version: uint8 = SupportedRlpxVersion): T =
|
||||||
## Create new `Handshake` object.
|
## Create new `Handshake` object.
|
||||||
|
@ -108,10 +104,10 @@ proc init*(
|
||||||
|
|
||||||
if Initiator in flags:
|
if Initiator in flags:
|
||||||
expectedLength = AckMessageV4Length
|
expectedLength = AckMessageV4Length
|
||||||
brHmacDrbgGenerate(rng, initiatorNonce)
|
rng.generate(initiatorNonce)
|
||||||
else:
|
else:
|
||||||
expectedLength = AuthMessageV4Length
|
expectedLength = AuthMessageV4Length
|
||||||
brHmacDrbgGenerate(rng, responderNonce)
|
rng.generate(responderNonce)
|
||||||
|
|
||||||
return T(
|
return T(
|
||||||
version: version,
|
version: version,
|
||||||
|
@ -124,7 +120,7 @@ proc init*(
|
||||||
)
|
)
|
||||||
|
|
||||||
proc authMessagePreEIP8(h: var Handshake,
|
proc authMessagePreEIP8(h: var Handshake,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
pubkey: PublicKey,
|
pubkey: PublicKey,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int,
|
outlen: var int,
|
||||||
|
@ -163,7 +159,7 @@ proc authMessagePreEIP8(h: var Handshake,
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc authMessageEIP8(h: var Handshake,
|
proc authMessageEIP8(h: var Handshake,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
pubkey: PublicKey,
|
pubkey: PublicKey,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int,
|
outlen: var int,
|
||||||
|
@ -172,7 +168,6 @@ proc authMessageEIP8(h: var Handshake,
|
||||||
## Create EIP8 authentication message.
|
## Create EIP8 authentication message.
|
||||||
var
|
var
|
||||||
buffer: array[PlainAuthMessageMaxEIP8, byte]
|
buffer: array[PlainAuthMessageMaxEIP8, byte]
|
||||||
padsize: array[1, byte]
|
|
||||||
|
|
||||||
doAssert(EIP8 in h.flags)
|
doAssert(EIP8 in h.flags)
|
||||||
outlen = 0
|
outlen = 0
|
||||||
|
@ -192,29 +187,33 @@ proc authMessageEIP8(h: var Handshake,
|
||||||
let
|
let
|
||||||
pencsize = eciesEncryptedLength(len(payload))
|
pencsize = eciesEncryptedLength(len(payload))
|
||||||
|
|
||||||
while true:
|
var padsize = int(rng.generate(byte)) # aka rand(max)
|
||||||
brHmacDrbgGenerate(rng, padsize)
|
while padsize <= (AuthMessageV4Length - (pencsize + 2)):
|
||||||
if int(padsize[0]) > (AuthMessageV4Length - (pencsize + 2)):
|
padsize = int(rng.generate(byte))
|
||||||
break
|
|
||||||
# It is possible to make packet size constant by uncommenting this line
|
# It is possible to make packet size constant by uncommenting this line
|
||||||
# padsize = 24
|
# padsize = 24
|
||||||
let wosize = pencsize + int(padsize[0])
|
let
|
||||||
let fullsize = wosize + 2
|
wosize = pencsize + padsize
|
||||||
brHmacDrbgGenerate(
|
fullsize = wosize + 2
|
||||||
rng, toa(buffer, PlainAuthMessageEIP8Length, int(padsize[0])))
|
|
||||||
|
rng.generate(toa(buffer, PlainAuthMessageEIP8Length, padsize))
|
||||||
|
|
||||||
if encrypt:
|
if encrypt:
|
||||||
copyMem(addr buffer[0], addr payload[0], len(payload))
|
|
||||||
if len(output) < fullsize:
|
if len(output) < fullsize:
|
||||||
return err(BufferOverrun)
|
return err(BufferOverrun)
|
||||||
|
|
||||||
|
copyMem(addr buffer[0], addr payload[0], len(payload))
|
||||||
|
|
||||||
let wosizeBE = uint16(wosize).toBytesBE()
|
let wosizeBE = uint16(wosize).toBytesBE()
|
||||||
output[0..<2] = wosizeBE
|
output[0..<2] = wosizeBE
|
||||||
if eciesEncrypt(rng, toa(buffer, 0, len(payload) + int(padsize[0])),
|
if eciesEncrypt(rng, toa(buffer, 0, len(payload) + padsize),
|
||||||
toa(output, 2, wosize), pubkey,
|
toa(output, 2, wosize), pubkey,
|
||||||
toa(output, 0, 2)).isErr:
|
toa(output, 0, 2)).isErr:
|
||||||
return err(EciesError)
|
return err(EciesError)
|
||||||
outlen = fullsize
|
outlen = fullsize
|
||||||
else:
|
else:
|
||||||
let plainsize = len(payload) + int(padsize[0])
|
let plainsize = len(payload) + padsize
|
||||||
if len(output) < plainsize:
|
if len(output) < plainsize:
|
||||||
return err(BufferOverrun)
|
return err(BufferOverrun)
|
||||||
copyMem(addr output[0], addr buffer[0], plainsize)
|
copyMem(addr output[0], addr buffer[0], plainsize)
|
||||||
|
@ -223,7 +222,7 @@ proc authMessageEIP8(h: var Handshake,
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc ackMessagePreEIP8(h: var Handshake,
|
proc ackMessagePreEIP8(h: var Handshake,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int,
|
outlen: var int,
|
||||||
flag: byte = 0,
|
flag: byte = 0,
|
||||||
|
@ -250,7 +249,7 @@ proc ackMessagePreEIP8(h: var Handshake,
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
proc ackMessageEIP8(h: var Handshake,
|
proc ackMessageEIP8(h: var Handshake,
|
||||||
rng: var BrHmacDrbgContext,
|
rng: var HmacDrbgContext,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int,
|
outlen: var int,
|
||||||
flag: byte = 0,
|
flag: byte = 0,
|
||||||
|
@ -267,7 +266,7 @@ proc ackMessageEIP8(h: var Handshake,
|
||||||
outlen = 0
|
outlen = 0
|
||||||
let pencsize = eciesEncryptedLength(len(payload))
|
let pencsize = eciesEncryptedLength(len(payload))
|
||||||
while true:
|
while true:
|
||||||
brHmacDrbgGenerate(rng, padsize)
|
generate(rng, padsize)
|
||||||
if int(padsize[0]) > (AckMessageV4Length - (pencsize + 2)):
|
if int(padsize[0]) > (AckMessageV4Length - (pencsize + 2)):
|
||||||
break
|
break
|
||||||
# It is possible to make packet size constant by uncommenting this line
|
# It is possible to make packet size constant by uncommenting this line
|
||||||
|
@ -275,8 +274,7 @@ proc ackMessageEIP8(h: var Handshake,
|
||||||
let wosize = pencsize + int(padsize[0])
|
let wosize = pencsize + int(padsize[0])
|
||||||
let fullsize = wosize + 2
|
let fullsize = wosize + 2
|
||||||
if int(padsize[0]) > 0:
|
if int(padsize[0]) > 0:
|
||||||
brHmacDrbgGenerate(
|
rng.generate(toa(buffer, PlainAckMessageEIP8Length, int(padsize[0])))
|
||||||
rng, toa(buffer, PlainAckMessageEIP8Length, int(padsize[0])))
|
|
||||||
|
|
||||||
copyMem(addr buffer[0], addr payload[0], len(payload))
|
copyMem(addr buffer[0], addr payload[0], len(payload))
|
||||||
if encrypt:
|
if encrypt:
|
||||||
|
@ -311,7 +309,7 @@ template ackSize*(h: Handshake, encrypt: bool = true): int =
|
||||||
else:
|
else:
|
||||||
if encrypt: (AckMessageV4Length) else: (PlainAckMessageV4Length)
|
if encrypt: (AckMessageV4Length) else: (PlainAckMessageV4Length)
|
||||||
|
|
||||||
proc authMessage*(h: var Handshake, rng: var BrHmacDrbgContext,
|
proc authMessage*(h: var Handshake, rng: var HmacDrbgContext,
|
||||||
pubkey: PublicKey,
|
pubkey: PublicKey,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int, flag: byte = 0,
|
outlen: var int, flag: byte = 0,
|
||||||
|
@ -323,7 +321,7 @@ proc authMessage*(h: var Handshake, rng: var BrHmacDrbgContext,
|
||||||
else:
|
else:
|
||||||
authMessagePreEIP8(h, rng, pubkey, output, outlen, flag, encrypt)
|
authMessagePreEIP8(h, rng, pubkey, output, outlen, flag, encrypt)
|
||||||
|
|
||||||
proc ackMessage*(h: var Handshake, rng: var BrHmacDrbgContext,
|
proc ackMessage*(h: var Handshake, rng: var HmacDrbgContext,
|
||||||
output: var openArray[byte],
|
output: var openArray[byte],
|
||||||
outlen: var int, flag: byte = 0,
|
outlen: var int, flag: byte = 0,
|
||||||
encrypt: bool = true): AuthResult[void] =
|
encrypt: bool = true): AuthResult[void] =
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/times,
|
std/times,
|
||||||
chronos, stint, nimcrypto/keccak, chronicles, bearssl,
|
chronos, stint, nimcrypto/keccak, chronicles,
|
||||||
stew/[objects, results],
|
stew/[objects, results],
|
||||||
".."/[keys, rlp],
|
".."/[keys, rlp],
|
||||||
"."/[kademlia, enode]
|
"."/[kademlia, enode]
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, options, hashes, net],
|
std/[tables, options, hashes, net],
|
||||||
nimcrypto, stint, chronicles, bearssl, stew/[results, byteutils], metrics,
|
nimcrypto, stint, chronicles, stew/[results, byteutils], metrics,
|
||||||
".."/../[rlp, keys],
|
".."/../[rlp, keys],
|
||||||
"."/[messages, node, enr, hkdf, sessions]
|
"."/[messages, node, enr, hkdf, sessions]
|
||||||
|
|
||||||
|
@ -193,18 +193,19 @@ proc encodeStaticHeader*(flag: Flag, nonce: AESGCMNonce, authSize: int):
|
||||||
# TODO: assert on authSize of > 2^16?
|
# TODO: assert on authSize of > 2^16?
|
||||||
result.add((uint16(authSize)).toBytesBE())
|
result.add((uint16(authSize)).toBytesBE())
|
||||||
|
|
||||||
proc encodeMessagePacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
proc encodeMessagePacket*(rng: var HmacDrbgContext, c: var Codec,
|
||||||
toId: NodeId, toAddr: Address, message: openArray[byte]):
|
toId: NodeId, toAddr: Address, message: openArray[byte]):
|
||||||
(seq[byte], AESGCMNonce) =
|
(seq[byte], AESGCMNonce) =
|
||||||
var nonce: AESGCMNonce
|
let
|
||||||
brHmacDrbgGenerate(rng, nonce) # Random AESGCM nonce
|
nonce = rng.generate(AESGCMNonce) # Random AESGCM nonce
|
||||||
var iv: array[ivSize, byte]
|
iv = rng.generate(array[ivSize, byte]) # Random IV
|
||||||
brHmacDrbgGenerate(rng, iv) # Random IV
|
|
||||||
|
|
||||||
# static-header
|
# static-header
|
||||||
let authdata = c.localNode.id.toByteArrayBE()
|
let
|
||||||
let staticHeader = encodeStaticHeader(Flag.OrdinaryMessage, nonce,
|
authdata = c.localNode.id.toByteArrayBE()
|
||||||
authdata.len())
|
staticHeader = encodeStaticHeader(Flag.OrdinaryMessage, nonce,
|
||||||
|
authdata.len())
|
||||||
|
|
||||||
# header = static-header || authdata
|
# header = static-header || authdata
|
||||||
var header: seq[byte]
|
var header: seq[byte]
|
||||||
header.add(staticHeader)
|
header.add(staticHeader)
|
||||||
|
@ -224,8 +225,7 @@ proc encodeMessagePacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
||||||
# message. 16 bytes for the gcm tag and 4 bytes for ping with requestId of
|
# message. 16 bytes for the gcm tag and 4 bytes for ping with requestId of
|
||||||
# 1 byte (e.g "01c20101"). Could increase to 27 for 8 bytes requestId in
|
# 1 byte (e.g "01c20101"). Could increase to 27 for 8 bytes requestId in
|
||||||
# case this must not look like a random packet.
|
# case this must not look like a random packet.
|
||||||
var randomData: array[gcmTagSize + 4, byte]
|
let randomData = rng.generate(array[gcmTagSize + 4, byte])
|
||||||
brHmacDrbgGenerate(rng, randomData)
|
|
||||||
messageEncrypted.add(randomData)
|
messageEncrypted.add(randomData)
|
||||||
discovery_session_lru_cache_misses.inc()
|
discovery_session_lru_cache_misses.inc()
|
||||||
|
|
||||||
|
@ -238,11 +238,11 @@ proc encodeMessagePacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
||||||
|
|
||||||
return (packet, nonce)
|
return (packet, nonce)
|
||||||
|
|
||||||
proc encodeWhoareyouPacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
proc encodeWhoareyouPacket*(rng: var HmacDrbgContext, c: var Codec,
|
||||||
toId: NodeId, toAddr: Address, requestNonce: AESGCMNonce, recordSeq: uint64,
|
toId: NodeId, toAddr: Address, requestNonce: AESGCMNonce, recordSeq: uint64,
|
||||||
pubkey: Option[PublicKey]): seq[byte] =
|
pubkey: Option[PublicKey]): seq[byte] =
|
||||||
var idNonce: IdNonce
|
let
|
||||||
brHmacDrbgGenerate(rng, idNonce)
|
idNonce = rng.generate(IdNonce)
|
||||||
|
|
||||||
# authdata
|
# authdata
|
||||||
var authdata: seq[byte]
|
var authdata: seq[byte]
|
||||||
|
@ -258,10 +258,9 @@ proc encodeWhoareyouPacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
||||||
header.add(staticHeader)
|
header.add(staticHeader)
|
||||||
header.add(authdata)
|
header.add(authdata)
|
||||||
|
|
||||||
var iv: array[ivSize, byte]
|
let
|
||||||
brHmacDrbgGenerate(rng, iv) # Random IV
|
iv = rng.generate(array[ivSize, byte]) # Random IV
|
||||||
|
maskedHeader = encryptHeader(toId, iv, header)
|
||||||
let maskedHeader = encryptHeader(toId, iv, header)
|
|
||||||
|
|
||||||
var packet: seq[byte]
|
var packet: seq[byte]
|
||||||
packet.add(iv)
|
packet.add(iv)
|
||||||
|
@ -280,14 +279,12 @@ proc encodeWhoareyouPacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
||||||
|
|
||||||
return packet
|
return packet
|
||||||
|
|
||||||
proc encodeHandshakePacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
proc encodeHandshakePacket*(rng: var HmacDrbgContext, c: var Codec,
|
||||||
toId: NodeId, toAddr: Address, message: openArray[byte],
|
toId: NodeId, toAddr: Address, message: openArray[byte],
|
||||||
whoareyouData: WhoareyouData, pubkey: PublicKey): seq[byte] =
|
whoareyouData: WhoareyouData, pubkey: PublicKey): seq[byte] =
|
||||||
var header: seq[byte]
|
let
|
||||||
var nonce: AESGCMNonce
|
nonce = rng.generate(AESGCMNonce)
|
||||||
brHmacDrbgGenerate(rng, nonce)
|
iv = rng.generate(array[ivSize, byte]) # Random IV
|
||||||
var iv: array[ivSize, byte]
|
|
||||||
brHmacDrbgGenerate(rng, iv) # Random IV
|
|
||||||
|
|
||||||
var authdata: seq[byte]
|
var authdata: seq[byte]
|
||||||
var authdataHead: seq[byte]
|
var authdataHead: seq[byte]
|
||||||
|
@ -316,6 +313,7 @@ proc encodeHandshakePacket*(rng: var BrHmacDrbgContext, c: var Codec,
|
||||||
let staticHeader = encodeStaticHeader(Flag.HandshakeMessage, nonce,
|
let staticHeader = encodeStaticHeader(Flag.HandshakeMessage, nonce,
|
||||||
authdata.len())
|
authdata.len())
|
||||||
|
|
||||||
|
var header: seq[byte]
|
||||||
header.add(staticHeader)
|
header.add(staticHeader)
|
||||||
header.add(authdata)
|
header.add(authdata)
|
||||||
|
|
||||||
|
@ -611,9 +609,9 @@ proc decodePacket*(c: var Codec, fromAddr: Address, input: openArray[byte]):
|
||||||
input.toOpenArray(0, ivSize - 1), header,
|
input.toOpenArray(0, ivSize - 1), header,
|
||||||
input.toOpenArray(ivSize + header.len, input.high))
|
input.toOpenArray(ivSize + header.len, input.high))
|
||||||
|
|
||||||
proc init*(T: type RequestId, rng: var BrHmacDrbgContext): T =
|
proc init*(T: type RequestId, rng: var HmacDrbgContext): T =
|
||||||
var reqId = RequestId(id: newSeq[byte](8)) # RequestId must be <= 8 bytes
|
var reqId = RequestId(id: newSeq[byte](8)) # RequestId must be <= 8 bytes
|
||||||
brHmacDrbgGenerate(rng, reqId.id)
|
rng.generate(reqId.id)
|
||||||
reqId
|
reqId
|
||||||
|
|
||||||
proc numFields(T: typedesc): int =
|
proc numFields(T: typedesc): int =
|
||||||
|
|
|
@ -86,11 +86,8 @@ func `==`*(a, b: Node): bool =
|
||||||
func hash*(id: NodeId): Hash =
|
func hash*(id: NodeId): Hash =
|
||||||
hash(id.toByteArrayBE)
|
hash(id.toByteArrayBE)
|
||||||
|
|
||||||
proc random*(T: type NodeId, rng: var BrHmacDrbgContext): T =
|
proc random*(T: type NodeId, rng: var HmacDrbgContext): T =
|
||||||
var id: NodeId
|
rng.generate(T)
|
||||||
brHmacDrbgGenerate(addr rng, addr id, csize_t(sizeof(id)))
|
|
||||||
|
|
||||||
id
|
|
||||||
|
|
||||||
func `$`*(id: NodeId): string =
|
func `$`*(id: NodeId): string =
|
||||||
id.toHex()
|
id.toHex()
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
import
|
import
|
||||||
std/[tables, sets, options, math, sequtils, algorithm],
|
std/[tables, sets, options, math, sequtils, algorithm],
|
||||||
stew/shims/net as stewNet, json_serialization/std/net,
|
stew/shims/net as stewNet, json_serialization/std/net,
|
||||||
stew/[endians2, results], chronicles, chronos, stint, bearssl, metrics,
|
stew/[endians2, results], chronicles, chronos, stint, metrics,
|
||||||
".."/../[rlp, keys, async_utils],
|
".."/../[rlp, keys, async_utils],
|
||||||
"."/[messages, encoding, node, routing_table, enr, random2, sessions, ip_vote,
|
"."/[messages, encoding, node, routing_table, enr, random2, sessions, ip_vote,
|
||||||
nodes_verification]
|
nodes_verification]
|
||||||
|
@ -147,7 +147,7 @@ type
|
||||||
enrAutoUpdate: bool
|
enrAutoUpdate: bool
|
||||||
talkProtocols*: Table[seq[byte], TalkProtocol] # TODO: Table is a bit of
|
talkProtocols*: Table[seq[byte], TalkProtocol] # TODO: Table is a bit of
|
||||||
# overkill here, use sequence
|
# overkill here, use sequence
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref HmacDrbgContext
|
||||||
|
|
||||||
PendingRequest = object
|
PendingRequest = object
|
||||||
node: Node
|
node: Node
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
import bearssl
|
import
|
||||||
|
bearssl/rand
|
||||||
|
|
||||||
## Random helpers: similar as in stdlib, but with BrHmacDrbgContext rng
|
export rand
|
||||||
|
|
||||||
|
## Random helpers: similar as in stdlib, but with HmacDrbgContext rng
|
||||||
# TODO: Move these somewhere else?
|
# TODO: Move these somewhere else?
|
||||||
const randMax = 18_446_744_073_709_551_615'u64
|
const randMax = 18_446_744_073_709_551_615'u64
|
||||||
|
|
||||||
proc rand*(rng: var BrHmacDrbgContext, max: Natural): int =
|
proc rand*(rng: var HmacDrbgContext, max: Natural): int =
|
||||||
if max == 0: return 0
|
if max == 0: return 0
|
||||||
|
|
||||||
var x: uint64
|
var x: uint64
|
||||||
while true:
|
while true:
|
||||||
brHmacDrbgGenerate(addr rng, addr x, csize_t(sizeof(x)))
|
rng.generate(x)
|
||||||
if x < randMax - (randMax mod (uint64(max) + 1'u64)): # against modulo bias
|
if x < randMax - (randMax mod (uint64(max) + 1'u64)): # against modulo bias
|
||||||
return int(x mod (uint64(max) + 1'u64))
|
return int(x mod (uint64(max) + 1'u64))
|
||||||
|
|
||||||
proc sample*[T](rng: var BrHmacDrbgContext, a: openArray[T]): T =
|
proc sample*[T](rng: var HmacDrbgContext, a: openArray[T]): T =
|
||||||
result = a[rng.rand(a.high)]
|
a[rng.rand(a.high)]
|
||||||
|
|
||||||
proc shuffle*[T](rng: var BrHmacDrbgContext, a: var openArray[T]) =
|
proc shuffle*[T](rng: var HmacDrbgContext, a: var openArray[T]) =
|
||||||
for i in countdown(a.high, 1):
|
for i in countdown(a.high, 1):
|
||||||
let j = rng.rand(i)
|
let j = rng.rand(i)
|
||||||
swap(a[i], a[j])
|
swap(a[i], a[j])
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[algorithm, times, sequtils, bitops, sets, options],
|
std/[algorithm, times, sequtils, bitops, sets, options],
|
||||||
stint, chronicles, metrics, bearssl, chronos, stew/shims/net as stewNet,
|
bearssl/rand,
|
||||||
|
stint, chronicles, metrics, chronos, stew/shims/net as stewNet,
|
||||||
../../net/utils,
|
../../net/utils,
|
||||||
"."/[node, random2, enr]
|
"."/[node, random2, enr]
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ type
|
||||||
ipLimits: IpLimits ## IP limits for total routing table: all buckets and
|
ipLimits: IpLimits ## IP limits for total routing table: all buckets and
|
||||||
## replacement caches.
|
## replacement caches.
|
||||||
distanceCalculator: DistanceCalculator
|
distanceCalculator: DistanceCalculator
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
|
|
||||||
KBucket = ref object
|
KBucket = ref object
|
||||||
istart, iend: NodeId ## Range of NodeIds this KBucket covers. This is not a
|
istart, iend: NodeId ## Range of NodeIds this KBucket covers. This is not a
|
||||||
|
@ -260,7 +261,7 @@ proc computeSharedPrefixBits(nodes: openArray[NodeId]): int =
|
||||||
doAssert(false, "Unable to calculate number of shared prefix bits")
|
doAssert(false, "Unable to calculate number of shared prefix bits")
|
||||||
|
|
||||||
proc init*(T: type RoutingTable, localNode: Node, bitsPerHop = DefaultBitsPerHop,
|
proc init*(T: type RoutingTable, localNode: Node, bitsPerHop = DefaultBitsPerHop,
|
||||||
ipLimits = DefaultTableIpLimits, rng: ref BrHmacDrbgContext,
|
ipLimits = DefaultTableIpLimits, rng: ref HmacDrbgContext,
|
||||||
distanceCalculator = XorDistanceCalculator): T =
|
distanceCalculator = XorDistanceCalculator): T =
|
||||||
## Initialize the routing table for provided `Node` and bitsPerHop value.
|
## Initialize the routing table for provided `Node` and bitsPerHop value.
|
||||||
## `bitsPerHop` is default set to 5 as recommended by original Kademlia paper.
|
## `bitsPerHop` is default set to 5 as recommended by original Kademlia paper.
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
import
|
import
|
||||||
bearssl, stew/[results, endians2],
|
stew/[results, endians2],
|
||||||
nimcrypto/[rijndael, bcmode, hash, hmac, sha2, utils],
|
nimcrypto/[rijndael, bcmode, hash, hmac, sha2, utils],
|
||||||
../keys
|
../keys
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ proc kdf*(data: openArray[byte]): array[KeyLength, byte] {.noinit.} =
|
||||||
ctx.clear() # clean ctx
|
ctx.clear() # clean ctx
|
||||||
copyMem(addr result[0], addr storage[0], KeyLength)
|
copyMem(addr result[0], addr storage[0], KeyLength)
|
||||||
|
|
||||||
proc eciesEncrypt*(rng: var BrHmacDrbgContext, input: openArray[byte],
|
proc eciesEncrypt*(rng: var HmacDrbgContext, input: openArray[byte],
|
||||||
output: var openArray[byte], pubkey: PublicKey,
|
output: var openArray[byte], pubkey: PublicKey,
|
||||||
sharedmac: openArray[byte] = emptyMac): EciesResult[void] =
|
sharedmac: openArray[byte] = emptyMac): EciesResult[void] =
|
||||||
## Encrypt data with ECIES method using given public key `pubkey`.
|
## Encrypt data with ECIES method using given public key `pubkey`.
|
||||||
|
@ -107,13 +107,10 @@ proc eciesEncrypt*(rng: var BrHmacDrbgContext, input: openArray[byte],
|
||||||
encKey: array[aes128.sizeKey, byte]
|
encKey: array[aes128.sizeKey, byte]
|
||||||
cipher: CTR[aes128]
|
cipher: CTR[aes128]
|
||||||
ctx: HMAC[sha256]
|
ctx: HMAC[sha256]
|
||||||
iv: array[aes128.sizeBlock, byte]
|
|
||||||
|
|
||||||
if len(output) < eciesEncryptedLength(len(input)):
|
if len(output) < eciesEncryptedLength(len(input)):
|
||||||
return err(BufferOverrun)
|
return err(BufferOverrun)
|
||||||
|
|
||||||
brHmacDrbgGenerate(rng, iv)
|
|
||||||
|
|
||||||
var
|
var
|
||||||
ephemeral = KeyPair.random(rng)
|
ephemeral = KeyPair.random(rng)
|
||||||
secret = ecdhRaw(ephemeral.seckey, pubkey)
|
secret = ecdhRaw(ephemeral.seckey, pubkey)
|
||||||
|
@ -130,13 +127,13 @@ proc eciesEncrypt*(rng: var BrHmacDrbgContext, input: openArray[byte],
|
||||||
var header = cast[ptr EciesHeader](addr output[0])
|
var header = cast[ptr EciesHeader](addr output[0])
|
||||||
header.version = 0x04
|
header.version = 0x04
|
||||||
header.pubkey = ephemeral.pubkey.toRaw()
|
header.pubkey = ephemeral.pubkey.toRaw()
|
||||||
header.iv = iv
|
rng.generate(header[].iv)
|
||||||
|
|
||||||
clear(ephemeral)
|
clear(ephemeral)
|
||||||
|
|
||||||
var so = eciesDataPos()
|
var so = eciesDataPos()
|
||||||
var eo = so + len(input)
|
var eo = so + len(input)
|
||||||
cipher.init(encKey, iv)
|
cipher.init(encKey, header.iv)
|
||||||
cipher.encrypt(input, toOpenArray(output, so, eo))
|
cipher.encrypt(input, toOpenArray(output, so, eo))
|
||||||
burnMem(encKey)
|
burnMem(encKey)
|
||||||
cipher.clear()
|
cipher.clear()
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, hashes, times, algorithm, sets, sequtils, random],
|
std/[tables, hashes, times, algorithm, sets, sequtils, random],
|
||||||
chronos, bearssl, chronicles, stint, nimcrypto/keccak,
|
chronos, chronicles, stint, nimcrypto/keccak,
|
||||||
../keys,
|
../keys,
|
||||||
./enode
|
./enode
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ type
|
||||||
pongFutures: Table[seq[byte], Future[bool]]
|
pongFutures: Table[seq[byte], Future[bool]]
|
||||||
pingFutures: Table[Node, Future[bool]]
|
pingFutures: Table[Node, Future[bool]]
|
||||||
neighboursCallbacks: Table[Node, proc(n: seq[Node]) {.gcsafe, raises: [Defect].}]
|
neighboursCallbacks: Table[Node, proc(n: seq[Node]) {.gcsafe, raises: [Defect].}]
|
||||||
rng: ref BrHmacDrbgContext
|
rng: ref HmacDrbgContext
|
||||||
|
|
||||||
NodeId* = UInt256
|
NodeId* = UInt256
|
||||||
|
|
||||||
|
@ -452,12 +452,7 @@ proc lookup*(k: KademliaProtocol, nodeId: NodeId): Future[seq[Node]] {.async.} =
|
||||||
result = closest
|
result = closest
|
||||||
|
|
||||||
proc lookupRandom*(k: KademliaProtocol): Future[seq[Node]] =
|
proc lookupRandom*(k: KademliaProtocol): Future[seq[Node]] =
|
||||||
var id: NodeId
|
k.lookup(k.rng[].generate(NodeId))
|
||||||
var buf: array[sizeof(id), byte]
|
|
||||||
brHmacDrbgGenerate(k.rng[], buf)
|
|
||||||
copyMem(addr id, addr buf[0], sizeof(id))
|
|
||||||
|
|
||||||
k.lookup(id)
|
|
||||||
|
|
||||||
proc resolve*(k: KademliaProtocol, id: NodeId): Future[Node] {.async.} =
|
proc resolve*(k: KademliaProtocol, id: NodeId): Future[Node] {.async.} =
|
||||||
let closest = await k.lookup(id)
|
let closest = await k.lookup(id)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[deques, tables],
|
std/[deques, tables],
|
||||||
bearssl, chronos,
|
chronos,
|
||||||
stew/results,
|
stew/results,
|
||||||
".."/../[rlp, keys], ".."/../common/eth_types,
|
".."/../[rlp, keys], ".."/../common/eth_types,
|
||||||
".."/[enode, kademlia, discovery, rlpxcrypt]
|
".."/[enode, kademlia, discovery, rlpxcrypt]
|
||||||
|
@ -38,7 +38,7 @@ type
|
||||||
discovery*: DiscoveryProtocol
|
discovery*: DiscoveryProtocol
|
||||||
when useSnappy:
|
when useSnappy:
|
||||||
protocolVersion*: uint
|
protocolVersion*: uint
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref HmacDrbgContext
|
||||||
|
|
||||||
Peer* = ref object
|
Peer* = ref object
|
||||||
remote*: Node
|
remote*: Node
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[algorithm, bitops, math, options, tables, times, hashes],
|
std/[algorithm, bitops, math, options, tables, times, hashes],
|
||||||
chronicles, stew/[byteutils, endians2], metrics, bearssl,
|
chronicles, stew/[byteutils, endians2], metrics,
|
||||||
nimcrypto/[bcmode, hash, keccak, rijndael],
|
nimcrypto/[bcmode, hash, keccak, rijndael],
|
||||||
".."/../../[keys, rlp, p2p], ../../ecies
|
".."/../../[keys, rlp, p2p], ../../ecies
|
||||||
|
|
||||||
|
@ -160,10 +160,8 @@ proc topicBloom*(topic: Topic): Bloom =
|
||||||
doAssert idx <= 511
|
doAssert idx <= 511
|
||||||
result[idx div 8] = result[idx div 8] or byte(1 shl (idx and 7'u16))
|
result[idx div 8] = result[idx div 8] or byte(1 shl (idx and 7'u16))
|
||||||
|
|
||||||
proc generateRandomID*(rng: var BrHmacDrbgContext): string =
|
proc generateRandomID*(rng: var HmacDrbgContext): string =
|
||||||
var bytes: array[256 div 8, byte]
|
toHex(rng.generate(array[256 div 8, byte]))
|
||||||
brHmacDrbgGenerate(rng, bytes)
|
|
||||||
toHex(bytes)
|
|
||||||
|
|
||||||
proc `or`(a, b: Bloom): Bloom =
|
proc `or`(a, b: Bloom): Bloom =
|
||||||
for i in 0..<a.len:
|
for i in 0..<a.len:
|
||||||
|
@ -231,7 +229,7 @@ proc decryptAesGcm(cipher: openArray[byte], key: SymKey): Option[seq[byte]] =
|
||||||
# simply because that makes it closer to EIP 627 - see also:
|
# simply because that makes it closer to EIP 627 - see also:
|
||||||
# https://github.com/paritytech/parity-ethereum/issues/9652
|
# https://github.com/paritytech/parity-ethereum/issues/9652
|
||||||
|
|
||||||
proc encode*(rng: var BrHmacDrbgContext, self: Payload): Option[seq[byte]] =
|
proc encode*(rng: var HmacDrbgContext, self: Payload): Option[seq[byte]] =
|
||||||
## Encode a payload according so as to make it suitable to put in an Envelope
|
## Encode a payload according so as to make it suitable to put in an Envelope
|
||||||
## The format follows EIP 627 - https://eips.ethereum.org/EIPS/eip-627
|
## The format follows EIP 627 - https://eips.ethereum.org/EIPS/eip-627
|
||||||
|
|
||||||
|
@ -284,7 +282,7 @@ proc encode*(rng: var BrHmacDrbgContext, self: Payload): Option[seq[byte]] =
|
||||||
plain.add self.padding.get()
|
plain.add self.padding.get()
|
||||||
else:
|
else:
|
||||||
var padding = newSeq[byte](padLen)
|
var padding = newSeq[byte](padLen)
|
||||||
brHmacDrbgGenerate(rng, padding)
|
rng.generate(padding)
|
||||||
|
|
||||||
plain.add padding
|
plain.add padding
|
||||||
|
|
||||||
|
@ -302,8 +300,7 @@ proc encode*(rng: var BrHmacDrbgContext, self: Payload): Option[seq[byte]] =
|
||||||
return some(res)
|
return some(res)
|
||||||
|
|
||||||
if self.symKey.isSome(): # Symmetric key present - encryption requested
|
if self.symKey.isSome(): # Symmetric key present - encryption requested
|
||||||
var iv: array[gcmIVLen, byte]
|
let iv = rng.generate(array[gcmIVLen, byte])
|
||||||
brHmacDrbgGenerate(rng, iv)
|
|
||||||
|
|
||||||
return some(encryptAesGcm(plain, self.symKey.get(), iv))
|
return some(encryptAesGcm(plain, self.symKey.get(), iv))
|
||||||
|
|
||||||
|
@ -579,7 +576,7 @@ proc initFilter*(src = none[PublicKey](), privateKey = none[PrivateKey](),
|
||||||
powReq: powReq, allowP2P: allowP2P, bloom: toBloom(topics))
|
powReq: powReq, allowP2P: allowP2P, bloom: toBloom(topics))
|
||||||
|
|
||||||
proc subscribeFilter*(
|
proc subscribeFilter*(
|
||||||
rng: var BrHmacDrbgContext, filters: var Filters, filter: Filter,
|
rng: var HmacDrbgContext, filters: var Filters, filter: Filter,
|
||||||
handler: FilterMsgHandler = nil): string =
|
handler: FilterMsgHandler = nil): string =
|
||||||
# NOTE: Should we allow a filter without a key? Encryption is mandatory in v6?
|
# NOTE: Should we allow a filter without a key? Encryption is mandatory in v6?
|
||||||
# Check if asymmetric _and_ symmetric key? Now asymmetric just has precedence.
|
# Check if asymmetric _and_ symmetric key? Now asymmetric just has precedence.
|
||||||
|
|
|
@ -10,10 +10,10 @@ import
|
||||||
std/[monotimes],
|
std/[monotimes],
|
||||||
faststreams,
|
faststreams,
|
||||||
chronos,
|
chronos,
|
||||||
stew/[endians2, results, objects, arrayops], bearssl,
|
stew/[endians2, results, objects, arrayops],
|
||||||
../p2p/discoveryv5/random2
|
../p2p/discoveryv5/random2
|
||||||
|
|
||||||
export results
|
export results, random2
|
||||||
|
|
||||||
const
|
const
|
||||||
minimalHeaderSize = 20
|
minimalHeaderSize = 20
|
||||||
|
@ -80,11 +80,11 @@ proc getMonoTimestamp*(): TimeStampInfo =
|
||||||
TimeStampInfo(moment: currentMoment, timestamp: timestamp)
|
TimeStampInfo(moment: currentMoment, timestamp: timestamp)
|
||||||
|
|
||||||
# Simple generator, not useful for cryptography
|
# Simple generator, not useful for cryptography
|
||||||
proc randUint16*(rng: var BrHmacDrbgContext): uint16 =
|
proc randUint16*(rng: var HmacDrbgContext): uint16 =
|
||||||
uint16(rand(rng, int(high(uint16))))
|
uint16(rand(rng, int(high(uint16))))
|
||||||
|
|
||||||
# Simple generator, not useful for cryptography
|
# Simple generator, not useful for cryptography
|
||||||
proc randUint32*(rng: var BrHmacDrbgContext): uint32 =
|
proc randUint32*(rng: var HmacDrbgContext): uint32 =
|
||||||
uint32(rand(rng, int(high(uint32))))
|
uint32(rand(rng, int(high(uint32))))
|
||||||
|
|
||||||
proc encodeTypeVer(h: PacketHeaderV1): uint8 =
|
proc encodeTypeVer(h: PacketHeaderV1): uint8 =
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, options, hashes, sugar, math],
|
std/[tables, options, hashes, sugar, math],
|
||||||
chronos, chronicles, bearssl,
|
chronos, chronicles,
|
||||||
./utp_router,
|
./utp_router,
|
||||||
../keys
|
../keys
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[tables, options, sugar],
|
std/[tables, options, sugar],
|
||||||
chronos, bearssl, chronicles, metrics,
|
chronos, chronicles, metrics,
|
||||||
../keys,
|
../keys,
|
||||||
./utp_socket,
|
./utp_socket,
|
||||||
./packets
|
./packets
|
||||||
|
@ -56,7 +56,7 @@ type
|
||||||
closed: bool
|
closed: bool
|
||||||
sendCb*: SendCallback[A]
|
sendCb*: SendCallback[A]
|
||||||
allowConnection*: AllowConnectionCallback[A]
|
allowConnection*: AllowConnectionCallback[A]
|
||||||
rng*: ref BrHmacDrbgContext
|
rng*: ref HmacDrbgContext
|
||||||
|
|
||||||
const
|
const
|
||||||
# Maximal number of tries to generate unique socket while establishing
|
# Maximal number of tries to generate unique socket while establishing
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[sugar, deques],
|
std/[sugar, deques],
|
||||||
chronos, chronicles, bearssl,
|
chronos, chronicles,
|
||||||
stew/[results, bitops2],
|
stew/[results, bitops2],
|
||||||
./growable_buffer,
|
./growable_buffer,
|
||||||
./packets,
|
./packets,
|
||||||
|
@ -1880,7 +1880,7 @@ proc newOutgoingSocket*[A](
|
||||||
snd: SendCallback[A],
|
snd: SendCallback[A],
|
||||||
cfg: SocketConfig,
|
cfg: SocketConfig,
|
||||||
rcvConnectionId: uint16,
|
rcvConnectionId: uint16,
|
||||||
rng: var BrHmacDrbgContext
|
rng: var HmacDrbgContext
|
||||||
): UtpSocket[A] =
|
): UtpSocket[A] =
|
||||||
let sndConnectionId = rcvConnectionId + 1
|
let sndConnectionId = rcvConnectionId + 1
|
||||||
let initialSeqNr = randUint16(rng)
|
let initialSeqNr = randUint16(rng)
|
||||||
|
@ -1905,7 +1905,7 @@ proc newIncomingSocket*[A](
|
||||||
cfg: SocketConfig,
|
cfg: SocketConfig,
|
||||||
connectionId: uint16,
|
connectionId: uint16,
|
||||||
ackNr: uint16,
|
ackNr: uint16,
|
||||||
rng: var BrHmacDrbgContext
|
rng: var HmacDrbgContext
|
||||||
): UtpSocket[A] =
|
): UtpSocket[A] =
|
||||||
let initialSeqNr = randUint16(rng)
|
let initialSeqNr = randUint16(rng)
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@ test:
|
||||||
# It is not the best idea to generate extra data and encrypt data but we do
|
# It is not the best idea to generate extra data and encrypt data but we do
|
||||||
# it like this as the decodeHeader proc does decrypt + decode + decrypt.
|
# it like this as the decodeHeader proc does decrypt + decode + decrypt.
|
||||||
# There is no separate decrypt step that can be skipped because of this.
|
# There is no separate decrypt step that can be skipped because of this.
|
||||||
var iv: array[ivSize, byte]
|
let
|
||||||
brHmacDrbgGenerate(rng[], iv)
|
iv = rng[].generate(array[ivSize, byte])
|
||||||
let maskedHeader = encryptHeader(nodeB.id, iv, payload)
|
maskedHeader = encryptHeader(nodeB.id, iv, payload)
|
||||||
|
|
||||||
let decoded = decodePacket(codecB, nodeA.address.get(), @iv & maskedHeader)
|
let decoded = decodePacket(codecB, nodeA.address.get(), @iv & maskedHeader)
|
||||||
if decoded.isErr():
|
if decoded.isErr():
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
unittest2,
|
unittest2,
|
||||||
nimcrypto/hash, nimcrypto/keccak, nimcrypto/utils, bearssl, stew/byteutils,
|
nimcrypto/hash, nimcrypto/keccak, nimcrypto/utils, stew/byteutils,
|
||||||
../../eth/keys
|
../../eth/keys
|
||||||
|
|
||||||
from strutils import toLowerAscii
|
from strutils import toLowerAscii
|
||||||
|
@ -218,8 +218,7 @@ suite "ECC/ECDSA/ECDHE tests suite":
|
||||||
test "ECDSA/100 signatures":
|
test "ECDSA/100 signatures":
|
||||||
# signature test
|
# signature test
|
||||||
for i in 1..100:
|
for i in 1..100:
|
||||||
var m: array[32, byte]
|
let m = rng[].generate(array[32, byte])
|
||||||
brHmacDrbgGenerate(rng[], m)
|
|
||||||
var s = PrivateKey.random(rng[])
|
var s = PrivateKey.random(rng[])
|
||||||
var key = s.toPublicKey()
|
var key = s.toPublicKey()
|
||||||
let sig = sign(s, SkMessage(m))
|
let sig = sign(s, SkMessage(m))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import
|
import
|
||||||
stew/shims/net, bearssl, chronos,
|
stew/shims/net, chronos,
|
||||||
../../eth/keys,
|
../../eth/keys,
|
||||||
../../eth/p2p/discoveryv5/[enr, node, routing_table],
|
../../eth/p2p/discoveryv5/[enr, node, routing_table],
|
||||||
../../eth/p2p/discoveryv5/protocol as discv5_protocol
|
../../eth/p2p/discoveryv5/protocol as discv5_protocol
|
||||||
|
@ -10,7 +10,7 @@ proc localAddress*(port: int): Address =
|
||||||
Address(ip: ValidIpAddress.init("127.0.0.1"), port: Port(port))
|
Address(ip: ValidIpAddress.init("127.0.0.1"), port: Port(port))
|
||||||
|
|
||||||
proc initDiscoveryNode*(
|
proc initDiscoveryNode*(
|
||||||
rng: ref BrHmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
privKey: PrivateKey,
|
privKey: PrivateKey,
|
||||||
address: Address,
|
address: Address,
|
||||||
bootstrapRecords: openArray[Record] = [],
|
bootstrapRecords: openArray[Record] = [],
|
||||||
|
@ -47,14 +47,14 @@ proc generateNode*(privKey: PrivateKey, port: int = 20302,
|
||||||
some(port), some(port), localEnrFields).expect("Properly intialized private key")
|
some(port), some(port), localEnrFields).expect("Properly intialized private key")
|
||||||
result = newNode(enr).expect("Properly initialized node")
|
result = newNode(enr).expect("Properly initialized node")
|
||||||
|
|
||||||
proc generateNRandomNodes*(rng: ref BrHmacDrbgContext, n: int): seq[Node] =
|
proc generateNRandomNodes*(rng: var HmacDrbgContext, n: int): seq[Node] =
|
||||||
var res = newSeq[Node]()
|
var res = newSeq[Node]()
|
||||||
for i in 1..n:
|
for i in 1..n:
|
||||||
let node = generateNode(PrivateKey.random(rng[]))
|
let node = generateNode(PrivateKey.random(rng))
|
||||||
res.add(node)
|
res.add(node)
|
||||||
res
|
res
|
||||||
|
|
||||||
proc nodeAndPrivKeyAtDistance*(n: Node, rng: var BrHmacDrbgContext, d: uint32,
|
proc nodeAndPrivKeyAtDistance*(n: Node, rng: var HmacDrbgContext, d: uint32,
|
||||||
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): (Node, PrivateKey) =
|
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): (Node, PrivateKey) =
|
||||||
while true:
|
while true:
|
||||||
let pk = PrivateKey.random(rng)
|
let pk = PrivateKey.random(rng)
|
||||||
|
@ -62,19 +62,19 @@ proc nodeAndPrivKeyAtDistance*(n: Node, rng: var BrHmacDrbgContext, d: uint32,
|
||||||
if logDistance(n.id, node.id) == d:
|
if logDistance(n.id, node.id) == d:
|
||||||
return (node, pk)
|
return (node, pk)
|
||||||
|
|
||||||
proc nodeAtDistance*(n: Node, rng: var BrHmacDrbgContext, d: uint32,
|
proc nodeAtDistance*(n: Node, rng: var HmacDrbgContext, d: uint32,
|
||||||
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): Node =
|
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): Node =
|
||||||
let (node, _) = n.nodeAndPrivKeyAtDistance(rng, d, ip)
|
let (node, _) = n.nodeAndPrivKeyAtDistance(rng, d, ip)
|
||||||
node
|
node
|
||||||
|
|
||||||
proc nodesAtDistance*(
|
proc nodesAtDistance*(
|
||||||
n: Node, rng: var BrHmacDrbgContext, d: uint32, amount: int,
|
n: Node, rng: var HmacDrbgContext, d: uint32, amount: int,
|
||||||
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): seq[Node] =
|
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): seq[Node] =
|
||||||
for i in 0..<amount:
|
for i in 0..<amount:
|
||||||
result.add(nodeAtDistance(n, rng, d, ip))
|
result.add(nodeAtDistance(n, rng, d, ip))
|
||||||
|
|
||||||
proc nodesAtDistanceUniqueIp*(
|
proc nodesAtDistanceUniqueIp*(
|
||||||
n: Node, rng: var BrHmacDrbgContext, d: uint32, amount: int,
|
n: Node, rng: var HmacDrbgContext, d: uint32, amount: int,
|
||||||
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): seq[Node] =
|
ip: ValidIpAddress = ValidIpAddress.init("127.0.0.1")): seq[Node] =
|
||||||
var ta = initTAddress(ip, Port(0))
|
var ta = initTAddress(ip, Port(0))
|
||||||
for i in 0..<amount:
|
for i in 0..<amount:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import
|
import
|
||||||
std/strutils,
|
std/strutils,
|
||||||
chronos, bearssl,
|
chronos,
|
||||||
../../eth/[keys, p2p], ../../eth/p2p/[discovery, enode]
|
../../eth/[keys, p2p], ../../eth/p2p/[discovery, enode]
|
||||||
|
|
||||||
var nextPort = 30303
|
var nextPort = 30303
|
||||||
|
@ -11,7 +11,7 @@ proc localAddress*(port: int): Address =
|
||||||
ip: parseIpAddress("127.0.0.1"))
|
ip: parseIpAddress("127.0.0.1"))
|
||||||
|
|
||||||
proc setupTestNode*(
|
proc setupTestNode*(
|
||||||
rng: ref BrHmacDrbgContext,
|
rng: ref HmacDrbgContext,
|
||||||
capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode {.gcsafe.} =
|
capabilities: varargs[ProtocolInfo, `protocolInfo`]): EthereumNode {.gcsafe.} =
|
||||||
# Don't create new RNG every time in production code!
|
# Don't create new RNG every time in production code!
|
||||||
let keys1 = KeyPair.random(rng[])
|
let keys1 = KeyPair.random(rng[])
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import
|
import
|
||||||
std/[tables, sequtils],
|
std/[tables, sequtils],
|
||||||
chronos, chronicles, stint, testutils/unittests, stew/shims/net,
|
chronos, chronicles, stint, testutils/unittests, stew/shims/net,
|
||||||
stew/byteutils, bearssl,
|
stew/byteutils,
|
||||||
../../eth/keys,
|
../../eth/keys,
|
||||||
../../eth/p2p/discoveryv5/[enr, node, routing_table, encoding, sessions,
|
../../eth/p2p/discoveryv5/[enr, node, routing_table, encoding, sessions,
|
||||||
messages, nodes_verification],
|
messages, nodes_verification],
|
||||||
|
|
|
@ -456,18 +456,15 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
||||||
check decryptGCM(encryptionKey, nonce, invalidCipher, ad).isNone()
|
check decryptGCM(encryptionKey, nonce, invalidCipher, ad).isNone()
|
||||||
|
|
||||||
test "Encrypt / Decrypt header":
|
test "Encrypt / Decrypt header":
|
||||||
var nonce: AESGCMNonce
|
|
||||||
brHmacDrbgGenerate(rng[], nonce)
|
|
||||||
let
|
let
|
||||||
|
nonce = rng[].generate(AESGCMNonce)
|
||||||
privKey = PrivateKey.random(rng[])
|
privKey = PrivateKey.random(rng[])
|
||||||
nodeId = privKey.toPublicKey().toNodeId()
|
nodeId = privKey.toPublicKey().toNodeId()
|
||||||
authdata = newSeq[byte](32)
|
authdata = newSeq[byte](32)
|
||||||
staticHeader = encodeStaticHeader(Flag.OrdinaryMessage, nonce,
|
staticHeader = encodeStaticHeader(Flag.OrdinaryMessage, nonce,
|
||||||
authdata.len())
|
authdata.len())
|
||||||
header = staticHeader & authdata
|
header = staticHeader & authdata
|
||||||
|
iv = rng[].generate(array[128 div 8, byte])
|
||||||
var iv: array[128 div 8, byte]
|
|
||||||
brHmacDrbgGenerate(rng[], iv)
|
|
||||||
|
|
||||||
let
|
let
|
||||||
encrypted = encryptHeader(nodeId, iv, header)
|
encrypted = encryptHeader(nodeId, iv, header)
|
||||||
|
@ -511,8 +508,7 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
||||||
decoded[].requestNonce == nonce
|
decoded[].requestNonce == nonce
|
||||||
|
|
||||||
test "Encode / Decode Whoareyou Packet":
|
test "Encode / Decode Whoareyou Packet":
|
||||||
var requestNonce: AESGCMNonce
|
let requestNonce = rng[].generate(AESGCMNonce)
|
||||||
brHmacDrbgGenerate(rng[], requestNonce)
|
|
||||||
let recordSeq = 0'u64
|
let recordSeq = 0'u64
|
||||||
|
|
||||||
let data = encodeWhoareyouPacket(rng[], codecA, nodeB.id,
|
let data = encodeWhoareyouPacket(rng[], codecA, nodeB.id,
|
||||||
|
@ -532,9 +528,8 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
||||||
decoded[].whoareyou.recordSeq == recordSeq
|
decoded[].whoareyou.recordSeq == recordSeq
|
||||||
|
|
||||||
test "Encode / Decode Handshake Message Packet":
|
test "Encode / Decode Handshake Message Packet":
|
||||||
var requestNonce: AESGCMNonce
|
|
||||||
brHmacDrbgGenerate(rng[], requestNonce)
|
|
||||||
let
|
let
|
||||||
|
requestNonce = rng[].generate(AESGCMNonce)
|
||||||
recordSeq = 1'u64
|
recordSeq = 1'u64
|
||||||
m = PingMessage(enrSeq: 0)
|
m = PingMessage(enrSeq: 0)
|
||||||
reqId = RequestId.init(rng[])
|
reqId = RequestId.init(rng[])
|
||||||
|
@ -563,9 +558,8 @@ suite "Discovery v5.1 Additional Encode/Decode":
|
||||||
decoded.get().node.isNone()
|
decoded.get().node.isNone()
|
||||||
|
|
||||||
test "Encode / Decode Handshake Message Packet with ENR":
|
test "Encode / Decode Handshake Message Packet with ENR":
|
||||||
var requestNonce: AESGCMNonce
|
|
||||||
brHmacDrbgGenerate(rng[], requestNonce)
|
|
||||||
let
|
let
|
||||||
|
requestNonce = rng[].generate(AESGCMNonce)
|
||||||
recordSeq = 0'u64
|
recordSeq = 0'u64
|
||||||
m = PingMessage(enrSeq: 0)
|
m = PingMessage(enrSeq: 0)
|
||||||
reqId = RequestId.init(rng[])
|
reqId = RequestId.init(rng[])
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
unittest2,
|
unittest2,
|
||||||
bearssl,
|
|
||||||
../../eth/keys, ../../eth/p2p/discoveryv5/[routing_table, node, enr],
|
../../eth/keys, ../../eth/p2p/discoveryv5/[routing_table, node, enr],
|
||||||
./discv5_test_helper
|
./discv5_test_helper
|
||||||
|
|
||||||
|
@ -528,7 +527,7 @@ suite "Routing Table Tests":
|
||||||
var table = RoutingTable.init(local, 1, ipLimits, rng = rng,
|
var table = RoutingTable.init(local, 1, ipLimits, rng = rng,
|
||||||
distanceCalculator = customDistanceCalculator)
|
distanceCalculator = customDistanceCalculator)
|
||||||
|
|
||||||
let nodes = generateNRandomNodes(rng, numNodes)
|
let nodes = generateNRandomNodes(rng[], numNodes)
|
||||||
|
|
||||||
for n in nodes:
|
for n in nodes:
|
||||||
check table.addNode(n) == Added
|
check table.addNode(n) == Added
|
||||||
|
@ -548,7 +547,7 @@ suite "Routing Table Tests":
|
||||||
var table = RoutingTable.init(local, 1, ipLimits, rng = rng,
|
var table = RoutingTable.init(local, 1, ipLimits, rng = rng,
|
||||||
distanceCalculator = customDistanceCalculator)
|
distanceCalculator = customDistanceCalculator)
|
||||||
|
|
||||||
let nodes = generateNRandomNodes(rng, numNodes)
|
let nodes = generateNRandomNodes(rng[], numNodes)
|
||||||
|
|
||||||
for n in nodes:
|
for n in nodes:
|
||||||
check table.addNode(n) == Added
|
check table.addNode(n) == Added
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[sequtils, options, tables],
|
std/[sequtils, options, tables],
|
||||||
chronos, testutils/unittests, bearssl,
|
chronos, testutils/unittests,
|
||||||
../../eth/[keys, p2p], ../../eth/p2p/peer_pool,
|
../../eth/[keys, p2p], ../../eth/p2p/peer_pool,
|
||||||
../../eth/p2p/rlpx_protocols/whisper_protocol,
|
../../eth/p2p/rlpx_protocols/whisper_protocol,
|
||||||
./p2p_test_helper
|
./p2p_test_helper
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/options,
|
std/options,
|
||||||
chronos, bearssl,
|
chronos,
|
||||||
stew/shims/net, stew/byteutils,
|
stew/shims/net, stew/byteutils,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
../../eth/p2p/discoveryv5/[enr, node, routing_table],
|
../../eth/p2p/discoveryv5/[enr, node, routing_table],
|
||||||
|
@ -17,11 +17,6 @@ import
|
||||||
../../eth/keys,
|
../../eth/keys,
|
||||||
../p2p/discv5_test_helper
|
../p2p/discv5_test_helper
|
||||||
|
|
||||||
proc generateByteArray(rng: var BrHmacDrbgContext, length: int): seq[byte] =
|
|
||||||
var bytes = newSeq[byte](length)
|
|
||||||
brHmacDrbgGenerate(rng, bytes)
|
|
||||||
return bytes
|
|
||||||
|
|
||||||
procSuite "Utp protocol over discovery v5 tests":
|
procSuite "Utp protocol over discovery v5 tests":
|
||||||
let rng = newRng()
|
let rng = newRng()
|
||||||
let utpProtId = "test-utp".toBytes()
|
let utpProtId = "test-utp".toBytes()
|
||||||
|
@ -91,7 +86,7 @@ procSuite "Utp protocol over discovery v5 tests":
|
||||||
|
|
||||||
let serverSocket = await queue.get()
|
let serverSocket = await queue.get()
|
||||||
|
|
||||||
let bytesToTransfer = generateByteArray(rng[], numOfBytes)
|
let bytesToTransfer = rng[].generateBytes(numOfBytes)
|
||||||
let written = await clientSocket.write(bytesToTransfer)
|
let written = await clientSocket.write(bytesToTransfer)
|
||||||
|
|
||||||
let received = await serverSocket.read(numOfBytes)
|
let received = await serverSocket.read(numOfBytes)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
sequtils,
|
sequtils,
|
||||||
chronos, bearssl,
|
chronos,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
./test_utils,
|
./test_utils,
|
||||||
../../eth/utp/utp_router,
|
../../eth/utp/utp_router,
|
||||||
|
@ -210,7 +210,7 @@ procSuite "Utp protocol over udp tests":
|
||||||
# Server socket is not in connected state, until first data transfer
|
# Server socket is not in connected state, until first data transfer
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
let bytesToTransfer = generateByteArray(rng[], 100)
|
let bytesToTransfer = rng[].generateBytes(100)
|
||||||
|
|
||||||
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
||||||
|
|
||||||
|
@ -237,7 +237,7 @@ procSuite "Utp protocol over udp tests":
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
# 5000 bytes is over maximal packet size
|
# 5000 bytes is over maximal packet size
|
||||||
let bytesToTransfer = generateByteArray(rng[], 5000)
|
let bytesToTransfer = rng[].generateBytes(5000)
|
||||||
|
|
||||||
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
||||||
let bytesReceivedFromServer = await transferData(s.serverSocket, s.clientSocket, bytesToTransfer)
|
let bytesReceivedFromServer = await transferData(s.serverSocket, s.clientSocket, bytesToTransfer)
|
||||||
|
@ -266,14 +266,14 @@ procSuite "Utp protocol over udp tests":
|
||||||
|
|
||||||
|
|
||||||
# 5000 bytes is over maximal packet size
|
# 5000 bytes is over maximal packet size
|
||||||
let bytesToTransfer = generateByteArray(rng[], 5000)
|
let bytesToTransfer = rng[].generateBytes(5000)
|
||||||
|
|
||||||
let written = await s.clientSocket.write(bytesToTransfer)
|
let written = await s.clientSocket.write(bytesToTransfer)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
written.get() == len(bytesToTransfer)
|
written.get() == len(bytesToTransfer)
|
||||||
|
|
||||||
let bytesToTransfer1 = generateByteArray(rng[], 5000)
|
let bytesToTransfer1 = rng[].generateBytes(5000)
|
||||||
|
|
||||||
let written1 = await s.clientSocket.write(bytesToTransfer1)
|
let written1 = await s.clientSocket.write(bytesToTransfer1)
|
||||||
|
|
||||||
|
@ -301,8 +301,8 @@ procSuite "Utp protocol over udp tests":
|
||||||
s.clientSocket2.numPacketsInOutGoingBuffer() == 0
|
s.clientSocket2.numPacketsInOutGoingBuffer() == 0
|
||||||
|
|
||||||
let numBytesToTransfer = 5000
|
let numBytesToTransfer = 5000
|
||||||
let client1Data = generateByteArray(rng[], numBytesToTransfer)
|
let client1Data = rng[].generateBytes(numBytesToTransfer)
|
||||||
let client2Data = generateByteArray(rng[], numBytesToTransfer)
|
let client2Data = rng[].generateBytes(numBytesToTransfer)
|
||||||
|
|
||||||
discard s.clientSocket1.write(client1Data)
|
discard s.clientSocket1.write(client1Data)
|
||||||
discard s.clientSocket2.write(client2Data)
|
discard s.clientSocket2.write(client2Data)
|
||||||
|
@ -327,7 +327,7 @@ procSuite "Utp protocol over udp tests":
|
||||||
# Server socket is not in connected state, until first data transfer
|
# Server socket is not in connected state, until first data transfer
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
let bytesToTransfer = generateByteArray(rng[], 100)
|
let bytesToTransfer = rng[].generateBytes(100)
|
||||||
|
|
||||||
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
||||||
|
|
||||||
|
@ -362,9 +362,9 @@ procSuite "Utp protocol over udp tests":
|
||||||
# Server socket is not in connected state, until first data transfer
|
# Server socket is not in connected state, until first data transfer
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
let bytesToTransfer1 = generateByteArray(rng[], 1000)
|
let bytesToTransfer1 = rng[].generateBytes(1000)
|
||||||
let bytesToTransfer2 = generateByteArray(rng[], 1000)
|
let bytesToTransfer2 = rng[].generateBytes(1000)
|
||||||
let bytesToTransfer3 = generateByteArray(rng[], 1000)
|
let bytesToTransfer3 = rng[].generateBytes(1000)
|
||||||
|
|
||||||
let w1 = await s.clientSocket.write(bytesToTransfer1)
|
let w1 = await s.clientSocket.write(bytesToTransfer1)
|
||||||
let w2 = await s.clientSocket.write(bytesToTransfer2)
|
let w2 = await s.clientSocket.write(bytesToTransfer2)
|
||||||
|
@ -436,7 +436,7 @@ procSuite "Utp protocol over udp tests":
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
# big transfer of 50kb
|
# big transfer of 50kb
|
||||||
let bytesToTransfer = generateByteArray(rng[], 50000)
|
let bytesToTransfer = rng[].generateBytes(50000)
|
||||||
|
|
||||||
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ procSuite "Utp protocol over udp tests":
|
||||||
(not s.serverSocket.isConnected())
|
(not s.serverSocket.isConnected())
|
||||||
|
|
||||||
# big transfer of 50kb
|
# big transfer of 50kb
|
||||||
let bytesToTransfer = generateByteArray(rng[], 50000)
|
let bytesToTransfer = rng[].generateBytes(50000)
|
||||||
|
|
||||||
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
let bytesReceivedFromClient = await transferData(s.clientSocket, s.serverSocket, bytesToTransfer)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[sequtils, tables, options, sugar],
|
std/[sequtils, tables, options, sugar],
|
||||||
chronos, bearssl,
|
chronos,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
./test_utils,
|
./test_utils,
|
||||||
../../eth/utp/utp_router,
|
../../eth/utp/utp_router,
|
||||||
|
@ -17,7 +17,7 @@ import
|
||||||
../../eth/p2p/discoveryv5/random2
|
../../eth/p2p/discoveryv5/random2
|
||||||
|
|
||||||
|
|
||||||
proc connectTillSuccess(p: UtpProtocol, to: TransportAddress, maxTries: int = 20): Future[UtpSocket[TransportAddress]] {.async.} =
|
proc connectTillSuccess(p: UtpProtocol, to: TransportAddress, maxTries: int = 20): Future[UtpSocket[TransportAddress]] {.async.} =
|
||||||
var i = 0
|
var i = 0
|
||||||
while true:
|
while true:
|
||||||
let res = await p.connectTo(to)
|
let res = await p.connectTo(to)
|
||||||
|
@ -31,7 +31,7 @@ proc connectTillSuccess(p: UtpProtocol, to: TransportAddress, maxTries: int = 20
|
||||||
|
|
||||||
proc buildAcceptConnection(
|
proc buildAcceptConnection(
|
||||||
t: ref Table[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]
|
t: ref Table[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]
|
||||||
): AcceptConnectionCallback[TransportAddress] =
|
): AcceptConnectionCallback[TransportAddress] =
|
||||||
return (
|
return (
|
||||||
proc (server: UtpRouter[TransportAddress], client: UtpSocket[TransportAddress]): Future[void] =
|
proc (server: UtpRouter[TransportAddress], client: UtpSocket[TransportAddress]): Future[void] =
|
||||||
let fut = newFuture[void]()
|
let fut = newFuture[void]()
|
||||||
|
@ -42,7 +42,7 @@ proc buildAcceptConnection(
|
||||||
)
|
)
|
||||||
|
|
||||||
proc getServerSocket(
|
proc getServerSocket(
|
||||||
t: ref Table[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]],
|
t: ref Table[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]],
|
||||||
clientAddress: TransportAddress,
|
clientAddress: TransportAddress,
|
||||||
clientConnectionId: uint16): Option[UtpSocket[TransportAddress]] =
|
clientConnectionId: uint16): Option[UtpSocket[TransportAddress]] =
|
||||||
let serverSocketKey = UtpSocketKey[TransportAddress](remoteAddress: clientAddress, rcvId: clientConnectionId + 1)
|
let serverSocketKey = UtpSocketKey[TransportAddress](remoteAddress: clientAddress, rcvId: clientConnectionId + 1)
|
||||||
|
@ -68,27 +68,27 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
proc testScenario(maxDelay: int, dropRate: int, cfg: SocketConfig = SocketConfig.init()):
|
proc testScenario(maxDelay: int, dropRate: int, cfg: SocketConfig = SocketConfig.init()):
|
||||||
Future[(
|
Future[(
|
||||||
UtpProtocol,
|
UtpProtocol,
|
||||||
UtpSocket[TransportAddress],
|
UtpSocket[TransportAddress],
|
||||||
UtpProtocol,
|
UtpProtocol,
|
||||||
UtpSocket[TransportAddress])
|
UtpSocket[TransportAddress])
|
||||||
] {.async.} =
|
] {.async.} =
|
||||||
|
|
||||||
var connections1 = newTable[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]()
|
var connections1 = newTable[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]()
|
||||||
let address1 = initTAddress("127.0.0.1", 9080)
|
let address1 = initTAddress("127.0.0.1", 9080)
|
||||||
let utpProt1 =
|
let utpProt1 =
|
||||||
UtpProtocol.new(
|
UtpProtocol.new(
|
||||||
buildAcceptConnection(connections1),
|
buildAcceptConnection(connections1),
|
||||||
address1,
|
address1,
|
||||||
socketConfig = cfg,
|
socketConfig = cfg,
|
||||||
sendCallbackBuilder = sendBuilder(maxDelay, dropRate),
|
sendCallbackBuilder = sendBuilder(maxDelay, dropRate),
|
||||||
rng = rng)
|
rng = rng)
|
||||||
|
|
||||||
var connections2 = newTable[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]()
|
var connections2 = newTable[UtpSocketKey[TransportAddress], UtpSocket[TransportAddress]]()
|
||||||
let address2 = initTAddress("127.0.0.1", 9081)
|
let address2 = initTAddress("127.0.0.1", 9081)
|
||||||
let utpProt2 =
|
let utpProt2 =
|
||||||
UtpProtocol.new(
|
UtpProtocol.new(
|
||||||
buildAcceptConnection(connections2),
|
buildAcceptConnection(connections2),
|
||||||
address2,
|
address2,
|
||||||
|
@ -112,9 +112,9 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
cfg: SocketConfig
|
cfg: SocketConfig
|
||||||
|
|
||||||
proc init(
|
proc init(
|
||||||
T: type TestCase,
|
T: type TestCase,
|
||||||
maxDelay: int,
|
maxDelay: int,
|
||||||
dropRate: int,
|
dropRate: int,
|
||||||
bytesToTransfer: int,
|
bytesToTransfer: int,
|
||||||
cfg: SocketConfig = SocketConfig.init(),
|
cfg: SocketConfig = SocketConfig.init(),
|
||||||
bytesPerRead: int = 0): TestCase =
|
bytesPerRead: int = 0): TestCase =
|
||||||
|
@ -138,7 +138,7 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
serverSocket) = await testScenario(testCase.maxDelay, testCase.dropRate, testcase.cfg)
|
serverSocket) = await testScenario(testCase.maxDelay, testCase.dropRate, testcase.cfg)
|
||||||
|
|
||||||
let smallBytes = 10
|
let smallBytes = 10
|
||||||
let smallBytesToTransfer = generateByteArray(rng[], smallBytes)
|
let smallBytesToTransfer = rng[].generateBytes(smallBytes)
|
||||||
# first transfer and read to make server socket connecteced
|
# first transfer and read to make server socket connecteced
|
||||||
let write1 = await clientSocket.write(smallBytesToTransfer)
|
let write1 = await clientSocket.write(smallBytesToTransfer)
|
||||||
let read1 = await serverSocket.read(smallBytes)
|
let read1 = await serverSocket.read(smallBytes)
|
||||||
|
@ -148,11 +148,11 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
read1 == smallBytesToTransfer
|
read1 == smallBytesToTransfer
|
||||||
|
|
||||||
let numBytes = testCase.bytesToTransfer
|
let numBytes = testCase.bytesToTransfer
|
||||||
let bytesToTransfer = generateByteArray(rng[], numBytes)
|
let bytesToTransfer = rng[].generateBytes(numBytes)
|
||||||
|
|
||||||
discard clientSocket.write(bytesToTransfer)
|
discard clientSocket.write(bytesToTransfer)
|
||||||
discard serverSocket.write(bytesToTransfer)
|
discard serverSocket.write(bytesToTransfer)
|
||||||
|
|
||||||
let serverReadFut = serverSocket.read(numBytes)
|
let serverReadFut = serverSocket.read(numBytes)
|
||||||
let clientReadFut = clientSocket.read(numBytes)
|
let clientReadFut = clientSocket.read(numBytes)
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
check:
|
check:
|
||||||
clientRead == bytesToTransfer
|
clientRead == bytesToTransfer
|
||||||
serverRead == bytesToTransfer
|
serverRead == bytesToTransfer
|
||||||
|
|
||||||
await clientProtocol.shutdownWait()
|
await clientProtocol.shutdownWait()
|
||||||
await serverProtocol.shutdownWait()
|
await serverProtocol.shutdownWait()
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
res.add(bytes)
|
res.add(bytes)
|
||||||
inc i
|
inc i
|
||||||
return res
|
return res
|
||||||
|
|
||||||
asyncTest "Write and Read large data in different network conditions split over several reads":
|
asyncTest "Write and Read large data in different network conditions split over several reads":
|
||||||
for testCase in testCases1:
|
for testCase in testCases1:
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
serverSocket) = await testScenario(testCase.maxDelay, testCase.dropRate, testcase.cfg)
|
serverSocket) = await testScenario(testCase.maxDelay, testCase.dropRate, testcase.cfg)
|
||||||
|
|
||||||
let smallBytes = 10
|
let smallBytes = 10
|
||||||
let smallBytesToTransfer = generateByteArray(rng[], smallBytes)
|
let smallBytesToTransfer = rng[].generateBytes(smallBytes)
|
||||||
# first transfer and read to make server socket connecteced
|
# first transfer and read to make server socket connecteced
|
||||||
let write1 = await clientSocket.write(smallBytesToTransfer)
|
let write1 = await clientSocket.write(smallBytesToTransfer)
|
||||||
let read1 = await serverSocket.read(smallBytes)
|
let read1 = await serverSocket.read(smallBytes)
|
||||||
|
@ -204,11 +204,11 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
read1 == smallBytesToTransfer
|
read1 == smallBytesToTransfer
|
||||||
|
|
||||||
let numBytes = testCase.bytesToTransfer
|
let numBytes = testCase.bytesToTransfer
|
||||||
let bytesToTransfer = generateByteArray(rng[], numBytes)
|
let bytesToTransfer = rng[].generateBytes(numBytes)
|
||||||
|
|
||||||
discard clientSocket.write(bytesToTransfer)
|
discard clientSocket.write(bytesToTransfer)
|
||||||
discard serverSocket.write(bytesToTransfer)
|
discard serverSocket.write(bytesToTransfer)
|
||||||
|
|
||||||
let numOfReads = int(testCase.bytesToTransfer / testCase.bytesPerRead)
|
let numOfReads = int(testCase.bytesToTransfer / testCase.bytesPerRead)
|
||||||
let serverReadFut = serverSocket.readWithMultipleReads(numOfReads, testCase.bytesPerRead)
|
let serverReadFut = serverSocket.readWithMultipleReads(numOfReads, testCase.bytesPerRead)
|
||||||
let clientReadFut = clientSocket.readWithMultipleReads(numOfReads, testCase.bytesPerRead)
|
let clientReadFut = clientSocket.readWithMultipleReads(numOfReads, testCase.bytesPerRead)
|
||||||
|
@ -244,7 +244,7 @@ procSuite "Utp protocol over udp tests with loss and delays":
|
||||||
|
|
||||||
|
|
||||||
let numBytes = testCase.bytesToTransfer
|
let numBytes = testCase.bytesToTransfer
|
||||||
let bytesToTransfer = generateByteArray(rng[], numBytes)
|
let bytesToTransfer = rng[].generateBytes(numBytes)
|
||||||
|
|
||||||
discard await clientSocket.write(bytesToTransfer)
|
discard await clientSocket.write(bytesToTransfer)
|
||||||
clientSocket.close()
|
clientSocket.close()
|
||||||
|
|
|
@ -9,11 +9,6 @@ type AssertionCallback = proc(): bool {.gcsafe, raises: [Defect].}
|
||||||
let testBufferSize = 1024'u32
|
let testBufferSize = 1024'u32
|
||||||
let defaultRcvOutgoingId = 314'u16
|
let defaultRcvOutgoingId = 314'u16
|
||||||
|
|
||||||
proc generateByteArray*(rng: var BrHmacDrbgContext, length: int): seq[byte] =
|
|
||||||
var bytes = newSeq[byte](length)
|
|
||||||
brHmacDrbgGenerate(rng, bytes)
|
|
||||||
return bytes
|
|
||||||
|
|
||||||
proc waitUntil*(f: AssertionCallback): Future[void] {.async.} =
|
proc waitUntil*(f: AssertionCallback): Future[void] {.async.} =
|
||||||
while true:
|
while true:
|
||||||
let res = f()
|
let res = f()
|
||||||
|
@ -65,7 +60,7 @@ template connectOutGoingSocketWithIncoming*(
|
||||||
|
|
||||||
let incomingSocket = newIncomingSocket[TransportAddress](
|
let incomingSocket = newIncomingSocket[TransportAddress](
|
||||||
testAddress,
|
testAddress,
|
||||||
initTestSnd(incomingQueue),
|
initTestSnd(incomingQueue),
|
||||||
cfg,
|
cfg,
|
||||||
initialPacket.header.connectionId,
|
initialPacket.header.connectionId,
|
||||||
initialPacket.header.seqNr,
|
initialPacket.header.seqNr,
|
||||||
|
@ -77,9 +72,9 @@ template connectOutGoingSocketWithIncoming*(
|
||||||
let responseAck = await incomingQueue.get()
|
let responseAck = await incomingQueue.get()
|
||||||
|
|
||||||
await outgoingSocket.processPacket(responseAck)
|
await outgoingSocket.processPacket(responseAck)
|
||||||
|
|
||||||
await waitUntil(proc (): bool = outgoingSocket.isConnected())
|
await waitUntil(proc (): bool = outgoingSocket.isConnected())
|
||||||
|
|
||||||
check:
|
check:
|
||||||
outgoingSocket.isConnected()
|
outgoingSocket.isConnected()
|
||||||
|
|
||||||
|
@ -91,7 +86,7 @@ proc generateDataPackets*(
|
||||||
initialSeqNr: uint16,
|
initialSeqNr: uint16,
|
||||||
connectionId: uint16,
|
connectionId: uint16,
|
||||||
ackNr: uint16,
|
ackNr: uint16,
|
||||||
rng: var BrHmacDrbgContext): seq[Packet] =
|
rng: var HmacDrbgContext): seq[Packet] =
|
||||||
let packetSize = 100
|
let packetSize = 100
|
||||||
var packets = newSeq[Packet]()
|
var packets = newSeq[Packet]()
|
||||||
var i = 0'u16
|
var i = 0'u16
|
||||||
|
@ -101,7 +96,7 @@ proc generateDataPackets*(
|
||||||
connectionId,
|
connectionId,
|
||||||
ackNr,
|
ackNr,
|
||||||
testBufferSize,
|
testBufferSize,
|
||||||
generateByteArray(rng, packetSize),
|
rng.generateBytes(packetSize),
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
packets.add(packet)
|
packets.add(packet)
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[hashes, options],
|
std/[hashes, options],
|
||||||
chronos, bearssl, chronicles,
|
chronos, chronicles,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
./test_utils,
|
./test_utils,
|
||||||
../../eth/utp/utp_router,
|
../../eth/utp/utp_router,
|
||||||
|
@ -313,7 +313,7 @@ procSuite "Utp router unit tests":
|
||||||
let connectResult = await connectFuture
|
let connectResult = await connectFuture
|
||||||
|
|
||||||
await waitUntil(proc (): bool = router.len() == 0)
|
await waitUntil(proc (): bool = router.len() == 0)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
connectResult.isErr()
|
connectResult.isErr()
|
||||||
connectResult.error().kind == ConnectionTimedOut
|
connectResult.error().kind == ConnectionTimedOut
|
||||||
|
@ -356,7 +356,7 @@ procSuite "Utp router unit tests":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
connectResult.isErr()
|
connectResult.isErr()
|
||||||
# even though send is failing we will just finish with timeout,
|
# even though send is failing we will just finish with timeout,
|
||||||
connectResult.error().kind == ConnectionTimedOut
|
connectResult.error().kind == ConnectionTimedOut
|
||||||
router.len() == 0
|
router.len() == 0
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[algorithm, random, sequtils, options],
|
std/[algorithm, random, sequtils, options],
|
||||||
chronos, bearssl, chronicles,
|
chronos, chronicles,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
./test_utils,
|
./test_utils,
|
||||||
../../eth/utp/utp_router,
|
../../eth/utp/utp_router,
|
||||||
|
@ -186,7 +186,7 @@ procSuite "Utp socket unit test":
|
||||||
await outgoingSocket.processPacket(p)
|
await outgoingSocket.processPacket(p)
|
||||||
|
|
||||||
var sentAcks: seq[Packet] = @[]
|
var sentAcks: seq[Packet] = @[]
|
||||||
|
|
||||||
for i in 0'u16..<numOfPackets:
|
for i in 0'u16..<numOfPackets:
|
||||||
let ack = await q.get()
|
let ack = await q.get()
|
||||||
sentAcks.add(ack)
|
sentAcks.add(ack)
|
||||||
|
@ -238,7 +238,7 @@ procSuite "Utp socket unit test":
|
||||||
await outgoingSocket.processPacket(p)
|
await outgoingSocket.processPacket(p)
|
||||||
|
|
||||||
var sentAcks: seq[Packet] = @[]
|
var sentAcks: seq[Packet] = @[]
|
||||||
|
|
||||||
for i in 0'u16..<numOfPackets:
|
for i in 0'u16..<numOfPackets:
|
||||||
let ack = await q.get()
|
let ack = await q.get()
|
||||||
sentAcks.add(ack)
|
sentAcks.add(ack)
|
||||||
|
@ -378,7 +378,7 @@ procSuite "Utp socket unit test":
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
|
|
||||||
# lot of data which will generate at least 5 packets
|
# lot of data which will generate at least 5 packets
|
||||||
let bigDataTowWrite = generateByteArray(rng[], 10000)
|
let bigDataTowWrite = rng[].generateBytes(10000)
|
||||||
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q)
|
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q)
|
||||||
|
|
||||||
let acker = outgoingSocket.ackAllPacket(q, initialRemoteSeq)
|
let acker = outgoingSocket.ackAllPacket(q, initialRemoteSeq)
|
||||||
|
@ -389,7 +389,7 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
await waitUntil(proc (): bool = outgoingSocket.numPacketsInOutGoingBuffer() == 0)
|
await waitUntil(proc (): bool = outgoingSocket.numPacketsInOutGoingBuffer() == 0)
|
||||||
|
|
||||||
let maxWindowAfterSuccesfulSends = outgoingSocket.currentMaxWindowSize()
|
let maxWindowAfterSuccesfulSends = outgoingSocket.currentMaxWindowSize()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
# after processing a lot of data, our window size should be a lot bigger than our packet size
|
# after processing a lot of data, our window size should be a lot bigger than our packet size
|
||||||
|
@ -397,9 +397,9 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
# cancel acking process, next writes will for sure timeout
|
# cancel acking process, next writes will for sure timeout
|
||||||
await acker.cancelAndWait()
|
await acker.cancelAndWait()
|
||||||
|
|
||||||
# data which fits one packet and will timeout
|
# data which fits one packet and will timeout
|
||||||
let smallerData = generateByteArray(rng[], 100)
|
let smallerData = rng[].generateBytes(100)
|
||||||
|
|
||||||
let bytesWritten1 = await outgoingSocket.write(smallerData)
|
let bytesWritten1 = await outgoingSocket.write(smallerData)
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
# ignore also first re-send
|
# ignore also first re-send
|
||||||
discard await q.get()
|
discard await q.get()
|
||||||
|
|
||||||
let maxWindowAfterTimeout = outgoingSocket.currentMaxWindowSize()
|
let maxWindowAfterTimeout = outgoingSocket.currentMaxWindowSize()
|
||||||
|
|
||||||
check:
|
check:
|
||||||
|
@ -1059,7 +1059,7 @@ procSuite "Utp socket unit test":
|
||||||
let q = newAsyncQueue[Packet]()
|
let q = newAsyncQueue[Packet]()
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
|
|
||||||
let dataToWrite = generateByteArray(rng[], 1001)
|
let dataToWrite = rng[].generateBytes(1001)
|
||||||
|
|
||||||
# remote is initialized with buffer to small to handle whole payload
|
# remote is initialized with buffer to small to handle whole payload
|
||||||
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q, cfg = SocketConfig.init(optSndBuffer = 1000))
|
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q, cfg = SocketConfig.init(optSndBuffer = 1000))
|
||||||
|
@ -1101,7 +1101,7 @@ procSuite "Utp socket unit test":
|
||||||
# remote is initialized with buffer to small to handle whole payload
|
# remote is initialized with buffer to small to handle whole payload
|
||||||
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q, cfg = SocketConfig.init(optSndBuffer = 1160))
|
let (outgoingSocket, initialPacket) = connectOutGoingSocket(initialRemoteSeq, q, cfg = SocketConfig.init(optSndBuffer = 1160))
|
||||||
|
|
||||||
let twoPacketData = generateByteArray(rng[], int(dataToWirte))
|
let twoPacketData = rng[].generateBytes(int(dataToWirte))
|
||||||
|
|
||||||
let writeResult = await outgoingSocket.write(twoPacketData)
|
let writeResult = await outgoingSocket.write(twoPacketData)
|
||||||
|
|
||||||
|
@ -1140,7 +1140,7 @@ procSuite "Utp socket unit test":
|
||||||
# we are using ack from remote to setup our snd window size to one packet size on one packet
|
# we are using ack from remote to setup our snd window size to one packet size on one packet
|
||||||
await outgoingSocket.processPacket(someAckFromRemote)
|
await outgoingSocket.processPacket(someAckFromRemote)
|
||||||
|
|
||||||
let twoPacketData = generateByteArray(rng[], int(2 * remoteRcvWindowSize))
|
let twoPacketData = rng[].generateBytes(int(2 * remoteRcvWindowSize))
|
||||||
|
|
||||||
let writeFut = outgoingSocket.write(twoPacketData)
|
let writeFut = outgoingSocket.write(twoPacketData)
|
||||||
|
|
||||||
|
@ -1197,7 +1197,7 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
# write result will be successfull as send buffer has space
|
# write result will be successfull as send buffer has space
|
||||||
let writeResult = await outgoingSocket.write(someData)
|
let writeResult = await outgoingSocket.write(someData)
|
||||||
|
|
||||||
# this will finish in seconds(3) as only after this time window will be set to min value
|
# this will finish in seconds(3) as only after this time window will be set to min value
|
||||||
let p = await q.get()
|
let p = await q.get()
|
||||||
|
|
||||||
|
@ -1356,7 +1356,7 @@ procSuite "Utp socket unit test":
|
||||||
|
|
||||||
let writeRes1 = await outgoingSocket.write(dataToWrite1)
|
let writeRes1 = await outgoingSocket.write(dataToWrite1)
|
||||||
let writeRes2 = await outgoingSocket.write(dataToWrite2)
|
let writeRes2 = await outgoingSocket.write(dataToWrite2)
|
||||||
let writeRes3 = await outgoingSocket.write(dataToWrite3)
|
let writeRes3 = await outgoingSocket.write(dataToWrite3)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
writeRes1.isOk()
|
writeRes1.isOk()
|
||||||
|
@ -1529,7 +1529,7 @@ procSuite "Utp socket unit test":
|
||||||
asyncTest "Maximum payload size should be configurable":
|
asyncTest "Maximum payload size should be configurable":
|
||||||
let q = newAsyncQueue[Packet]()
|
let q = newAsyncQueue[Packet]()
|
||||||
let initalRemoteSeqNr = 10'u16
|
let initalRemoteSeqNr = 10'u16
|
||||||
let d = generateByteArray(rng[], 5000)
|
let d = rng[].generateBytes(5000)
|
||||||
let maxPayloadSize = 800'u32
|
let maxPayloadSize = 800'u32
|
||||||
let config = SocketConfig.init(payloadSize = maxPayloadSize)
|
let config = SocketConfig.init(payloadSize = maxPayloadSize)
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
import
|
import
|
||||||
std/[options, sequtils],
|
std/[options, sequtils],
|
||||||
chronos, bearssl, chronicles,
|
chronos, chronicles,
|
||||||
stew/bitops2,
|
stew/bitops2,
|
||||||
testutils/unittests,
|
testutils/unittests,
|
||||||
./test_utils,
|
./test_utils,
|
||||||
|
@ -62,7 +62,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
numOfSetBits = numOfSetBits + countOnes(b)
|
numOfSetBits = numOfSetBits + countOnes(b)
|
||||||
return numOfSetBits
|
return numOfSetBits
|
||||||
|
|
||||||
proc hasOnlyOneBitSet(arr: openArray[byte]): bool =
|
proc hasOnlyOneBitSet(arr: openArray[byte]): bool =
|
||||||
return numOfSetBits(arr) == 1
|
return numOfSetBits(arr) == 1
|
||||||
|
|
||||||
asyncTest "Socket with empty buffer should generate array with only zeros":
|
asyncTest "Socket with empty buffer should generate array with only zeros":
|
||||||
|
@ -75,7 +75,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
|
|
||||||
check:
|
check:
|
||||||
extArray == [0'u8, 0, 0, 0]
|
extArray == [0'u8, 0, 0, 0]
|
||||||
|
|
||||||
asyncTest "Socket should generate correct bit mask for each missing packet":
|
asyncTest "Socket should generate correct bit mask for each missing packet":
|
||||||
# 1 means that received packet is packet just after expected packet i.e
|
# 1 means that received packet is packet just after expected packet i.e
|
||||||
# packet.seqNr - receivingSocket.ackNr = 2
|
# packet.seqNr - receivingSocket.ackNr = 2
|
||||||
|
@ -113,7 +113,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
let bitMask = await connectAndProcessMissingPacketWithIndexes(missingIndexes)
|
let bitMask = await connectAndProcessMissingPacketWithIndexes(missingIndexes)
|
||||||
check:
|
check:
|
||||||
numOfSetBits(bitMask) == len(missingIndexes)
|
numOfSetBits(bitMask) == len(missingIndexes)
|
||||||
|
|
||||||
for idx in missingIndexes:
|
for idx in missingIndexes:
|
||||||
check:
|
check:
|
||||||
getBit(bitMask, idx - 1)
|
getBit(bitMask, idx - 1)
|
||||||
|
@ -128,7 +128,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
check:
|
check:
|
||||||
numOfSetBits(bitMask) == 32
|
numOfSetBits(bitMask) == 32
|
||||||
len(bitMask) == 4
|
len(bitMask) == 4
|
||||||
|
|
||||||
type TestCase = object
|
type TestCase = object
|
||||||
# number of packet to generate by writitng side
|
# number of packet to generate by writitng side
|
||||||
numOfPackets: int
|
numOfPackets: int
|
||||||
|
@ -155,7 +155,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
outgoingQueue: AsyncQueue[Packet],
|
outgoingQueue: AsyncQueue[Packet],
|
||||||
incomingQueue: AsyncQueue[Packet],
|
incomingQueue: AsyncQueue[Packet],
|
||||||
testCase: TestCase): Future[(UtpSocket[TransportAddress], UtpSocket[TransportAddress], seq[Packet])] {.async.} =
|
testCase: TestCase): Future[(UtpSocket[TransportAddress], UtpSocket[TransportAddress], seq[Packet])] {.async.} =
|
||||||
let (outgoingSocket, incomingSocket) =
|
let (outgoingSocket, incomingSocket) =
|
||||||
connectOutGoingSocketWithIncoming(
|
connectOutGoingSocketWithIncoming(
|
||||||
initialRemoteSeq,
|
initialRemoteSeq,
|
||||||
outgoingQueue,
|
outgoingQueue,
|
||||||
|
@ -168,7 +168,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
discard await outgoingSocket.write(dataToWrite)
|
discard await outgoingSocket.write(dataToWrite)
|
||||||
let packet = await outgoingQueue.get()
|
let packet = await outgoingQueue.get()
|
||||||
packets.add(packet)
|
packets.add(packet)
|
||||||
|
|
||||||
for toDeliver in testCase.packetsDelivered:
|
for toDeliver in testCase.packetsDelivered:
|
||||||
await incomingSocket.processPacket(packets[toDeliver])
|
await incomingSocket.processPacket(packets[toDeliver])
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
asyncTest "Socket should calculate number of bytes acked by selective acks":
|
asyncTest "Socket should calculate number of bytes acked by selective acks":
|
||||||
let dataSize = 10
|
let dataSize = 10
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
let smallData = generateByteArray(rng[], 10)
|
let smallData = rng[].generateBytes(10)
|
||||||
|
|
||||||
for testCase in selectiveAckTestCases:
|
for testCase in selectiveAckTestCases:
|
||||||
let outgoingQueue = newAsyncQueue[Packet]()
|
let outgoingQueue = newAsyncQueue[Packet]()
|
||||||
|
@ -209,7 +209,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
|
|
||||||
let ackedBytes = outgoingSocket.calculateSelectiveAckBytes(finalAck.header.ackNr, finalAck.eack.unsafeGet())
|
let ackedBytes = outgoingSocket.calculateSelectiveAckBytes(finalAck.header.ackNr, finalAck.eack.unsafeGet())
|
||||||
|
|
||||||
check:
|
check:
|
||||||
int(ackedBytes) == len(testCase.packetsDelivered) * dataSize
|
int(ackedBytes) == len(testCase.packetsDelivered) * dataSize
|
||||||
|
|
||||||
await outgoingSocket.destroyWait()
|
await outgoingSocket.destroyWait()
|
||||||
|
@ -218,12 +218,12 @@ procSuite "Utp socket selective acks unit test":
|
||||||
asyncTest "Socket should ack packets based on selective ack packet":
|
asyncTest "Socket should ack packets based on selective ack packet":
|
||||||
let dataSize = 10
|
let dataSize = 10
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
let smallData = generateByteArray(rng[], 10)
|
let smallData = rng[].generateBytes(10)
|
||||||
|
|
||||||
for testCase in selectiveAckTestCases:
|
for testCase in selectiveAckTestCases:
|
||||||
let outgoingQueue = newAsyncQueue[Packet]()
|
let outgoingQueue = newAsyncQueue[Packet]()
|
||||||
let incomingQueue = newAsyncQueue[Packet]()
|
let incomingQueue = newAsyncQueue[Packet]()
|
||||||
|
|
||||||
let (outgoingSocket, incomingSocket, _) = await setupTestCase(
|
let (outgoingSocket, incomingSocket, _) = await setupTestCase(
|
||||||
smallData,
|
smallData,
|
||||||
initialRemoteSeq,
|
initialRemoteSeq,
|
||||||
|
@ -252,8 +252,8 @@ procSuite "Utp socket selective acks unit test":
|
||||||
await outgoingSocket.processPacket(finalAck)
|
await outgoingSocket.processPacket(finalAck)
|
||||||
|
|
||||||
let expectedPackets = testCase.numOfPackets - len(testCase.packetsDelivered)
|
let expectedPackets = testCase.numOfPackets - len(testCase.packetsDelivered)
|
||||||
|
|
||||||
await waitUntil(proc (): bool = outgoingSocket.numPacketsInOutGoingBuffer() == expectedPackets)
|
await waitUntil(proc (): bool = outgoingSocket.numPacketsInOutGoingBuffer() == expectedPackets)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
outgoingSocket.numPacketsInOutGoingBuffer() == expectedPackets
|
outgoingSocket.numPacketsInOutGoingBuffer() == expectedPackets
|
||||||
|
@ -276,7 +276,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
asyncTest "Socket should re-send packets when there are at least 3 packets acked ahead":
|
asyncTest "Socket should re-send packets when there are at least 3 packets acked ahead":
|
||||||
let dataSize = 10
|
let dataSize = 10
|
||||||
let initialRemoteSeq = 10'u16
|
let initialRemoteSeq = 10'u16
|
||||||
let smallData = generateByteArray(rng[], 10)
|
let smallData = rng[].generateBytes(10)
|
||||||
|
|
||||||
for testCase in packetResendTestCases:
|
for testCase in packetResendTestCases:
|
||||||
let outgoingQueue = newAsyncQueue[Packet]()
|
let outgoingQueue = newAsyncQueue[Packet]()
|
||||||
|
@ -314,7 +314,7 @@ procSuite "Utp socket selective acks unit test":
|
||||||
resentPacket.header.seqNr == initialPackets[idx].header.seqNr
|
resentPacket.header.seqNr == initialPackets[idx].header.seqNr
|
||||||
|
|
||||||
let endBufferSize = outgoingSocket.currentMaxWindowSize()
|
let endBufferSize = outgoingSocket.currentMaxWindowSize()
|
||||||
|
|
||||||
if len(testCase.packetsResent) == 0:
|
if len(testCase.packetsResent) == 0:
|
||||||
check:
|
check:
|
||||||
# when there is no packet loss (no resent packets), buffer size increases
|
# when there is no packet loss (no resent packets), buffer size increases
|
||||||
|
|
Loading…
Reference in New Issue