Ensure target snode isn't included in onion request path

pull/148/head
gmbnt 5 years ago
parent 547f7943c3
commit 92aba98cb7

@ -123,16 +123,16 @@ internal enum OnionRequestAPI {
}
/// Returns a `Path` to be used for building an onion request. Builds new paths as needed.
///
/// - Note: Exposed for testing purposes.
internal static func getPath() -> Promise<Path> {
private static func getPath(excluding snode: LokiAPITarget) -> Promise<Path> {
guard pathSize >= 1 else { preconditionFailure("Cannot build path of size zero.") }
// randomElement() uses the system's default random generator, which is cryptographically secure
if paths.count >= pathCount {
return Promise<Path> { $0.fulfill(paths.randomElement()!) }
return Promise<Path> { seal in
seal.fulfill(paths.filter { !$0.contains(snode) }.randomElement()!)
}
} else {
return buildPaths().map(on: workQueue) { paths in
let path = paths.randomElement()!
let path = paths.filter { !$0.contains(snode) }.randomElement()!
OnionRequestAPI.paths = paths
return path
}
@ -148,7 +148,7 @@ internal enum OnionRequestAPI {
var guardSnode: LokiAPITarget!
var targetSnodeSymmetricKey: Data! // Needed by invoke(_:on:with:) to decrypt the response sent back by the target snode
var encryptionResult: EncryptionResult!
return getPath().then(on: workQueue) { path -> Promise<EncryptionResult> in
return getPath(excluding: snode).then(on: workQueue) { path -> Promise<EncryptionResult> in
guardSnode = path.first!
// Encrypt in reverse order, i.e. the target snode first
return encrypt(payload, forTargetSnode: snode).then(on: workQueue) { r -> Promise<EncryptionResult> in

@ -4,18 +4,6 @@ import XCTest
class OnionRequestAPITests : XCTestCase {
func testPathBuilding() {
let semaphore = DispatchSemaphore(value: 0)
var error: Error? = nil
let _ = OnionRequestAPI.getPath().done(on: OnionRequestAPI.workQueue) { _ in
semaphore.signal()
}.catch(on: OnionRequestAPI.workQueue) {
error = $0; semaphore.signal()
}
semaphore.wait()
XCTAssert(error == nil)
}
/// Builds a path and then routes the same request through it several times. Logs the number of successes
/// versus the number of failures.
func testOnionRequestSending() {

Loading…
Cancel
Save