Skip to content
This repository was archived by the owner on Jan 30, 2026. It is now read-only.

Commit 7c5adfc

Browse files
committed
fix: ensure destination and exit nodes are not selected as part of SURBs path
1 parent e45cd05 commit 7c5adfc

File tree

1 file changed

+17
-25
lines changed

1 file changed

+17
-25
lines changed

mix/mix_protocol.nim

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ proc buildSurbs(
359359
mixProto: MixProtocol,
360360
incoming: AsyncQueue[seq[byte]],
361361
numSurbs: uint8,
362+
destPeerId: PeerId,
362363
exitPeerId: PeerId,
363364
): Result[seq[SURB], string] =
364365
var response: seq[SURB]
@@ -373,32 +374,23 @@ proc buildSurbs(
373374
hops: seq[Hop] = @[]
374375
delay: seq[seq[byte]] = @[]
375376

376-
# Select L mix nodes at random
377-
let numMixNodes = mixProto.pubNodeInfo.len
378-
379377
if mixProto.pubNodeInfo.len < L:
380378
return err("No. of public mix nodes less than path length")
381379

382-
var
383-
pubNodeInfoKeys = toSeq(mixProto.pubNodeInfo.keys)
384-
randPeerId: PeerId
385-
availableIndices = toSeq(0 ..< numMixNodes)
386-
387-
# Remove exit node from nodes to consider for surbs
388-
let index = pubNodeInfoKeys.find(exitPeerId)
389-
if index != -1:
390-
availableIndices.del(index)
391-
else:
392-
return err("could not find exit node")
380+
# Remove exit and dest node from nodes to consider for surbs
381+
var pubNodeInfoKeys =
382+
mixProto.pubNodeInfo.keys.toSeq().filterIt(it != exitPeerId and it != destPeerId)
383+
var availableIndices = toSeq(0 ..< pubNodeInfoKeys.len)
393384

385+
# Select L mix nodes at random
394386
var i = 0
395387
while i < L:
396388
let (multiAddr, mixPubKey, delayMillisec) =
397389
if i < L - 1:
398390
let randomIndexPosition = cryptoRandomInt(availableIndices.len).valueOr:
399391
return err("failed to generate random num: " & error)
400392
let selectedIndex = availableIndices[randomIndexPosition]
401-
randPeerId = pubNodeInfoKeys[selectedIndex]
393+
let randPeerId = pubNodeInfoKeys[selectedIndex]
402394
availableIndices.del(randomIndexPosition)
403395
debug "Selected mix node for surbs: ", indexInPath = i, peerId = randPeerId
404396
let mixPubInfo = getMixPubInfo(mixProto.pubNodeInfo.getOrDefault(randPeerId))
@@ -441,9 +433,10 @@ proc prepareMsgWithSurbs(
441433
incoming: AsyncQueue[seq[byte]],
442434
msg: seq[byte],
443435
numSurbs: uint8 = 0,
436+
destPeerId: PeerId,
444437
exitPeerId: PeerId,
445438
): Result[seq[byte], string] =
446-
let surbs = mixProto.buildSurbs(incoming, numSurbs, exitPeerId).valueOr:
439+
let surbs = mixProto.buildSurbs(incoming, numSurbs, destPeerId, exitPeerId).valueOr:
447440
return err(error)
448441

449442
let serialized = ?serializeMessageWithSURBs(msg, surbs)
@@ -594,10 +587,10 @@ proc anonymizeLocalProtocolSend*(
594587
mix_messages_error.inc(labelValues = ["Entry", "LOW_MIX_POOL"])
595588
return
596589

597-
var
598-
pubNodeInfoKeys = toSeq(mixProto.pubNodeInfo.keys)
599-
randPeerId: PeerId
600-
availableIndices = toSeq(0 ..< numMixNodes)
590+
# Skip the destination peer
591+
var pubNodeInfoKeys =
592+
mixProto.pubNodeInfo.keys.toSeq().filterIt(it != destination.peerId)
593+
var availableIndices = toSeq(0 ..< pubNodeInfoKeys.len)
601594

602595
var i = 0
603596
while i < L:
@@ -606,12 +599,9 @@ proc anonymizeLocalProtocolSend*(
606599
mix_messages_error.inc(labelValues = ["Entry", "NON_RECOVERABLE"])
607600
return
608601
let selectedIndex = availableIndices[randomIndexPosition]
609-
randPeerId = pubNodeInfoKeys[selectedIndex]
602+
let randPeerId = pubNodeInfoKeys[selectedIndex]
610603
availableIndices.del(randomIndexPosition)
611604

612-
# Skip the destination peer
613-
if randPeerId == destination.peerId:
614-
continue
615605
# Last hop will be the exit node that will forward the request
616606
if i == L - 1:
617607
exitPeerId = randPeerId
@@ -653,7 +643,9 @@ proc anonymizeLocalProtocolSend*(
653643
return
654644
let destHop = Hop.init(destAddrBytes)
655645

656-
let msgWithSurbs = mixProto.prepareMsgWithSurbs(incoming, msg, numSurbs, exitPeerId).valueOr:
646+
let msgWithSurbs = mixProto.prepareMsgWithSurbs(
647+
incoming, msg, numSurbs, destination.peerId, exitPeerId
648+
).valueOr:
657649
error "Could not prepend SURBs", err = error
658650
return
659651

0 commit comments

Comments
 (0)