blacklist for mobiles
This commit is contained in:
+106
-98
@@ -3,146 +3,154 @@ use hickory_proto::op::{Message, MessageType, ResponseCode};
|
||||
use hickory_proto::rr::{RData, Record, RecordType};
|
||||
use netrunner_logger::{debug, error, info, warn};
|
||||
use std::collections::HashSet;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::path::Path;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use tokio::fs::{self, File};
|
||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||
pub struct DnsHandler {
|
||||
block_list: HashSet<String>,
|
||||
forbidden_suffixes: Vec<String>,
|
||||
cache_path: String,
|
||||
}
|
||||
|
||||
impl DnsHandler {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(cache_dir: &str) -> Self {
|
||||
Self {
|
||||
block_list: HashSet::new(),
|
||||
forbidden_suffixes: vec![
|
||||
".lan".to_string(),
|
||||
".local".to_string(),
|
||||
".home".to_string(),
|
||||
".arpa".to_string(),
|
||||
],
|
||||
cache_path: "hosts_cache.txt".to_string(),
|
||||
forbidden_suffixes: vec![".lan", ".local", ".home", ".arpa"]
|
||||
.into_iter()
|
||||
.map(String::from)
|
||||
.collect(),
|
||||
cache_path: format!("{}/hosts_cache.txt", cache_dir),
|
||||
}
|
||||
}
|
||||
|
||||
/// Основной метод инициализации: решает, качать или брать из кэша
|
||||
pub fn init(&mut self) -> anyhow::Result<()> {
|
||||
let url = "https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts";
|
||||
let path = Path::new(&self.cache_path);
|
||||
pub async fn init(&mut self) -> anyhow::Result<()> {
|
||||
let path = std::path::PathBuf::from(&self.cache_path);
|
||||
|
||||
let should_download = if path.exists() {
|
||||
let metadata = fs::metadata(path)?;
|
||||
let last_modified = metadata.modified()?;
|
||||
let elapsed = SystemTime::now().duration_since(last_modified)?.as_secs();
|
||||
if path.exists() {
|
||||
let _ = self.load_from_file().await;
|
||||
}
|
||||
|
||||
elapsed > 604800
|
||||
let needs_update = if let Ok(meta) = fs::metadata(&path).await {
|
||||
SystemTime::now()
|
||||
.duration_since(meta.modified()?)
|
||||
.unwrap_or_default()
|
||||
> Duration::from_secs(604800)
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
if should_download {
|
||||
info!("Blocklist is outdated or missing. Trying to download...");
|
||||
if let Err(e) = self.download_and_cache(url) {
|
||||
warn!(
|
||||
"Failed to download blocklist ({}), trying to use cache if available",
|
||||
e
|
||||
);
|
||||
if needs_update {
|
||||
let p_clone = self.cache_path.clone();
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||
Self::download_blocklist(p_clone);
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn download_blocklist(cache_path: String) {
|
||||
let runtime = crate::RUNTIME.get_or_init(|| {
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("Failed to create Tokio runtime")
|
||||
});
|
||||
|
||||
runtime.block_on(async move {
|
||||
info!("DNS: Starting background download to {}", cache_path);
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.build();
|
||||
|
||||
let client = match client {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
netrunner_logger::error!("DNS: Failed to create client: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match client
|
||||
.get("https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts")
|
||||
.send()
|
||||
.await
|
||||
{
|
||||
Ok(resp) if resp.status().is_success() => {
|
||||
if let Ok(bytes) = resp.bytes().await {
|
||||
if let Err(e) = tokio::fs::write(&cache_path, bytes).await {
|
||||
netrunner_logger::error!("DNS: File write error: {}", e);
|
||||
} else {
|
||||
info!("DNS: Blocklist downloaded successfully to {}", cache_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(resp) => {
|
||||
netrunner_logger::error!("DNS: Download failed with status {}", resp.status())
|
||||
}
|
||||
Err(e) => {
|
||||
netrunner_logger::error!("DNS: Request error (check internet/TLS): {}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if path.exists() {
|
||||
self.load_from_file()?;
|
||||
} else {
|
||||
error!("No blocklist available (neither online nor cache)!");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
fn download_and_cache(&self, url: &str) -> anyhow::Result<()> {
|
||||
let mut response = reqwest::blocking::get(url)?;
|
||||
if !response.status().is_success() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Server returned status {}",
|
||||
response.status()
|
||||
));
|
||||
}
|
||||
|
||||
let mut file = File::create(&self.cache_path)?;
|
||||
response.copy_to(&mut file)?;
|
||||
info!("Blocklist downloaded and cached locally.");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_from_file(&mut self) -> anyhow::Result<()> {
|
||||
let file = File::open(&self.cache_path)?;
|
||||
let reader = BufReader::new(file);
|
||||
async fn load_from_file(&mut self) -> anyhow::Result<()> {
|
||||
let file = File::open(&self.cache_path).await?;
|
||||
let mut lines = BufReader::new(file).lines();
|
||||
let mut count = 0;
|
||||
|
||||
for line in reader.lines() {
|
||||
let line = line?;
|
||||
if line.starts_with('#') || line.trim().is_empty() {
|
||||
while let Some(line) = lines.next_line().await? {
|
||||
let line = line.trim();
|
||||
if line.is_empty() || line.starts_with('#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||
if parts.len() >= 2 {
|
||||
// Берем домен (второй столбец в StevenBlack hosts)
|
||||
self.block_list.insert(parts[1].to_lowercase());
|
||||
if let Some(domain) = line.split_whitespace().nth(1) {
|
||||
self.block_list.insert(domain.to_lowercase());
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
info!("Loaded {} domains from cache.", count);
|
||||
info!("DNS: Loaded {} domains from cache.", count);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_query(&self, data: &[u8], store: &mut FakeIpStore) -> Option<Vec<u8>> {
|
||||
let request = Message::from_vec(data).ok()?;
|
||||
let query = request.queries().first()?;
|
||||
|
||||
let mut response = Message::new();
|
||||
response
|
||||
.set_id(request.id())
|
||||
.set_message_type(MessageType::Response)
|
||||
.set_recursion_available(true)
|
||||
.add_query(query.clone());
|
||||
|
||||
let req = Message::from_vec(data).ok()?;
|
||||
let query = req.queries().first()?;
|
||||
let name = query
|
||||
.name()
|
||||
.to_string()
|
||||
.trim_end_matches('.')
|
||||
.to_lowercase();
|
||||
|
||||
// 1. Спец. суффиксы
|
||||
if self.forbidden_suffixes.iter().any(|s| name.ends_with(s)) {
|
||||
info!(domain = %name, "DNS: Blocked (Suffix)");
|
||||
response.set_response_code(ResponseCode::NXDomain);
|
||||
return response.to_vec().ok();
|
||||
let mut res = Message::new();
|
||||
res.set_id(req.id())
|
||||
.set_message_type(MessageType::Response)
|
||||
.set_recursion_available(true)
|
||||
.add_query(query.clone());
|
||||
|
||||
// Проверка блокировок
|
||||
if self.forbidden_suffixes.iter().any(|s| name.ends_with(s))
|
||||
|| self.block_list.contains(&name)
|
||||
{
|
||||
info!(domain = %name, "DNS: Blocked");
|
||||
res.set_response_code(ResponseCode::NXDomain);
|
||||
return res.to_vec().ok();
|
||||
}
|
||||
|
||||
// 2. Бан-лист (AdBlock)
|
||||
if self.block_list.contains(&name) {
|
||||
info!(domain = %name, "DNS: Blocked (AdList)");
|
||||
response.set_response_code(ResponseCode::NXDomain);
|
||||
return response.to_vec().ok();
|
||||
if query.query_type() == RecordType::A {
|
||||
let fake_ip = store.get_or_assign(&name);
|
||||
res.add_answer(Record::from_rdata(
|
||||
query.name().clone(),
|
||||
60,
|
||||
RData::A(fake_ip.into()),
|
||||
));
|
||||
res.set_response_code(ResponseCode::NoError);
|
||||
}
|
||||
|
||||
// 3. Fake IP Logic
|
||||
match query.query_type() {
|
||||
RecordType::A => {
|
||||
let fake_ip = store.get_or_assign(&name);
|
||||
let record = Record::from_rdata(query.name().clone(), 60, RData::A(fake_ip.into()));
|
||||
response.set_response_code(ResponseCode::NoError);
|
||||
response.add_answer(record);
|
||||
}
|
||||
_ => {
|
||||
response.set_response_code(ResponseCode::NoError);
|
||||
}
|
||||
}
|
||||
|
||||
response.to_vec().ok()
|
||||
res.to_vec().ok()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@ uniffi::setup_scaffolding!();
|
||||
pub mod connections;
|
||||
pub mod tun;
|
||||
use netrunner_logger::info;
|
||||
use std::sync::OnceLock;
|
||||
use tokio::runtime::Runtime;
|
||||
use std::{sync::OnceLock, time::Duration};
|
||||
use tokio::{fs::File, io::AsyncWriteExt, runtime::Runtime};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::tun::routing::reset_platform_routing;
|
||||
|
||||
+67
-71
@@ -1,5 +1,3 @@
|
||||
use std::net::Ipv4Addr;
|
||||
|
||||
use netrunner_client::{
|
||||
connections::dns::DnsHandler,
|
||||
tun::{
|
||||
@@ -11,94 +9,92 @@ use netrunner_client::{
|
||||
use netrunner_core::proxy::{connection::connection::ConnectionRole, network::Network};
|
||||
use netrunner_logger::{error, info};
|
||||
use smoltcp::{iface::Config, phy::DeviceCapabilities};
|
||||
use std::net::Ipv4Addr;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
// Убираем макрос #[tokio::main]
|
||||
fn main() -> anyhow::Result<()> {
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
// 1. Инициализация логгера (теперь он внутри асинхронного контекста)
|
||||
netrunner_logger::Logger::init();
|
||||
info!("Initializing NetRunner Stack...");
|
||||
|
||||
// 1. СИНХРОННАЯ ЧАСТЬ
|
||||
// Здесь reqwest::blocking может спокойно создавать и удалять свои ресурсы
|
||||
let mut dns_handler = DnsHandler::new();
|
||||
if let Err(e) = dns_handler.init() {
|
||||
// 2. Инициализация DNS асинхронно
|
||||
// Передаем пустую строку или путь к кэшу (на десктопе можно ".")
|
||||
let mut dns_handler = DnsHandler::new(".");
|
||||
if let Err(e) = dns_handler.init().await {
|
||||
error!("Failed to initialize DNS blocklist: {}", e);
|
||||
}
|
||||
|
||||
// 2. АСИНХРОННАЯ ЧАСТЬ
|
||||
// Создаем рантайм вручную
|
||||
let rt = tokio::runtime::Runtime::new()?;
|
||||
// 3. Настройка TUN устройства
|
||||
let tun_device = Tun::create(|config| {
|
||||
config
|
||||
.tun_name("netr0")
|
||||
.address((10, 0, 0, 1))
|
||||
.netmask((255, 255, 255, 0))
|
||||
.destination((10, 0, 0, 2))
|
||||
.up();
|
||||
})
|
||||
.expect("Failed to initialize TUN device");
|
||||
|
||||
// Передаем управление в асинхронный блок
|
||||
rt.block_on(async move {
|
||||
let tun_device = Tun::create(|config| {
|
||||
config
|
||||
.tun_name("netr0")
|
||||
.address((10, 0, 0, 1))
|
||||
.netmask((255, 255, 255, 0))
|
||||
.destination((10, 0, 0, 2))
|
||||
.up();
|
||||
})
|
||||
.expect("Failed to initialize TUN device");
|
||||
let remote_address: String = "62.60.244.156:443".into();
|
||||
setup_platform_routing(&remote_address);
|
||||
|
||||
let remote_address: String = "62.60.244.156:443".into();
|
||||
setup_platform_routing(&remote_address);
|
||||
info!("TUN interface is UP: 10.0.0.1/24");
|
||||
|
||||
info!("TUN interface is UP: 10.0.0.1/24");
|
||||
// 4. Конфигурация стека протоколов (MTU 1280 для стабильности)
|
||||
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
let mut caps = DeviceCapabilities::default();
|
||||
caps.max_transmission_unit = 1280;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
|
||||
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
let mut caps = DeviceCapabilities::default();
|
||||
caps.max_transmission_unit = 1280;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
let network = Network::new(
|
||||
"0.0.0.0".into(),
|
||||
8080,
|
||||
ConnectionRole::Client,
|
||||
Some(remote_address.clone()),
|
||||
);
|
||||
|
||||
let network = Network::new(
|
||||
"0.0.0.0".into(),
|
||||
8080,
|
||||
ConnectionRole::Client,
|
||||
Some(remote_address.clone()),
|
||||
);
|
||||
let proxy_ip = network.get_self_local_address();
|
||||
|
||||
let proxy_ip = network.get_self_local_address();
|
||||
// 5. Запуск сетевого прокси в отдельной задаче
|
||||
let network_token = CancellationToken::new();
|
||||
let net_token_for_spawn = network_token.clone();
|
||||
tokio::spawn(async move {
|
||||
info!("Network thread started");
|
||||
network.run(net_token_for_spawn).await;
|
||||
});
|
||||
|
||||
// Запускаем сетевой поток
|
||||
let network_token = CancellationToken::new();
|
||||
tokio::spawn(async move {
|
||||
info!("Network thread started");
|
||||
network.run(network_token).await;
|
||||
});
|
||||
// 6. Инициализация Engine
|
||||
let mut engine = Engine::new(config, caps, proxy_ip, dns_handler);
|
||||
engine.set_any_ip(true);
|
||||
engine.set_transparent_mode();
|
||||
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2));
|
||||
engine.activate();
|
||||
|
||||
// Создаем Engine и передаем уже готовый dns_handler
|
||||
let mut engine = Engine::new(config, caps, proxy_ip, dns_handler);
|
||||
engine.set_any_ip(true);
|
||||
engine.set_transparent_mode();
|
||||
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2));
|
||||
engine.activate();
|
||||
info!("Stack IP initialized: 10.0.0.2");
|
||||
info!("Engine starting process loop...");
|
||||
|
||||
info!("Stack IP initialized: 10.0.0.2");
|
||||
info!("Engine starting process loop...");
|
||||
|
||||
let ctrl_c = tokio::signal::ctrl_c();
|
||||
|
||||
tokio::select! {
|
||||
res = engine.run(tun_device) => {
|
||||
error!("Engine loop error: {:?}", res);
|
||||
},
|
||||
_ = ctrl_c => {
|
||||
info!("Ctrl+C received, shutting down...");
|
||||
}
|
||||
let ctrl_c = tokio::signal::ctrl_c();
|
||||
tokio::select! {
|
||||
res = engine.run(tun_device) => {
|
||||
error!("Engine loop error: {:?}", res);
|
||||
},
|
||||
_ = ctrl_c => {
|
||||
info!("Ctrl+C received, shutting down...");
|
||||
}
|
||||
}
|
||||
|
||||
// Очистка при выходе
|
||||
info!("Restoring system routing...");
|
||||
let addr: std::net::SocketAddr = remote_address.parse().expect("Invalid address format");
|
||||
let p_ip = addr.ip().to_string();
|
||||
if let Err(e) = reset_platform_routing(Some(&p_ip)) {
|
||||
error!("Failed to reset routing: {}", e);
|
||||
} else {
|
||||
info!("System routing restored successfully.");
|
||||
}
|
||||
// 8. Очистка ресурсов
|
||||
network_token.cancel();
|
||||
info!("Restoring system routing...");
|
||||
let addr: std::net::SocketAddr = remote_address.parse().expect("Invalid address format");
|
||||
let p_ip = addr.ip().to_string();
|
||||
|
||||
Ok::<(), anyhow::Error>(())
|
||||
})?;
|
||||
if let Err(e) = reset_platform_routing(Some(&p_ip)) {
|
||||
error!("Failed to restore routing: {}", e);
|
||||
} else {
|
||||
info!("System routing restored successfully.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ namespace netrunner_client {};
|
||||
|
||||
interface SessionManager {
|
||||
constructor();
|
||||
Session start_mobile(string remote_address, optional i32 tun_fd);
|
||||
Session start_desktop(string remote_address);
|
||||
Session start_mobile(string remote_address, optional i32 tun_fd, string cache_path);
|
||||
};
|
||||
|
||||
interface Session {
|
||||
|
||||
@@ -2,9 +2,8 @@ use super::{Session, SessionManager};
|
||||
use std::sync::Arc;
|
||||
use uniffi;
|
||||
|
||||
#[uniffi::export]
|
||||
impl SessionManager {
|
||||
pub fn start_desktop(&self, remote_address: String) -> Arc<Session> {
|
||||
self.spawn_session(remote_address, None)
|
||||
self.spawn_session(remote_address)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,16 @@ use uniffi;
|
||||
|
||||
#[uniffi::export]
|
||||
impl SessionManager {
|
||||
pub fn start_mobile(&self, remote_address: String, tun_fd: i32) -> Arc<Session> {
|
||||
self.spawn_session(remote_address, Some(tun_fd))
|
||||
pub fn start_mobile(
|
||||
&self,
|
||||
remote_address: String,
|
||||
tun_fd: i32,
|
||||
cache_dir: String,
|
||||
) -> Arc<Session> {
|
||||
self.spawn_session(remote_address, Some(tun_fd), cache_dir)
|
||||
}
|
||||
|
||||
pub fn start_desktop(&self, remote_address: String, cache_dir: String) -> Arc<Session> {
|
||||
self.spawn_session(remote_address, None, cache_dir)
|
||||
}
|
||||
}
|
||||
|
||||
+38
-18
@@ -47,21 +47,37 @@ impl SessionManager {
|
||||
pub(crate) fn spawn_session(
|
||||
&self,
|
||||
remote_address: String,
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))] // Путь обязателен для мобилок
|
||||
tun_fd: Option<i32>,
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))] cache_dir: String,
|
||||
) -> Arc<Session> {
|
||||
let runtime = get_runtime();
|
||||
let cancel_token = CancellationToken::new();
|
||||
let sesison_token = cancel_token.clone();
|
||||
let net_token = cancel_token.clone();
|
||||
let shutdown_signal = signal::ctrl_c();
|
||||
|
||||
let addr: std::net::SocketAddr = remote_address.parse().expect("Invalid address format");
|
||||
let remote_proxy_ip = addr.ip().to_string();
|
||||
let proxy_ip_for_thread = remote_proxy_ip.clone();
|
||||
|
||||
runtime.spawn(async move {
|
||||
info!("Starting VPN session thread...");
|
||||
|
||||
let cache_path = {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
{
|
||||
cache_dir
|
||||
} // Используем путь из мобильного приложения
|
||||
#[cfg(any(target_os = "linux", target_os = "windows"))]
|
||||
{
|
||||
".".to_string()
|
||||
} // На ПК пишем в локальную папку
|
||||
};
|
||||
|
||||
let mut dns_handler = DnsHandler::new(&cache_path);
|
||||
if let Err(e) = dns_handler.init().await {
|
||||
error!("Failed to initialize DNS blocklist: {}", e);
|
||||
}
|
||||
|
||||
let tun_device = {
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
{
|
||||
@@ -93,7 +109,7 @@ impl SessionManager {
|
||||
|
||||
let config = Config::new(smoltcp::wire::HardwareAddress::Ip);
|
||||
let mut caps = DeviceCapabilities::default();
|
||||
caps.max_transmission_unit = 1500;
|
||||
caps.max_transmission_unit = 1280;
|
||||
caps.medium = smoltcp::phy::Medium::Ip;
|
||||
|
||||
let network = Network::new(
|
||||
@@ -104,11 +120,6 @@ impl SessionManager {
|
||||
);
|
||||
let proxy_ip = network.get_self_local_address();
|
||||
|
||||
let mut dns_handler = DnsHandler::new();
|
||||
if let Err(e) = dns_handler.init() {
|
||||
error!("Failed to initialize DNS blocklist: {}", e);
|
||||
}
|
||||
|
||||
tokio::spawn(async move {
|
||||
network.run(net_token).await;
|
||||
});
|
||||
@@ -119,17 +130,26 @@ impl SessionManager {
|
||||
engine.set_default_gateway(Ipv4Addr::new(10, 0, 0, 2));
|
||||
engine.activate();
|
||||
|
||||
tokio::select! {
|
||||
res = engine.run(tun_device) => error!("Engine loop error: {:?}", res),
|
||||
_ = cancel_token.cancelled() => {
|
||||
info!("Shutdown signal received");
|
||||
let cancel_token_for_engine = cancel_token.clone();
|
||||
std::thread::spawn(move || {
|
||||
info!("Dedicated OS thread started for Engine");
|
||||
|
||||
let _ = reset_platform_routing(Some(&proxy_ip_for_thread));
|
||||
},
|
||||
_ = shutdown_signal => {
|
||||
cancel_token.cancel();
|
||||
}
|
||||
}
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
tokio::select! {
|
||||
res = engine.run(tun_device) => {
|
||||
error!("Engine loop error: {:?}", res);
|
||||
},
|
||||
_ = cancel_token_for_engine.cancelled() => {
|
||||
info!("Engine thread shutting down via token");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Arc::new(Session {
|
||||
|
||||
@@ -175,26 +175,39 @@ impl ConnectionManager {
|
||||
}
|
||||
|
||||
fn create_tcp_socket<'a>() -> tcp::Socket<'a> {
|
||||
const BUF_SIZE: usize = 65536;
|
||||
tcp::Socket::new(
|
||||
const BUF_SIZE: usize = 128 * 1024; // Увеличил до 128KB для стабильного потока
|
||||
let mut socket = tcp::Socket::new(
|
||||
tcp::SocketBuffer::new(vec![0; BUF_SIZE]),
|
||||
tcp::SocketBuffer::new(vec![0; BUF_SIZE]),
|
||||
)
|
||||
);
|
||||
socket.set_nagle_enabled(false);
|
||||
socket.set_ack_delay(None);
|
||||
socket.set_keep_alive(Some(smoltcp::time::Duration::from_secs(30)));
|
||||
socket.set_hop_limit(Some(64));
|
||||
socket
|
||||
}
|
||||
|
||||
fn create_udp_socket<'a>() -> udp::Socket<'a> {
|
||||
const BUF_SIZE: usize = 32768;
|
||||
const BUF_SIZE: usize = 65536;
|
||||
const PACKET_COUNT: usize = 128;
|
||||
|
||||
udp::Socket::new(
|
||||
udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY; 16], vec![0; BUF_SIZE]),
|
||||
udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY; 16], vec![0; BUF_SIZE]),
|
||||
udp::PacketBuffer::new(
|
||||
vec![udp::PacketMetadata::EMPTY; PACKET_COUNT],
|
||||
vec![0; BUF_SIZE],
|
||||
),
|
||||
udp::PacketBuffer::new(
|
||||
vec![udp::PacketMetadata::EMPTY; PACKET_COUNT],
|
||||
vec![0; BUF_SIZE],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn create_icmp_socket<'a>() -> icmp::Socket<'a> {
|
||||
let icmp_rx_buffer =
|
||||
icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY; 4], vec![0; 1024]);
|
||||
icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY; 8], vec![0; 2048]);
|
||||
let icmp_tx_buffer =
|
||||
icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY; 4], vec![0; 1024]);
|
||||
icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY; 8], vec![0; 2048]);
|
||||
icmp::Socket::new(icmp_rx_buffer, icmp_tx_buffer)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user