Skip to content

Commit 8651374

Browse files
committed
Merge PR #9: dynamic Google IP discovery + frontend validation
Thanks @v4g4b0nd-0x76 for the feature. Two small fixes folded in on the merge so master still builds + doesn't hit sharp edges: - src/scan_ips.rs: rand::thread_rng() held across an .await tripped the Send bound on the async fn (ThreadRng isn't Send). Scoped the rng in a block so it drops before subsequent awaits. - src/scan_ips.rs: guard /0 and /32 CIDRs in cidr_to_ips and ip_in_cidr against the 1u32 << 32 shift panic (debug mode). goog.json is unlikely to contain either but defensive. Behavior unchanged otherwise: - fetch_ips_from_api=false (default): identical to previous static scan-ips behavior. - fetch_ips_from_api=true: fetches goog.json from www.gstatic.com, resolves famous Google domain IPs, prioritises matching CIDRs, samples up to max_ips_to_scan candidates, validates with gws/ x-google-/alt-svc headers. If the fetch fails, falls back to the static list cleanly — verified locally. Closes #10.
2 parents 48c66dc + 2e8dd8d commit 8651374

4 files changed

Lines changed: 545 additions & 26 deletions

File tree

README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,32 @@ Then:
174174

175175
`script_id` can also be a JSON array: `["id1", "id2", "id3"]`.
176176

177+
#### scan-ips configuration (optional)
178+
179+
By default, the scan-ips subcommand uses a static array of IPs.
180+
181+
You can enable dynamic IP discovery by setting fetch_ips_from_api to true in config.json:
182+
183+
```json
184+
{
185+
"fetch_ips_from_api": true,
186+
"max_ips_to_scan": 100,
187+
"scan_batch_size":100,
188+
"google_ip_validation": true // check whether ips belongs to frontend sites of google or not
189+
}
190+
```
191+
192+
When enabled:
193+
194+
- Fetches goog.json from Google’s public IP ranges API
195+
- Extracts all CIDRs and expands them to individual IPs
196+
- Prioritizes IPs from famous Google domains (google.com, youtube.com, etc.)
197+
- Randomly selects up to max_ips_to_scan candidates (prioritized IPs first)
198+
- Tests only the selected candidates for connectivity and frontend validation.
199+
200+
By using this options you may find ips witch are faster than static array that is provided as default but there is no guarantee that this ips would work.
201+
202+
177203
### Step 5 — Point your client at the proxy
178204

179205
The tool listens on **two** ports. Use whichever your client supports:
@@ -423,6 +449,32 @@ Original project: <https://github.com/masterking32/MasterHttpRelayVPN> by [@mast
423449

424450
**فایرفاکس (ساده‌ترین):**
425451

452+
453+
#### پیکربندی scan-ips (اختیاری)
454+
به‌طور پیش‌فرض، دستور scan-ips از آرایه‌ای ثابت از IPها استفاده می‌کند.
455+
456+
می‌توانید کشف پویای IP را با تنظیم fetch_ips_from_api روی true در config.json فعال کنید:
457+
458+
```json
459+
{
460+
"fetch_ips_from_api": true,
461+
"max_ips_to_scan": 100,
462+
"scan_batch_size":100,
463+
"google_ip_validation": true // برسی هدر های بازگشته از ایپی برای برسی هدر ها و تشخیص کاربردی بودن ایپی
464+
}
465+
```
466+
467+
زمانی که فعال باشد:
468+
469+
- فایل goog.json را از API محدوده‌های عمومی IP گوگل دریافت می‌کند
470+
تمام CIDRها را استخراج کرده و به IPهای جداگانه تبدیل می‌کند
471+
- به IPهای دامنه‌های معروف گوگل (google.com، youtube.com و غیره) اولویت می‌دهد
472+
به‌صورت تصادفی تا max_ips_to_scan کاندید انتخاب می‌کند (ابتدا IPهای اولویت‌دار)
473+
فقط کاندیدهای انتخاب‌شده را برای اتصال و اعتبارسنجی frontend تست می‌کند.
474+
475+
با استفاده از این گزینه‌ها ممکن است IPهایی پیدا کنید که سریع‌تر از آرایه ثابت پیش‌فرض هستند اما تضمینی وجود ندارد که این IPها کار کنند.
476+
477+
#### ۵. تنظیم proxy در کلاینت
426478
۱. منوی `Settings` را باز کنید، در خانهٔ جست‌وجو عبارت `proxy` را تایپ کنید
427479
۲. روی **`Network Settings`** کلیک کنید
428480
۳. گزینهٔ **`Manual proxy configuration`** را انتخاب کنید

src/bin/ui.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ struct FormState {
137137
sni_custom_input: String,
138138
/// Whether the floating SNI editor window is open.
139139
sni_editor_open: bool,
140+
fetch_ips_from_api: bool,
141+
max_ips_to_scan: usize,
142+
scan_batch_size:usize,
143+
google_ip_validation: bool
140144
}
141145

142146
#[derive(Clone, Debug)]
@@ -182,6 +186,10 @@ fn load_form() -> FormState {
182186
sni_pool,
183187
sni_custom_input: String::new(),
184188
sni_editor_open: false,
189+
fetch_ips_from_api:c.fetch_ips_from_api,
190+
max_ips_to_scan:c.max_ips_to_scan,
191+
google_ip_validation: c.google_ip_validation,
192+
scan_batch_size:c.scan_batch_size
185193
}
186194
} else {
187195
FormState {
@@ -200,6 +208,10 @@ fn load_form() -> FormState {
200208
sni_pool: sni_pool_for_form(None, "www.google.com"),
201209
sni_custom_input: String::new(),
202210
sni_editor_open: false,
211+
fetch_ips_from_api:false,
212+
max_ips_to_scan:100,
213+
google_ip_validation:true,
214+
scan_batch_size:500
203215
}
204216
}
205217
}
@@ -321,6 +333,10 @@ impl FormState {
321333
Some(active)
322334
}
323335
},
336+
fetch_ips_from_api:self.fetch_ips_from_api,
337+
max_ips_to_scan: self.max_ips_to_scan,
338+
google_ip_validation:self.google_ip_validation,
339+
scan_batch_size:self.scan_batch_size
324340
})
325341
}
326342
}

src/config.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,24 @@ pub struct Config {
8080
/// various times). Can be tested per-name via the UI or `mhrv-rs test-sni`.
8181
#[serde(default)]
8282
pub sni_hosts: Option<Vec<String>>,
83+
#[serde(default = "default_fetch_ips_from_api")]
84+
pub fetch_ips_from_api: bool,
85+
86+
#[serde(default = "default_max_ips_to_scan")]
87+
pub max_ips_to_scan: usize,
88+
89+
#[serde(default = "default_scan_batch_size")]
90+
pub scan_batch_size:usize,
91+
92+
#[serde(default = "default_google_ip_validation")]
93+
pub google_ip_validation: bool
8394
}
8495

96+
fn default_fetch_ips_from_api() -> bool { false }
97+
fn default_max_ips_to_scan() -> usize { 100 }
98+
fn default_scan_batch_size() -> usize {500}
99+
fn default_google_ip_validation() -> bool {true}
100+
85101
fn default_google_ip() -> String {
86102
"216.239.38.120".into()
87103
}

0 commit comments

Comments
 (0)