فهرست منبع

Refactor: migrate to tun2socket

kr328 4 سال پیش
والد
کامیت
41ab062103

+ 10 - 8
core/src/foss/golang/go.mod

@@ -9,22 +9,24 @@ require (
 	github.com/Dreamacro/clash v1.7.1 // indirect
 	github.com/Dreamacro/clash v1.7.1 // indirect
 	github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
 	github.com/Dreamacro/go-shadowsocks2 v0.1.7 // indirect
 	github.com/dlclark/regexp2 v1.4.0 // indirect
 	github.com/dlclark/regexp2 v1.4.0 // indirect
-	github.com/gofrs/uuid v4.0.0+incompatible // indirect
+	github.com/gofrs/uuid v4.1.0+incompatible // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
 	github.com/gorilla/websocket v1.4.2 // indirect
-	github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac // indirect
-	github.com/kr328/tun2socket-lwip v0.0.0-20211015022349-94b5374d46e5 // indirect
+	github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd // indirect
+	github.com/kr/pretty v0.1.0 // indirect
+	github.com/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7 // indirect
 	github.com/miekg/dns v1.1.43 // indirect
 	github.com/miekg/dns v1.1.43 // indirect
 	github.com/oschwald/geoip2-golang v1.5.0 // indirect
 	github.com/oschwald/geoip2-golang v1.5.0 // indirect
 	github.com/oschwald/maxminddb-golang v1.8.0 // indirect
 	github.com/oschwald/maxminddb-golang v1.8.0 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
 	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
+	github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 // indirect
 	go.etcd.io/bbolt v1.3.6 // indirect
 	go.etcd.io/bbolt v1.3.6 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
 	go.uber.org/atomic v1.9.0 // indirect
-	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
-	golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f // indirect
+	golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
+	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-	golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 // indirect
-	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/sys v0.0.0-20211113001501-0c823b97ae02 // indirect
+	golang.org/x/text v0.3.7 // indirect
+	gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
 )
 
 

+ 24 - 12
core/src/foss/golang/go.sum

@@ -9,8 +9,9 @@ github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:Pjfxu
 github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-chi/chi/v5 v5.0.4/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
 github.com/go-chi/cors v1.2.0/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
 github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
 github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
-github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.1.0+incompatible h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk=
+github.com/gofrs/uuid v4.1.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -20,18 +21,22 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
 github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
-github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac h1:IO6EfdRnPhxgKOsk9DbewdtQZHKZKnGlW7QCUttvNys=
 github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
 github.com/insomniacslk/dhcp v0.0.0-20210827173440-b95caade3eac/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
+github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd h1:jupbuQFZtwOBg/3EmK91/rGaYFkqCb9bwHOnwn7Cav0=
+github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd/go.mod h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
 github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
 github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
 github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
 github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
 github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
 github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
 github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
 github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7 h1:ln3WnceaKthifUEYKWyiZmZfPH88FTKbOHrEfSCd3dk=
+github.com/kr328/tun2socket v0.0.0-20211114060954-370f53a7d3d7/go.mod h1:4NsuTykBBcrx78C3WMzjkIMC2vJicF6nSQUm1alZqYM=
 github.com/kr328/tun2socket-lwip v0.0.0-20211011111457-aee61f59119e/go.mod h1:JFkXLCpLkNVvLMRkq3gexTlRHfzbqcP5HfFOoq5Mj+g=
 github.com/kr328/tun2socket-lwip v0.0.0-20211011111457-aee61f59119e/go.mod h1:JFkXLCpLkNVvLMRkq3gexTlRHfzbqcP5HfFOoq5Mj+g=
-github.com/kr328/tun2socket-lwip v0.0.0-20211015020707-5db8ce531486 h1:vr7UW621Q53YUKUlsXojehQ4dtKXwyzin0hjwegC7gw=
-github.com/kr328/tun2socket-lwip v0.0.0-20211015020707-5db8ce531486/go.mod h1:JFkXLCpLkNVvLMRkq3gexTlRHfzbqcP5HfFOoq5Mj+g=
-github.com/kr328/tun2socket-lwip v0.0.0-20211015022349-94b5374d46e5 h1:Hsz4nGstXCWTLjf3mFDytJ0u1HfbrOfvbWRfphsLvBg=
-github.com/kr328/tun2socket-lwip v0.0.0-20211015022349-94b5374d46e5/go.mod h1:JFkXLCpLkNVvLMRkq3gexTlRHfzbqcP5HfFOoq5Mj+g=
 github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
 github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7/go.mod h1:U6ZQobyTjI/tJyq2HG+i/dfSoFUt8/aZCM+GKtmFk/Y=
 github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
 github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA=
 github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
 github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M=
@@ -57,8 +62,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/u-root/uio v0.0.0-20210528114334-82958018845c h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA=
 github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
 github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
+github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7 h1:XMAtQHwKjWHIRwg+8Nj/rzUomQY1q6cM3ncA0wP8GU4=
+github.com/u-root/uio v0.0.0-20210528151154-e40b768296a7/go.mod h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
 go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
 go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
 go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
 go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@@ -66,8 +72,9 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
+golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -78,8 +85,9 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f h1:w6wWR0H+nyVpbSAQbzVEIACVyr/h8l/BEkY6Sokc7Eg=
 golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210903162142-ad29c8ab022f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -102,18 +110,22 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34 h1:GkvMjFtXUmahfDtashnc1mnrCtuBVcwse5QV2lUk/tI=
 golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211113001501-0c823b97ae02 h1:7NCfEGl0sfUojmX78nK9pBJuUlSZWEJA/TwASvfiPLo=
+golang.org/x/sys v0.0.0-20211113001501-0c823b97ae02/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=

+ 13 - 6
core/src/main/cpp/jni_helper.c

@@ -54,20 +54,27 @@ int jni_catch_exception(JNIEnv *env) {
     return result;
     return result;
 }
 }
 
 
-void jni_attach_thread(JNIEnv **penv) {
+void jni_attach_thread(struct _scoped_jni *jni) {
     JavaVM *vm = global_java_vm();
     JavaVM *vm = global_java_vm();
 
 
-    if ((*vm)->AttachCurrentThread(vm, penv, NULL) != JNI_OK) {
+    if ((*vm)->GetEnv(vm, (void **) &jni->env, JNI_VERSION_1_6) == JNI_OK) {
+        jni->require_release = 0;
+        return;
+    }
+
+    if ((*vm)->AttachCurrentThread(vm, &jni->env, NULL) != JNI_OK) {
         abort();
         abort();
     }
     }
-}
 
 
-void jni_detach_thread(JNIEnv **env) {
-    (void) env;
+    jni->require_release = 1;
+}
 
 
+void jni_detach_thread(struct _scoped_jni *jni) {
     JavaVM *vm = global_java_vm();
     JavaVM *vm = global_java_vm();
 
 
-    (*vm)->DetachCurrentThread(vm);
+    if (jni->require_release) {
+        (*vm)->DetachCurrentThread(vm);
+    }
 }
 }
 
 
 void release_string(char **str) {
 void release_string(char **str) {

+ 11 - 9
core/src/main/cpp/jni_helper.h

@@ -6,21 +6,23 @@
 #include <malloc.h>
 #include <malloc.h>
 #include <android/log.h>
 #include <android/log.h>
 
 
-extern void initialize_jni(JavaVM *vm, JNIEnv *env);
+struct _scoped_jni {
+    JNIEnv *env;
+    int require_release;
+};
 
 
+extern void initialize_jni(JavaVM *vm, JNIEnv *env);
 extern jstring jni_new_string(JNIEnv *env, const char *str);
 extern jstring jni_new_string(JNIEnv *env, const char *str);
-
 extern char *jni_get_string(JNIEnv *env, jstring str);
 extern char *jni_get_string(JNIEnv *env, jstring str);
-
 extern int jni_catch_exception(JNIEnv *env);
 extern int jni_catch_exception(JNIEnv *env);
-
-extern void jni_attach_thread(JNIEnv **penv);
-
-extern void jni_detach_thread(JNIEnv **env);
-
+extern void jni_attach_thread(struct _scoped_jni *jni);
+extern void jni_detach_thread(struct _scoped_jni *env);
 extern void release_string(char **str);
 extern void release_string(char **str);
 
 
-#define ATTACH_JNI() __attribute__((unused, cleanup(jni_detach_thread))) JNIEnv *env = NULL; jni_attach_thread(&env)
+#define ATTACH_JNI() __attribute__((unused, cleanup(jni_detach_thread))) \
+                    struct _scoped_jni _jni; \
+                    jni_attach_thread(&_jni); \
+                    JNIEnv *env = _jni.env
 
 
 #define scoped_string __attribute__((cleanup(release_string))) char*
 #define scoped_string __attribute__((cleanup(release_string))) char*
 
 

+ 7 - 4
core/src/main/cpp/main.c

@@ -107,16 +107,19 @@ Java_com_github_kr328_clash_core_bridge_Bridge_nativeNotifyInstalledAppChanged(J
 
 
 JNIEXPORT void JNICALL
 JNIEXPORT void JNICALL
 Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobject thiz,
 Java_com_github_kr328_clash_core_bridge_Bridge_nativeStartTun(JNIEnv *env, jobject thiz,
-                                                              jint fd, jint mtu,
-                                                              jstring dns, jstring blocking,
+                                                              jint fd,
+                                                              jstring gateway,
+                                                              jstring portal,
+                                                              jstring dns,
                                                               jobject cb) {
                                                               jobject cb) {
     TRACE_METHOD();
     TRACE_METHOD();
 
 
-    scoped_string _blocking = get_string(blocking);
+    scoped_string _gateway = get_string(gateway);
+    scoped_string _portal = get_string(portal);
     scoped_string _dns = get_string(dns);
     scoped_string _dns = get_string(dns);
     jobject _interface = new_global(cb);
     jobject _interface = new_global(cb);
 
 
-    startTun(fd, mtu, _dns, _blocking, _interface);
+    startTun(fd, _gateway, _portal, _dns, _interface);
 }
 }
 
 
 JNIEXPORT void JNICALL
 JNIEXPORT void JNICALL

+ 0 - 8
core/src/main/golang/native/config/defaults.go

@@ -7,10 +7,6 @@ var (
 		"8.8.8.8",
 		"8.8.8.8",
 		"1.1.1.1",
 		"1.1.1.1",
 	}
 	}
-	defaultFallback = []string{
-		"https://1.1.1.1/dns-query",
-		"https://doh.pub/dns-query",
-	}
 	defaultFakeIPFilter = []string{
 	defaultFakeIPFilter = []string{
 		// stun services
 		// stun services
 		"+.stun.*.*",
 		"+.stun.*.*",
@@ -24,8 +20,4 @@ var (
 		// Nintendo Switch
 		// Nintendo Switch
 		"*.n.n.srv.nintendo.net",
 		"*.n.n.srv.nintendo.net",
 	}
 	}
-	localNetwork = []string{
-		"0.0.0.0/8",
-		"127.0.0.0/8",
-	}
 )
 )

+ 4 - 5
core/src/main/golang/native/config/process.go

@@ -10,6 +10,7 @@ import (
 	"github.com/dlclark/regexp2"
 	"github.com/dlclark/regexp2"
 
 
 	"cfa/native/common"
 	"cfa/native/common"
+	C "github.com/Dreamacro/clash/constant"
 	"github.com/Dreamacro/clash/log"
 	"github.com/Dreamacro/clash/log"
 
 
 	"github.com/Dreamacro/clash/config"
 	"github.com/Dreamacro/clash/config"
@@ -54,6 +55,7 @@ func patchGeneral(cfg *config.RawConfig, _ string) error {
 
 
 func patchProfile(cfg *config.RawConfig, _ string) error {
 func patchProfile(cfg *config.RawConfig, _ string) error {
 	cfg.Profile.StoreSelected = false
 	cfg.Profile.StoreSelected = false
+	cfg.Profile.StoreFakeIP = true
 
 
 	return nil
 	return nil
 }
 }
@@ -63,11 +65,8 @@ func patchDns(cfg *config.RawConfig, _ string) error {
 		cfg.DNS.Enable = true
 		cfg.DNS.Enable = true
 		cfg.DNS.IPv6 = false
 		cfg.DNS.IPv6 = false
 		cfg.DNS.NameServer = defaultNameServers
 		cfg.DNS.NameServer = defaultNameServers
-		cfg.DNS.Fallback = defaultFallback
-		cfg.DNS.FallbackFilter.GeoIP = false
-		cfg.DNS.FallbackFilter.IPCIDR = localNetwork
-		cfg.DNS.EnhancedMode = dns.MAPPING
-		cfg.DNS.FakeIPRange = "198.18.0.0/16"
+		cfg.DNS.EnhancedMode = C.DNSFakeIP
+		cfg.DNS.FakeIPRange = "28.0.0.0/8"
 		cfg.DNS.DefaultNameserver = defaultNameServers
 		cfg.DNS.DefaultNameserver = defaultNameServers
 		cfg.DNS.FakeIPFilter = defaultFakeIPFilter
 		cfg.DNS.FakeIPFilter = defaultFakeIPFilter
 
 

+ 38 - 9
core/src/main/golang/native/tun.go

@@ -5,6 +5,8 @@ import "C"
 
 
 import (
 import (
 	"context"
 	"context"
+	"io"
+	"sync"
 	"unsafe"
 	"unsafe"
 
 
 	"golang.org/x/sync/semaphore"
 	"golang.org/x/sync/semaphore"
@@ -13,7 +15,11 @@ import (
 	"cfa/native/tun"
 	"cfa/native/tun"
 )
 )
 
 
+var rTunLock sync.Mutex
+var rTun *remoteTun
+
 type remoteTun struct {
 type remoteTun struct {
+	closer   io.Closer
 	callback unsafe.Pointer
 	callback unsafe.Pointer
 
 
 	closed bool
 	closed bool
@@ -21,7 +27,7 @@ type remoteTun struct {
 }
 }
 
 
 func (t *remoteTun) markSocket(fd int) {
 func (t *remoteTun) markSocket(fd int) {
-	_ = t.limit.Acquire(context.TODO(), 1)
+	_ = t.limit.Acquire(context.Background(), 1)
 	defer t.limit.Release(1)
 	defer t.limit.Release(1)
 
 
 	if t.closed {
 	if t.closed {
@@ -32,7 +38,7 @@ func (t *remoteTun) markSocket(fd int) {
 }
 }
 
 
 func (t *remoteTun) querySocketUid(protocol int, source, target string) int {
 func (t *remoteTun) querySocketUid(protocol int, source, target string) int {
-	_ = t.limit.Acquire(context.TODO(), 1)
+	_ = t.limit.Acquire(context.Background(), 1)
 	defer t.limit.Release(1)
 	defer t.limit.Release(1)
 
 
 	if t.closed {
 	if t.closed {
@@ -42,38 +48,61 @@ func (t *remoteTun) querySocketUid(protocol int, source, target string) int {
 	return int(C.query_socket_uid(t.callback, C.int(protocol), C.CString(source), C.CString(target)))
 	return int(C.query_socket_uid(t.callback, C.int(protocol), C.CString(source), C.CString(target)))
 }
 }
 
 
-func (t *remoteTun) stop() {
-	_ = t.limit.Acquire(context.Background(), 4)
+func (t *remoteTun) close() {
+	_ = t.limit.Acquire(context.TODO(), 4)
 	defer t.limit.Release(4)
 	defer t.limit.Release(4)
 
 
 	t.closed = true
 	t.closed = true
 
 
+	if t.closer != nil {
+		_ = t.closer.Close()
+	}
+
 	app.ApplyTunContext(nil, nil)
 	app.ApplyTunContext(nil, nil)
 
 
 	C.release_object(t.callback)
 	C.release_object(t.callback)
 }
 }
 
 
 //export startTun
 //export startTun
-func startTun(fd, mtu C.int, gateway, dns C.c_string, callback unsafe.Pointer) C.int {
+func startTun(fd C.int, gateway, portal, dns C.c_string, callback unsafe.Pointer) C.int {
+	rTunLock.Lock()
+	defer rTunLock.Unlock()
+
+	if rTun != nil {
+		rTun.close()
+		rTun = nil
+	}
+
 	f := int(fd)
 	f := int(fd)
-	m := int(mtu)
 	g := C.GoString(gateway)
 	g := C.GoString(gateway)
+	p := C.GoString(portal)
 	d := C.GoString(dns)
 	d := C.GoString(dns)
 
 
 	remote := &remoteTun{callback: callback, closed: false, limit: semaphore.NewWeighted(4)}
 	remote := &remoteTun{callback: callback, closed: false, limit: semaphore.NewWeighted(4)}
 
 
 	app.ApplyTunContext(remote.markSocket, remote.querySocketUid)
 	app.ApplyTunContext(remote.markSocket, remote.querySocketUid)
 
 
-	if tun.Start(f, m, g, d, remote.stop) != nil {
-		app.ApplyTunContext(nil, nil)
+	closer, err := tun.Start(f, g, p, d)
+	if err != nil {
+		remote.close()
 
 
 		return 1
 		return 1
 	}
 	}
 
 
+	remote.closer = closer
+
+	rTun = remote
+
 	return 0
 	return 0
 }
 }
 
 
 //export stopTun
 //export stopTun
 func stopTun() {
 func stopTun() {
-	tun.Stop()
+	rTunLock.Lock()
+	defer rTunLock.Unlock()
+
+	if rTun != nil {
+		rTun.close()
+		rTun = nil
+	}
 }
 }

+ 0 - 39
core/src/main/golang/native/tun/link.go

@@ -1,39 +0,0 @@
-package tun
-
-import "github.com/Dreamacro/clash/log"
-
-func (a *adapter) rx() {
-	log.Infoln("[ATUN] Device rx started")
-	defer log.Infoln("[ATUN] Device rx exited")
-	defer a.once.Do(a.stop)
-	defer a.close()
-
-	buf := make([]byte, a.mtu)
-
-	for {
-		n, err := a.device.Read(buf)
-		if err != nil {
-			return
-		}
-
-		_, _ = a.stack.Link().Write(buf[:n])
-	}
-}
-
-func (a *adapter) tx() {
-	log.Infoln("[ATUN] Device tx started")
-	defer log.Infoln("[ATUN] Device tx exited")
-	defer a.once.Do(a.stop)
-	defer a.close()
-
-	buf := make([]byte, a.mtu)
-
-	for {
-		n, err := a.stack.Link().Read(buf)
-		if err != nil {
-			return
-		}
-
-		_, _ = a.device.Write(buf[:n])
-	}
-}

+ 0 - 105
core/src/main/golang/native/tun/tcp.go

@@ -1,105 +0,0 @@
-package tun
-
-import (
-	"encoding/binary"
-	"io"
-	"net"
-	"strconv"
-	"time"
-
-	C "github.com/Dreamacro/clash/constant"
-	"github.com/Dreamacro/clash/context"
-	"github.com/Dreamacro/clash/log"
-	"github.com/Dreamacro/clash/tunnel"
-)
-
-const defaultDnsReadTimeout = time.Second * 30
-
-func (a *adapter) tcp() {
-	log.Infoln("[ATUN] TCP listener started")
-	defer log.Infoln("[ATUN] TCP listener exited")
-	defer a.stack.Close()
-
-accept:
-	for {
-		conn, err := a.stack.TCP().Accept()
-		if err != nil {
-			return
-		}
-
-		sAddr := conn.LocalAddr().(*net.TCPAddr)
-		tAddr := conn.RemoteAddr().(*net.TCPAddr)
-
-		// handle dns messages
-		if a.hijackTCPDNS(conn, tAddr) {
-			continue
-		}
-
-		// drop all connections connect to blocking list
-		for _, b := range a.blocking {
-			if b.Contains(tAddr.IP) {
-				_ = conn.Close()
-
-				continue accept
-			}
-		}
-
-		metadata := &C.Metadata{
-			NetWork:    C.TCP,
-			Type:       C.SOCKS5,
-			SrcIP:      sAddr.IP,
-			DstIP:      tAddr.IP,
-			SrcPort:    strconv.Itoa(sAddr.Port),
-			DstPort:    strconv.Itoa(tAddr.Port),
-			AddrType:   C.AtypIPv4,
-			Host:       "",
-			RawSrcAddr: sAddr,
-			RawDstAddr: tAddr,
-		}
-
-		tunnel.TCPIn() <- context.NewConnContext(conn, metadata)
-	}
-}
-
-func (a *adapter) hijackTCPDNS(conn net.Conn, tAddr *net.TCPAddr) bool {
-	if !shouldHijackDns(a.dns, tAddr.IP, tAddr.Port) {
-		return false
-	}
-
-	go func() {
-		defer conn.Close()
-
-		for {
-			if err := conn.SetReadDeadline(time.Now().Add(defaultDnsReadTimeout)); err != nil {
-				return
-			}
-
-			var length uint16
-			if binary.Read(conn, binary.BigEndian, &length) != nil {
-				return
-			}
-
-			data := make([]byte, length)
-
-			_, err := io.ReadFull(conn, data)
-			if err != nil {
-				return
-			}
-
-			rb, err := relayDns(data)
-			if err != nil {
-				continue
-			}
-
-			if binary.Write(conn, binary.BigEndian, uint16(len(rb))) != nil {
-				return
-			}
-
-			if _, err := conn.Write(rb); err != nil {
-				return
-			}
-		}
-	}()
-
-	return true
-}

+ 140 - 63
core/src/main/golang/native/tun/tun.go

@@ -1,91 +1,168 @@
 package tun
 package tun
 
 
 import (
 import (
+	"encoding/binary"
+	"io"
 	"net"
 	"net"
 	"os"
 	"os"
-	"strings"
-	"sync"
-	"syscall"
-
-	"github.com/kr328/tun2socket-lwip"
+	"strconv"
+	"time"
+
+	"github.com/kr328/tun2socket"
+
+	"github.com/Dreamacro/clash/adapter/inbound"
+	"github.com/Dreamacro/clash/common/pool"
+	C "github.com/Dreamacro/clash/constant"
+	"github.com/Dreamacro/clash/context"
+	"github.com/Dreamacro/clash/log"
+	"github.com/Dreamacro/clash/transport/socks5"
+	"github.com/Dreamacro/clash/tunnel"
 )
 )
 
 
-type adapter struct {
-	device   *os.File
-	stack    tun2socket.Stack
-	blocking []*net.IPNet
-	dns      net.IP
-	mtu      int
-	once     sync.Once
-	stop     func()
-}
-
-var lock sync.Mutex
-var instance *adapter
-
-func (a *adapter) close() {
-	_ = a.stack.Close()
-	_ = a.device.Close()
-}
+var _, ipv4LoopBack, _ = net.ParseCIDR("127.0.0.0/8")
 
 
-func Start(fd, mtu int, dns string, blocking string, stop func()) error {
-	lock.Lock()
-	defer lock.Unlock()
-
-	if instance != nil {
-		instance.close()
-	}
-
-	_ = syscall.SetNonblock(fd, true)
+func Start(fd int, gateway, portal, dns string) (io.Closer, error) {
+	log.Debugln("TUN: fd = %d, gateway = %s, portal = %s, dns = %s", fd, gateway, portal, dns)
 
 
 	device := os.NewFile(uintptr(fd), "/dev/tun")
 	device := os.NewFile(uintptr(fd), "/dev/tun")
-	stack, err := tun2socket.NewStack(mtu)
+	stack, err := tun2socket.StartTun2Socket(device, net.ParseIP(gateway), net.ParseIP(portal))
 	if err != nil {
 	if err != nil {
 		_ = device.Close()
 		_ = device.Close()
 
 
-		return err
+		return nil, err
 	}
 	}
 
 
-	dn := net.ParseIP(dns)
+	dnsAddr := net.ParseIP(dns)
 
 
-	var blk []*net.IPNet
+	tcp := func() {
+		defer stack.TCP().Close()
+		defer log.Debugln("TCP: closed")
 
 
-	for _, b := range strings.Split(blocking, ";") {
-		_, n, err := net.ParseCIDR(b)
-		if err != nil {
-			device.Close()
+		for stack.TCP().SetDeadline(time.Time{}) == nil {
+			conn, err := stack.TCP().Accept()
+			if err != nil {
+				log.Debugln("Accept connection: %v", err)
 
 
-			return err
-		}
+				continue
+			}
 
 
-		blk = append(blk, n)
-	}
+			lAddr := conn.RemoteAddr().(*net.TCPAddr)
+			rAddr := conn.RemoteAddr().(*net.TCPAddr)
+
+			if ipv4LoopBack.Contains(rAddr.IP) {
+				conn.Close()
+
+				continue
+			}
+
+			if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) {
+				go func() {
+					defer conn.Close()
+
+					buf := pool.Get(pool.UDPBufferSize)
+					defer pool.Put(buf)
+
+					for {
+						conn.SetReadDeadline(time.Now().Add(C.DefaultTCPTimeout))
+
+						length := uint16(0)
+						if err := binary.Read(conn, binary.BigEndian, &length); err != nil {
+							return
+						}
+
+						if int(length) > len(buf) {
+							return
+						}
 
 
-	instance = &adapter{
-		device:   device,
-		stack:    stack,
-		blocking: blk,
-		dns:      dn,
-		mtu:      mtu,
-		once:     sync.Once{},
-		stop:     stop,
+						n, err := conn.Read(buf[:length])
+						if err != nil {
+							return
+						}
+
+						msg, err := relayDns(buf[:n])
+						if err != nil {
+							return
+						}
+
+						_, _ = conn.Write(msg)
+					}
+				}()
+
+				continue
+			}
+
+			metadata := &C.Metadata{
+				NetWork:    C.TCP,
+				Type:       C.SOCKS5,
+				SrcIP:      lAddr.IP,
+				DstIP:      rAddr.IP,
+				SrcPort:    strconv.Itoa(lAddr.Port),
+				DstPort:    strconv.Itoa(rAddr.Port),
+				AddrType:   C.AtypIPv4,
+				Host:       "",
+				RawSrcAddr: lAddr,
+				RawDstAddr: rAddr,
+			}
+
+			tunnel.TCPIn() <- context.NewConnContext(conn, metadata)
+		}
 	}
 	}
 
 
-	go instance.rx()
-	go instance.tx()
-	go instance.tcp()
-	go instance.udp()
+	udp := func() {
+		defer stack.UDP().Close()
+		defer log.Debugln("UDP: closed")
 
 
-	return nil
-}
+		for {
+			buf := pool.Get(pool.UDPBufferSize)
+
+			n, lRAddr, rRAddr, err := stack.UDP().ReadFrom(buf)
+			if err != nil {
+				return
+			}
+
+			raw := buf[:n]
+			lAddr := lRAddr.(*net.UDPAddr)
+			rAddr := rRAddr.(*net.UDPAddr)
 
 
-func Stop() {
-	lock.Lock()
-	defer lock.Unlock()
+			if ipv4LoopBack.Contains(rAddr.IP) {
+				pool.Put(buf)
 
 
-	if instance != nil {
-		instance.close()
+				continue
+			}
+
+			if shouldHijackDns(dnsAddr, rAddr.IP, rAddr.Port) {
+				go func() {
+					defer pool.Put(buf)
+
+					msg, err := relayDns(raw)
+					if err != nil {
+						return
+					}
+
+					_, _ = stack.UDP().WriteTo(msg, rAddr, lAddr)
+				}()
+
+				continue
+			}
+
+			pkt := &packet{
+				local: lAddr,
+				data:  raw,
+				writeBack: func(b []byte, addr net.Addr) (int, error) {
+					return stack.UDP().WriteTo(b, addr, lAddr)
+				},
+				drop: func() {
+					pool.Put(buf)
+				},
+			}
+
+			tunnel.UDPIn() <- inbound.NewPacket(socks5.ParseAddrToSocksAddr(rAddr), pkt, C.SOCKS5)
+		}
 	}
 	}
 
 
-	instance = nil
+	go tcp()
+	go udp()
+	go udp()
+
+	return stack, nil
 }
 }

+ 7 - 78
core/src/main/golang/native/tun/udp.go

@@ -2,21 +2,13 @@ package tun
 
 
 import (
 import (
 	"net"
 	"net"
-
-	"github.com/Dreamacro/clash/adapter/inbound"
-	"github.com/Dreamacro/clash/common/pool"
-	C "github.com/Dreamacro/clash/constant"
-	"github.com/Dreamacro/clash/log"
-	"github.com/Dreamacro/clash/transport/socks5"
-	"github.com/Dreamacro/clash/tunnel"
-
-	"github.com/kr328/tun2socket-lwip"
 )
 )
 
 
 type packet struct {
 type packet struct {
-	stack tun2socket.Stack
-	local *net.UDPAddr
-	data  []byte
+	local     *net.UDPAddr
+	data      []byte
+	writeBack func(b []byte, addr net.Addr) (int, error)
+	drop      func()
 }
 }
 
 
 func (pkt *packet) Data() []byte {
 func (pkt *packet) Data() []byte {
@@ -24,76 +16,13 @@ func (pkt *packet) Data() []byte {
 }
 }
 
 
 func (pkt *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
 func (pkt *packet) WriteBack(b []byte, addr net.Addr) (n int, err error) {
-	return pkt.stack.UDP().WriteTo(b, pkt.local, addr)
+	return pkt.writeBack(b, addr)
 }
 }
 
 
 func (pkt *packet) Drop() {
 func (pkt *packet) Drop() {
-	pool.Put(pkt.data)
+	pkt.drop()
 }
 }
 
 
 func (pkt *packet) LocalAddr() net.Addr {
 func (pkt *packet) LocalAddr() net.Addr {
-	return &net.UDPAddr{
-		IP:   pkt.local.IP,
-		Port: pkt.local.Port,
-		Zone: "",
-	}
-}
-
-func (a *adapter) udp() {
-	log.Infoln("[ATUN] UDP receiver started")
-	defer log.Infoln("[ATUN] UDP receiver exited")
-	defer a.stack.Close()
-
-read:
-	for {
-		buf := pool.Get(a.mtu)
-
-		n, lAddr, rAddr, err := a.stack.UDP().ReadFrom(buf)
-		if err != nil {
-			return
-		}
-
-		sAddr := lAddr.(*net.UDPAddr)
-		tAddr := rAddr.(*net.UDPAddr)
-
-		// handle dns messages
-		if a.hijackUDPDNS(buf[:n], sAddr, tAddr) {
-			continue
-		}
-
-		// drop all packet send to blocking list
-		for _, b := range a.blocking {
-			if b.Contains(tAddr.IP) {
-				continue read
-			}
-		}
-
-		pkt := &packet{
-			stack: a.stack,
-			local: sAddr,
-			data:  buf[:n],
-		}
-
-		tunnel.UDPIn() <- inbound.NewPacket(socks5.ParseAddrToSocksAddr(tAddr), pkt, C.SOCKS5)
-	}
-}
-
-func (a *adapter) hijackUDPDNS(pkt []byte, sAddr, tAddr *net.UDPAddr) bool {
-	if !shouldHijackDns(a.dns, tAddr.IP, tAddr.Port) {
-		return false
-	}
-
-	go func() {
-		answer, err := relayDns(pkt)
-
-		if err != nil {
-			return
-		}
-
-		_, _ = a.stack.UDP().WriteTo(answer, sAddr, tAddr)
-
-		pool.Put(pkt)
-	}()
-
-	return true
+	return pkt.local
 }
 }

+ 3 - 3
core/src/main/java/com/github/kr328/clash/core/Clash.kt

@@ -64,13 +64,13 @@ object Clash {
 
 
     fun startTun(
     fun startTun(
         fd: Int,
         fd: Int,
-        mtu: Int,
+        gateway: String,
+        portal: String,
         dns: String,
         dns: String,
-        blocking: String,
         markSocket: (Int) -> Boolean,
         markSocket: (Int) -> Boolean,
         querySocketUid: (protocol: Int, source: InetSocketAddress, target: InetSocketAddress) -> Int
         querySocketUid: (protocol: Int, source: InetSocketAddress, target: InetSocketAddress) -> Int
     ) {
     ) {
-        Bridge.nativeStartTun(fd, mtu, dns, blocking, object : TunInterface {
+        Bridge.nativeStartTun(fd, gateway, portal, dns, object : TunInterface {
             override fun markSocket(fd: Int) {
             override fun markSocket(fd: Int) {
                 markSocket(fd)
                 markSocket(fd)
             }
             }

+ 4 - 1
core/src/main/java/com/github/kr328/clash/core/bridge/Bridge.kt

@@ -4,6 +4,7 @@ import android.os.Build
 import android.os.ParcelFileDescriptor
 import android.os.ParcelFileDescriptor
 import androidx.annotation.Keep
 import androidx.annotation.Keep
 import com.github.kr328.clash.common.Global
 import com.github.kr328.clash.common.Global
+import com.github.kr328.clash.common.log.Log
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.CompletableDeferred
 import java.io.File
 import java.io.File
 
 
@@ -18,7 +19,7 @@ object Bridge {
     external fun nativeNotifyDnsChanged(dnsList: String)
     external fun nativeNotifyDnsChanged(dnsList: String)
     external fun nativeNotifyTimeZoneChanged(name: String, offset: Int)
     external fun nativeNotifyTimeZoneChanged(name: String, offset: Int)
     external fun nativeNotifyInstalledAppChanged(uidList: String)
     external fun nativeNotifyInstalledAppChanged(uidList: String)
-    external fun nativeStartTun(fd: Int, mtu: Int, dns: String, blocking: String, cb: TunInterface)
+    external fun nativeStartTun(fd: Int, gateway: String, portal: String, dns: String, cb: TunInterface)
     external fun nativeStopTun()
     external fun nativeStopTun()
     external fun nativeStartHttp(listenAt: String): String?
     external fun nativeStartHttp(listenAt: String): String?
     external fun nativeStopHttp()
     external fun nativeStopHttp()
@@ -63,6 +64,8 @@ object Bridge {
         val versionName = ctx.packageManager.getPackageInfo(ctx.packageName, 0).versionName
         val versionName = ctx.packageManager.getPackageInfo(ctx.packageName, 0).versionName
         val sdkVersion = Build.VERSION.SDK_INT
         val sdkVersion = Build.VERSION.SDK_INT
 
 
+        Log.d("Home = $home")
+
         nativeInit(home, versionName, sdkVersion)
         nativeInit(home, versionName, sdkVersion)
     }
     }
 }
 }

+ 4 - 3
service/src/main/java/com/github/kr328/clash/service/TunService.kt

@@ -207,8 +207,8 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
             TunModule.TunDevice(
             TunModule.TunDevice(
                 fd = establish()?.detachFd()
                 fd = establish()?.detachFd()
                     ?: throw NullPointerException("Establish VPN rejected by system"),
                     ?: throw NullPointerException("Establish VPN rejected by system"),
-                mtu = TUN_MTU,
-                blocking = blocking.joinToString(";"),
+                gateway = TUN_GATEWAY,
+                portal = TUN_PORTAL,
                 dns = if (store.dnsHijacking) NET_ANY else TUN_DNS,
                 dns = if (store.dnsHijacking) NET_ANY else TUN_DNS,
             )
             )
         }
         }
@@ -220,7 +220,8 @@ class TunService : VpnService(), CoroutineScope by CoroutineScope(Dispatchers.De
         private const val TUN_MTU = 9000
         private const val TUN_MTU = 9000
         private const val TUN_SUBNET_PREFIX = 30
         private const val TUN_SUBNET_PREFIX = 30
         private const val TUN_GATEWAY = "172.19.0.1"
         private const val TUN_GATEWAY = "172.19.0.1"
-        private const val TUN_DNS = "172.19.0.2"
+        private const val TUN_PORTAL = "172.19.0.2"
+        private const val TUN_DNS = TUN_PORTAL
         private const val NET_ANY = "0.0.0.0"
         private const val NET_ANY = "0.0.0.0"
         private const val NET_SUBNET_LOOPBACK = "127.0.0.0/8"
         private const val NET_SUBNET_LOOPBACK = "127.0.0.0/8"
 
 

+ 4 - 4
service/src/main/java/com/github/kr328/clash/service/clash/module/TunModule.kt

@@ -15,8 +15,8 @@ import java.security.SecureRandom
 class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
 class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
     data class TunDevice(
     data class TunDevice(
         val fd: Int,
         val fd: Int,
-        val mtu: Int,
-        val blocking: String,
+        val gateway: String,
+        val portal: String,
         val dns: String,
         val dns: String,
     )
     )
 
 
@@ -56,9 +56,9 @@ class TunModule(private val vpn: VpnService) : Module<Unit>(vpn) {
     fun attach(device: TunDevice) {
     fun attach(device: TunDevice) {
         Clash.startTun(
         Clash.startTun(
             fd = device.fd,
             fd = device.fd,
-            mtu = device.mtu,
+            gateway = device.gateway,
+            portal = device.portal,
             dns = device.dns,
             dns = device.dns,
-            blocking = device.blocking,
             markSocket = vpn::protect,
             markSocket = vpn::protect,
             querySocketUid = this::queryUid
             querySocketUid = this::queryUid
         )
         )