1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2025-01-17 23:06:30 -05:00

Remove hysteria2

The hysteria2 fork used "github.com/JimmyHuang454/hysteria" removed the original license of hysteria2 (which is not allowed) and replaced it with GPL which conflicts with v2ray's license.

Given that the quality of the related code is very poor and it is not synchronized with the upstream, I deleted it.
This commit is contained in:
世界 2024-12-27 09:50:22 +08:00
parent d59c2b4c85
commit 1d21d7a077
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
23 changed files with 10 additions and 2529 deletions

9
go.mod
View File

@ -6,8 +6,6 @@ toolchain go1.22.7
require ( require (
github.com/adrg/xdg v0.5.3 github.com/adrg/xdg v0.5.3
github.com/apernet/hysteria/core/v2 v2.4.5
github.com/apernet/quic-go v0.45.2-0.20240702221538-ed74cfbe8b6e
github.com/go-chi/chi/v5 v5.1.0 github.com/go-chi/chi/v5 v5.1.0
github.com/go-chi/render v1.0.3 github.com/go-chi/render v1.0.3
github.com/go-playground/validator/v10 v10.22.1 github.com/go-playground/validator/v10 v10.22.1
@ -67,8 +65,10 @@ require (
github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/klauspost/reedsolomon v1.11.7 // indirect github.com/klauspost/reedsolomon v1.11.7 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/mustafaturan/monoton v1.0.0 // indirect github.com/mustafaturan/monoton v1.0.0 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/onsi/ginkgo/v2 v2.17.0 // indirect github.com/onsi/ginkgo/v2 v2.17.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pion/logging v0.2.2 // indirect github.com/pion/logging v0.2.2 // indirect
@ -76,10 +76,8 @@ require (
github.com/pion/sctp v1.8.7 // indirect github.com/pion/sctp v1.8.7 // indirect
github.com/pion/transport/v3 v3.0.7 // indirect github.com/pion/transport/v3 v3.0.7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect github.com/secure-io/siv-go v0.0.0-20180922214919-5ff40651e2c4 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/xtaci/smux v1.5.24 // indirect github.com/xtaci/smux v1.5.24 // indirect
go.uber.org/mock v0.4.0 // indirect go.uber.org/mock v0.4.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
@ -88,8 +86,7 @@ require (
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
) )
replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248 replace github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 => github.com/xiaokangwang/struc v0.0.0-20231031203518-0e381172f248
replace github.com/apernet/hysteria/core/v2 v2.4.5 => github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240724161647-b3347cf6334d

24
go.sum
View File

@ -14,8 +14,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w= github.com/FlowerWrong/water v0.0.0-20180301012659-01a4eaa1f6f2/go.mod h1:xrG5L7lq7T2DLnPr2frMnL906CNEoKRwLB+VYFhPq2w=
github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240724161647-b3347cf6334d h1:DN3vqWeuVa1anRkwCueIqPEUPnSyFCk4PR2LcyJKrZk=
github.com/JimmyHuang454/hysteria/core/v2 v2.0.0-20240724161647-b3347cf6334d/go.mod h1:3OIt9vhWrxoHUMPm6WcpAg7jUEqfy6Q4IyFZA67Azcg=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
@ -27,8 +25,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/apernet/quic-go v0.45.2-0.20240702221538-ed74cfbe8b6e h1:KBs8aBfKl5AKPKGpfn3bl0joDJXDq5fnH+AjFODiU+A=
github.com/apernet/quic-go v0.45.2-0.20240702221538-ed74cfbe8b6e/go.mod h1:MjGWpXA31DZZWESdX3/PjIpSWIT1fOm8FNCqyXXFZFU=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
@ -54,6 +50,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -192,11 +189,10 @@ github.com/klauspost/reedsolomon v1.11.7/go.mod h1:4bXRN+cVzMdml6ti7qLouuYi32KHJ
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 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/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg= github.com/lunixbochs/struc v0.0.0-20190916212049-a5c72983bc42/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
@ -225,6 +221,8 @@ github.com/mustafaturan/monoton v1.0.0/go.mod h1:FOnE7NV3s3EWPXb8/7+/OSdiMBbdlkV
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI= github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI=
github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
@ -273,8 +271,6 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE=
github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs=
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM= github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
@ -283,8 +279,6 @@ github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
@ -313,8 +307,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@ -358,8 +350,6 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8= go.starlark.net v0.0.0-20230612165344-9532f5667272 h1:2/wtqS591wZyD2OsClsVBKRPEvBsQt/Js+fsCiYhwu8=
go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.starlark.net v0.0.0-20230612165344-9532f5667272/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@ -580,8 +570,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=

View File

@ -1,78 +0,0 @@
package v4
import (
"github.com/golang/protobuf/proto"
"github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
"github.com/v2fly/v2ray-core/v5/common/protocol"
"github.com/v2fly/v2ray-core/v5/common/serial"
"github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon"
"github.com/v2fly/v2ray-core/v5/proxy/hysteria2"
)
// Hysteria2ServerTarget is configuration of a single hysteria2 server
type Hysteria2ServerTarget struct {
Address *cfgcommon.Address `json:"address"`
Port uint16 `json:"port"`
Email string `json:"email"`
Level byte `json:"level"`
}
// Hysteria2ClientConfig is configuration of hysteria2 servers
type Hysteria2ClientConfig struct {
Servers []*Hysteria2ServerTarget `json:"servers"`
}
// Build implements Buildable
func (c *Hysteria2ClientConfig) Build() (proto.Message, error) {
config := new(hysteria2.ClientConfig)
if len(c.Servers) == 0 {
return nil, newError("0 Hysteria2 server configured.")
}
serverSpecs := make([]*protocol.ServerEndpoint, len(c.Servers))
for idx, rec := range c.Servers {
if rec.Address == nil {
return nil, newError("Hysteria2 server address is not set.")
}
if rec.Port == 0 {
return nil, newError("Invalid Hysteria2 port.")
}
account := &hysteria2.Account{}
hysteria2 := &protocol.ServerEndpoint{
Address: rec.Address.Build(),
Port: uint32(rec.Port),
User: []*protocol.User{
{
Level: uint32(rec.Level),
Email: rec.Email,
Account: serial.ToTypedMessage(account),
},
},
}
serverSpecs[idx] = hysteria2
}
config.Server = serverSpecs
return config, nil
}
// Hysteria2ServerConfig is Inbound configuration
type Hysteria2ServerConfig struct {
PacketEncoding string `json:"packetEncoding"`
}
// Build implements Buildable
func (c *Hysteria2ServerConfig) Build() (proto.Message, error) {
config := new(hysteria2.ServerConfig)
switch c.PacketEncoding {
case "Packet":
config.PacketEncoding = packetaddr.PacketAddrType_Packet
case "", "None":
config.PacketEncoding = packetaddr.PacketAddrType_None
}
return config, nil
}

View File

@ -16,7 +16,6 @@ import (
"github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket" "github.com/v2fly/v2ray-core/v5/transport/internet/domainsocket"
httpheader "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" httpheader "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http"
"github.com/v2fly/v2ray-core/v5/transport/internet/http" "github.com/v2fly/v2ray-core/v5/transport/internet/http"
"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
"github.com/v2fly/v2ray-core/v5/transport/internet/kcp" "github.com/v2fly/v2ray-core/v5/transport/internet/kcp"
"github.com/v2fly/v2ray-core/v5/transport/internet/quic" "github.com/v2fly/v2ray-core/v5/transport/internet/quic"
"github.com/v2fly/v2ray-core/v5/transport/internet/tcp" "github.com/v2fly/v2ray-core/v5/transport/internet/tcp"
@ -144,26 +143,6 @@ type Hy2ConfigCongestion struct {
DownMbps uint64 `json:"down_mbps"` DownMbps uint64 `json:"down_mbps"`
} }
type Hy2Config struct {
Password string `json:"password"`
Congestion Hy2ConfigCongestion `json:"congestion"`
UseUdpExtension bool `json:"use_udp_extension"`
IgnoreClientBandwidth bool `json:"ignore_client_bandwidth"`
}
// Build implements Buildable.
func (c *Hy2Config) Build() (proto.Message, error) {
return &hysteria2.Config{Password: c.Password,
Congestion: &hysteria2.Congestion{
Type: c.Congestion.Type,
DownMbps: c.Congestion.DownMbps,
UpMbps: c.Congestion.UpMbps,
},
UseUdpExtension: c.UseUdpExtension,
IgnoreClientBandwidth: c.IgnoreClientBandwidth,
}, nil
}
type WebSocketConfig struct { type WebSocketConfig struct {
Path string `json:"path"` Path string `json:"path"`
Headers map[string]string `json:"headers"` Headers map[string]string `json:"headers"`
@ -306,8 +285,6 @@ func (p TransportProtocol) Build() (string, error) {
return "quic", nil return "quic", nil
case "gun", "grpc": case "gun", "grpc":
return "gun", nil return "gun", nil
case "hy2", "hysteria2":
return "hysteria2", nil
default: default:
return "", newError("Config: unknown transport protocol: ", p) return "", newError("Config: unknown transport protocol: ", p)
} }
@ -325,7 +302,6 @@ type StreamConfig struct {
QUICSettings *QUICConfig `json:"quicSettings"` QUICSettings *QUICConfig `json:"quicSettings"`
GunSettings *GunConfig `json:"gunSettings"` GunSettings *GunConfig `json:"gunSettings"`
GRPCSettings *GunConfig `json:"grpcSettings"` GRPCSettings *GunConfig `json:"grpcSettings"`
Hy2Settings *Hy2Config `json:"hy2Settings"`
SocketSettings *socketcfg.SocketConfig `json:"sockopt"` SocketSettings *socketcfg.SocketConfig `json:"sockopt"`
} }
@ -427,16 +403,6 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) {
Settings: serial.ToTypedMessage(gs), Settings: serial.ToTypedMessage(gs),
}) })
} }
if c.Hy2Settings != nil {
hy2, err := c.Hy2Settings.Build()
if err != nil {
return nil, newError("Failed to build hy2 config.").Base(err)
}
config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{
ProtocolName: "hysteria2",
Settings: serial.ToTypedMessage(hy2),
})
}
if c.SocketSettings != nil { if c.SocketSettings != nil {
ss, err := c.SocketSettings.Build() ss, err := c.SocketSettings.Build()
if err != nil { if err != nil {

View File

@ -35,7 +35,6 @@ var (
"vless": func() interface{} { return new(VLessInboundConfig) }, "vless": func() interface{} { return new(VLessInboundConfig) },
"vmess": func() interface{} { return new(VMessInboundConfig) }, "vmess": func() interface{} { return new(VMessInboundConfig) },
"trojan": func() interface{} { return new(TrojanServerConfig) }, "trojan": func() interface{} { return new(TrojanServerConfig) },
"hysteria2": func() interface{} { return new(Hysteria2ServerConfig) },
}, "protocol", "settings") }, "protocol", "settings")
outboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{ outboundConfigLoader = loader.NewJSONConfigLoader(loader.ConfigCreatorCache{
@ -47,7 +46,6 @@ var (
"vless": func() interface{} { return new(VLessOutboundConfig) }, "vless": func() interface{} { return new(VLessOutboundConfig) },
"vmess": func() interface{} { return new(VMessOutboundConfig) }, "vmess": func() interface{} { return new(VMessOutboundConfig) },
"trojan": func() interface{} { return new(TrojanClientConfig) }, "trojan": func() interface{} { return new(TrojanClientConfig) },
"hysteria2": func() interface{} { return new(Hysteria2ClientConfig) },
"dns": func() interface{} { return new(DNSOutboundConfig) }, "dns": func() interface{} { return new(DNSOutboundConfig) },
"loopback": func() interface{} { return new(LoopbackConfig) }, "loopback": func() interface{} { return new(LoopbackConfig) },
}, "protocol", "settings") }, "protocol", "settings")

View File

@ -53,7 +53,6 @@ import (
_ "github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound" _ "github.com/v2fly/v2ray-core/v5/proxy/vlite/inbound"
_ "github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound" _ "github.com/v2fly/v2ray-core/v5/proxy/vlite/outbound"
_ "github.com/v2fly/v2ray-core/v5/proxy/hysteria2"
_ "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022" _ "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks2022"
// Transports // Transports
@ -83,8 +82,6 @@ import (
_ "github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade" _ "github.com/v2fly/v2ray-core/v5/transport/internet/httpupgrade"
_ "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
// Transport headers // Transport headers
_ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http" _ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/http"
_ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop" _ "github.com/v2fly/v2ray-core/v5/transport/internet/headers/noop"

View File

@ -1,216 +0,0 @@
package hysteria2
import (
"context"
hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol"
core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
"github.com/v2fly/v2ray-core/v5/common/protocol"
"github.com/v2fly/v2ray-core/v5/common/retry"
"github.com/v2fly/v2ray-core/v5/common/session"
"github.com/v2fly/v2ray-core/v5/common/signal"
"github.com/v2fly/v2ray-core/v5/common/task"
"github.com/v2fly/v2ray-core/v5/features/policy"
"github.com/v2fly/v2ray-core/v5/proxy"
"github.com/v2fly/v2ray-core/v5/transport"
"github.com/v2fly/v2ray-core/v5/transport/internet"
hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
"github.com/v2fly/v2ray-core/v5/transport/internet/udp"
)
// Client is an inbound handler
type Client struct {
serverPicker protocol.ServerPicker
policyManager policy.Manager
}
// NewClient create a new client.
func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
serverList := protocol.NewServerList()
for _, rec := range config.Server {
s, err := protocol.NewServerSpecFromPB(rec)
if err != nil {
return nil, newError("failed to parse server spec").Base(err)
}
serverList.AddServer(s)
}
if serverList.Size() == 0 {
return nil, newError("0 server")
}
v := core.MustFromContext(ctx)
client := &Client{
serverPicker: protocol.NewRoundRobinServerPicker(serverList),
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
}
return client, nil
}
// Process implements OutboundHandler.Process().
func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
outbound := session.OutboundFromContext(ctx)
if outbound == nil || !outbound.Target.IsValid() {
return newError("target not specified")
}
destination := outbound.Target
network := destination.Network
var server *protocol.ServerSpec
var conn internet.Connection
err := retry.ExponentialBackoff(5, 100).On(func() error {
server = c.serverPicker.PickServer()
rawConn, err := dialer.Dial(ctx, server.Destination())
if err != nil {
return err
}
conn = rawConn
return nil
})
if err != nil {
return newError("failed to find an available destination").AtWarning().Base(err)
}
newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))
defer conn.Close()
iConn := conn
if statConn, ok := conn.(*internet.StatCouterConnection); ok {
iConn = statConn.Connection // will not count the UDP traffic.
}
hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn)
if !IsHy2Transport && network == net.Network_UDP {
// hysteria2 need to use udp extension to proxy UDP.
return newError(hyTransport.CanNotUseUdpExtension)
}
user := server.PickUser()
userLevel := uint32(0)
if user != nil {
userLevel = user.Level
}
sessionPolicy := c.policyManager.ForLevel(userLevel)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
if packetConn, err := packetaddr.ToPacketAddrConn(link, destination); err == nil {
postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
var buffer [2048]byte
n, addr, err := packetConn.ReadFrom(buffer[:])
if err != nil {
return newError("failed to read a packet").Base(err)
}
dest := net.DestinationFromAddr(addr)
bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
connWriter := &ConnWriter{Writer: bufferWriter, Target: dest}
packetWriter := &PacketWriter{Writer: connWriter, Target: dest, HyConn: hyConn}
// write some request payload to buffer
if _, err := packetWriter.WriteTo(buffer[:n], addr); err != nil {
return newError("failed to write a request payload").Base(err)
}
// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer
if err = bufferWriter.SetBuffered(false); err != nil {
return newError("failed to flush payload").Base(err).AtWarning()
}
return udp.CopyPacketConn(packetWriter, packetConn, udp.UpdateActivity(timer))
}
getResponse := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
packetReader := &PacketReader{Reader: conn, HyConn: hyConn}
packetConnectionReader := &PacketConnectionReader{reader: packetReader}
return udp.CopyPacketConn(packetConn, packetConnectionReader, udp.UpdateActivity(timer))
}
responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))
if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {
return newError("connection ends").Base(err)
}
return nil
}
postRequest := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
var bodyWriter buf.Writer
bufferWriter := buf.NewBufferedWriter(buf.NewWriter(conn))
connWriter := &ConnWriter{Writer: bufferWriter, Target: destination}
bodyWriter = connWriter
if network == net.Network_UDP {
bodyWriter = &PacketWriter{Writer: connWriter, Target: destination, HyConn: hyConn}
} else {
// write some request payload to buffer
err = buf.CopyOnceTimeout(link.Reader, bodyWriter, proxy.FirstPayloadTimeout)
switch err {
case buf.ErrNotTimeoutReader, buf.ErrReadTimeout:
if err := connWriter.WriteTCPHeader(); err != nil {
return newError("failed to write request header").Base(err).AtWarning()
}
case nil:
default:
return newError("failed to write a request payload").Base(err).AtWarning()
}
// Flush; bufferWriter.WriteMultiBuffer now is bufferWriter.writer.WriteMultiBuffer
if err = bufferWriter.SetBuffered(false); err != nil {
return newError("failed to flush payload").Base(err).AtWarning()
}
}
if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transfer request payload").Base(err).AtInfo()
}
return nil
}
getResponse := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
var reader buf.Reader
if network == net.Network_UDP {
reader = &PacketReader{
Reader: conn, HyConn: hyConn,
}
} else {
ok, msg, err := hyProtocol.ReadTCPResponse(conn)
if err != nil {
return err
}
if !ok {
return newError(msg)
}
reader = buf.NewReader(conn)
}
return buf.Copy(reader, link.Writer, buf.UpdateActivity(timer))
}
responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))
if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {
return newError("connection ends").Base(err)
}
return nil
}
func init() {
common.Must(common.RegisterConfig((*ClientConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewClient(ctx, config.(*ClientConfig))
}))
}

View File

@ -1,18 +0,0 @@
package hysteria2
import (
"github.com/v2fly/v2ray-core/v5/common/protocol"
)
// MemoryAccount is an account type converted from Account.
type MemoryAccount struct{}
// AsAccount implements protocol.AsAccount.
func (a *Account) AsAccount() (protocol.Account, error) {
return &MemoryAccount{}, nil
}
// Equals implements protocol.Account.Equals().
func (a *MemoryAccount) Equals(another protocol.Account) bool {
return false
}

View File

@ -1,282 +0,0 @@
package hysteria2
import (
packetaddr "github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
protocol "github.com/v2fly/v2ray-core/v5/common/protocol"
_ "github.com/v2fly/v2ray-core/v5/common/protoext"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Account struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Account) Reset() {
*x = Account{}
if protoimpl.UnsafeEnabled {
mi := &file_proxy_hysteria2_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Account) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Account) ProtoMessage() {}
func (x *Account) ProtoReflect() protoreflect.Message {
mi := &file_proxy_hysteria2_config_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Account.ProtoReflect.Descriptor instead.
func (*Account) Descriptor() ([]byte, []int) {
return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{0}
}
type ClientConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Server []*protocol.ServerEndpoint `protobuf:"bytes,1,rep,name=server,proto3" json:"server,omitempty"`
}
func (x *ClientConfig) Reset() {
*x = ClientConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_proxy_hysteria2_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ClientConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ClientConfig) ProtoMessage() {}
func (x *ClientConfig) ProtoReflect() protoreflect.Message {
mi := &file_proxy_hysteria2_config_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ClientConfig.ProtoReflect.Descriptor instead.
func (*ClientConfig) Descriptor() ([]byte, []int) {
return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{1}
}
func (x *ClientConfig) GetServer() []*protocol.ServerEndpoint {
if x != nil {
return x.Server
}
return nil
}
type ServerConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PacketEncoding packetaddr.PacketAddrType `protobuf:"varint,1,opt,name=packet_encoding,json=packetEncoding,proto3,enum=v2ray.core.net.packetaddr.PacketAddrType" json:"packet_encoding,omitempty"`
}
func (x *ServerConfig) Reset() {
*x = ServerConfig{}
if protoimpl.UnsafeEnabled {
mi := &file_proxy_hysteria2_config_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ServerConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ServerConfig) ProtoMessage() {}
func (x *ServerConfig) ProtoReflect() protoreflect.Message {
mi := &file_proxy_hysteria2_config_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ServerConfig.ProtoReflect.Descriptor instead.
func (*ServerConfig) Descriptor() ([]byte, []int) {
return file_proxy_hysteria2_config_proto_rawDescGZIP(), []int{2}
}
func (x *ServerConfig) GetPacketEncoding() packetaddr.PacketAddrType {
if x != nil {
return x.PacketEncoding
}
return packetaddr.PacketAddrType(0)
}
var File_proxy_hysteria2_config_proto protoreflect.FileDescriptor
var file_proxy_hysteria2_config_proto_rawDesc = []byte{
0x0a, 0x1c, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61,
0x32, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1a,
0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79,
0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x1a, 0x22, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2f, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64, 0x64,
0x72, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x21,
0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f,
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x65,
0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x22, 0x09, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x6d,
0x0a, 0x0c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42,
0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a,
0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, 0x72, 0x76,
0x65, 0x72, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76,
0x65, 0x72, 0x3a, 0x19, 0x82, 0xb5, 0x18, 0x15, 0x0a, 0x08, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75,
0x6e, 0x64, 0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x22, 0x7c, 0x0a,
0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x52, 0x0a,
0x0f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63,
0x6f, 0x72, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x61, 0x64,
0x64, 0x72, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x41, 0x64, 0x64, 0x72, 0x54, 0x79, 0x70,
0x65, 0x52, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e,
0x67, 0x3a, 0x18, 0x82, 0xb5, 0x18, 0x14, 0x0a, 0x07, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64,
0x12, 0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x6f, 0x0a, 0x1e, 0x63,
0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x78, 0x79, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a,
0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c,
0x79, 0x2f, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f,
0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa,
0x02, 0x1a, 0x56, 0x32, 0x52, 0x61, 0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x50, 0x72, 0x6f,
0x78, 0x79, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proxy_hysteria2_config_proto_rawDescOnce sync.Once
file_proxy_hysteria2_config_proto_rawDescData = file_proxy_hysteria2_config_proto_rawDesc
)
func file_proxy_hysteria2_config_proto_rawDescGZIP() []byte {
file_proxy_hysteria2_config_proto_rawDescOnce.Do(func() {
file_proxy_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_proxy_hysteria2_config_proto_rawDescData)
})
return file_proxy_hysteria2_config_proto_rawDescData
}
var file_proxy_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_proxy_hysteria2_config_proto_goTypes = []any{
(*Account)(nil), // 0: v2ray.core.proxy.hysteria2.Account
(*ClientConfig)(nil), // 1: v2ray.core.proxy.hysteria2.ClientConfig
(*ServerConfig)(nil), // 2: v2ray.core.proxy.hysteria2.ServerConfig
(*protocol.ServerEndpoint)(nil), // 3: v2ray.core.common.protocol.ServerEndpoint
(packetaddr.PacketAddrType)(0), // 4: v2ray.core.net.packetaddr.PacketAddrType
}
var file_proxy_hysteria2_config_proto_depIdxs = []int32{
3, // 0: v2ray.core.proxy.hysteria2.ClientConfig.server:type_name -> v2ray.core.common.protocol.ServerEndpoint
4, // 1: v2ray.core.proxy.hysteria2.ServerConfig.packet_encoding:type_name -> v2ray.core.net.packetaddr.PacketAddrType
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_proxy_hysteria2_config_proto_init() }
func file_proxy_hysteria2_config_proto_init() {
if File_proxy_hysteria2_config_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proxy_hysteria2_config_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Account); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proxy_hysteria2_config_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*ClientConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proxy_hysteria2_config_proto_msgTypes[2].Exporter = func(v any, i int) any {
switch v := v.(*ServerConfig); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proxy_hysteria2_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_proxy_hysteria2_config_proto_goTypes,
DependencyIndexes: file_proxy_hysteria2_config_proto_depIdxs,
MessageInfos: file_proxy_hysteria2_config_proto_msgTypes,
}.Build()
File_proxy_hysteria2_config_proto = out.File
file_proxy_hysteria2_config_proto_rawDesc = nil
file_proxy_hysteria2_config_proto_goTypes = nil
file_proxy_hysteria2_config_proto_depIdxs = nil
}

View File

@ -1,28 +0,0 @@
syntax = "proto3";
package v2ray.core.proxy.hysteria2;
option csharp_namespace = "V2Ray.Core.Proxy.Hysteria2";
option go_package = "github.com/v2fly/v2ray-core/v5/proxy/hysteria2";
option java_package = "com.v2ray.core.proxy.hysteria2";
option java_multiple_files = true;
import "common/net/packetaddr/config.proto";
import "common/protocol/server_spec.proto";
import "common/protoext/extensions.proto";
message Account {
}
message ClientConfig {
option (v2ray.core.common.protoext.message_opt).type = "outbound";
option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2";
repeated v2ray.core.common.protocol.ServerEndpoint server = 1;
}
message ServerConfig {
option (v2ray.core.common.protoext.message_opt).type = "inbound";
option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2";
v2ray.core.net.packetaddr.PacketAddrType packet_encoding = 1;
}

View File

@ -1,9 +0,0 @@
package hysteria2
import "github.com/v2fly/v2ray-core/v5/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -1 +0,0 @@
package hysteria2

View File

@ -1,210 +0,0 @@
package hysteria2
import (
"io"
"math/rand"
hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol"
"github.com/apernet/quic-go/quicvarint"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/net"
hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
)
const (
paddingChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
)
// ConnWriter is TCP Connection Writer Wrapper
type ConnWriter struct {
io.Writer
Target net.Destination
TCPHeaderSent bool
}
// Write implements io.Writer
func (c *ConnWriter) Write(p []byte) (n int, err error) {
if !c.TCPHeaderSent {
if err := c.writeTCPHeader(); err != nil {
return 0, newError("failed to write request header").Base(err)
}
}
return c.Writer.Write(p)
}
// WriteMultiBuffer implements buf.Writer
func (c *ConnWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
defer buf.ReleaseMulti(mb)
for _, b := range mb {
if !b.IsEmpty() {
if _, err := c.Write(b.Bytes()); err != nil {
return err
}
}
}
return nil
}
func (c *ConnWriter) WriteTCPHeader() error {
if !c.TCPHeaderSent {
if err := c.writeTCPHeader(); err != nil {
return err
}
}
return nil
}
func QuicLen(s int) int {
return int(quicvarint.Len(uint64(s)))
}
func (c *ConnWriter) writeTCPHeader() error {
c.TCPHeaderSent = true
paddingLen := 64 + rand.Intn(512-64)
padding := make([]byte, paddingLen)
for i := range padding {
padding[i] = paddingChars[rand.Intn(len(paddingChars))]
}
addressAndPort := c.Target.NetAddr()
addressLen := len(addressAndPort)
if addressLen > hyProtocol.MaxAddressLength {
return newError("address length too large: ", addressLen)
}
size := QuicLen(addressLen) + addressLen + QuicLen(paddingLen) + paddingLen
buf := make([]byte, size)
i := hyProtocol.VarintPut(buf, uint64(addressLen))
i += copy(buf[i:], addressAndPort)
i += hyProtocol.VarintPut(buf[i:], uint64(paddingLen))
copy(buf[i:], padding)
_, err := c.Writer.Write(buf)
return err
}
// PacketWriter UDP Connection Writer Wrapper
type PacketWriter struct {
io.Writer
HyConn *hyTransport.HyConn
Target net.Destination
}
// WriteMultiBuffer implements buf.Writer
func (w *PacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
for _, b := range mb {
if b.IsEmpty() {
continue
}
if _, err := w.writePacket(b.Bytes(), w.Target); err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}
// WriteMultiBufferWithMetadata writes udp packet with destination specified
func (w *PacketWriter) WriteMultiBufferWithMetadata(mb buf.MultiBuffer, dest net.Destination) error {
for _, b := range mb {
if b.IsEmpty() {
continue
}
if _, err := w.writePacket(b.Bytes(), dest); err != nil {
buf.ReleaseMulti(mb)
return err
}
}
return nil
}
func (w *PacketWriter) WriteTo(payload []byte, addr net.Addr) (int, error) {
dest := net.DestinationFromAddr(addr)
return w.writePacket(payload, dest)
}
func (w *PacketWriter) writePacket(payload []byte, dest net.Destination) (int, error) {
return w.HyConn.WritePacket(payload, dest)
}
// ConnReader is TCP Connection Reader Wrapper
type ConnReader struct {
io.Reader
Target net.Destination
}
// Read implements io.Reader
func (c *ConnReader) Read(p []byte) (int, error) {
return c.Reader.Read(p)
}
// ReadMultiBuffer implements buf.Reader
func (c *ConnReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
b := buf.New()
_, err := b.ReadFrom(c)
if err != nil {
return nil, err
}
return buf.MultiBuffer{b}, nil
}
// PacketPayload combines udp payload and destination
type PacketPayload struct {
Target net.Destination
Buffer buf.MultiBuffer
}
// PacketReader is UDP Connection Reader Wrapper
type PacketReader struct {
io.Reader
HyConn *hyTransport.HyConn
}
// ReadMultiBuffer implements buf.Reader
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
p, err := r.ReadMultiBufferWithMetadata()
if p != nil {
return p.Buffer, err
}
return nil, err
}
// ReadMultiBufferWithMetadata reads udp packet with destination
func (r *PacketReader) ReadMultiBufferWithMetadata() (*PacketPayload, error) {
_, data, dest, err := r.HyConn.ReadPacket()
if err != nil {
return nil, err
}
b := buf.FromBytes(data)
return &PacketPayload{Target: *dest, Buffer: buf.MultiBuffer{b}}, nil
}
type PacketConnectionReader struct {
reader *PacketReader
payload *PacketPayload
}
func (r *PacketConnectionReader) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
if r.payload == nil || r.payload.Buffer.IsEmpty() {
r.payload, err = r.reader.ReadMultiBufferWithMetadata()
if err != nil {
return
}
}
addr = &net.UDPAddr{
IP: r.payload.Target.Address.IP(),
Port: int(r.payload.Target.Port),
}
r.payload.Buffer, n = buf.SplitFirstBytes(r.payload.Buffer, p)
return
}

View File

@ -1,216 +0,0 @@
package hysteria2
import (
"context"
"io"
"time"
hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol"
core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/errors"
"github.com/v2fly/v2ray-core/v5/common/log"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
udp_proto "github.com/v2fly/v2ray-core/v5/common/protocol/udp"
"github.com/v2fly/v2ray-core/v5/common/session"
"github.com/v2fly/v2ray-core/v5/common/signal"
"github.com/v2fly/v2ray-core/v5/common/task"
"github.com/v2fly/v2ray-core/v5/features/policy"
"github.com/v2fly/v2ray-core/v5/features/routing"
"github.com/v2fly/v2ray-core/v5/transport/internet"
hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
"github.com/v2fly/v2ray-core/v5/transport/internet/udp"
)
func init() {
common.Must(common.RegisterConfig((*ServerConfig)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
return NewServer(ctx, config.(*ServerConfig))
}))
}
// Server is an inbound connection handler that handles messages in protocol.
type Server struct {
policyManager policy.Manager
packetEncoding packetaddr.PacketAddrType
}
// NewServer creates a new inbound handler.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
v := core.MustFromContext(ctx)
server := &Server{
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
packetEncoding: config.PacketEncoding,
}
return server, nil
}
// Network implements proxy.Inbound.Network().
func (s *Server) Network() []net.Network {
return []net.Network{net.Network_TCP, net.Network_UNIX}
}
// Process implements proxy.Inbound.Process().
func (s *Server) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher routing.Dispatcher) error {
sid := session.ExportIDToError(ctx)
iConn := conn
if statConn, ok := conn.(*internet.StatCouterConnection); ok {
iConn = statConn.Connection // will not count the UDP traffic.
}
hyConn, IsHy2Transport := iConn.(*hyTransport.HyConn)
if IsHy2Transport && hyConn.IsUDPExtension {
network = net.Network_UDP
}
if !IsHy2Transport && network == net.Network_UDP {
return newError(hyTransport.CanNotUseUdpExtension)
}
sessionPolicy := s.policyManager.ForLevel(0)
if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning()
}
bufferedReader := &buf.BufferedReader{
Reader: buf.NewReader(conn),
}
clientReader := &ConnReader{Reader: bufferedReader}
if err := conn.SetReadDeadline(time.Time{}); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning()
}
if network == net.Network_UDP { // handle udp request
return s.handleUDPPayload(ctx,
&PacketReader{Reader: clientReader, HyConn: hyConn},
&PacketWriter{Writer: conn, HyConn: hyConn}, dispatcher)
}
var reqAddr string
var err error
reqAddr, err = hyProtocol.ReadTCPRequest(conn)
if err != nil {
return newError("failed to parse header").Base(err)
}
err = hyProtocol.WriteTCPResponse(conn, true, "")
if err != nil {
return newError("failed to send response").Base(err)
}
address, stringPort, err := net.SplitHostPort(reqAddr)
if err != nil {
return err
}
port, err := net.PortFromString(stringPort)
if err != nil {
return err
}
destination := net.Destination{Network: network, Address: net.ParseAddress(address), Port: port}
inbound := session.InboundFromContext(ctx)
if inbound == nil {
panic("no inbound metadata")
}
sessionPolicy = s.policyManager.ForLevel(0)
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
From: conn.RemoteAddr(),
To: destination,
Status: log.AccessAccepted,
Reason: "",
})
newError("received request for ", destination).WriteToLog(sid)
return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher)
}
func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Session,
destination net.Destination,
clientReader buf.Reader,
clientWriter buf.Writer, dispatcher routing.Dispatcher,
) error {
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)
ctx = policy.ContextWithBufferPolicy(ctx, sessionPolicy.Buffer)
link, err := dispatcher.Dispatch(ctx, destination)
if err != nil {
return newError("failed to dispatch request to ", destination).Base(err)
}
requestDone := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
if err := buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)); err != nil {
return newError("failed to transfer request").Base(err)
}
return nil
}
responseDone := func() error {
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {
return newError("failed to write response").Base(err)
}
return nil
}
requestDonePost := task.OnSuccess(requestDone, task.Close(link.Writer))
if err := task.Run(ctx, requestDonePost, responseDone); err != nil {
common.Must(common.Interrupt(link.Reader))
common.Must(common.Interrupt(link.Writer))
return newError("connection ends").Base(err)
}
return nil
}
func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReader, clientWriter *PacketWriter, dispatcher routing.Dispatcher) error {
udpDispatcherConstructor := udp.NewSplitDispatcher
switch s.packetEncoding {
case packetaddr.PacketAddrType_None:
case packetaddr.PacketAddrType_Packet:
packetAddrDispatcherFactory := udp.NewPacketAddrDispatcherCreator(ctx)
udpDispatcherConstructor = packetAddrDispatcherFactory.NewPacketAddrDispatcher
}
udpServer := udpDispatcherConstructor(dispatcher, func(ctx context.Context, packet *udp_proto.Packet) {
if err := clientWriter.WriteMultiBufferWithMetadata(buf.MultiBuffer{packet.Payload}, packet.Source); err != nil {
newError("failed to write response").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
}
})
inbound := session.InboundFromContext(ctx)
for {
select {
case <-ctx.Done():
return nil
default:
p, err := clientReader.ReadMultiBufferWithMetadata()
if err != nil {
if errors.Cause(err) != io.EOF {
return newError("unexpected EOF").Base(err)
}
return nil
}
currentPacketCtx := ctx
currentPacketCtx = log.ContextWithAccessMessage(currentPacketCtx, &log.AccessMessage{
From: inbound.Source,
To: p.Target,
Status: log.AccessAccepted,
Reason: "",
})
newError("tunnelling request to ", p.Target).WriteToLog(session.ExportIDToError(ctx))
for _, b := range p.Buffer {
udpServer.Dispatch(currentPacketCtx, p.Target, b)
}
}
}
}

View File

@ -1,468 +0,0 @@
package scenarios
import (
"testing"
"time"
"golang.org/x/sync/errgroup"
"google.golang.org/protobuf/types/known/anypb"
core "github.com/v2fly/v2ray-core/v5"
"github.com/v2fly/v2ray-core/v5/app/log"
"github.com/v2fly/v2ray-core/v5/app/proxyman"
"github.com/v2fly/v2ray-core/v5/common"
clog "github.com/v2fly/v2ray-core/v5/common/log"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/protocol"
"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert"
"github.com/v2fly/v2ray-core/v5/common/serial"
"github.com/v2fly/v2ray-core/v5/common/uuid"
"github.com/v2fly/v2ray-core/v5/proxy/dokodemo"
"github.com/v2fly/v2ray-core/v5/proxy/freedom"
"github.com/v2fly/v2ray-core/v5/proxy/hysteria2"
"github.com/v2fly/v2ray-core/v5/proxy/vmess"
"github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound"
"github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound"
"github.com/v2fly/v2ray-core/v5/testing/servers/tcp"
"github.com/v2fly/v2ray-core/v5/testing/servers/udp"
"github.com/v2fly/v2ray-core/v5/transport/internet"
"github.com/v2fly/v2ray-core/v5/transport/internet/headers/http"
hyTransport "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
tcpTransport "github.com/v2fly/v2ray-core/v5/transport/internet/tcp"
"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
)
func TestVMessHysteria2Congestion(t *testing.T) {
for _, v := range []string{"bbr", "brutal"} {
testVMessHysteria2(t, v)
}
}
func testVMessHysteria2(t *testing.T, congestionType string) {
tcpServer := tcp.Server{
MsgProcessor: xor,
}
dest, err := tcpServer.Start()
common.Must(err)
defer tcpServer.Close()
userID := protocol.NewID(uuid.New())
serverPort := udp.PickPort()
serverConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
StreamSettings: &internet.StreamConfig{
ProtocolName: "hysteria2",
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
},
),
},
TransportSettings: []*internet.TransportConfig{
{
ProtocolName: "hysteria2",
Settings: serial.ToTypedMessage(&hyTransport.Config{
Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100},
Password: "password",
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&inbound.Config{
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
AlterId: 0,
}),
},
},
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
clientPort := tcp.PickPort()
clientConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
StreamSettings: &internet.StreamConfig{
ProtocolName: "hysteria2",
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
ServerName: "www.v2fly.org",
AllowInsecure: true,
},
),
},
TransportSettings: []*internet.TransportConfig{
{
ProtocolName: "hysteria2",
Settings: serial.ToTypedMessage(&hyTransport.Config{
Congestion: &hyTransport.Congestion{Type: congestionType, UpMbps: 100, DownMbps: 100},
Password: "password",
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
AlterId: 0,
SecuritySettings: &protocol.SecurityConfig{
Type: protocol.SecurityType_NONE,
},
}),
},
},
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
if err != nil {
t.Fatal("Failed to initialize all servers: ", err.Error())
}
defer CloseAllServers(servers)
var errg errgroup.Group
for i := 0; i < 10; i++ {
errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))
}
if err := errg.Wait(); err != nil {
t.Error(err)
}
}
func TestHysteria2Offical(t *testing.T) {
for _, v := range []bool{true, false} {
testHysteria2Offical(t, v)
}
}
func testHysteria2Offical(t *testing.T, isUDP bool) {
var dest net.Destination
var err error
if isUDP {
udpServer := udp.Server{
MsgProcessor: xor,
}
dest, err = udpServer.Start()
common.Must(err)
defer udpServer.Close()
} else {
tcpServer := tcp.Server{
MsgProcessor: xor,
}
dest, err = tcpServer.Start()
common.Must(err)
defer tcpServer.Close()
}
serverPort := udp.PickPort()
serverConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
StreamSettings: &internet.StreamConfig{
ProtocolName: "hysteria2",
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
},
),
},
TransportSettings: []*internet.TransportConfig{
{
ProtocolName: "hysteria2",
Settings: serial.ToTypedMessage(&hyTransport.Config{
Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100},
UseUdpExtension: true,
Password: "password",
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
clientPort := tcp.PickPort()
clientConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP, net.Network_UDP},
},
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
StreamSettings: &internet.StreamConfig{
ProtocolName: "hysteria2",
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
ServerName: "www.v2fly.org",
AllowInsecure: true,
},
),
},
TransportSettings: []*internet.TransportConfig{
{
ProtocolName: "hysteria2",
Settings: serial.ToTypedMessage(&hyTransport.Config{
Congestion: &hyTransport.Congestion{Type: "brutal", UpMbps: 100, DownMbps: 100},
UseUdpExtension: true,
Password: "password",
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{
Server: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&hysteria2.Account{}),
},
},
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
if err != nil {
t.Fatal("Failed to initialize all servers: ", err.Error())
}
defer CloseAllServers(servers)
var errg errgroup.Group
for i := 0; i < 10; i++ {
if isUDP {
errg.Go(testUDPConn(clientPort, 1024, time.Second*4))
} else {
errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))
}
}
if err := errg.Wait(); err != nil {
t.Error(err)
}
}
func TestHysteria2OnTCP(t *testing.T) {
tcpServer := tcp.Server{
MsgProcessor: xor,
}
dest, err := tcpServer.Start()
common.Must(err)
defer tcpServer.Close()
serverPort := udp.PickPort()
serverConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(serverPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
StreamSettings: &internet.StreamConfig{
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
Certificate: []*tls.Certificate{tls.ParseCertificate(cert.MustGenerate(nil))},
},
),
},
TransportSettings: []*internet.TransportConfig{
{
Protocol: internet.TransportProtocol_TCP,
Settings: serial.ToTypedMessage(&tcpTransport.Config{
HeaderSettings: serial.ToTypedMessage(&http.Config{}),
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&hysteria2.ServerConfig{}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&freedom.Config{}),
},
},
}
clientPort := tcp.PickPort()
clientConfig := &core.Config{
App: []*anypb.Any{
serial.ToTypedMessage(&log.Config{
Error: &log.LogSpecification{Level: clog.Severity_Debug, Type: log.LogType_Console},
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortRange: net.SinglePortRange(clientPort),
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
SenderSettings: serial.ToTypedMessage(&proxyman.SenderConfig{
StreamSettings: &internet.StreamConfig{
SecurityType: serial.GetMessageType(&tls.Config{}),
SecuritySettings: []*anypb.Any{
serial.ToTypedMessage(
&tls.Config{
ServerName: "www.v2fly.org",
AllowInsecure: true,
},
),
},
TransportSettings: []*internet.TransportConfig{
{
Protocol: internet.TransportProtocol_TCP,
Settings: serial.ToTypedMessage(&tcpTransport.Config{
HeaderSettings: serial.ToTypedMessage(&http.Config{}),
}),
},
},
},
}),
ProxySettings: serial.ToTypedMessage(&hysteria2.ClientConfig{
Server: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&hysteria2.Account{}),
},
},
},
},
}),
},
},
}
servers, err := InitializeServerConfigs(serverConfig, clientConfig)
if err != nil {
t.Fatal("Failed to initialize all servers: ", err.Error())
}
defer CloseAllServers(servers)
var errg errgroup.Group
for i := 0; i < 1; i++ {
errg.Go(testTCPConn(clientPort, 10240*1024, time.Second*40))
}
if err := errg.Wait(); err != nil {
t.Error(err)
}
}

View File

@ -1,271 +0,0 @@
package hysteria2
import (
_ "github.com/v2fly/v2ray-core/v5/common/protoext"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type Congestion struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
UpMbps uint64 `protobuf:"varint,2,opt,name=up_mbps,json=upMbps,proto3" json:"up_mbps,omitempty"`
DownMbps uint64 `protobuf:"varint,3,opt,name=down_mbps,json=downMbps,proto3" json:"down_mbps,omitempty"`
}
func (x *Congestion) Reset() {
*x = Congestion{}
if protoimpl.UnsafeEnabled {
mi := &file_transport_internet_hysteria2_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Congestion) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Congestion) ProtoMessage() {}
func (x *Congestion) ProtoReflect() protoreflect.Message {
mi := &file_transport_internet_hysteria2_config_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Congestion.ProtoReflect.Descriptor instead.
func (*Congestion) Descriptor() ([]byte, []int) {
return file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{0}
}
func (x *Congestion) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Congestion) GetUpMbps() uint64 {
if x != nil {
return x.UpMbps
}
return 0
}
func (x *Congestion) GetDownMbps() uint64 {
if x != nil {
return x.DownMbps
}
return 0
}
type Config struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Password string `protobuf:"bytes,3,opt,name=password,proto3" json:"password,omitempty"`
Congestion *Congestion `protobuf:"bytes,4,opt,name=congestion,proto3" json:"congestion,omitempty"`
IgnoreClientBandwidth bool `protobuf:"varint,5,opt,name=ignore_client_bandwidth,json=ignoreClientBandwidth,proto3" json:"ignore_client_bandwidth,omitempty"`
UseUdpExtension bool `protobuf:"varint,6,opt,name=use_udp_extension,json=useUdpExtension,proto3" json:"use_udp_extension,omitempty"`
}
func (x *Config) Reset() {
*x = Config{}
if protoimpl.UnsafeEnabled {
mi := &file_transport_internet_hysteria2_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Config) ProtoMessage() {}
func (x *Config) ProtoReflect() protoreflect.Message {
mi := &file_transport_internet_hysteria2_config_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
func (*Config) Descriptor() ([]byte, []int) {
return file_transport_internet_hysteria2_config_proto_rawDescGZIP(), []int{1}
}
func (x *Config) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
func (x *Config) GetCongestion() *Congestion {
if x != nil {
return x.Congestion
}
return nil
}
func (x *Config) GetIgnoreClientBandwidth() bool {
if x != nil {
return x.IgnoreClientBandwidth
}
return false
}
func (x *Config) GetUseUdpExtension() bool {
if x != nil {
return x.UseUdpExtension
}
return false
}
var File_transport_internet_hysteria2_config_proto protoreflect.FileDescriptor
var file_transport_internet_hysteria2_config_proto_rawDesc = []byte{
0x0a, 0x29, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x2f, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x27, 0x76, 0x32, 0x72,
0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72,
0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65,
0x72, 0x69, 0x61, 0x32, 0x1a, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2f, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x65, 0x78, 0x74, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x56, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x70, 0x5f, 0x6d,
0x62, 0x70, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x4d, 0x62, 0x70,
0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6f, 0x77, 0x6e, 0x5f, 0x6d, 0x62, 0x70, 0x73, 0x18, 0x03,
0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x6f, 0x77, 0x6e, 0x4d, 0x62, 0x70, 0x73, 0x22, 0xf9,
0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73,
0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x53, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x76, 0x32, 0x72, 0x61,
0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72,
0x69, 0x61, 0x32, 0x2e, 0x43, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a,
0x63, 0x6f, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x67,
0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x64,
0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x69, 0x67, 0x6e,
0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x64, 0x77, 0x69, 0x64,
0x74, 0x68, 0x12, 0x2a, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x75, 0x64, 0x70, 0x5f, 0x65, 0x78,
0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x75,
0x73, 0x65, 0x55, 0x64, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3a, 0x1a,
0x82, 0xb5, 0x18, 0x16, 0x0a, 0x09, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x12,
0x09, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x42, 0x96, 0x01, 0x0a, 0x2b, 0x63,
0x6f, 0x6d, 0x2e, 0x76, 0x32, 0x72, 0x61, 0x79, 0x2e, 0x63, 0x6f, 0x72, 0x65, 0x2e, 0x74, 0x72,
0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74,
0x2e, 0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0x50, 0x01, 0x5a, 0x3b, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x32, 0x66, 0x6c, 0x79, 0x2f, 0x76,
0x32, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x76, 0x35, 0x2f, 0x74, 0x72, 0x61,
0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2f,
0x68, 0x79, 0x73, 0x74, 0x65, 0x72, 0x69, 0x61, 0x32, 0xaa, 0x02, 0x27, 0x56, 0x32, 0x52, 0x61,
0x79, 0x2e, 0x43, 0x6f, 0x72, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74,
0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2e, 0x48, 0x79, 0x73, 0x74, 0x65, 0x72,
0x69, 0x61, 0x32, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_transport_internet_hysteria2_config_proto_rawDescOnce sync.Once
file_transport_internet_hysteria2_config_proto_rawDescData = file_transport_internet_hysteria2_config_proto_rawDesc
)
func file_transport_internet_hysteria2_config_proto_rawDescGZIP() []byte {
file_transport_internet_hysteria2_config_proto_rawDescOnce.Do(func() {
file_transport_internet_hysteria2_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_transport_internet_hysteria2_config_proto_rawDescData)
})
return file_transport_internet_hysteria2_config_proto_rawDescData
}
var file_transport_internet_hysteria2_config_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_transport_internet_hysteria2_config_proto_goTypes = []any{
(*Congestion)(nil), // 0: v2ray.core.transport.internet.hysteria2.Congestion
(*Config)(nil), // 1: v2ray.core.transport.internet.hysteria2.Config
}
var file_transport_internet_hysteria2_config_proto_depIdxs = []int32{
0, // 0: v2ray.core.transport.internet.hysteria2.Config.congestion:type_name -> v2ray.core.transport.internet.hysteria2.Congestion
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_transport_internet_hysteria2_config_proto_init() }
func file_transport_internet_hysteria2_config_proto_init() {
if File_transport_internet_hysteria2_config_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_transport_internet_hysteria2_config_proto_msgTypes[0].Exporter = func(v any, i int) any {
switch v := v.(*Congestion); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_transport_internet_hysteria2_config_proto_msgTypes[1].Exporter = func(v any, i int) any {
switch v := v.(*Config); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_transport_internet_hysteria2_config_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_transport_internet_hysteria2_config_proto_goTypes,
DependencyIndexes: file_transport_internet_hysteria2_config_proto_depIdxs,
MessageInfos: file_transport_internet_hysteria2_config_proto_msgTypes,
}.Build()
File_transport_internet_hysteria2_config_proto = out.File
file_transport_internet_hysteria2_config_proto_rawDesc = nil
file_transport_internet_hysteria2_config_proto_goTypes = nil
file_transport_internet_hysteria2_config_proto_depIdxs = nil
}

View File

@ -1,26 +0,0 @@
syntax = "proto3";
package v2ray.core.transport.internet.hysteria2;
option csharp_namespace = "V2Ray.Core.Transport.Internet.Hysteria2";
option go_package = "github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2";
option java_package = "com.v2ray.core.transport.internet.hysteria2";
option java_multiple_files = true;
import "common/protoext/extensions.proto";
message Congestion{
string type = 1;
uint64 up_mbps = 2;
uint64 down_mbps = 3;
}
message Config {
option (v2ray.core.common.protoext.message_opt).type = "transport";
option (v2ray.core.common.protoext.message_opt).short_name = "hysteria2";
string password = 3;
Congestion congestion = 4;
bool ignore_client_bandwidth = 5;
bool use_udp_extension = 6;
}

View File

@ -1,127 +0,0 @@
package hysteria2
import (
"time"
hyClient "github.com/apernet/hysteria/core/v2/client"
"github.com/apernet/hysteria/core/v2/international/protocol"
hyServer "github.com/apernet/hysteria/core/v2/server"
"github.com/apernet/quic-go"
"github.com/v2fly/v2ray-core/v5/common/net"
)
const CanNotUseUdpExtension = "Only hysteria2 proxy protocol can use udpExtension."
const Hy2MustNeedTLS = "Hysteria2 based on QUIC that requires TLS."
type HyConn struct {
IsUDPExtension bool
IsServer bool
ClientUDPSession hyClient.HyUDPConn
ServerUDPSession *hyServer.UdpSessionEntry
stream quic.Stream
local net.Addr
remote net.Addr
}
func (c *HyConn) Read(b []byte) (int, error) {
if c.IsUDPExtension {
n, data, _, err := c.ReadPacket()
copy(b, data)
return n, err
}
return c.stream.Read(b)
}
func (c *HyConn) Write(b []byte) (int, error) {
if c.IsUDPExtension {
dest, _ := net.ParseDestination("udp:v2fly.org:6666")
return c.WritePacket(b, dest)
}
return c.stream.Write(b)
}
func (c *HyConn) WritePacket(b []byte, dest net.Destination) (int, error) {
if !c.IsUDPExtension {
return 0, newError(CanNotUseUdpExtension)
}
if c.IsServer {
msg := &protocol.UDPMessage{
SessionID: c.ServerUDPSession.ID,
PacketID: 0,
FragID: 0,
FragCount: 1,
Addr: dest.NetAddr(),
Data: b,
}
c.ServerUDPSession.SendCh <- msg
return len(b), nil
}
return len(b), c.ClientUDPSession.Send(b, dest.NetAddr())
}
func (c *HyConn) ReadPacket() (int, []byte, *net.Destination, error) {
if !c.IsUDPExtension {
return 0, nil, nil, newError(CanNotUseUdpExtension)
}
if c.IsServer {
msg := <-c.ServerUDPSession.ReceiveCh
dest, err := net.ParseDestination("udp:" + msg.Addr)
return len(msg.Data), msg.Data, &dest, err
}
data, address, err := c.ClientUDPSession.Receive()
if err != nil {
return 0, nil, nil, err
}
dest, err := net.ParseDestination("udp:" + address)
if err != nil {
return 0, nil, nil, err
}
return len(data), data, &dest, nil
}
func (c *HyConn) Close() error {
if c.IsUDPExtension {
if !c.IsServer && c.ClientUDPSession == nil || (c.IsServer && c.ServerUDPSession == nil) {
return newError(CanNotUseUdpExtension)
}
if c.IsServer {
c.ServerUDPSession.Close()
return c.ServerUDPSession.Conn.Close()
}
return c.ClientUDPSession.Close()
}
return c.stream.Close()
}
func (c *HyConn) LocalAddr() net.Addr {
return c.local
}
func (c *HyConn) RemoteAddr() net.Addr {
return c.remote
}
func (c *HyConn) SetDeadline(t time.Time) error {
if c.IsUDPExtension {
return nil
}
return c.stream.SetDeadline(t)
}
func (c *HyConn) SetReadDeadline(t time.Time) error {
if c.IsUDPExtension {
return nil
}
return c.stream.SetReadDeadline(t)
}
func (c *HyConn) SetWriteDeadline(t time.Time) error {
if c.IsUDPExtension {
return nil
}
return c.stream.SetWriteDeadline(t)
}

View File

@ -1,207 +0,0 @@
package hysteria2
import (
"context"
"sync"
hyClient "github.com/apernet/hysteria/core/v2/client"
hyProtocol "github.com/apernet/hysteria/core/v2/international/protocol"
"github.com/apernet/quic-go/quicvarint"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/session"
"github.com/v2fly/v2ray-core/v5/transport/internet"
"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
)
type dialerConf struct {
net.Destination
*internet.MemoryStreamConfig
}
var RunningClient map[dialerConf](hyClient.Client)
var ClientMutex sync.Mutex
var MBps uint64 = 1000000 / 8 // MByte
func GetClientTLSConfig(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (*hyClient.TLSConfig, error) {
config := tls.ConfigFromStreamSettings(streamSettings)
if config == nil {
return nil, newError(Hy2MustNeedTLS)
}
tlsConfig := config.GetTLSConfig(tls.WithDestination(dest))
return &hyClient.TLSConfig{
RootCAs: tlsConfig.RootCAs,
ServerName: tlsConfig.ServerName,
InsecureSkipVerify: tlsConfig.InsecureSkipVerify,
VerifyPeerCertificate: tlsConfig.VerifyPeerCertificate,
}, nil
}
func ResolveAddress(dest net.Destination) (net.Addr, error) {
var destAddr *net.UDPAddr
if dest.Address.Family().IsIP() {
destAddr = &net.UDPAddr{
IP: dest.Address.IP(),
Port: int(dest.Port),
}
} else {
addr, err := net.ResolveUDPAddr("udp", dest.NetAddr())
if err != nil {
return nil, err
}
destAddr = addr
}
return destAddr, nil
}
type connFactory struct {
hyClient.ConnFactory
NewFunc func(addr net.Addr) (net.PacketConn, error)
}
func (f *connFactory) New(addr net.Addr) (net.PacketConn, error) {
return f.NewFunc(addr)
}
func NewHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) {
tlsConfig, err := GetClientTLSConfig(dest, streamSettings)
if err != nil {
return nil, err
}
serverAddr, err := ResolveAddress(dest)
if err != nil {
return nil, err
}
config := streamSettings.ProtocolSettings.(*Config)
client, _, err := hyClient.NewClient(&hyClient.Config{
Auth: config.GetPassword(),
TLSConfig: *tlsConfig,
ServerAddr: serverAddr,
ConnFactory: &connFactory{
NewFunc: func(addr net.Addr) (net.PacketConn, error) {
rawConn, err := internet.ListenSystemPacket(context.Background(), &net.UDPAddr{
IP: []byte{0, 0, 0, 0},
Port: 0,
}, streamSettings.SocketSettings)
if err != nil {
return nil, err
}
return rawConn.(*net.UDPConn), nil
},
},
BandwidthConfig: hyClient.BandwidthConfig{MaxTx: config.Congestion.GetUpMbps() * MBps, MaxRx: config.GetCongestion().GetDownMbps() * MBps},
})
if err != nil {
return nil, err
}
return client, nil
}
func CloseHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) error {
ClientMutex.Lock()
defer ClientMutex.Unlock()
client, found := RunningClient[dialerConf{dest, streamSettings}]
if found {
delete(RunningClient, dialerConf{dest, streamSettings})
return client.Close()
}
return nil
}
func GetHyClient(dest net.Destination, streamSettings *internet.MemoryStreamConfig) (hyClient.Client, error) {
var err error
var client hyClient.Client
ClientMutex.Lock()
client, found := RunningClient[dialerConf{dest, streamSettings}]
ClientMutex.Unlock()
if !found || !CheckHyClientHealthy(client) {
if found {
// retry
CloseHyClient(dest, streamSettings)
}
client, err = NewHyClient(dest, streamSettings)
if err != nil {
return nil, err
}
ClientMutex.Lock()
RunningClient[dialerConf{dest, streamSettings}] = client
ClientMutex.Unlock()
}
return client, nil
}
func CheckHyClientHealthy(client hyClient.Client) bool {
quicConn := client.GetQuicConn()
if quicConn == nil {
return false
}
select {
case <-quicConn.Context().Done():
return false
default:
}
return true
}
func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (internet.Connection, error) {
config := streamSettings.ProtocolSettings.(*Config)
client, err := GetHyClient(dest, streamSettings)
if err != nil {
CloseHyClient(dest, streamSettings)
return nil, err
}
quicConn := client.GetQuicConn()
conn := &HyConn{
local: quicConn.LocalAddr(),
remote: quicConn.RemoteAddr(),
}
outbound := session.OutboundFromContext(ctx)
network := net.Network_TCP
if outbound != nil {
network = outbound.Target.Network
}
if network == net.Network_UDP && config.GetUseUdpExtension() { // only hysteria2 can use udpExtension
conn.IsUDPExtension = true
conn.IsServer = false
conn.ClientUDPSession, err = client.UDP()
if err != nil {
CloseHyClient(dest, streamSettings)
return nil, err
}
return conn, nil
}
conn.stream, err = client.OpenStream()
if err != nil {
CloseHyClient(dest, streamSettings)
return nil, err
}
// write TCP frame type
frameSize := int(quicvarint.Len(hyProtocol.FrameTypeTCPRequest))
buf := make([]byte, frameSize)
hyProtocol.VarintPut(buf, hyProtocol.FrameTypeTCPRequest)
_, err = conn.stream.Write(buf)
if err != nil {
CloseHyClient(dest, streamSettings)
return nil, err
}
return conn, nil
}
func init() {
RunningClient = make(map[dialerConf]hyClient.Client)
common.Must(internet.RegisterTransportDialer(protocolName, Dial))
}

View File

@ -1,9 +0,0 @@
package hysteria2
import "github.com/v2fly/v2ray-core/v5/common/errors"
type errPathObjHolder struct{}
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).WithPathObj(errPathObjHolder{})
}

View File

@ -1,128 +0,0 @@
package hysteria2
import (
"context"
hyServer "github.com/apernet/hysteria/core/v2/server"
"github.com/apernet/quic-go"
"github.com/apernet/quic-go/http3"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/transport/internet"
"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
)
// Listener is an internet.Listener that listens for TCP connections.
type Listener struct {
hyServer hyServer.Server
rawConn net.PacketConn
addConn internet.ConnHandler
}
// Addr implements internet.Listener.Addr.
func (l *Listener) Addr() net.Addr {
return l.rawConn.LocalAddr()
}
// Close implements internet.Listener.Close.
func (l *Listener) Close() error {
return l.hyServer.Close()
}
func (l *Listener) StreamHijacker(ft http3.FrameType, conn quic.Connection, stream quic.Stream, err error) (bool, error) {
// err always == nil
tcpConn := &HyConn{
stream: stream,
local: conn.LocalAddr(),
remote: conn.RemoteAddr(),
}
l.addConn(tcpConn)
return true, nil
}
func (l *Listener) UdpHijacker(entry *hyServer.UdpSessionEntry, originalAddr string) {
addr, err := net.ResolveUDPAddr("udp", originalAddr)
if err != nil {
return
}
udpConn := &HyConn{
IsUDPExtension: true,
IsServer: true,
ServerUDPSession: entry,
remote: addr,
local: l.rawConn.LocalAddr(),
}
l.addConn(udpConn)
}
// Listen creates a new Listener based on configurations.
func Listen(ctx context.Context, address net.Address, port net.Port, streamSettings *internet.MemoryStreamConfig, handler internet.ConnHandler) (internet.Listener, error) {
tlsConfig, err := GetServerTLSConfig(streamSettings)
if err != nil {
return nil, err
}
if address.Family().IsDomain() {
return nil, nil
}
config := streamSettings.ProtocolSettings.(*Config)
rawConn, err := internet.ListenSystemPacket(context.Background(),
&net.UDPAddr{
IP: address.IP(),
Port: int(port),
}, streamSettings.SocketSettings)
if err != nil {
return nil, err
}
listener := &Listener{
rawConn: rawConn,
addConn: handler,
}
hyServer, err := hyServer.NewServer(&hyServer.Config{
Conn: rawConn,
TLSConfig: *tlsConfig,
DisableUDP: !config.GetUseUdpExtension(),
Authenticator: &Authenticator{Password: config.GetPassword()},
StreamHijacker: listener.StreamHijacker, // acceptStreams
BandwidthConfig: hyServer.BandwidthConfig{MaxTx: config.Congestion.GetUpMbps() * MBps, MaxRx: config.GetCongestion().GetDownMbps() * MBps},
UdpSessionHijacker: listener.UdpHijacker, // acceptUDPSession
IgnoreClientBandwidth: config.GetIgnoreClientBandwidth(),
})
if err != nil {
return nil, err
}
listener.hyServer = hyServer
go hyServer.Serve()
return listener, nil
}
func GetServerTLSConfig(streamSettings *internet.MemoryStreamConfig) (*hyServer.TLSConfig, error) {
config := tls.ConfigFromStreamSettings(streamSettings)
if config == nil {
return nil, newError(Hy2MustNeedTLS)
}
tlsConfig := config.GetTLSConfig()
return &hyServer.TLSConfig{Certificates: tlsConfig.Certificates, GetCertificate: tlsConfig.GetCertificate}, nil
}
type Authenticator struct {
Password string
}
func (a *Authenticator) Authenticate(addr net.Addr, auth string, tx uint64) (ok bool, id string) {
if auth == a.Password || a.Password == "" {
return true, "user"
}
return false, ""
}
func init() {
common.Must(internet.RegisterTransportListener(protocolName, Listen))
}

View File

@ -1,155 +0,0 @@
package hysteria2_test
import (
"context"
"crypto/rand"
"fmt"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/common/buf"
"github.com/v2fly/v2ray-core/v5/common/net"
"github.com/v2fly/v2ray-core/v5/common/protocol/tls/cert"
"github.com/v2fly/v2ray-core/v5/common/session"
"github.com/v2fly/v2ray-core/v5/testing/servers/udp"
"github.com/v2fly/v2ray-core/v5/transport/internet"
"github.com/v2fly/v2ray-core/v5/transport/internet/hysteria2"
"github.com/v2fly/v2ray-core/v5/transport/internet/tls"
)
func TestTCP(t *testing.T) {
port := udp.PickPort()
listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{
ProtocolName: "hysteria2",
ProtocolSettings: &hysteria2.Config{Password: "123"},
SecurityType: "tls",
SecuritySettings: &tls.Config{
Certificate: []*tls.Certificate{
tls.ParseCertificate(
cert.MustGenerate(nil,
cert.DNSNames("www.v2fly.org"),
),
),
},
},
}, func(conn internet.Connection) {
go func() {
defer conn.Close()
b := buf.New()
defer b.Release()
for {
b.Clear()
if _, err := b.ReadFrom(conn); err != nil {
fmt.Println(err)
return
}
common.Must2(conn.Write(b.Bytes()))
}
}()
})
common.Must(err)
defer listener.Close()
time.Sleep(time.Second)
dctx := context.Background()
conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{
ProtocolName: "hysteria2",
ProtocolSettings: &hysteria2.Config{Password: "123"},
SecurityType: "tls",
SecuritySettings: &tls.Config{
ServerName: "www.v2fly.org",
AllowInsecure: true,
},
})
common.Must(err)
defer conn.Close()
const N = 1000
b1 := make([]byte, N)
common.Must2(rand.Read(b1))
b2 := buf.New()
common.Must2(conn.Write(b1))
b2.Clear()
common.Must2(b2.ReadFullFrom(conn, N))
if r := cmp.Diff(b2.Bytes(), b1); r != "" {
t.Error(r)
}
}
func TestUDP(t *testing.T) {
port := udp.PickPort()
listener, err := hysteria2.Listen(context.Background(), net.LocalHostIP, port, &internet.MemoryStreamConfig{
ProtocolName: "hysteria2",
ProtocolSettings: &hysteria2.Config{Password: "123", UseUdpExtension: true},
SecurityType: "tls",
SecuritySettings: &tls.Config{
Certificate: []*tls.Certificate{
tls.ParseCertificate(
cert.MustGenerate(nil,
cert.DNSNames("www.v2fly.org"),
),
),
},
},
}, func(conn internet.Connection) {
fmt.Println("incoming")
go func() {
defer conn.Close()
b := buf.New()
defer b.Release()
for {
b.Clear()
if _, err := b.ReadFrom(conn); err != nil {
fmt.Println(err)
return
}
common.Must2(conn.Write(b.Bytes()))
}
}()
})
common.Must(err)
defer listener.Close()
time.Sleep(time.Second)
address, err := net.ParseDestination("udp:127.0.0.1:1180")
dctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: address})
conn, err := hysteria2.Dial(dctx, net.TCPDestination(net.LocalHostIP, port), &internet.MemoryStreamConfig{
ProtocolName: "hysteria2",
ProtocolSettings: &hysteria2.Config{Password: "123", UseUdpExtension: true},
SecurityType: "tls",
SecuritySettings: &tls.Config{
ServerName: "www.v2fly.org",
AllowInsecure: true,
},
})
common.Must(err)
defer conn.Close()
const N = 1000
b1 := make([]byte, N)
common.Must2(rand.Read(b1))
common.Must2(conn.Write(b1))
b2 := buf.New()
b2.Clear()
common.Must2(b2.ReadFullFrom(conn, N))
if r := cmp.Diff(b2.Bytes(), b1); r != "" {
t.Error(r)
}
}

View File

@ -1,18 +0,0 @@
package hysteria2
import (
"github.com/v2fly/v2ray-core/v5/common"
"github.com/v2fly/v2ray-core/v5/transport/internet"
)
//go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen
const (
protocolName = "hysteria2"
)
func init() {
common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {
return new(Config)
}))
}