Додали сте домен на листу дозвољених, упит стиже до ваше апликације, поклапач враћа дозвољено, а страница се ипак никада не учита. У том тренутку већина почиње да преписује поклапач и додаје поређења са џокерима. По мом искуству поклапач је обично исправан, а квар лежи један слој ниже: у DNS одговору који сте синтетизовали, у рути коју сте инсталирали или у сокету који сте користили за прослеђивање упита. Листа је лакши део; пут пакета је место где се листе дозвољених ломе.

Поклапач је ретко кривац

Прво што треба раздвојити је блокирано од поквареног. Блокирано име треба брзо и видљиво да падне, јер прегледач добије одговор да име не постоји и заустави се. Покварено име се замрзава, понавља покушаје преко IPv6, прелази на други транспорт и оставља вас са покретним индикатором. Ако видите покретни индикатор, ваша листа дозвољених вероватно одговара нечим на шта клијент не може да реагује.

Празан A запис је класична грешка. Враћање NOERROR са нула одговора изгледа као важећи одговор, па га stub резолвер прихвати, прегледач покуша поново, покуша AAAA, покуша други резолвер и одустане много касније. Код одговора 3, то јест NXDOMAIN, са поновљеним одељком питања и копираним ID-ом трансакције завршава разговор одмах. Користите га за свако име које намерно одбијате.

IPv6 заслужује исту одлуку, а не подразумевану вредност. Ако на A одговорите NXDOMAIN а AAAA пропустите, клијент може доћи до блокираног имена преко IPv6 и филтер пропушта. Неке имплементације на блокиране AAAA упите одговарају loopback адресом како би веза одмах пала уместо да пређе на резерву. Изаберите једну политику, примените је на оба типа записа и бележите оба.

Рута која хвата све поседује све

Дизајн само са DNS-ом никада не додаје addRoute("0.0.0.0", 0), па у TUN интерфејс улазе само упити, а све остало наставља да користи доњу мрежу. То је сигуран облик и објашњава зашто неке листе дозвољених раде на Wi-Fi мрежи а падају на мобилној.

У тренутку када постоји подразумевана рута, сваки ток је ваш. TCP пакет који стигне на интерфејс и није ни прослеђен ни одговорен стоји у реду док клијенту не истекне време, а грешке нема за бележење јер ништа није погрешило. Гледао сам како неко проведе поподне на поквареној листи дозвољених која је заправо била прослеђивач који недостаје за порт 443. Бележите протокол и одредиште сваког пакета који одлучите да одбаците.

Сокет резолвера мора да изађе из тунела

Прослеђивање је место следеће замке. Резолвери оператера често живе на приватној адреси до које тунел не досеже, па упит који проследите оде никуда и апликација пријави истек времена читања. Шаљите одобрене упите резолверу за који знате да је доступан и прво предајте тај сокет функцији VpnService.protect(). Незаштићен сокет враћа упит натраг у ваш сопствени тунел, где поново стигне до апликације и кружи док не активира тајмер.

Квар изгледа идентично као прекид мреже, зато тако дуго преживљава у пријавама грешака. Држите бројаче послатих упита и примљених одговора: ако први број расте а други остаје на нули, гледате у сокет, не у листу.

Величина и контролне суме падају без поруке

Тиха одбацивања долазе и од величине. DNS одговор са великим скупом одговора или TCP руковање са издашним опцијама може премашити MTU пута који никада нисте изричито поставили; фрагмент нестаје узводно и клијент или понови покушај са мањим или престане да покушава. Постављање MTU-а интерфејса на 1280 је конзервативан избор који преживљава већину мобилних путева, а изричитост је боља од наслеђивања подразумеване вредности коју нико није измерио.

Ако сами градите пакете, контролна сума је други тихи убица. UDP контролна сума израчуната преко псеудозаглавља које изоставља дужину UDP-а или поље протокола даје пакет који на вашој страни изгледа исправно, а прималац га одбацује без трага. Упоредите своје псеудозаглавље са спецификацијом поље по поље и испишите израчунату контролну суму за један познат ток док отклањате грешку.

Шта VpnService неће урадити за вас

Две границе вреди знати пре него што дизајнирате око њих. Ниједна обична апликација не може инсталирати системски прокси или PAC датотеку изван Wi-Fi везе, а тај део се није променио. Пут по апликацији јесте: пре API-ја 29 VpnService.Builder уопште није могао носити прокси, а од API-ја 29 setHttpProxy(ProxyInfo.buildPacProxy(uri)) даје платформи PAC скрипту за процену за VPN мрежу. Процењујте правила у сопственом коду када циљате старије API-је или када PAC модел не може изразити правило. Ни UDP није бесплатан: прегледачи шаљу само TCP кроз SOCKS прокси, а већина SOCKS5 клијената никада не имплементира UDP ASSOCIATE, па дизајн заснован на проксију одбацује или пропушта UDP док TCP изгледа здраво.

Та друга граница је разлог зашто протокол заснован на UDP-у може радити на обичној мрежи и пасти оног тренутка кад се ваш VPN повеже. Ако се од тунела очекује да носи UDP, прослеђивач мора имплементирати пут прослеђивања за њега, не само TCP пут са другим типом сокета.

Проверавајте овим редом

Прођите листу редом и зауставите се на првом кораку који падне, јер је свака каснија провера шум док претходна не држи.

  1. Наведите инсталиране руте и потврдите да ли пакети који нису DNS уопште улазе у TUN интерфејс.
  2. Бележите име упита, одлуку и код одговора за једно блокирано и једно одобрено име.
  3. Потврдите да је сокет резолвера заштићен и да изабрани резолвер одговара из унутрашњости тунела.
  4. Потврдите MTU интерфејса и контролну суму једног ручно састављеног одговора.
  5. Поновите исту страницу на Wi-Fi и мобилној мрежи, јер се резолвери оператера и MTU пута разликују.

Ако свих пет држи а страница се још замрзава, следећи осумњичени је сам прослеђивач: упоредите снимљени захтев са снимљеним одговором и тражите број бајтова који недостаје или напола затворен сокет. Референца за VpnService.Builder покрива уговоре о рути, DNS-у и MTU-у, а protect() је одвојен позив VpnService, а не опција builder-а; повезан интерфејс значи само да је први уговор испуњен.

Повезани чланци