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

સિસ્ટમ તમને શું આપે છે અને શું નહીં

establish() tun ઇન્ટરફેસ માટે ParcelFileDescriptor પરત આપે છે. સિસ્ટમ બહાર જતાં IP પેકેટ તેમાં લખે છે અને ધારે છે કે તમારી પ્રક્રિયા તેમને વાંચશે, ક્યાં જવાના છે તે નક્કી કરશે અને સામાન્ય સોકેટ દ્વારા મોકલશે. નીચે કર્નલ ફોરવર્ડિંગ નથી, તેથી જ્યારે કોઈ વાંચતું નથી ત્યારે પેકેટ ફેંકાઈ જાય છે અને ઇન્ટરફેસના કાઉન્ટર કદી ખસતા નથી.

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

બ્લોકિંગ વાંચન નક્કી કરે છે કે લૂપ ખસે છે કે નહીં

setBlocking(true) ડિસ્ક્રિપ્ટરને બ્લોકિંગ મોડમાં મૂકે છે અને API 21 થી અસ્તિત્વમાં છે. જૂની આવૃત્તિઓમાં ઉપાય નાનકડો JNI સહાયક છે જે કાચા ડિસ્ક્રિપ્ટર પર fcntl વડે O_NONBLOCK સાફ કરે છે. મોડ મહત્વપૂર્ણ છે કારણ કે તે નક્કી કરે છે કે બાકી પેકેટ વગરના વાંચનને શું કરવાની મંજૂરી છે.

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

દરેક કૉલમાં ઇન્ટરફેસના MTU કદના બફરમાં એક પેકેટ વાંચો, અને શૂન્ય કે નકારાત્મક પરતને ખાલી પેકેટ નહીં પણ ભૂલ ગણો.

પ્રથમ મોકલવાના પહેલાં protect(), પછી નહીં

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

ક્રમ છે protect, પછી connect કે bind, પછી send. connect પછી protect બોલાવવાથી પહેલાનો રૂટ નિર્ણય યથાવત્ રહી શકે, તેથી કૉલ true પરત આપ્યો હોવા છતાં સોકેટ ખોટો માર્ગ વાપરે છે. તે પરત આપતું બુલિયન તપાસો અને false હોય ત્યારે મોટેથી નિષ્ફળ થાઓ, એવા send માં પ્રવેશવાને બદલે જે કામ કરી શકતું નથી.

જે સોકેટે કદી protect() સ્પર્શ્યું નથી તેના પર sendto તરફથી આવતી પરવાનગી ભૂલ આ ભૂલની સામાન્ય ઓળખ છે.

UDP નમૂનો HTTPS વહન કરતું નથી

મોટાભાગના ટ્યુટોરિયલ કોપી કરે છે તે ફોરવર્ડિંગ નમૂનો ફક્ત UDP સંભાળે છે. TCP ને હેન્ડશેક, ક્રમ સંખ્યા, સ્વીકૃતિ અને ફરી મોકલવાની જરૂર છે, અને tun ડિસ્ક્રિપ્ટર તથા સોકેટ વચ્ચે પેલોડ કોપી કરતું લૂપ એમાંનું એક પણ આપતું નથી. તેથી જ UDP DNS ક્વેરી પસાર થઈ શકે જ્યારે દરેક HTTPS વિનંતી અટકી જાય. કાં તો વપરાશકર્તા અવકાશમાં TCP સ્ટેક ચલાવો અથવા જોડાણો સ્થાનિક પ્રોક્સીને આપો જે ઉપકરણ પર TCP સમાપ્ત કરે અને પ્રવાહ ફોરવર્ડ કરે.

કંઈ પણ ફરી લખતા પહેલાં વિભાજન ચકાસો: એક UDP ક્વેરી મોકલો અને એ જ હોસ્ટ સાથે એક TCP જોડાણ ખોલો. જો UDP માર્ગ કામ કરે અને TCP માર્ગ પ્રથમ SYN પર અટકે, તો સમસ્યા ફોરવર્ડિંગ કોડમાં છે, સર્વરમાં નહીં. એ એક સરખામણી બિનઉપયોગી સર્વર લોગ વાંચવામાં વીતતો ઘણો સમય બચાવે છે.

રૂટ યાદી અને એપ મુજબના ફિલ્ટર તમે શું જુઓ છો તે મર્યાદિત કરે છે

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

એપ મુજબની પસંદગીનો પોતાનો ન્યૂનતમ સ્તર છે: addAllowedApplication અને addDisallowedApplication ને API 21 જોઈએ, અને જૂની આવૃત્તિઓમાં એ પદ્ધતિઓ સાવ નથી. પેકેટ પ્રમાણે ફિલ્ટર કરતી રચના ત્યાં બિલકુલ ચાલી શકતી નથી.

ફરી સ્થાપિત કરવાથી જૂનાં ડિસ્ક્રિપ્ટર રહી જાય છે

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

દરેક ભૂલ તે જે પગલાની છે તે પ્રમાણે વાંચો. recvfrom તરફથી કનેક્શન રીસેટનો અર્થ છે કે દૂરનો છેડો બંધ થયો જ્યારે તમારો કોડ હજુ વાંચતો હતો. ખોટા સરનામાની ભૂલ હેડર પાર્સિંગ કે ઓફસેટ ભૂલ તરફ ઇશારો કરે છે, નેટવર્ક તરફ નહીં.

કામનો ક્રમ: બ્લોકિંગ મોડ ચાલુ, દરેક વાંચને એક પેકેટ, હેડર પાર્સ થયેલું, સોકેટ સુરક્ષિત, પેલોડ મોકલેલું, સોંપણી વખતે સ્વચ્છ બંધ અને લક્ષ્ય આવરી લેતી રૂટ યાદી.

સંબંધિત લેખો