خطای timeout در فیلترشکن یعنی چه؟ راهنمای v2rayNG
در v2rayNG، i/o timeout یعنی جوابی در مهلت نرسید، اما عدد منفی یک لزوماً چنین نیست. فرق TCPing و آزمایش تأخیر واقعی را بشناسید و شش کار را امتحان کنید.
خطای timeout در فیلترشکن یعنی چه؟
خطای timeout در فیلترشکن یعنی برنامه چیزی فرستاده و تا پایان مهلتش هیچ جوابی برنگشته است. timeout یعنی سکوت. برای همین خود پیام هیچوقت نمیگوید چرا جواب نیامد. فقط میگوید برنامه منتظر ماند و چیزی نرسید.
این راهنما درباره پیامهایی است که داخل خود برنامه فیلترشکن میبینید: عدد -1 کنار اسم سرور، یا متنهایی مثل i/o timeout و net/http: TLS handshake timeout. صفحه خطای مرورگر، مثل ERR_TIMED_OUT، موضوع دیگری است و اینجا سراغش نمیرویم.
تمرکز این راهنما روی v2rayNG است. رشتهها و رفتارهایی که از v2rayNG نقل میکنیم از کد منبع نسخه 2.3.15 خوانده شدهاند. این نسخه در ۱۰ آبان ۱۴۰۵ (۱ نوامبر ۲۰۲۶) منتشر شد و ما کدش را در ۱۷ آبان ۱۴۰۵ خواندیم. معنای timeout در Hiddify و v2rayN و v2rayTun هم همین است، اما نام دکمهها و متن خطاهای آن برنامهها را بررسی نکردهایم.
timeout با refused و reset چه فرقی دارد؟
وقتی اتصال refused (رد شده) یا reset (قطع شده) است، یعنی چیزی جواب داده است. مقصد، یا دستگاهی در میانه راه، بستهای برگردانده که معنایش «نه» است. این خودش اطلاعات است، چون نشان میدهد مسیر تا همان نقطه باز است.
در timeout هیچ بستهای برنمیگردد. ممکن است بستهها در راه دور ریخته شوند. ممکن است سرور خاموش باشد. ممکن است سرور عمداً به ترافیکی که نمیشناسد جواب ندهد. از سمت گوشی همه این حالتها یک شکل دارند: انتظار، و بعد پایان مهلت.
همین تمایز را برای SSH در فرق Connection refused و Connection timed out در SSH با جزئیات توضیح دادهایم. منطق آن برای فیلترشکن هم درست است.
دو آزمایش v2rayNG: TCPing و آزمایش تأخیر واقعی
v2rayNG دو آزمایش جدا دارد. در نسخه فارسی برنامه با این دو نام دیده میشوند:
آزمایش تأخیر TCP (TCPing)
آزمایش تأخیر واقعیدر نسخه انگلیسی نامها Test TCP delays (TCPing) و Test real delays است. این دو آزمایش چیزهای متفاوتی را میسنجند. اگر فرقشان را بدانید، عدد -1 خیلی بیشتر به شما میگوید.
TCPing فقط میپرسد: پورت سرور جواب میدهد؟
«آزمایش تأخیر TCP (TCPing)» یک اتصال ساده TCP به آدرس و پورت سرور باز میکند و زمانش را اندازه میگیرد. مهلت این اتصال در کد ۱۰۰۰ میلیثانیه، یعنی یک ثانیه، است. اگر اتصال در این مدت برقرار نشود، نتیجه -1 است.
این آزمایش هیچ کانفیگی برای هسته Xray نمیسازد و هیچ ترافیکی از تونل رد نمیکند. پس عدد سالم TCPing فقط یعنی پورت سرور اتصال TCP را پذیرفته است. نمیگوید پروتکل درست کار میکند. نمیگوید از آن طرف سرور به اینترنت راه هست.
یک نکته مهم دیگر: TCPing بعضی کانفیگها را اصلاً آزمایش نمیکند و مستقیم -1 برمیگرداند. در نسخه 2.3.15 این موارد رد میشوند: کانفیگهای WireGuard، کانفیگهای Hysteria2، کانفیگهای از نوع complex (کانفیگ سفارشی پیچیده)، کانفیگهایی که همه مقدارهای ALPN آنها با h3 شروع میشود، و کانفیگهایی که آدرس سرورشان خالی است یا پورتشان قابل خواندن نیست. برای این کانفیگها، -1 در TCPing هیچ چیزی درباره سرور نمیگوید.
آزمایش تأخیر واقعی یک درخواست واقعی از تونل میفرستد
«آزمایش تأخیر واقعی» دو مرحله دارد. در مرحله اول همان اتصال TCP یکثانیهای به سرور را امتحان میکند. اگر این مرحله شکست بخورد، همانجا -1 میدهد و مرحله دوم اصلاً اجرا نمیشود. برای WireGuard و Hysteria2، کانفیگهای complex و کانفیگهایی که ALPN آنها با h3 شروع میشود، این پیشآزمون انجام نمیشود و برنامه مستقیم سراغ مرحله دوم میرود.
مرحله دوم کار اصلی است. برنامه یک کانفیگ آزمایشی برای هسته میسازد و از داخل همان پروکسی یک درخواست به آدرسی میفرستد که در تنظیمات با نام «URL آزمایش تأخیر واقعی» آمده است (در نسخه انگلیسی Real delay test URL). اگر این تنظیم خالی باشد، برنامه از آدرس پیشفرض استفاده میکند. پیشفرض در نسخه 2.3.15 این است:
https://www.gstatic.com/generate_204جزئیات اندازهگیری در کتابخانه هستهای است که برنامه از آن استفاده میکند: AndroidLibXrayLite، که ما شاخه main آن را در ۱۷ آبان ۱۴۰۵ خواندیم. نتوانستیم تأیید کنیم که فایل هسته داخل نسخه 2.3.15 دقیقاً از همین کد ساخته شده است، پس این اعداد را رفتار کد فعلی بدانید. در این کد، جواب HTTP با کد 200 یا 204 موفقیت حساب میشود. درخواست دو بار فرستاده میشود و سریعترین تلاش موفق گزارش میشود. هر درخواست روی هم ۱۲ ثانیه مهلت دارد و دستدادن TLS (همان مرحله آغاز اتصال رمزشده HTTPS) ۶ ثانیه.
پس این آزمایش کل مسیر را یکجا امتحان میکند: از گوشی تا سرور، پروتکل و رمزنگاری، و راه سرور تا اینترنت. یک نتیجه مهم از همینجا میآید. درخواست آزمایش از سمت سرور به اینترنت میرود. پس اگر خود سرور به آدرس آزمایش نرسد، نتیجه شکست است، حتی اگر بقیه سایتها از همان سرور باز شوند.
عدد -1 کنار سرور یعنی چه؟
در فهرست سرورها، نتیجه شکست یک عدد منفی است که با رنگ قرمز چاپ میشود. متن هر ردیف از قالب «%1$d میلیثانیه» ساخته میشود. پس شکست با مقدار -1 باید به شکل «-1 میلیثانیه» دیده شود. این را از کد نتیجه گرفتهایم، نه از تصویر صفحه. اگر مقدار صفر باشد، ردیف خالی میماند.
ردیف فهرست هیچوقت کلمه timeout یا متن خطا را نشان نمیدهد. خطاهایی که حین آزمایش هر سرور رخ میدهند در کد بیصدا کنار گذاشته میشوند. پس -1 یک عدد کلی است. معنایش این است که جواب سالم نیامد، یا آزمایش برای این نوع کانفیگ انجام نشد. نمیگوید کدام مرحله شکست خورده است.
خود برنامه هم به این محدودیت اشاره میکند. در توضیح گزینه حذف خودکار کانفیگهای نامعتبر بعد از آزمایش آمده است که نتیجه پینگ همیشه دقیق نیست و کانفیگ حذفشده برنمیگردد. اگر این گزینه را روشن کنید، ممکن است کانفیگی را که کار میکرد از دست بدهید.
پیام «آزمایش اتصال ناموفق بود» از کجا میآید؟
متن خطا را جای دیگری میبینید: در خط وضعیت اتصال، وقتی برنامه وصل است و اتصال را آزمایش میکند. اگر آزمایش موفق باشد، این متن را میبینید:
اتصال در %1$s با موفقیت برقرار شدبه جای %1$s مدت زمان اتصال مینشیند. اگر شکست بخورد، این متن را میبینید:
آزمایش اتصال ناموفق بود: %sبه جای %s متن خطای خود هسته مینشیند. در نسخه انگلیسی همین پیام Connection test failed: %s است. اگر هسته متنی برنگرداند، به جای آن «جزئیاتی در دسترس نیست» نوشته میشود. یک نکته کوچک: برنامه پیش از نمایش، ابتدای پیام هسته را تا اولین ": حذف میکند. پس معمولاً فقط انتهای پیام اصلی را میبینید.
در این آزمایش اتصال، اگر تلاش اول -1 بدهد، برنامه یک بار دیگر با آدرس دوم امتحان میکند:
https://www.google.com/generate_204هر دو آدرس پیشفرض متعلق به Google هستند. این نکته در قدم پنجم چکلیست به کار میآید.
i/o timeout و TLS handshake timeout و context deadline exceeded
این متنها را v2rayNG ننوشته است. کتابخانه هستهای که v2rayNG استفاده میکند به زبان Go نوشته شده است و این پیامها متن خطاهای کتابخانه استاندارد Go هستند. هر کدام میگوید کدام ساعت تمام شد.
i/o timeout متن خطایی است که Go وقتی برمیگرداند که مهلت یک عمل شبکه تمام شود، مثلاً خواندن، نوشتن یا برقراری اتصال. در کد Go توضیح داده شده که این متن عمداً عوض نمیشود، چون نسخههای قدیمی هم همین را برمیگرداندند. معنای عملیاش ساده است: یک عمل شبکه منتظر ماند و جوابی نیامد. از این پیام بهتنهایی نمیشود فهمید کدام مرحله در هسته Xray منتظر مانده بود.
net/http: TLS handshake timeout یعنی دستدادن TLS در مهلت تعیینشده تمام نشد. در کد هسته این مهلت ۶ ثانیه است. دقت کنید این دستدادن TLS با سایت آزمایش است، یعنی www.gstatic.com، که از داخل پروکسی رد میشود. پس این پیام لزوماً درباره دستدادن TLS خود پروکسی شما با سرور نیست.
context deadline exceeded متن خطای Go برای وقتی است که مهلت کلی یک کار تمام شود. در کد هسته، آزمایش با هسته در حال اجرا ۱۲ ثانیه بودجه کلی دارد. این پیام یعنی کل آن ۱۲ ثانیه گذشت و آزمایش تمام نشد.
گاهی هم عبارتی مثل (Client.Timeout exceeded while awaiting headers) در پیام Go هست. این یعنی مهلت کلی درخواست HTTP تمام شد و هنوز سرآیند جواب نرسیده بود. اما چون برنامه ابتدای پیام را کوتاه میکند، قول نمیدهیم این عبارت را دقیقاً همینطور ببینید.
نتیجه این بخش: این پیامها در اصل یک چیز میگویند، یعنی سکوت تا پایان مهلت. فرقشان فقط در این است که کدام مهلت تمام شد. هیچکدام علت را نمیگوید.
اگر TCPing سالم است ولی تأخیر واقعی -1 میدهد
ترکیب نتیجه دو آزمایش از هر کدام بهتنهایی مفیدتر است.
- TCPing سالم، تأخیر واقعی
-1. پورت سرور اتصال TCP را میپذیرد، پس سرور خاموش نیست و پورتش هم کامل بسته نیست. مشکل بعد از اتصال TCP است: تنظیمات کانفیگ (شناسه کاربر، رمز، SNI یا مسیر)، مسدود شدن خود پروتکل بعد از اتصال، راه سرور به اینترنت، یا نرسیدن سرور به آدرس آزمایش. - هر دو
-1. اینجا دو مدرک جدا ندارید. آزمایش تأخیر واقعی همان پیشآزمون TCP را اجرا میکند، پس ممکن است هر دو نتیجه از یک شکست TCP آمده باشند: سرور خاموش است، پورتش بسته است، یا راه شما به آن آدرس بسته است. - TCPing
-1روی WireGuard یا Hysteria2. این نتیجه چیزی نمیگوید، چون TCPing این کانفیگها را آزمایش نمیکند. فقط به آزمایش تأخیر واقعی نگاه کنید. - تأخیر واقعی سالم، ولی سایتها باز نمیشوند. تونل کار میکند. سراغ DNS بروید (قدم ششم).
یک گزارش قدیمی هم هست که باید بدانید. در issue شماره 2993 مخزن v2rayNG، یک کاربر در فروردین ۱۴۰۳ گزارش داد که روی سرورهای WireGuard، چه با TCPing و چه با آزمایش واقعی، همیشه -1ms نشان داده میشود، حتی وقتی بعضی از آن سرورها در عمل کار میکنند. این issue بدون پاسخ نوشتهشده از نگهدارنده پروژه، با وضعیت «not planned» بسته شد. این گزارش درباره یک نسخه قدیمی است و نمیدانیم در 2.3.15 هنوز همینطور است یا نه. اما نکتهاش درست میماند: -1 ثابت نمیکند که کانفیگ مرده است. قبل از دور انداختن یک کانفیگ، یک بار واقعاً به آن وصل شوید و یک سایت را باز کنید.
چکلیست بدون ترمینال، به ترتیب
این قدمها را به همین ترتیب امتحان کنید. قدمهای اول ارزانترند و بیشتر مشکلها را جدا میکنند.
۱. یک کانفیگ یا سرور دیگر از همان اشتراک
اگر اشتراک شما چند سرور دارد، چند تا را آزمایش کنید. اگر همه -1 میدهند، مشکل احتمالاً مشترک است: شبکه شما، اشتراک شما یا سرویسدهنده. اگر فقط یکی -1 میدهد، همان سرور مشکل دارد و بقیه را استفاده کنید.
۲. وایفای در برابر اینترنت همراه
یک بار با وایفای و یک بار با اینترنت همراه امتحان کنید. شبکههای مختلف ممکن است ترافیک را متفاوت فیلتر کنند. اگر کانفیگ روی یکی کار میکند و روی دیگری timeout میدهد، کانفیگ سالم است و مسیر شبکه فرق میکند. این را هم به فروشنده بگویید، چون برای او اطلاعات مفیدی است.
۳. اشتراک را بهروز کنید و انقضا را بپرسید
ممکن است آدرس یا پورت سرور عوض شده باشد. در v2rayNG گزینه «بهروزرسانی گروه فعلی اشتراک» را بزنید تا کانفیگهای تازه را بگیرد، و اگر لازم است «به روزرسانی خودکار اشتراک ها» را روشن کنید. بعد از فروشنده بپرسید اشتراک شما منقضی نشده و حجمش تمام نشده است.
۴. تاریخ و ساعت گوشی را روی خودکار بگذارید
در تنظیمات اندروید، تاریخ و ساعت را روی حالت خودکار بگذارید. مستندات Xray برای پروتکل VMess صریح است: ساعت UTC دستگاهی که Xray روی آن اجرا میشود باید حداکثر ۱۲۰ ثانیه با زمان واقعی فاصله داشته باشد. منطقه زمانی مهم نیست، خود ساعت مهم است. این قاعده در مستندات فقط برای VMess آمده است. برای VLESS و Trojan و Reality چنین عددی در صفحاتی که خواندیم ندیدیم، پس آن را به آنها تعمیم ندهید.
این قاعده برای هر دو طرف است، یعنی سرور هم باید ساعت درستی داشته باشد. شما فقط ساعت گوشی را در دست دارید. اگر سرور مال خودتان است، تنظیم و همگامسازی ساعت سرور مجازی را بخوانید.
۵. آدرس آزمایش تأخیر واقعی را عوض کنید
هر دو آدرس پیشفرض متعلق به Google هستند. اگر سرور شما به این آدرسها نمیرسد، آزمایش واقعی همیشه شکست میخورد، حتی وقتی تونل کار میکند. در تنظیمات دنبال «URL آزمایش تأخیر واقعی» بگردید و یک آدرس HTTPS دیگر بگذارید که با کد 204 یا 200 جواب میدهد. اگر با آدرس تازه نتیجه سالم شد، مشکل از آدرس آزمایش بود، نه از اتصال شما. این تغییر فقط آزمایش را عوض میکند و روی خود اتصال اثری ندارد.
۶. تنظیمات DNS داخل برنامه را بررسی کنید
اگر تونل وصل است ولی سایتها باز نمیشوند، DNS (سامانهای که نام سایت را به آدرس IP تبدیل میکند) مقصر رایجی است. v2rayNG چند تنظیم DNS دارد. در تنظیمات دنبال این نامها بگردید:
فعال کردن DNS محلی
DNS راه دور (UDP/TCP/HTTPS/QUIC، اختیاری)
DNS مستقیم (اختیاری)
VPN DNS (فقط IPv4/IPv6)
فعالسازی DNS مجازی (FakeDNS)اگر یکی از اینها را قبلاً تغییر دادهاید، آن را به حالت قبل برگردانید و دوباره امتحان کنید. اگر فروشنده مقدار خاصی برای DNS گفته است، همان را وارد کنید.
اپهای WireGuard و OpenVPN چه نشان میدهند؟
اگر به جای v2rayNG از برنامه WireGuard یا OpenVPN استفاده میکنید، دنبال کلمه timeout نگردید. این برنامهها سکوت را به شکل دیگری نشان میدهند.
برنامه WireGuard برای اندروید
در متنهای برنامه WireGuard برای اندروید هیچ رشتهای با کلمه timeout نیست. خطاهای آن درباره روشن کردن تونلاند، مثل Error bringing up tunnel: %s. وقتی سرور جواب نمیدهد، تونل روشن به نظر میرسد، ولی خط «Latest handshake» (آخرین دستدادن) و شمارندههای ترافیک در صفحه جزئیات دیده نمیشوند. برنامه این بخش را تا وقتی دستدادنی انجام نشده پنهان میکند و چیزی مثل «never» هم نمینویسد.
دلیلش در طراحی پروتکل WireGuard است. صفحه پروتکل WireGuard میگوید سرور به کلاینتی که مجاز نیست اصلاً جواب نمیدهد و ساکت و نامرئی است. کلاینت شروع دستدادن را چند بار تکرار میکند و بعد از مدتی دست میکشد. پس از سمت شما، کلید اشتباه و سروری که جواب نمیدهد یک شکل دارند: تونل روشن، بدون خط Latest handshake. برای اینکه بفهمید چرا WireGuard اینطور ساخته شده، نحوه کار WireGuard و مسیریابی بر اساس کلید را ببینید.
برنامه OpenVPN برای اندروید
برنامه متنباز OpenVPN for Android وضعیت اتصال را با برچسب نشان میدهد. برچسب مهم برای این موضوع «Waiting for server reply» (در انتظار پاسخ سرور) است. اگر اتصال روی این وضعیت بماند، یعنی سرور جواب نمیدهد. در متنهای این برنامه رشتهای مثل «timed out» نیست.
متن دقیقتر در لاگ برنامه است. خود OpenVPN وقتی تبادل کلید TLS در مهلت تمام نشود این خط را مینویسد:
TLS Error: TLS key negotiation failed to occur within %d seconds (check your network connectivity)به جای %d مقدار گزینه --hand-window مینشیند که در راهنمای OpenVPN 2.6 پیشفرضش ۶۰ ثانیه است. برنامه OpenVPN Connect (برنامه رسمی و غیرمتنباز) را بررسی نکردهایم، پس متن آن ممکن است فرق کند.
وقتی کانفیگ مال شما نیست
حرف آخر را صادقانه بگوییم. روی کانفیگی که از کس دیگری گرفتهاید، بیشتر timeoutها فقط به دست صاحب کانفیگ درست میشوند. شما میتوانید با این چکلیست مشکلهای سمت خودتان را کنار بگذارید: ساعت گوشی، شبکه، اشتراک قدیمی و آدرس آزمایش. اگر بعد از همه اینها هنوز -1 میبینید، سرور و پورت و پروتکل در اختیار شما نیستند.
بهترین کار این است که اطلاعات دقیق به فروشنده بدهید: کدام سرورها، روی وایفای یا اینترنت همراه، نتیجه TCPing و نتیجه آزمایش واقعی، و متنی که بعد از «آزمایش اتصال ناموفق بود:» آمده است. این اطلاعات خیلی بیشتر از جمله «کار نمیکند» کمک میکند.
این را هم در نظر داشته باشید که صاحب سرور مسیر همه ترافیک شما را در دست دارد. کانفیگ رایگان یا ناشناس یعنی به کسی اعتماد میکنید که نمیشناسید. اگر میخواهید سرور و کلیدها مال خودتان باشد، راهاندازی WireGuard روی سرور مجازی خودتان قدم به قدم توضیح داده شده است. اگر مدیریت با رابط وب برایتان راحتتر است، راهاندازی wg-easy با Docker را ببینید. سرور شخصی هم ممکن است فیلتر شود، اما دستکم لاگ و تنظیمات دو طرف را خودتان میبینید.
پرسشهای پرتکرار (FAQ)
عدد -1 در v2rayNG یعنی سرور از کار افتاده است؟
نه لزوماً. -1 یعنی آزمایش جواب سالمی نگرفت، یا برای این نوع کانفیگ اصلاً آزمایشی انجام نشد. در نسخه 2.3.15، TCPing برای کانفیگهای WireGuard و Hysteria2 بدون آزمایش -1 برمیگرداند. یک کاربر هم در issue شماره 2993 مخزن v2rayNG گزارش داده بود که سرورهای WireGuard با وجود -1 کار میکردند. قبل از کنار گذاشتن کانفیگ، یک بار به آن وصل شوید و سایتی را باز کنید.
چرا TCPing جواب میدهد ولی فیلترشکن وصل نمیشود؟
TCPing در v2rayNG فقط یک اتصال TCP به پورت سرور باز میکند و ترافیکی از تونل رد نمیکند. پس TCPing سالم فقط یعنی پورت باز است. اگر «آزمایش تأخیر واقعی» شکست بخورد، مشکل بعد از اتصال TCP است: تنظیمات کانفیگ، مسدود شدن پروتکل، راه سرور به اینترنت، یا نرسیدن سرور به آدرس آزمایش پیشفرض، https://www.gstatic.com/generate_204.
پیام i/o timeout در فیلترشکن یعنی چه؟
i/o timeout متن خطای کتابخانه استاندارد Go است و کتابخانه هسته v2rayNG با Go نوشته شده است. Go این متن را وقتی برمیگرداند که مهلت یک عمل شبکه، مثل خواندن یا برقراری اتصال، تمام شود. یعنی برنامه منتظر ماند و جوابی نیامد. علت را نمیگوید، پس با چکلیست بالا سمت خودتان را بررسی کنید و بعد جزئیات را به صاحب کانفیگ بدهید.
آیا ساعت گوشی روی timeout در فیلترشکن اثر دارد؟
برای پروتکل VMess بله. مستندات Xray میگوید ساعت UTC دستگاهی که Xray روی آن اجرا میشود باید حداکثر ۱۲۰ ثانیه با زمان واقعی فاصله داشته باشد، و منطقه زمانی مهم نیست. تاریخ و ساعت اندروید را روی حالت خودکار بگذارید. مستندات این عدد را برای پروتکلهای دیگر نگفته است، ولی خودکار گذاشتن ساعت در هر حال ضرری ندارد.