Android-ന്റെ VpnService-ന് ഒഴിവാക്കൽ റൂട്ട് ഇല്ല, എത്ര API വായിച്ചാലും ഒന്ന് ഉണ്ടാകില്ല. Builder.addRoute() ടണലിലേക്ക് ലക്ഷ്യസ്ഥാനങ്ങൾ മാത്രമേ ചേർക്കുന്നുള്ളൂ, അതിനാൽ ഒരു LAN സെഗ്മെന്റ് പ്രാദേശികമായി നിലനിർത്തുക എന്നാൽ ആ സെഗ്മെന്റ് ഒരിക്കലും റൂട്ട് പട്ടികയിൽ പ്രവേശിക്കില്ല എന്നാണ്. പകരം നിങ്ങൾ ചേർക്കുന്നത് സെഗ്മെന്റിന്റെ പൂരകമാണ്, സാധാരണ പ്രിഫിക്സുകളായി പ്രകടിപ്പിക്കുന്നു. ജോലി ഗണിതമാണ്, അത് ഏതാനും പ്രവചനീയമായ സ്ഥലങ്ങളിൽ പരാജയപ്പെടുന്നു.

താഴെയുള്ള പരിശോധനകൾ ക്രമത്തിൽ ചെയ്യുക. ഓരോന്നും മുമ്പത്തേത് നിലനിന്നു എന്ന് അനുമാനിക്കുന്നു, അതിനാൽ താഴെയുള്ള ലക്ഷണങ്ങൾ പാച്ച് ചെയ്യുന്നതിനുപകരം ആദ്യ പരാജയത്തിൽ നിർത്തുക.

ടണൽ അവകാശപ്പെടുന്നതിൽ നിന്ന് തുടങ്ങുക

0.0.0.0/0 addRoute()-ലേക്ക് കൈമാറുന്നത് എല്ലാ IPv4 ലക്ഷ്യവും ടണലിന്റേതാണെന്ന് Android-നോട് പറയുന്നു. അതുകൊണ്ടാണ് ഒരുപാട് ക്ലയന്റുകൾ വിഭജിത ടണലിംഗിന് കഴിവില്ലാത്തവരായി തോന്നുന്നത്: അവർ മുഴുവൻ വിലാസ ഇടവും അവകാശപ്പെട്ട് പിന്നീട് അതിൽ നിന്ന് കുറയ്ക്കാൻ ശ്രമിക്കുന്നു. ബിൽഡറിൽ ഒന്നും കുറയ്ക്കുന്നില്ല. പ്രാദേശികമായി നിലനിർത്താൻ ആഗ്രഹിച്ച നെറ്റ്വർക്കിനുള്ള കൂടുതൽ നിർദ്ദിഷ്ട റൂട്ട് ആളുകൾ പ്രതീക്ഷിക്കുന്നതിന് വിപരീതമായി പ്രവർത്തിക്കുന്നു, കാരണം ഏറ്റവും നീളമുള്ള പൊരുത്തപ്പെടുന്ന പ്രിഫിക്സ് വിജയിക്കുന്നു, ആ നെറ്റ്വർക്ക് ടണലിനുള്ളിൽ എത്തുന്നു.

റൂട്ട് പട്ടികയാണ് മുഴുവൻ നയം. അതിന് പിന്നിൽ ഓരോ ലക്ഷ്യത്തിനും വീറ്റോ ഇല്ല, Builder റഫറൻസ് അത് നൽകുന്ന ഒരു രീതിയും പട്ടികപ്പെടുത്തുന്നില്ല.

പ്രിഫിക്സ് ഗണിതത്തിൽ നിന്ന് പൂരകം സൃഷ്ടിക്കുക

ഒഴിവാക്കിയ പ്രിഫിക്സിന്റെ പൂരകം വിലാസ വൃക്ഷത്തിന്റെ മൂലത്തിലേക്കുള്ള വഴിയിലെ അതിന്റെ സഹോദരങ്ങളുടെ ഗണമാണ്. 1 മുതൽ ഒഴിവാക്കിയ നീളം വരെ ഓരോ നീളത്തിനും, നിങ്ങളുടെ പ്രിഫിക്സ് ഉൾക്കൊള്ളുന്ന ആ നീളത്തിലുള്ള ബ്ലോക്ക് എടുത്ത്, പ്രിഫിക്സിന് തൊട്ടുതാഴെയുള്ള ബിറ്റ് മറിക്കുക, ഫലം പുറത്തുവിടുക. നിങ്ങൾ അത് പ്രവർത്തിപ്പിക്കുന്നതുവരെ അത് അമൂർത്തമായി തോന്നും.

10.0.0.0/8 ഒഴിവാക്കിയാൽ എട്ട് റൂട്ടുകൾ ലഭിക്കും: 128.0.0.0/1, 64.0.0.0/2, 32.0.0.0/3, 16.0.0.0/4, 0.0.0.0/5, 12.0.0.0/6, 8.0.0.0/7, 11.0.0.0/8. അവയിൽ ഒന്നും 10.0.0.0/8 ഉൾക്കൊള്ളുന്നില്ല, ഒരുമിച്ച് അവ ബാക്കിയെല്ലാം ഉൾക്കൊള്ളുന്നു.

ഏത് പ്രിഫിക്സിനും എട്ട് വരികൾ ആ പട്ടിക സൃഷ്ടിക്കുന്നു:

import ipaddress
def complement(addr, length):
    base = int(ipaddress.IPv4Address(addr))
    out = []
    for k in range(1, length + 1):
        block = base & (0xFFFFFFFF << (32 - k))
        sibling = block ^ (1 << (32 - k))
        out.append(f"{ipaddress.IPv4Address(sibling)}/{k}")
    return out
print(complement("10.0.0.0", 8))

റൂട്ടുകളുടെ എണ്ണം പ്രിഫിക്സ് നീളത്തിന് തുല്യമാണ്, അതാണ് ശ്രദ്ധിക്കേണ്ട സംഖ്യ. ഒരു /21 ഒഴിവാക്കൽ 21 റൂട്ടുകൾ ചെലവാക്കുന്നു, വായനയോഗ്യമായി തുടരുന്നു. പത്ത് ഒഴിവാക്കലുകൾ കുറച്ച് നൂറുകൾ ചെലവാക്കാം, അതിന്റെ അർത്ഥം സാധാരണയായി ജനറേറ്ററല്ല, നെറ്റ്വർക്ക് ഡിസൈൻ മാറ്റണം എന്നാണ്.

വിലാസ കുടുംബവും ടണലിന്റെ പരിധിയും പരിശോധിക്കുക

IPv4 റൂട്ടുകൾ IPv6-ന് ഒന്നും ചെയ്യുന്നില്ല. ടണൽ IPv6 വിലാസം അവകാശപ്പെടുന്നുവെങ്കിൽ, IPv6 LAN പ്രിഫിക്സിന് അതിന്റെ സ്വന്തം പൂരകം വേണം, 128 ബിറ്റുകളിൽ അതേ ഗണിതത്താൽ സൃഷ്ടിക്കുന്നത്. കടലാസിൽ ഒഴിവാക്കൽ പ്രവർത്തിക്കുമ്പോൾ പ്രാദേശിക ഉപകരണം എത്താനാകാതെ തുടരുന്നതിന്റെ സാധാരണ കാരണം ഇതാണ്: ഹോസ്റ്റിൽ IPv6 വഴി എത്തി, IPv4 മാത്രമാണ് മുറിച്ചത്. ഗണിതം തെറ്റാണെന്ന് തീരുമാനിക്കുന്നതിന് മുമ്പ് രണ്ട് കുടുംബങ്ങളും പരിശോധിക്കുക.

പരിധി പരിശോധനയുടെ മറ്റേ പകുതിയാണ്. Android നെറ്റ്വർക്ക് അനുസരിച്ചും ആപ്പ് അനുസരിച്ചും റൂട്ടിംഗ് ട്രാക്ക് ചെയ്യുന്നു, അതിനാൽ ഒരേ പ്രിഫിക്സ് ഒരു ആപ്പിന് ടണലിലൂടെയും മറ്റൊന്നിന് നേരിട്ടും പോകാം, VPN എങ്ങനെ പ്രഖ്യാപിച്ചു എന്നതിനെ ആശ്രയിച്ച്.

DNS, ഓരോ ആപ്പിന്റെയും നിയമങ്ങൾ ശരിയായ സ്ഥലത്ത് വയ്ക്കുക

റൂട്ട് ഒഴിവാക്കലുകൾ റിസോൾവറിനെ മാറ്റുന്നില്ല. പ്രാദേശിക ഹോസ്റ്റ്നാമിന് ഇപ്പോഴും ടണലിന്റെ DNS സെർവറിൽ നിന്ന് ഉത്തരം ലഭിക്കാം, അതിന്റെ വിലാസം പ്രാദേശികമായി റൂട്ട് ചെയ്യുമ്പോൾ, പൊരുത്തക്കേട് LAN എത്താനാകാത്ത ഒന്നിലേക്ക് പരിഹരിക്കുന്ന പേരായി പ്രത്യക്ഷപ്പെടുന്നു. റിസോൾവർ നയം ബോധപൂർവ്വം സജ്ജമാക്കുക, തിരച്ചിൽ ഡൊമെയ്നോ വിഭജിത DNS നിയമമോ ഉപയോഗിച്ച്. റൂട്ടുകൾ അത് നിങ്ങൾക്കുവേണ്ടി തീരുമാനിച്ചു എന്ന് അനുമാനിക്കരുത്.

addDisallowedApplication() ഒരു ആപ്പിനെ ടണലിന് പുറത്ത് നിർത്തുന്നു; അകത്ത് തുടരുന്ന ആപ്പുകൾക്ക് ലക്ഷ്യം പുറത്ത് നിർത്തുന്നില്ല. protect() നിങ്ങൾ തുറക്കുന്ന സോക്കറ്റിനെ ടണൽ ഒഴിവാക്കാൻ അനുവദിക്കുന്നു, അങ്ങനെ ടണൽ സ്വന്തം ഗതാഗതം പിടിക്കുന്നത് ഒഴിവാക്കുന്നു. രണ്ടും പൂരകത്തെ മാറ്റിസ്ഥാപിക്കുന്നില്ല.

സ്വന്തം പട്ടികയല്ല, തിരച്ചിൽ ഉപയോഗിച്ച് പരിശോധിക്കുക

ടണൽ ഉയർന്നുകഴിഞ്ഞാൽ, നിങ്ങൾ നിർമ്മിച്ച പട്ടിക വീണ്ടും വായിക്കുന്നതിനുപകരം ഒരു വിലാസം യഥാർത്ഥത്തിൽ എവിടെ പോകുന്നു എന്ന് ഉപകരണത്തോട് ചോദിക്കുക. iproute2 ഉള്ള ബിൽഡിൽ, adb shell ip route get 10.1.2.3 കർണൽ തിരഞ്ഞെടുത്ത ഇന്റർഫേസ് പേരിടുന്നു. പൊതു വിലാസത്തിനും അതേ കമാൻഡ് പ്രവർത്തിപ്പിച്ച് അത് ടണലിനെ പേരിടുന്നുവെന്ന് സ്ഥിരീകരിക്കുക.

കൂടുതൽ രണ്ട് പരിശോധനകൾ വൃത്തം അടയ്ക്കുന്നു. ആദ്യം പ്രാദേശിക പേര് പരിഹരിക്കുക, പിന്നീട് പരിഹരിച്ച വിലാസത്തിൽ adb shell ip route get പ്രവർത്തിപ്പിച്ച് ടണലല്ലാത്ത ഇന്റർഫേസ് ആവശ്യപ്പെടുക, കാരണം വിജയകരമായ adb shell ping -c 1 host.lan എത്തിച്ചേരൽ തെളിയിക്കുന്നു, വഴിയല്ല. ടണൽ ഒന്ന് അവകാശപ്പെടുന്നുവെങ്കിൽ IPv6-ൽ വിലാസ-കുടുംബ പരീക്ഷ ആവർത്തിക്കുക. നിങ്ങൾ അയക്കുന്ന API നിലയിൽ പരീക്ഷിക്കുക, കാരണം VPN നെറ്റ്വർക്കുകൾ റൂട്ടിംഗ് പട്ടികയ്ക്ക് എങ്ങനെ വെളിപ്പെടുന്നു എന്നത് പതിപ്പുകൾക്കിടയിൽ മാറിയിട്ടുണ്ട്. കടലാസിൽ ശരിയായി തോന്നുന്ന റൂട്ട് പട്ടികയും തെറ്റായ ഇന്റർഫേസ് തിരഞ്ഞെടുക്കുന്ന തിരച്ചിലും വ്യത്യസ്ത ബഗ്ഗുകളാണ്, രണ്ടാമത്തേത് മാത്രമാണ് ഉപയോക്താക്കളിലെത്തുന്നത്.

ഒഴിവാക്കൽ പട്ടിക വളരുന്നുണ്ടെങ്കിൽ, റൂട്ടുകൾ സൃഷ്ടിക്കുന്നത് നിർത്തി ദൂര നെറ്റ്വർക്ക് പുനർനമ്പർ ചെയ്യുക അല്ലെങ്കിൽ പകരം ടണൽ ചുരുക്കുക. ജനറേറ്റർ കാണാത്ത API-യ്ക്കുള്ള ഒരു വഴിത്തിരിവാണ്, ഡിസൈൻ ഉപകരണമല്ല.

അനുബന്ധ ലേഖനങ്ങൾ