App rẹ pe VpnService.prepare, ó gba null, ó kọ́ tunnel, descriptor sì dàbí ẹni tí ó tọ́, ṣùgbọ́n kò sí ohun tí ó dé server. Tàbí prepare da Intent padà, olùmúlò fọwọ́ sí i, establish sì ṣì kùnà. Àwọn àbájáde méjèèjì sábà túmọ̀ sí ohun kan: app mìíràn ti ni interface VPN fún olùmúlò yìí, àwọn ìpè protect rẹ sì ń samisi socket tí tunnel rẹ kò lè lò. Lọ nípasẹ̀ àwọn àyẹ̀wò ní ìsàlẹ̀ ní ìtẹ̀lé kí ó sì dúró ní èkíní tí ó kùnà, nítorí ìgbésẹ̀ tó kan kò lè tún ti ṣáájú ṣe.

Ṣàyẹ̀wò ààyè VPN kí o tó fọwọ́ kan protect

Android fún olùmúlò kọ̀ọ̀kan ní interface VPN kan ṣoṣo tí ń ṣiṣẹ́. Èyí jẹ́ ìlànà pẹpẹ, kì í ṣe àṣẹ tí app rẹ lè béèrè fún, nítorí náà àwọn oníbàárà méjì tí àwọn méjèèjì fẹ́ jẹ́ tunnel kò lè wà papọ̀.

VPN tí ó wà ní ṣíṣí nígbà gbogbo tí a ṣètò fún app mìíràn ni ipò tí ó ṣòro jùlọ, nítorí ẹ̀rọ náà ń pa app yẹn mọ́ ní ìsopọ̀ kí ó sì kọ ìgbàkọ́kọ̀ọ́. Àlẹ̀mọ́ ìrìnàjò bí AdGuard, oníbàárà ilé-iṣẹ́ tàbí VPN olùmúlò lè di ààyè náà mú nígbà tí olùmúlò bá ti gbàgbé pé ó ti fi sórí ẹ̀rọ. Sọ fún olùmúlò pé kí ó ṣí Ètò kí ó ka àkọsílẹ̀ tí ó wà lábẹ́ VPN; orúkọ tí ó wà níbẹ̀ ni olóhun tí o ń ṣe ìdíje rẹ̀. Títí àkọsílẹ̀ yẹn yóò fi jáni kúrò tàbí ètò ṣíṣí nígbà gbogbo yóò fi pa, VpnService rẹ kò lè di interface.

Ìgbésẹ̀ 1: ka ohun tí prepare ń dá padà

VpnService.prepare ń dáhùn ìbéèrè kan ṣoṣo: ṣé app yìí lè di VPN? Ó ń dá null padà nígbà tí ìfọwọ́sí ti wà tẹ́lẹ̀, ó sì ń fún Intent nígbà tí olùmúlò ṣì ní láti fọwọ́ sí i, èyí tí o gbọ́dọ̀ gbé jáde pẹ̀lú startActivityForResult. Kà sí ìdá null padà gẹ́gẹ́ bí àṣẹ láti tẹ̀síwájú, kì í ṣe ẹ̀rí pé establish yóò ṣàṣeyọrí.

Intent intent = VpnService.prepare(context);
if (intent != null) {
    startActivityForResult(intent, REQUEST_VPN);
}

Tí ọ̀nà Intent bá padà tí olùmúlò sì kọ̀, prepare yóò tẹ̀síwájú láti dá Intent padà ní ìgbìyànjú tó kan. Ṣàkọsílẹ̀ kóòdù àbájáde dípò gbìyànjú lẹ́ẹ̀kan sí i nínú loop, nítorí ìfọwọ́sí tí a kọ̀ jẹ́ ìpinnu olùmúlò, kì í ṣe àṣìṣe ìgbà díẹ̀.

Ìgbésẹ̀ 2: jẹ́rìí pé interface jẹ́ ti app rẹ

Lẹ́yìn establish, ParcelFileDescriptor tí o gbà ni ẹ̀rí ìní rẹ, ó sì yẹ kí o ṣàyẹ̀wò rẹ̀ kí o tó ṣe iṣẹ́ socket kankan. Descriptor tí ó jẹ́ null tàbí tí a ti pa mọ́ túmọ̀ sí pé a kò tíì dá interface rí, bí kò tilẹ̀ sí ìyàtọ̀ tí ó yọ jáde. Fi orúkọ interface láti builder wé èyí tí ẹ̀rọ ń ròyìn fún VPN tí ń ṣiṣẹ́, ní lílo dumpsys lórí ẹ̀rọ ìdánwò. Bí wọ́n bá yàtọ̀, tunnel tí o kọ́ kì í ṣe tunnel tí ń gbé ìrìnàjò.

adb shell dumpsys connectivity

Àìbáramu kan náà ni ó ń ṣàlàyé àmì tí ó so pọ̀ pẹ̀lú ìrìnàjò tí ó kú. Ẹ̀rọ ń fi tunnel app mìíràn hàn, nígbà tí kóòdù rẹ ń di descriptor interface tí kì í ṣe tirẹ̀ mú.

Ìgbésẹ̀ 3: pe protect kí o tó ṣe connect

Nígbà tí interface bá wà, àwọn socket tí app rẹ ń ṣí ni a ń darí sínú tunnel ní àìpé. Ẹ̀rọ ìgbékalẹ̀ ìta kò lè tẹ̀lé ìlànà yẹn bí bẹ́ẹ̀ kọ́ packet tí a fi pamọ́ yóò padà sínú interface, nítorí náà VpnService protect ń samisi socket kan láti forí VPN kọjá kí ó sì lo nẹ́tíwọ́kì tí ó wà ní ìsàlẹ̀. Ìpè náà ń dá boolean padà, ìgbà tí a bá pa á tì ni ọ̀nà tí o fi ń parí pẹ̀lú socket tí ó dàbí ẹni tí ó ní ìlera tí kò sì gbé ohunkóhun.

Pe protect kí o tó ṣe connect tàbí bind, kì í ṣe lẹ́yìn rẹ̀. Ìdáàbò gbọ́dọ̀ wà kí socket tó so pọ̀ tàbí kí a tó dè é, nítorí socket tí ó so pọ̀ ti yan ọ̀nà rẹ̀ tẹ́lẹ̀, protect tí ó wá lẹ́yìn kò sì ń gbé e lọ ní ọ̀nà tí a lè gbẹ́kẹ̀ lé. Bí protect bá dá false padà, dúró kí o sì tún ṣàyẹ̀wò ìní: ó ń kùnà nígbà tí interface kì í ṣe ti app rẹ, èyí ni pàtó ipò tí VPN mìíràn ń fi sílẹ̀. Ìdá false padà jẹ́ àmì láti padà sí Ìgbésẹ̀ 1, kì í ṣe láti tún socket kan náà gbìyànjú.

DatagramSocket socket = new DatagramSocket();
if (!vpnService.protect(socket)) {
    return;
}
socket.connect(serverAddress, serverPort);

Ìgbésẹ̀ 4: so ìlànà kan nígbà tí socket bá ṣòro

Àwọn ìgbékalẹ̀ ìta kan kì í ṣe socket kan: ilé-ìkàwé lè ṣí ọ̀pọ̀lọpọ̀, tàbí o lè fẹ́ kí gbogbo ìsopọ̀ nínú ìlànà olùrànlọ́wọ́ lo ọ̀nà àbájáde kan náà. ConnectivityManager.bindProcessToNetwork ń so ìlànà mọ́ nẹ́tíwọ́kì tí a yàn, setProcessDefaultNetwork àtijọ́ sì ṣe bẹ́ẹ̀ kí ó tó di àtijọ́. Béèrè ìsopọ̀ tí ó wà ní ìsàlẹ̀ pẹ̀lú NET_CAPABILITY_NOT_VPN kí ìsopọ̀ náà lè yan nẹ́tíwọ́kì tí ó wà lábẹ́ tunnel rẹ, kì í ṣe tunnel fúnrarẹ̀.

NetworkRequest request = new NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
    .build();

Sísopọ̀ ìlànà kì í ṣe VPN kejì. Ó ń yan ọ̀nà àbájáde fún ìlànà yẹn, èyí tí ó wúlò fún ìgbékalẹ̀ ìta rẹ tí kò sì wúlò fún ṣíṣe tunnel méjì ní àkókò kan.

Tún ẹ̀rọ olùmúlò ṣe, kì í ṣe ọ̀nà kóòdù

Kò sí API tí ó ń gbà àwọn app méjì láàyè láti pín ààyè VPN, nítorí náà àtúnṣe náà jẹ́ ti ipò ẹ̀rọ. Fun olùmúlò ní ọ̀nà méjì tí ó ṣe kedere: jáni kúrò tàbí pa ètò ṣíṣí nígbà gbogbo ti app mìíràn rẹ́ kí prepare rẹ lè gbà á, tàbí ṣí ètò fún app kọ̀ọ̀kan ti app yẹn kí o sì yọ app rẹ kúrò nínú tunnel rẹ̀. Ìyọkúrò náà ń jẹ́ kí àlẹ̀mọ́ náà máa ṣiṣẹ́ fún gbogbo nnkan mìíràn, ó sì ń jẹ́ kí app rẹ lo ìsopọ̀ déédé, èyí tí ó sábà jẹ́ àbájáde tí olùmúlò fẹ́ ní tòótọ́.

Kọ ọ̀nà méjèèjì sínú ìwé àtìlẹ́yìn rẹ, nítorí àwọn olùmúlò kì í sábà mọ app tí ó ni VPN. Béèrè pé kí wọ́n fi orúkọ VPN tí ń ṣiṣẹ́ láti Ètò àti àwọn àbájáde prepare, establish àti protect láti àwọn àkọsílẹ̀ rẹ ránṣẹ́, ìwọ yóò sì lè sọ ní ìṣẹ́jú kan ìgbésẹ̀ tí ó kùnà. Lẹ́yìn náà ṣàyẹ̀wò pẹ̀lú ìrìnàjò gidi: wíwá orúkọ, ìsopọ̀ TCP àti ìbéèrè kan nípasẹ̀ tunnel, kì í ṣe àmì tí ó so pọ̀ nìkan. Descriptor tí ó tọ́ àti àmì àwọ̀ ewé ń jẹ́rìí ìní ní àgbáyé, kì í ṣe pé ìgbékalẹ̀ ìta ye àwọn ìlànà ìtọ́sọ́nà kọjá rárá.

Bí gbogbo àwọn àyẹ̀wò mẹ́rin bá kọjá tí ìrìnàjò sì ṣì kú, ìní kì í ṣe ìṣòro rẹ mọ́. Lọ sí ìtọ́sọ́nà àti ìdè ọ̀nà sí server, kí o sì dán àwọn ẹ̀rí kan náà wò láti ẹ̀rọ tí kò ní app VPN tí a fi sórí ẹ̀rọ.

Àwọn àpilẹ̀kọ tó jọra