Lisäsit verkkotunnuksen sallimaluetteloon, kysely saapuu sovellukseesi, täsmäyttäjä palauttaa sallittu, eikä sivu silti koskaan lataudu. Siinä vaiheessa useimmat alkavat kirjoittaa täsmäyttäjää uudelleen ja lisätä jokerimerkkivertailuja. Kokemukseni mukaan täsmäyttäjä on yleensä oikeassa ja vika on kerrosta alempana: syntetisoimassasi DNS-vastauksessa, asentamassasi reitissä tai pistokkeessa, jolla välitit kyselyn. Luettelo on helppo osa; paketin polku on se, missä sallimaluettelot hajoavat.

Täsmäyttäjä on harvoin syyllinen

Ensimmäinen eroteltava asia on estetty ja rikki. Estetyn nimen pitäisi epäonnistua nopeasti ja näkyvästi, koska selain saa vastauksen, ettei nimeä ole, ja pysähtyy. Rikki oleva nimi jumittuu, yrittää uudelleen IPv6:n kautta, putoaa toiselle siirtotielle ja jättää sinut pyörivän ilmaisimen kanssa. Jos näet pyörivän ilmaisimen, sallimaluettelosi vastaa luultavasti jotain, jolla asiakasohjelma ei voi tehdä mitään.

Tyhjä A-tietue on klassinen virhe. NOERRORin palauttaminen nollalla vastauksella näyttää kelvolliselta vastaukselta, joten stub-resolveri hyväksyy sen, selain yrittää uudelleen, kokeilee AAAA:ta, kokeilee toista resolveria ja antaa periksi paljon myöhemmin. Vastauskoodi 3, NXDOMAIN, jossa kysymysosio toistetaan ja tapahtuman tunniste kopioidaan, lopettaa keskustelun heti. Käytä sitä jokaiselle nimelle, jonka tarkoituksella kiellät.

IPv6 ansaitsee saman päätöksen eikä oletusarvoa. Jos vastaat NXDOMAINilla A:lle ja päästät AAAAn läpi, asiakasohjelma voi tavoittaa estetyn nimen IPv6:n kautta ja suodatin vuotaa. Jotkin toteutukset vastaavat estettyihin AAAA-kyselyihin loopback-osoitteella, jotta yhteys epäonnistuu heti sen sijaan, että se putoaisi varavaihtoehtoon. Valitse yksi käytäntö, sovella sitä molempiin tietuetyyppeihin ja kirjaa molemmat.

Reitti, joka kaappaa kaiken, omistaa kaiken

Vain DNS:ään perustuva rakenne ei koskaan lisää addRoute("0.0.0.0", 0)-riviä, joten vain kyselyt tulevat TUN-rajapintaan ja kaikki muu jatkaa alla olevan verkon käyttöä. Se on turvallinen muoto, ja se selittää myös, miksi jotkin sallimaluettelot näyttävät toimivan Wi-Fi-verkossa ja epäonnistuvan matkapuhelinverkossa.

Heti kun oletusreitti on olemassa, jokainen virtaus on sinun. TCP-paketti, joka saapuu rajapintaan eikä tule välitetyksi eikä vastatuksi, istuu jonossa, kunnes asiakasohjelman aika loppuu, eikä kirjattavaa virhettä ole, koska mikään ei epäonnistunut. Näin jonkun viettävän iltapäivän rikkinäisen sallimaluettelon parissa, joka olikin puuttuva välittäjä portille 443. Kirjaa protokolla ja kohde jokaisesta paketista, jonka päätät hylätä.

Resolverin pistokkeen on poistuttava tunnelista

Välitys on seuraavan ansan paikka. Operaattorin resolverit asuvat usein yksityisosoitteessa, johon tunneli ei yllä, joten välittämäsi kysely menee hukkaan ja sovellus raportoi lukemisen aikakatkaisun. Lähetä hyväksytyt kyselyt resolverille, jonka tiedät olevan tavoitettavissa, ja anna se pistoke ensin VpnService.protect():lle. Suojaamaton pistoke lähettää kyselyn takaisin omaan tunneliisi, jossa se saapuu jälleen sovellukseen ja kiertää, kunnes aikakatkaisu laukeaa.

Vika näyttää samalta kuin verkkokatkos, ja siksi se säilyy virheraporteissa niin kauan. Pidä laskureita lähetetyille kyselyille ja vastaanotetuille vastauksille: jos ensimmäinen luku kasvaa ja toinen pysyy nollassa, katsot pistoketta etkä luetteloa.

Koko ja tarkistussummat epäonnistuvat ilman viestiä

Hiljaiset pudotukset tulevat myös koosta. DNS-vastaus, jossa on suuri vastausjoukko, tai TCP-kättely anteliailla valinnoilla voi ylittää polun MTU:n, jota et koskaan asettanut eksplisiittisesti; fragmentti katoaa ylävirtaan ja asiakasohjelma joko yrittää pienempänä uudelleen tai lopettaa yrittämisen. Rajapinnan MTU:n asettaminen arvoon 1280 on konservatiivinen valinta, joka kestää useimmat matkapuhelinpolut, ja eksplisiittisyys on parempi kuin periä oletusarvo, jota kukaan ei mitannut.

Jos rakennat paketit itse, tarkistussumma on toinen hiljainen tappaja. UDP-tarkistussumma, joka lasketaan näennäisotsikon yli, josta puuttuu UDP:n pituus tai protokollakenttä, tuottaa paketin, joka näyttää sinun puolellasi hyvin muodostetulta ja jonka vastaanottaja hylkää jälkiä jättämättä. Vertaa näennäisotsikkoasi määritykseen kenttä kentältä ja tulosta laskettu tarkistussumma yhdelle tunnetulle virtaukselle virheenkorjauksen aikana.

Mitä VpnService ei tee puolestasi

Kaksi rajaa kannattaa tuntea ennen kuin suunnittelee niiden ympärille. Mikään tavallinen sovellus ei voi asentaa järjestelmänlaajuista välityspalvelinta tai PAC-tiedostoa Wi-Fi-verkon ulkopuolella, eikä se osa ole muuttunut. Sovelluskohtainen polku on: ennen API 29:ää VpnService.Builder ei voinut kantaa välityspalvelinta lainkaan, ja API 29:stä lähtien setHttpProxy(ProxyInfo.buildPacProxy(uri)) antaa alustalle PAC-komentosarjan arvioitavaksi VPN-verkkoa varten. Arvioi säännöt omassa koodissasi, kun kohdistat vanhempiin API-versioihin tai kun PAC-malli ei pysty ilmaisemaan sääntöä. UDP ei ole ilmaista sekään: selaimet lähettävät SOCKS-välityspalvelimen kautta vain TCP:tä, ja useimmat SOCKS5-asiakkaat eivät koskaan toteuta UDP ASSOCIATEa, joten välityspalvelinpohjainen rakenne pudottaa tai vuotaa UDP:tä TCP:n näyttäessä terveeltä.

Tämä toinen raja on syy siihen, miksi UDP-pohjainen protokolla voi toimia tavallisessa verkossa ja epäonnistua heti, kun VPN:si yhdistää. Jos tunnelin odotetaan kuljettavan UDP:tä, välittäjän on toteutettava sille välityspolku, ei vain TCP-polkua toisella pistoketyypillä.

Tarkista tässä järjestyksessä

Käy luettelo järjestyksessä ja pysähdy ensimmäiseen vaiheeseen, joka epäonnistuu, koska jokainen myöhempi tarkistus on kohinaa, kunnes edellinen pitää.

  1. Listaa asennetut reitit ja varmista, tulevatko muut kuin DNS-paketit lainkaan TUN-rajapintaan.
  2. Kirjaa kyselyn nimi, päätös ja vastauskoodi yhdelle estetylle ja yhdelle hyväksytylle nimelle.
  3. Varmista, että resolverin pistoke on suojattu ja että valittu resolveri vastaa tunnelin sisältä.
  4. Varmista rajapinnan MTU ja yhden käsin rakennetun vastauksen tarkistussumma.
  5. Toista sama sivu Wi-Fi-verkossa ja matkapuhelinverkossa, koska operaattorin resolverit ja polun MTU eroavat.

Jos kaikki viisi pitävät ja sivu on silti jumissa, seuraava epäilty on välittäjä itse: vertaa kaapattua pyyntöä kaapattuun vastaukseen ja etsi puuttuvaa tavumäärää tai puoliksi suljettua pistoketta. VpnService.Builder-viite kattaa reitin, DNS:n ja MTU:n sopimukset, ja protect() on erillinen VpnService-kutsu eikä builder-valinta; yhdistetty rajapinta tarkoittaa vain, että ensimmäinen sopimus täyttyi.

Aiheeseen liittyvät artikkelit