/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2026 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
use std::{
future::Future,
io,
sync::{atomic::Ordering, Arc},
time::Duration,
};
use futures::{
future::{select, Either},
pin_mut,
};
use smol::lock::RwLock as AsyncRwLock;
use url::Url;
use super::{
channel::{Channel, ChannelPtr},
session::SessionWeakPtr,
settings::Settings,
transport::Dialer,
};
use crate::{net::hosts::HostContainer, system::CondVar, util::logger::verbose, Error, Result};
type DialRoute = (Url, bool, Duration);
type DialFailures = Vec<(Url, io::Error)>;
#[derive(Debug)]
enum DialRoutesError {
Stopped(Url),
Failed(DialFailures),
}
fn partition_blacklisted_endpoints(
endpoints: Vec<(Url, bool)>,
mut is_blacklisted: F,
) -> (Vec<(Url, bool)>, Vec)
where
F: FnMut(&Url) -> bool,
{
let mut allowed = vec![];
let mut blocked = vec![];
for (endpoint, mixed_transport) in endpoints {
if is_blacklisted(&endpoint) {
blocked.push(endpoint);
} else {
allowed.push((endpoint, mixed_transport));
}
}
(allowed, blocked)
}
fn build_dial_routes(endpoints: Vec<(Url, bool)>, settings: &Settings) -> Vec {
endpoints
.into_iter()
.map(|(endpoint, mixed_transport)| {
let timeout = Duration::from_secs(settings.outbound_connect_timeout(endpoint.scheme()));
(endpoint, mixed_transport, timeout)
})
.collect()
}
async fn try_dial_routes(
routes: Vec,
stop_signal: &CondVar,
mut dial: F,
) -> std::result::Result<(Url, bool, T), DialRoutesError>
where
F: FnMut(Url, Duration) -> Fut,
Fut: Future