2021-04-28 14:20:05 +00:00
|
|
|
# nim-eth - Node Discovery Protocol v5
|
|
|
|
# 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.
|
|
|
|
#
|
2021-02-02 21:47:21 +00:00
|
|
|
## Session cache as mentioned at
|
|
|
|
## https://github.com/ethereum/devp2p/blob/master/discv5/discv5-theory.md#session-cache
|
|
|
|
##
|
2021-04-28 14:20:05 +00:00
|
|
|
|
|
|
|
{.push raises: [Defect].}
|
|
|
|
|
2020-09-10 12:49:48 +00:00
|
|
|
import
|
|
|
|
std/options,
|
|
|
|
stint, stew/endians2, stew/shims/net,
|
2021-02-02 21:47:21 +00:00
|
|
|
node, lru
|
2020-09-10 12:49:48 +00:00
|
|
|
|
|
|
|
export lru
|
|
|
|
|
2021-02-02 21:47:21 +00:00
|
|
|
const
|
|
|
|
aesKeySize* = 128 div 8
|
|
|
|
keySize = sizeof(NodeId) +
|
|
|
|
16 + # max size of ip address (ipv6)
|
|
|
|
2 # Sizeof port
|
2020-09-10 12:49:48 +00:00
|
|
|
|
|
|
|
type
|
2021-02-02 21:47:21 +00:00
|
|
|
AesKey* = array[aesKeySize, byte]
|
2020-09-10 12:49:48 +00:00
|
|
|
SessionKey* = array[keySize, byte]
|
|
|
|
SessionValue* = array[sizeof(AesKey) + sizeof(AesKey), byte]
|
|
|
|
Sessions* = LRUCache[SessionKey, SessionValue]
|
|
|
|
|
2021-02-02 21:47:21 +00:00
|
|
|
func makeKey(id: NodeId, address: Address): SessionKey =
|
2020-09-10 12:49:48 +00:00
|
|
|
var pos = 0
|
|
|
|
result[pos ..< pos+sizeof(id)] = toBytes(id)
|
|
|
|
pos.inc(sizeof(id))
|
|
|
|
case address.ip.family
|
|
|
|
of IpAddressFamily.IpV4:
|
|
|
|
result[pos ..< pos+sizeof(address.ip.address_v4)] = address.ip.address_v4
|
|
|
|
of IpAddressFamily.IpV6:
|
|
|
|
result[pos ..< pos+sizeof(address.ip.address_v6)] = address.ip.address_v6
|
|
|
|
pos.inc(sizeof(address.ip.address_v6))
|
|
|
|
result[pos ..< pos+sizeof(address.port)] = toBytes(address.port.uint16)
|
|
|
|
|
2021-02-02 21:47:21 +00:00
|
|
|
func store*(s: var Sessions, id: NodeId, address: Address, r, w: AesKey) =
|
2020-09-10 12:49:48 +00:00
|
|
|
var value: array[sizeof(r) + sizeof(w), byte]
|
|
|
|
value[0 .. 15] = r
|
|
|
|
value[16 .. ^1] = w
|
|
|
|
s.put(makeKey(id, address), value)
|
|
|
|
|
2021-02-02 21:47:21 +00:00
|
|
|
func load*(s: var Sessions, id: NodeId, address: Address, r, w: var AesKey): bool =
|
2020-09-10 12:49:48 +00:00
|
|
|
let res = s.get(makeKey(id, address))
|
|
|
|
if res.isSome():
|
|
|
|
let val = res.get()
|
|
|
|
copyMem(addr r[0], unsafeAddr val[0], sizeof(r))
|
|
|
|
copyMem(addr w[0], unsafeAddr val[sizeof(r)], sizeof(w))
|
|
|
|
return true
|
|
|
|
else:
|
|
|
|
return false
|
|
|
|
|
2021-02-02 21:47:21 +00:00
|
|
|
func del*(s: var Sessions, id: NodeId, address: Address) =
|
2020-09-10 12:49:48 +00:00
|
|
|
s.del(makeKey(id, address))
|