Android VpnService: darllen TUN yn stondio yn erbyn gwallau ysgrifennu ENOBUFS
Mae darllen nad yw byth yn dychwelyd ac ysgrifennu sy'n methu ag ENOBUFS yn cael achosion cyferbyniol. Mesurwch y ffenestr a hysbysebir a hyd y pecyn i ddewis y gwelliant.
Mae dau symptom yn ymddangos yn yr un ddolen VpnService ac yn cael eu beio ar yr un peth: darllenydd nad yw byth yn dychwelyd, ac ysgrifennu sy'n methu ag ENOBUFS. Nid ydynt yn amrywiadau o un nam. Mae darlleniad sydd wedi stondio yn anghytundeb am reoli llif gyda'r peer; mae ysgrifennu wedi methu yn becyn na fydd y rhyngwyneb yn ei dderbyn. Os byddwch yn eu trin fel un broblem, byddwch yn treulio diwrnod yn tiwnio byfferau na chawsant eu cynnwys erioed. Y rhaniad isod yw sut yr wyf yn penderfynu pa hanner o'r ddolen i'w hofferynnoli gyntaf.
Un ddolen, dau bwynt methiant annibynnol
Mae eich gwasanaeth yn darllen pecyn IP o ddisgrifydd ffeil TUN, yn ei archwilio ac yn ysgrifennu ateb yn ôl i'r un disgrifydd. Mae popeth sy'n torri ar y llwybr hwnnw yn dod i'r amlwg ar un o'r ddau alwad hynny, a dyna pam y caiff y ddau eu hadrodd fel y tiwnel wedi torri. Mae gan y galwadau gontractau gwahanol. Mae darllen yn aros i'r cnewyllyn roi pecyn i chi, ac mae ysgrifennu yn rhoi i'r cnewyllyn becyn y mae ganddo hawl i'w wrthod.
Darlleniadau yw'r hanner hawdd i resymu amdano. Mae darlleniad nad yw'n dychwelyd dim naill ai'n aros am draffig nad yw byth yn cyrraedd neu'n aros oherwydd bod y peer wedi stopio anfon.
Mae darlleniad wedi stondio yn anghytundeb rheoli llif
Mae darllen dyfais TUN yn blocio nes bod pecyn ar gael. Ymddygiad bwriadedig yw hwnnw, a dyna pam mae edau wedi'i pharcio y tu mewn i read yn edrych yn normal ar ddolen segur. Mae'n troi'n hongiad pan fydd eich stac TCP eich hun yn parhau i dderbyn data o'r ap lleol ond byth yn hysbysebu digon o ffenestr i'r peer pell anfon mwy. Mae'r peer yn llenwi'r ffenestr a hysbysebwyd gennych, yn aros am ACK ac am ddiweddariad ffenestr, ac yn stopio. Yna nid oes gan eich darllenydd ddim i'w ddychwelyd, ac mae'r ap yn gweld cysylltiad sy'n agored ac yn dawel.
Yr achosion cyffredin yw stac sy'n ysgrifennu i'r soced heb olrhain y ffenestr a hysbysebir, ac un sy'n anghofio anfon diweddariad ffenestr ar ôl draenio ei fywffer. O'r tu allan maent yn edrych yn union yr un fath: mae beitiau'n mynd allan, nid oes dim yn dod yn ôl, nid oes gwall yn cael ei godi. Mae blocio'r edau ddarllen ar barsio, datrysiad DNS neu I/O disg yn cynhyrchu'r un siâp o symptom am reswm anghysylltiedig, felly cadarnhewch fod yr edau mewn gwirionedd y tu mewn i read cyn beio rheoli llif.
Gwiriwch giw anfon y peer a'r ffenestr y gwelodd hi ddiwethaf. Os yw'r peer yn dal data oherwydd bod eich ffenestr yn sero, mae'r gwelliant yn eich llwybr ACK, nid yn narlleniad TUN.
Mae ENOBUFS yn broblem maint, nid prinder byffer
Mae ysgrifennu sy'n dychwelyd ENOBUFS ar ryngwyneb TUN fel arfer yn gwrthod hyd y pecyn. Mae gan y rhyngwyneb MTU, ni ellir ciwio pecyn mwy na hynny, ac mae ailgynnig yr un pecyn yn methu yr un ffordd bob tro. Yr awgrym yw'r deterministiaeth honno. Mae gwir brinder byffer yn clirio wrth i'r pwysau ostwng, tra nad yw gwrthodiad maint yn poeni faint yr arhoswch.
Mae gan TCP fecanwaith ar gyfer hyn yn union, a dyma'r cam y mae pobl yn ei hepgor: y clamp MSS. Pan fyddwch yn syntheseiddio segmentau yn y gofod defnyddiwr chi sy'n dewis maint y payload, ac mae ei ddewis o MTU'r rhyngwyneb lleol yn lle MTU'r tiwnel yn allyrru segmentau na all y tiwnel eu cario. Clampwch i'r lleiaf o'r ddau. Dim ond TCP y mae'r clamp yn ei gynnwys, felly rhaid i'ch cod darnio neu ollwng datagram UDP gormodol.
Cofnodwch hyd pob pecyn a ysgrifennwch wrth ddadfygio. Y hyd sy'n methu yw'r ateb, ac ni fydd yn symud rhwng ymgais.
Tri mesuriad sy'n gwahanu'r achosion
Nid oes angen dadfygiwr arnoch ar gyfer y naill fethiant na'r llall. Mae tri arsylwi yn ddigon i'ch cyfeirio at yr adran gywir, ac maent yn cymryd llai o amser nag ailadeiladu.
| What you see | Where to look |
|---|---|
| Reader parked, peer send queue empty, last advertised window zero | Window updates in your ACK path |
| Write fails on one length and succeeds on a smaller one | MSS clamp and tunnel MTU |
| Both directions look fine, app still sees no data | Protected socket and routing loop |
Os yw'r drydedd res yn cyfateb, mae'r ddolen ei hun yn iawn ac mae'r broblem lle na all y tiwnel ei gweld: soced cludo heb ei warchod yn cario eich traffig VPN eich hun yn ôl i'r tiwnel, sy'n ymddangos fel arfer fel cysylltiad sy'n llwyddo ac yna'n danfon dim.
Trwsiwch y plwm y mae'r ddau lwybr yn dibynnu arno
Nid oes unrhyw symptom yn werth ei erlid nes bod y rhyngwyneb wedi'i adeiladu'n gywir. Y galwadau builder sy'n bwysig yw'r cyfeiriad, y llwybr, yr MTU a'r cydsyniad, yn y drefn honno:
Builder()
.addAddress(10.8.0.2, 32)
.addRoute(0.0.0.0, 0)
.setMtu(1400)
.establish()Gosodwch yr MTU i wir werth y tiwnel yn lle ei adael ar beth bynnag a ddefnyddiwyd gan yr enghraifft. Mae popeth a ysgrifennwch yn ddiweddarach wedi'i ffinio gan y rhif hwnnw, ac anghysondeb rhwng yr MTU a osodwch a'r MSS yr ydych yn clampio iddo yw'r ffordd fwyaf cyffredin o ailgyflwyno'r methiant ysgrifennu ar ôl gwelliant. Yna gwarchodwch y soced sy'n cario traffig i'r gweinydd VPN ei hun. Heb protect, mae'r pecynnau hynny'n cael eu llwybro'n ôl i'ch tiwnel eich hun ac ni fydd y cysylltiad byth yn cwblhau, sy'n edrych fel darlleniad wedi stondio ond yn ddolen llwybro.
Ni ellir osgoi cydsyniad. Nid yw gwasanaeth a gychwynnwyd heb i prepare ddychwelyd null yn cael rhyngwyneb, ac mae establish yn dychwelyd null yn lle taflu, felly gwiriwch y disgrifydd cyn dechrau eich dolen. Cyfeirlyfr VpnService yw'r lle i gadarnhau contract y builder yn lle copio enghraifft.
Gwiriwch un cyfeiriad ar y tro
Anfonwch eco UDP trwy'r tiwnel a gwylio hyd y pecynnau cyn i chi gyffwrdd â TCP. Yna agorwch handshake a chadarnhau bod y segmentau'n aros o dan yr MSS a gyfrifwyd gennych. Cyfrifwch becynnau yn hytrach na chysylltiadau, fel bod stondiad yn ymddangos fel bwlch yn y rhifydd yn lle soced wedi hongian. Os bydd darlleniadau'n stopio ar ôl ffrwydrad o ysgrifeniadau, y ffenestr yw'r sawl dan amheuaeth; os bydd ysgrifeniadau'n methu ar unwaith, y hyd ydyw.
Yna ailgychwynnwch y ddyfais ac ailadroddwch unwaith, oherwydd mae VpnService sy'n gweithio dim ond tan y newid rhwydwaith cyntaf yn broblem llwybro yn hytrach na rheoli llif.