VpnService માં કંઈ પણ જાતે ટ્રાફિકને અટકાવતું નથી. તે સિસ્ટમ પાસે tun ઇન્ટરફેસ માંગે છે, તે ઇન્ટરફેસને સરનામાં અને રૂટનો સમૂહ આપે છે, અને તે ક્ષણથી કર્નેલ તે રૂટ સાથે મેળ ખાતું દરેક પેકેટ એપ વાંચી શકે તેવા ફાઇલ ડિસ્ક્રિપ્ટરમાં કૉપિ કરે છે. એપનો કોડ રૂટે ન પસંદ કરેલા પેકેટ ક્યારેય જોતો નથી, તેથી ટનલનો વ્યાપ પ્રોગ્રામિંગ પ્રશ્ન બનતા પહેલાં રૂટિંગ ટેબલનો પ્રશ્ન છે. તેથી જ એક જ સેવા અમલીકરણ એક ફોન પર દરેક પ્રવાહ ગળી શકે છે અને બીજા પર ફક્ત એક ટુકડો, અને તેથી જ રૂટ ઉમેરવાથી ક્યારેક તૂટેલી દેખાતી ટનલ સુધરે છે. તમને જે મળે છે તે તમે જાહેર કર્યું છે તે જ, બિલ્ડરે ચૂપચાપ નકારેલી દરેક વસ્તુ બાદ કરીને.

રૂટ નક્કી કરે છે કયા પેકેટ આવે છે

Builder.addRoute(prefix, prefixLength) VPN નેટવર્કના રૂટિંગ ટેબલમાં પ્રીફિક્સ સ્થાપિત કરે છે. સિસ્ટમ તે નેટવર્કને વ્યાપની એપ માટે ડિફૉલ્ટ ગણે છે, તેથી તેની એન્ટ્રીઓ ભૌતિક નેટવર્કના ડિફૉલ્ટ રૂટ પહેલાં જોવાય છે અને મેળ ખાતું પ્રીફિક્સ પ્રવાહને વાળવા માટે પૂરતું છે. તેથી 0.0.0.0/0 માટેનો રૂટ IPv4 સંપૂર્ણ લે છે, જેમાં પ્રિન્ટર, cast લક્ષ્ય અને રાઉટરનું એડમિન પૃષ્ઠ સામેલ છે.

ભૌતિક ડિફૉલ્ટ એન્ટ્રી ન હટાવતાં તે આવરણ ઇચ્છતા ક્લાઇન્ટ તેના બદલે 0.0.0.0/1 અને 128.0.0.0/1 જોડી વાપરે છે. બે વધુ ચોક્કસ રૂટ ડિફૉલ્ટ રૂટને હરાવે છે, સાથે તેઓ આખું સરનામા અવકાશ આવરે છે, અને ફોનની પોતાની ડિફૉલ્ટ એન્ટ્રી ભૌતિક નેટવર્ક સાથે બંધાયેલા સૉકેટ માટે ટેબલમાં રહે છે.

સરનામાં અને DNS એન્ટ્રીઓ એક જ બિલ્ડર પાસેથી આવે છે અને બીજા પ્રશ્નનો જવાબ આપે છે. addAddress ઇન્ટરફેસને પ્રીફિક્સ લંબાઈ સાથે સરનામું આપે છે, અને addDnsServer એવો રિઝોલ્વર સ્થાપિત કરે છે જેને વ્યાપની એપ ઇન્ટરફેસ દ્વારા પૂછશે. બંને પરિવાર એક જ ઇન્ટરફેસ પર રહી શકે છે, તેથી IPv6 સરનામા પાસે ફક્ત IPv4 રૂટનો સમૂહ એવી ગોઠવણી છે જે સાચી વંચાય છે અને તો પણ લીક થાય છે. ઇન્ટરફેસમાં જે પરિવારનું સરનામું નથી તે પરિવારને રૂટ કરો તો કર્નેલ પાસે તે પેકેટ માટે સ્રોત સરનામું હોતું નથી અને તે ડિસ્ક્રિપ્ટર પર ક્યારેય દેખાતા નથી.

establish() શું પાછું આપે છે

establish() ParcelFileDescriptor પાછું આપે છે, અથવા null જ્યારે એપ અધિકૃત ન હોય. null નેટવર્ક ભૂલ નહીં પણ સંમતિની સ્થિતિ છે: VpnService.prepare() પહેલેથી null પાછું આપી ચૂક્યું હોવું જોઈએ, અથવા વપરાશકર્તાએ કૉલ પહેલાં સિસ્ટમ સંવાદ મંજૂર કર્યો હોવો જોઈએ. સેવા ચાલુ હોય ત્યારે સંમતિ પાછી ખેંચી શકાય છે, અને ઇન્ટરફેસ તમારા વાંચન લૂપમાં કોઈ કૉલબેક વિના તમારા પગ નીચેથી બંધ થાય છે.

તમે અન્યથા ન કહો તો ડિસ્ક્રિપ્ટર બ્લૉક કરતું નથી, તેથી વાંચન થ્રેડને પાર્ક કરવાને બદલે ડેટા વિના તરત પાછું આવે છે. બ્લૉકિંગ સૉકેટ માટે લખાયેલો લૂપ એક કોર બાળે છે, અને ખાલી વાંચનને ઘાતક ગણતો લૂપ નિષ્ક્રિય સેકન્ડમાં ટનલ ફાડી નાખે છે. Builder.setBlocking(true) તે વર્તન બદલે છે, અને કિંમત છે વાંચનની અંદર રાહ જોતો થ્રેડ.

રૂટ અને સરનામાના દલીલો LinkAddress મૂલ્યો તરીકે માન્ય કરાય છે, અને 224.0.0.0/4 જેવા મલ્ટિકાસ્ટ લક્ષ્ય સીધા નકારાય છે. પૉઇન્ટ-ટુ-પૉઇન્ટ tun ઇન્ટરફેસમાં પણ બ્રૉડકાસ્ટ ડોમેન હોતું નથી, તેથી તેના પર મલ્ટિકાસ્ટ શોધ માટે વધુ એક રૂટ નહીં પણ અલગ ડિઝાઇન જરૂરી છે. VpnService.Builder સંદર્ભ એ યાદી છે જે કૉલ અવગણાયો હોવાનું તારણ કાઢતા પહેલાં તપાસવી જોઈએ.

એપ-વાર વ્યાપ સમૂહ સાંકડો કરે છે, ટનલ નહીં

API 21 થી બિલ્ડર addAllowedApplication અને addDisallowedApplication સ્વીકારે છે, અને બંને યાદીઓ એક જ બિલ્ડરમાં પરસ્પર વિશિષ્ટ છે. મંજૂર યાદી તે પેકેટ માટે ટનલ રાખે છે જ્યારે બાકીનું બધું ભૌતિક નેટવર્ક રાખે છે; નિષેધ યાદી નામિત પેકેટ સિવાય બધું પકડે છે, જેને ક્લાઇન્ટ વિભાજિત ટનલિંગ તરીકે આપે છે. API 21 પહેલાં પ્લેટફૉર્મની કોઈ પદ્ધતિ જ નથી, અને એપ-વાર વર્તન તૃતીય-પક્ષ ક્લાઇન્ટમાંથી આવતું જે પોતાના ફૉરવર્ડરમાં UID પ્રમાણે ગાળણ કરતા. ડિબગ કરતી વખતે આ ભેદ મહત્ત્વનો છે, કારણ કે એક પેકેટની મંજૂર યાદી ધરાવતી એપ-વાર ટનલ લગભગ કોઈ ટ્રાફિક ઉત્પન્ન કરતી નથી અને તે સાચું વર્તન છે, તૂટેલો રૂટ નહીં.

વ્યાપ ગમે તે હોય, તમારી એપ VPN સર્વર તરફ ખોલતું સૉકેટ તે બનાવતી ટનલમાંથી પસાર થવું ન જોઈએ. VpnService.protect(socket) તે સૉકેટને અંતર્ગત નેટવર્ક સાથે બાંધે છે જેથી તેના પેકેટ tun ઉપકરણ છોડી જાય. કૉલ છોડી દો તો હેન્ડશેકને તે ઇન્ટરફેસ ગળી જાય છે જે તેને ઉભો કરવાનો હતો.

VpnService.setUnderlyingNetworks સિસ્ટમને કહીને લૂપ બંધ કરે છે કે કયું ભૌતિક નેટવર્ક ટનલ વહન કરે છે. તે મૂલ્ય નક્કી કરે છે કે VPN અન્ય એપને કનેક્ટિવિટી કેવી રીતે જણાવે છે, અને null કે જૂનું મૂલ્ય જોડાયેલી ટનલનું સામાન્ય કારણ છે જેને ફોનનો બાકીનો ભાગ ઑફલાઇન ગણે છે. અંતર્ગત નેટવર્ક બદલાય ત્યારે તેને અદ્યતન કરો, ફક્ત શરૂઆતમાં નહીં.

ચેકસમ અને MTU: જ્યાં સાચો રૂટ તો પણ નિષ્ફળ જાય છે

પેકેટ આવ્યા પછી પેકેટ સ્તરની બે વિગતો નક્કી કરે છે કે કંઈ શરૂઆતથી અંત સુધી કામ કરે છે કે નહીં. પ્રથમ સ્રોત સરનામું છે: અનેક ઇન્ટરફેસ સરનામાં હોય તો કર્નેલ પ્રથમ વહન કરતા પેકેટ મોકલી શકે છે, તેથી હેડર ફરી લખતા ફૉરવર્ડરે સરનામું અને તેને આવરતું ચેકસમ સુધારવું પડે.

બીજું ચેકસમનો વ્યાપ છે. એપ પોતે TCP કે UDP પેકેટ બનાવે ત્યારે ચેકસમ સ્રોત સરનામું, લક્ષ્ય સરનામું, પ્રોટોકૉલ નંબર અને પરિવહન લંબાઈ ધરાવતું સ્યૂડો-હેડર આવરે છે, અને તેમાંથી કોઈ પણ છોડી દેવાથી એવા પેકેટ મળે છે જે પહોંચે અને ફેંકાય. તે નિષ્ફળતા એવા જવાબ પછીના સમય-સમાપ્તિ જેવી દેખાય છે જે ક્યારેય આવતો નથી, અને તે મોટાભાગના લોકોને રૂટ પર પાછા મોકલે છે. setMtu ઇન્ટરફેસનું MTU નક્કી કરે છે, અને દરેક વાંચન બરાબર એક સંપૂર્ણ IP પેકેટ પાછું આપે છે, તેથી બાઇટ પ્રવાહ માટે લખાયેલું બફર પેકેટ નહીં પણ તમારું પાર્સિંગ ટુકડે-ટુકડે કરશે.

સ્તરોને અલગ કરતો ચકાસણી પાસ

વ્યાપ ક્યાં ખોટો ગયો તે શોધવા સ્તરોને ક્રમમાં ચકાસો. ઉપકરણને પૂછો કે VPN નેટવર્ક ખરેખર કયા રૂટ ધરાવે છે, પછી તપાસો કે જાણીતા સરનામા તરફનો પ્રવાહ ડિસ્ક્રિપ્ટર પર વાંચન તરીકે દેખાય છે કે નહીં, પછી તપાસો કે તમારું ફૉરવર્ડર જે પેકેટ મોકલે છે તે સુઘડ છે કે નહીં. રૂટની સમસ્યા ડિસ્ક્રિપ્ટર પર કંઈ દેખાડતી નથી, જ્યારે ચેકસમની સમસ્યા એવું પેકેટ દેખાડે છે જે પહોંચે અને અદૃશ્ય થાય.

ડિસ્ક્રિપ્ટર સુધી કંઈ ન પહોંચે તો શંકાસ્પદ વાંચનાર નહીં પણ રૂટનો સમૂહ છે: પ્રીફિક્સ ખાતરી કરો, એ જ પરિવારમાં સરનામું છે તે ખાતરી કરો, અને એપ તમે નક્કી કરેલા વ્યાપમાં છે તે ખાતરી કરો. પેકેટ ડિસ્ક્રિપ્ટર સુધી પહોંચે પણ કંઈ પાછું ન આવે તો ફરી રૂટને અડકતા પહેલાં protect() અને અંતર્ગત નેટવર્કનું મૂલ્ય તપાસો. જો દૂરનો છેડો વિકૃત પેકેટની જાણ કરે તો ચેકસમ અને MTU જોવાનાં સ્થાન છે. દરેક સ્તરે એક પ્રોબ અડધો દિવસની અટકળ બચાવે છે.

સંબંધિત લેખો