OpenVPN روی TCP: rto_min گرفتگی سر صف را رفع نمیکند
جریان بایت بیرونی به ترتیب تحویل میدهد، پس یک قطعه گمشده میتواند هر جریان درونی را متوقف کند. تایمر درونی بلندتر یک ساعت را عوض میکند، نه این محدودیت را.
یک پوسته تعاملی روی تونل چند ثانیه یخ میزند در حالی که کپی فایل اجرا میشود، سپس طوری ادامه میدهد که گویی هیچ اتفاقی نیفتاده است. فقط دانلود مشکل دارد، با این حال پوسته هم منتظر میماند، و هر دو در یک لحظه بهبود مییابند. این الگو امضای یک جریان مطمئن واحد است که گفتگوهای بسیاری را حمل میکند، و تقریباً از هر تنظیمی که مردم اول امتحان میکنند جان سالم به در میبرد.
ارزش دارد نشانه را با دقت خواند چون به یک سازوکار اشاره دارد نه به یک تنظیم: توقف مشترک است، پس علت مشترک است، و شیء مشترک اتصال بیرونی است. بقیه گزارش در این مدت عادی به نظر میرسد.
نشانه: همهچیز همزمان متوقف میشود
دو اتصال درونی که با هم گیر میکنند سرنخ هستند. دانلود کند و پوسته کند دو گفتگوی جداگانه TCP با شمارههای ترتیب جداگانه و وضعیت ازدحام جداگانه هستند، پس خرابی در یکی نباید به دیگری دست بزند. وقتی هماهنگ متوقف میشوند، چیزی بالای آنها بایتهایشان را مرتب میکند.
آن چیز لایه انتقال تونل است. در حالت TCP، OpenVPN بستههای کپسولهشده را در یک اتصال TCP به همتا مینویسد، و قرارداد TCP تحویل به ترتیب یک جریان بایت واحد است. بایتهای بعدی پیش از بایتهای گمشده به برنامه داده نمیشوند، هر گفتگوی درونی که باشند.
توجه کنید نشانه چه نمیگوید. نمیگوید مسیر خراب است، سرور بیش از حد بار دارد، یا رمزنگاری کند است. آنها شکلهای دیگری میسازند: توان عبوری یکنواخت پایین، پایان مهلتها، یا خرابیهایی که یک جهت را درگیر میکنند. توقف مشترکی که با ارسال دوباره یک قطعه گمشده تمام میشود، دقیقاً یک اثر ترتیب است.
یک جریان بایت بیرونی، گفتگوهای درونی بسیار
تصور کنید تونل همزمان یک دانلود و یک پوسته را حمل میکند. یک قطعه از اتصال بیرونی گم میشود. قطعههای بعدی ممکن است به میزبان گیرنده برسند و پشته TCP گیرنده آنها را تأیید کند، اما تا پر شدن شکاف نمیتواند آنها را به بالا تحویل دهد. بنابراین OpenVPN چیزی برای خواندن برای پوسته ندارد، هرچند بایتهای خود پوسته مدتها پیش رسیدهاند.
این گرفتگی سر صف درون یک اتصال است، و لازم نیست دو برنامه یک اتصال درونی را شریک شوند. آنها اتصال بیرونی را شریک میشوند، و همین کافی است.
اثر مرتبه دوم بدترش میکند. فرستنده درونی که تأییدی نمیبیند ممکن است دادهای را دوباره بفرستد که لایه بیرونی از قبل در تلاش تحویل آن است. آن ارسال دوباره به ترافیک اضافی تونل روی مسیری تبدیل میشود که همین حالا ثابت کرد میتواند قطعه گم کند، پس کار بازیابی با بازیابی مهم رقابت میکند.
هیچکدام از اینها فروپاشی را تضمین نمیکند. روی مسیری پاک با رفتوبرگشتهای کوتاه و صفهای سخاوتمندانه، این چیدمان میتواند سالها کاملاً قابل استفاده باشد. خرابی وقتی ظاهر میشود که گمشدن، تأخیر و عمق صف همزمان شوند، و به همین دلیل گزارشها پیرامون پیوندهای بالارو شلوغ و پیوندهای همراه خوشه میبندند نه پیرامون دفترهای مجهز.
چرا تایمر درونی بلندتر نمیتواند کمک کند
بالا بردن کمینه مهلت ارسال دوباره روی یک مسیر، با rto_min، ارسال دوباره مبتنی بر تایمر را برای ترافیک TCP تولیدشده محلی که از آن مسیر استفاده میکند به تعویق میاندازد. این یک پیچ واقعی با اثر واقعی است، و مشکل مرتبه دوم را هدف میگیرد نه اولی را.
ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1
چیزی که نمیتواند: بایتهای بیرونی را بیرون از ترتیب آزاد کند، قطعه گمشده را سریعتر بازیابد، یا سرور برنامه دوردست را وادار کند همان تایمر را بپذیرد. پشته گیرنده همچنان به ترتیب تحویل میدهد، و فرستنده در انتهای دور همچنان از اندازهگیریهای رفتوبرگشت خودش استفاده میکند.
همچنین هر سازوکار دیگری برای بازیابی گمشدن را خاموش نمیکند. جایی که گمشدن واقعی به بازیابی مبتنی بر تایمر نیاز دارد، کمینه بزرگتر برنامه را وادار میکند بیشتر صبر کند پیش از اقدام، که عکس چیزی است که نشست حساس به تأخیر نیاز دارد.
یک کف ثابت دوازده ثانیهای در توصیههای این موضوع ظاهر میشود انگار وجود یک تونل TCP آن را ایجاب میکند. تایمر ارسال دوباره توصیفشده در RFC 6298 از زمان رفتوبرگشت اندازهگیریشده با عقبنشینی نمایی مشتق میشود، پس کف ثابت یک انتخاب سیاست برای مسیری خاص است نه یک الزام پروتکل. در کاربرد گسترده، نشانه را پنهان میکند و در همان حال بازیابی را برای هر جریانی که آن مسیر پوشش میدهد تغییر میدهد.
tcp-nodelay چه میکند و چه نمیکند
گزینه تونل که بافرینگ سبک Nagle را روی سوکت انتقال خاموش میکند هدف باریکی دارد: جلوی نوشتنهای کوچک را میگیرد که برای داده بیشتر پیش از ارسال صبر کنند. این کمک میکند ترافیک تعاملی از تأخیر اضافی روی مسیری که در بقیه موارد سالم است بپرهیزد.
انتقال را بیترتیب نمیکند و بازیابی پس از قطعه گمشده را کوتاه نمیکند. پوستهای که برای مهلت ارسال دوباره متوقف شود با فعال بودن آن گزینه هم متوقف میماند، چون گزینه هرگز به قاعده ترتیب دست نزده است.
اشتباه گرفتن این دو آسان است چون هر دو به عنوان اصلاح تأخیر توصیف میشوند. یکی انتظار مصنوعی ناشی از بافرینگ را برمیدارد، دیگری نیازمند تغییر چیزی است که انتقال تضمین میکند، و هیچ گزینه سوکتی این کار را نمیکند.
چگونه انتقالها را منصفانه مقایسه کنیم
اگر اپراتور اجازه دهد و هر دو سرویس وجود داشته باشند، یک سرویس UDP و یک سرویس TCP را که بار کاری یکسان را حمل میکنند روی همان مسیر دسترسی به همان سرور مقایسه کنید. تغییر کشور، ارائهدهنده یا نسل سرور بین دو آزمون متغیری وارد میکند که بر نتیجه چیره خواهد شد.
به توقف مشترک نگاه کنید نه به یک عدد توان عبوری. گیر کردن چند برنامه درونی با هم در طول گمشدن بیرونی همان مشاهدهای است که گرفتگی سر صف را شناسایی میکند; یک عدد پایینتر در آزمون سرعت این کار را نمیکند.
ضبطهای مجاز روی رابط تونل و روی رابط فیزیکی دو لایه را به روشنی جدا میکنند، چون ارسالهای دوباره درونی و بیرونی به اتصالهای متفاوت با فضاهای ترتیب متفاوت تعلق دارند. دیدن ارسال دوباره درونی در حالی که جریان بیرونی شکاف نشان میدهد همان شاهد مستقیم است.
گذر به UDP جریان مطمئن اضافی را برمیدارد و میگذارد TCP درونی بازیابی خودش را انجام دهد. نه گمشدن صفر را وعده میدهد نه تأخیر پایین، و پیوند بالاروی اشباعشده، صفهای بزرگ یا مشکل MTU همچنان نیاز به رفع دارند. ترافیک بیرون تونل هرگز پشت شکاف ترتیب تونل نگه داشته نمیشود، هرچند میتواند هنوز رنج ببرد وقتی هر دو مسیر یک پیوند شلوغ را شریک شوند، و آن گلوگاه مشترک ارزش بررسی جداگانه دارد به جای اینکه در این یکی گنجانده شود.