OpenVPN TCP-vasvriesing: rto_min los nie hoof-van-die-lyn op nie
'n Buitenste greepstroom lewer in volgorde, so een ontbrekende segment kan elke binneste stroom laat pouseer. 'n Langer binneste tydhouer verander 'n klok, nie daardie beperking nie.
'n Interaktiewe shell oor die tonnel vries vir 'n paar sekondes terwyl 'n lêerkopie loop en hervat dan asof niks gebeur het nie. Die aflaai is die enigste ding met 'n probleem, tog wag die shell ook, en albei herstel op dieselfde oomblik. Daardie patroon is die kenmerk van een betroubare stroom wat baie gesprekke dra, en dit oorleef byna elke instellingverandering wat mense eerste probeer.
Die simptoom is werd om aandagtig te lees, want dit wys op 'n meganisme eerder as 'n instelling: die pouse word gedeel, dus word die oorsaak gedeel, en die gedeelde objek is die buitenste verbinding. Alles anders in die log lyk normaal terwyl dit gebeur.
Die simptoom: alles pouseer terselfdertyd
Twee binneste verbindings wat saam vasval, is die leidraad. 'n Stadige aflaai en 'n stadige shell is aparte TCP-gesprekke met aparte volgordenommers en aparte oorbelastingstoestand, so 'n fout in een van hulle behoort nie die ander te raak nie. Wanneer hulle in pas pouseer, is daar iets bokant hulle wat hul grepe orden.
Daardie iets is die tonnel se vervoerlaag. In TCP-modus skryf OpenVPN die ingekapselde pakkette in een TCP-verbinding na die eweknie, en TCP se kontrak is in-volgorde aflewering van 'n enkele greepstroom. Latere grepe word nie aan die toepassing oorhandig voordat die ontbrekende nie, maak nie saak aan watter binneste gesprek hulle behoort nie.
Let op wat die simptoom jou nie vertel nie. Dit sê nie die pad is stukkend nie, die bediener is oorlaai nie, of die syfer is te stadig nie. Dié lewer ander vorms: eenvormig lae deurvloei, tydsverstrykings, of foute wat een rigting raak. 'n Gedeelde pouse wat eindig wanneer een verlore segment hertransmitteer word, is spesifiek 'n ordeningseffek.
Een buitenste greepstroom, baie binneste gesprekke
Stel jou voor die tonnel dra 'n aflaai en 'n shell op dieselfde tyd. 'n Segment van die buitenste verbinding gaan verlore. Die volgende segmente kom dalk by die ontvangende gasheer aan, en die ontvangende TCP-stapel sal hulle erken, maar dit kan hulle nie opwaarts aflewer voordat die gaping gevul is nie. OpenVPN het dus niks om vir die shell te lees nie, al het die shell se eie grepe lank gelede aangekom.
Dit is hoof-van-die-lyn-blokkering binne een verbinding, en dit vereis nie dat die twee toepassings 'n binneste verbinding deel nie. Hulle deel die buitenste een, en dit is genoeg.
Die tweede-orde-effek maak dit erger. 'n Binneste sender wat geen erkenning sien nie, kan data hertransmitteer wat die buitenste laag reeds probeer aflewer. Daardie hertransmissie word bykomende tonnelverkeer op 'n pad wat pas bewys het dat dit segmente kan verloor, so die herstelwerk meeding met die herstel wat saak maak.
Niks hiervan waarborg 'n ineenstorting nie. Op 'n skoon pad met kort heen-en-weer-tye en ruim toue kan die reëling jare lank heeltemal bruikbaar wees. Die faling verskyn wanneer verlies, vertraging en tou-diepte in lyn kom, en daarom kluster die verslae rondom oorlaaide opstroomskakels en mobiele skakels eerder as rondom goed toegeruste kantore.
Waarom 'n langer binneste tydhouer nie kan help nie
Om die minimum hertransmissie-tydsverstryking op 'n roete te verhoog met rto_min stel tydhouer-gebaseerde hertransmissie uit vir plaaslik gegenereerde TCP-verkeer wat daardie roete gebruik. Dit is 'n werklike knop met 'n werklike effek, en dit pak die tweede-orde-probleem aan eerder as die eerste.
ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1
Wat dit nie kan doen nie, is om buitenste grepe buite volgorde vry te stel, die ontbrekende segment vinniger te herwin, of die afgeleë toepassingbediener dieselfde tydhouer te laat aanneem. Die ontvangende stapel lewer steeds in volgorde, en die sender aan die ander kant gebruik steeds sy eie heen-en-weer-metings.
Dit skakel ook nie elke ander verliesherwinningsmeganisme af nie. Waar werklike verlies tydhouer-gebaseerde herwinning vereis, laat 'n groter minimum die toepassing langer wag voordat dit optree, wat die teenoorgestelde is van wat 'n latency-sensitiewe sessie nodig het.
'n Vaste vloer van twaalf sekondes verskyn in advies oor hierdie onderwerp asof die bestaan van 'n TCP-tonnel dit impliseer. Die hertransmissie-tydhouer wat in RFC 6298 beskryf word volg uit gemete heen-en-weer-tyd met eksponensiële terugtrekking, so 'n konstante vloer is 'n beleidskeuse vir 'n spesifieke pad eerder as 'n protokolvereiste. Wyd toegepas, verberg dit die simptoom terwyl dit herwinning verander vir elke stroom wat daardie roete dek.
Wat tcp-nodelay doen en nie doen nie
Die tonnel-opsie wat Nagle-tipe buffering op die vervoersokkel afskakel, het 'n nou doel: dit keer dat klein skrywes op meer data wag voordat hulle gestuur word. Dit help interaktiewe verkeer om 'n ekstra vertraging op 'n andersins gesonde pad te vermy.
Dit maak die vervoer nie ongesorteerd nie, en dit verkort nie herwinning ná 'n verlore segment nie. 'n Shell wat vir 'n hertransmissie-tydsverstryking pouseer, sal steeds pouseer met daardie opsie geaktiveer, want die opsie het nooit aan die ordeningsreël geraak nie.
Dit is maklik om die twee te verwar, want albei word as latency-oplossings beskryf. Een verwyder 'n kunsmatige wag wat deur buffering ingebring is; die ander sou vereis dat verander word wat die vervoer waarborg, wat geen sokkelopsie doen nie.
Hoe om vervoer regverdig te vergelyk
As die operateur dit toelaat en albei dienste bestaan, vergelyk 'n UDP-diens en 'n TCP-diens wat dieselfde werklading dra oor dieselfde toegangspad na dieselfde bediener. Om land, verskaffer of bedienergenerasie tussen die twee toetse te verander, bring 'n veranderlike in wat die resultaat sal oorheers.
Let op die gedeelde pouse eerder as op 'n deurvloei-syfer. Verskeie binneste toepassings wat saam vasval tydens buitenste verlies is die waarneming wat hoof-van-die-lyn-blokkering identifiseer; 'n enkele laer spoedtoets-syfer doen dit nie.
Gemagtigde opnames op die tonnelkoppelvlak en op die fisiese koppelvlak skei die twee lae skoon, want binneste en buitenste hertransmissies behoort aan verskillende verbindings met verskillende volgorde-ruimtes. Om binneste hertransmissies te sien terwyl die buitenste stroom 'n gaping toon, is die direkte bewys.
Om na UDP oor te skakel verwyder die ekstra betroubare stroom en laat die binneste TCP sy eie herwinning doen. Dit belowe nie zero verlies of lae latency nie, en 'n versadigde opstroomskakel, oorgroot toue of 'n MTU-probleem sal steeds reggemaak moet word. Verkeer buite die tonnel word nooit agter die tonnel se volgorde-gaping gehou nie, al kan dit steeds ly wanneer albei paaie een oorlaaide skakel deel, en daardie gedeelde bottelnek verdien sy eie ondersoek eerder as om by hierdie een ingevou te word.