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

@ -4,18 +4,6 @@ import XCTest
class OnionRequestAPITests : XCTestCase { 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 /// Builds a path and then routes the same request through it several times. Logs the number of successes
/// versus the number of failures. /// versus the number of failures.
func testOnionRequestSending() { func testOnionRequestSending() {

Loading…
Cancel
Save