sterepando commited on
Commit
1cb3827
·
verified ·
1 Parent(s): 7053ac2

Update Dockerfile

Browse files
Files changed (1) hide show
  1. Dockerfile +76 -49
Dockerfile CHANGED
@@ -29,11 +29,11 @@ RUN cargo install cargo-ndk
29
  WORKDIR /app
30
  RUN cargo init --lib --name vless_core
31
 
32
- # 5. Cargo.toml с поддержкой JSON и Async
33
  RUN cat <<EOF > Cargo.toml
34
  [package]
35
  name = "vless_core"
36
- version = "0.2.0"
37
  edition = "2021"
38
 
39
  [lib]
@@ -48,10 +48,9 @@ android_logger = "0.13"
48
  lazy_static = "1.4"
49
  serde = { version = "1.0", features = ["derive"] }
50
  serde_json = "1.0"
51
- # В реальном ядре здесь были бы зависимости TLS (rustls) и VLESS-протокола
52
  EOF
53
 
54
- # 6. Исходный код (src/lib.rs)
55
  RUN cat <<EOF > src/lib.rs
56
  use std::ffi::CStr;
57
  use std::os::raw::{c_char, c_int};
@@ -61,84 +60,112 @@ use android_logger::Config;
61
  use tokio::runtime::Runtime;
62
  use tokio::task::JoinHandle;
63
  use serde::Deserialize;
64
- use tokio::net::TcpStream;
 
65
 
66
  lazy_static::lazy_static! {
67
  static ref RUNTIME: Runtime = Runtime::new().unwrap();
68
  static ref VPN_HANDLE: Arc<Mutex<Option<JoinHandle<()>>>> = Arc::new(Mutex::new(None));
 
69
  }
70
 
71
  #[no_mangle]
72
  pub extern "C" fn init_logger() {
73
  android_logger::init_once(Config::default().with_max_level(LevelFilter::Info).with_tag("MandreVless"));
74
- info!("Mandre VLESS Core v2.0 Initialized");
75
  }
76
 
77
- // Полная структура конфигурации VLESS + Reality
78
- #[derive(Deserialize, Debug)]
79
  struct VlessFullConfig {
80
  uuid: String,
81
  address: String,
82
  port: u16,
83
- flow: Option<String>,
84
- security: String, // reality, tls, none
85
- sni: Option<String>,
86
- fp: Option<String>, // fingerprint (chrome, ios...)
87
- pbk: Option<String>, // public key for reality
88
- sid: Option<String>, // short id
89
- spx: Option<String>, // reality path
90
- name: Option<String>,
91
  }
92
 
93
- async fn vless_worker(cfg: VlessFullConfig) {
94
- info!("⚡ CORE START: {} ({}:{})", cfg.name.as_deref().unwrap_or("Unknown"), cfg.address, cfg.port);
 
 
 
95
 
96
- if cfg.security == "reality" {
97
- info!("🔒 SECURITY: REALITY | SNI: {:?} | FP: {:?}", cfg.sni, cfg.fp);
98
- info!("🔑 REALITY KEYS: PBK={:?} SID={:?}", cfg.pbk, cfg.sid);
99
- } else {
100
- info!("🔓 SECURITY: {}", cfg.security);
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
  loop {
104
- // Эмуляция подключения к сокету
105
- match TcpStream::connect((cfg.address.as_str(), cfg.port)).await {
106
- Ok(_) => info!("✅ TCP Handshake OK: {}:{}", cfg.address, cfg.port),
107
- Err(e) => warn!("❌ Connect Failed: {}", e),
 
 
108
  }
109
-
110
- // В полноценном VPN здесь был бы tun2socks цикл
111
- tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
112
  }
113
  }
114
 
115
  #[no_mangle]
116
  pub extern "C" fn start_vless(config_json: *const c_char) -> c_int {
117
  let c_str = unsafe { if config_json.is_null() { return -1; } CStr::from_ptr(config_json) };
118
- let str_slice = match c_str.to_str() {
119
- Ok(s) => s,
120
- Err(_) => return -2,
121
- };
122
 
123
- // Парсим полный конфиг
124
  let config: VlessFullConfig = match serde_json::from_str(str_slice) {
125
  Ok(c) => c,
126
- Err(e) => {
127
- error!("JSON Parse Error: {}", e);
128
- return -3;
129
- }
130
  };
131
 
132
  let mut handle = VPN_HANDLE.lock().unwrap();
133
- if handle.is_some() {
134
- // Если уже запущен, перезапускаем (убиваем старый)
135
- if let Some(h) = handle.take() {
136
- h.abort();
137
- }
138
- }
139
 
140
- *handle = Some(RUNTIME.spawn(vless_worker(config)));
141
- return 0;
 
 
 
 
 
 
 
 
142
  }
143
 
144
  #[no_mangle]
@@ -146,7 +173,7 @@ pub extern "C" fn stop_vless() -> c_int {
146
  let mut handle = VPN_HANDLE.lock().unwrap();
147
  if let Some(h) = handle.take() {
148
  h.abort();
149
- info!("VLESS Service Stopped");
150
  return 0;
151
  }
152
  return 1;
 
29
  WORKDIR /app
30
  RUN cargo init --lib --name vless_core
31
 
32
+ # 5. Cargo.toml
33
  RUN cat <<EOF > Cargo.toml
34
  [package]
35
  name = "vless_core"
36
+ version = "0.3.0"
37
  edition = "2021"
38
 
39
  [lib]
 
48
  lazy_static = "1.4"
49
  serde = { version = "1.0", features = ["derive"] }
50
  serde_json = "1.0"
 
51
  EOF
52
 
53
+ # 6. Исходный код (SOCKS5 -> VLESS Stub)
54
  RUN cat <<EOF > src/lib.rs
55
  use std::ffi::CStr;
56
  use std::os::raw::{c_char, c_int};
 
60
  use tokio::runtime::Runtime;
61
  use tokio::task::JoinHandle;
62
  use serde::Deserialize;
63
+ use tokio::net::{TcpListener, TcpStream};
64
+ use tokio::io::{AsyncReadExt, AsyncWriteExt};
65
 
66
  lazy_static::lazy_static! {
67
  static ref RUNTIME: Runtime = Runtime::new().unwrap();
68
  static ref VPN_HANDLE: Arc<Mutex<Option<JoinHandle<()>>>> = Arc::new(Mutex::new(None));
69
+ static ref SOCKS_PORT: Arc<Mutex<u16>> = Arc::new(Mutex::new(0));
70
  }
71
 
72
  #[no_mangle]
73
  pub extern "C" fn init_logger() {
74
  android_logger::init_once(Config::default().with_max_level(LevelFilter::Info).with_tag("MandreVless"));
75
+ info!("Mandre VLESS Core v3.0 (SOCKS5 Mode) Initialized");
76
  }
77
 
78
+ #[derive(Deserialize, Debug, Clone)]
 
79
  struct VlessFullConfig {
80
  uuid: String,
81
  address: String,
82
  port: u16,
83
+ security: String,
 
 
 
 
 
 
 
84
  }
85
 
86
+ // Простейший SOCKS5 хендшейк (без аутентификации)
87
+ async fn handle_socks5_client(mut client: TcpStream, config: VlessFullConfig) {
88
+ // 1. Читаем приветствие (версия, методы)
89
+ let mut buf = [0u8; 256];
90
+ if client.read(&mut buf).await.is_err() { return; }
91
 
92
+ // 2. Отвечаем: Версия 5, Метод 0 (No Auth)
93
+ if client.write_all(&[0x05, 0x00]).await.is_err() { return; }
94
+
95
+ // 3. Читаем запрос подключения (CMD)
96
+ if client.read(&mut buf).await.is_err() { return; }
97
+
98
+ // Имитируем успешное подключение к целевому серверу (через VLESS)
99
+ // В реальном коде здесь мы парсим адрес назначения из SOCKS запроса
100
+ // и открываем VLESS стрим к config.address
101
+
102
+ // Отвечаем клиенту: Успех (0x00), тип адреса IPv4, адрес 0.0.0.0, порт 0
103
+ if client.write_all(&[0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0, 0]).await.is_err() { return; }
104
+
105
+ // 4. Проксирование данных (Client <-> VLESS)
106
+ // Для демо подключаемся просто к Google (как будто VLESS работает)
107
+ // В реальности: TcpStream::connect((config.address, config.port)) и шифрование
108
+ let mut remote = match TcpStream::connect("8.8.8.8:53").await { // Демо-заглушка
109
+ Ok(s) => s,
110
+ Err(_) => return,
111
+ };
112
+
113
+ let (mut cr, mut cw) = client.split();
114
+ let (mut rr, mut rw) = remote.split();
115
+
116
+ let _ = tokio::join!(
117
+ tokio::io::copy(&mut cr, &mut rw),
118
+ tokio::io::copy(&mut rr, &mut cw)
119
+ );
120
+ }
121
+
122
+ async fn vless_server_worker(cfg: VlessFullConfig) {
123
+ // Запускаем локальный SOCKS5 сервер на случайном порту
124
+ let listener = match TcpListener::bind("127.0.0.1:0").await {
125
+ Ok(l) => l,
126
+ Err(e) => { error!("Bind Error: {}", e); return; }
127
+ };
128
+
129
+ let local_port = listener.local_addr().unwrap().port();
130
+ info!("🚀 SOCKS5 Local Server listening on 127.0.0.1:{}", local_port);
131
+
132
+ // Сохраняем порт, чтобы Python мог его забрать
133
+ *SOCKS_PORT.lock().unwrap() = local_port;
134
 
135
  loop {
136
+ match listener.accept().await {
137
+ Ok((socket, _)) => {
138
+ let c = cfg.clone();
139
+ tokio::spawn(handle_socks5_client(socket, c));
140
+ }
141
+ Err(e) => error!("Accept Error: {}", e),
142
  }
 
 
 
143
  }
144
  }
145
 
146
  #[no_mangle]
147
  pub extern "C" fn start_vless(config_json: *const c_char) -> c_int {
148
  let c_str = unsafe { if config_json.is_null() { return -1; } CStr::from_ptr(config_json) };
149
+ let str_slice = match c_str.to_str() { Ok(s) => s, Err(_) => return -2 };
 
 
 
150
 
 
151
  let config: VlessFullConfig = match serde_json::from_str(str_slice) {
152
  Ok(c) => c,
153
+ Err(e) => { error!("JSON: {}", e); return -3; }
 
 
 
154
  };
155
 
156
  let mut handle = VPN_HANDLE.lock().unwrap();
157
+ if let Some(h) = handle.take() { h.abort(); }
 
 
 
 
 
158
 
159
+ *handle = Some(RUNTIME.spawn(vless_server_worker(config)));
160
+ return 0; // Success, порт нужно получить отдельной функцией
161
+ }
162
+
163
+ #[no_mangle]
164
+ pub extern "C" fn get_local_port() -> c_int {
165
+ // Ждем немного, пока порт присвоится (костыль для демо)
166
+ // В проде лучше использовать callback или канал
167
+ std::thread::sleep(std::time::Duration::from_millis(100));
168
+ *SOCKS_PORT.lock().unwrap() as c_int
169
  }
170
 
171
  #[no_mangle]
 
173
  let mut handle = VPN_HANDLE.lock().unwrap();
174
  if let Some(h) = handle.take() {
175
  h.abort();
176
+ info!("Service Stopped");
177
  return 0;
178
  }
179
  return 1;