mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Sat Aug 24 20:31:52 CEST 2024
This commit is contained in:
39
echo/go.mod
39
echo/go.mod
@@ -12,19 +12,19 @@ require (
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7
|
||||
github.com/juju/ratelimit v1.0.2
|
||||
github.com/labstack/echo/v4 v4.12.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/client_golang v1.20.0
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/prometheus/common v0.55.0
|
||||
github.com/prometheus/node_exporter v1.8.1
|
||||
github.com/sagernet/sing v0.4.1
|
||||
github.com/sagernet/sing-box v1.9.3
|
||||
github.com/prometheus/node_exporter v1.8.2
|
||||
github.com/sagernet/sing v0.4.2
|
||||
github.com/sagernet/sing-box v1.9.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/urfave/cli/v2 v2.27.2
|
||||
github.com/xtls/xray-core v1.8.16
|
||||
github.com/urfave/cli/v2 v2.27.4
|
||||
github.com/xtls/xray-core v1.8.23
|
||||
go.uber.org/atomic v1.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/time v0.6.0
|
||||
google.golang.org/grpc v1.65.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
@@ -66,7 +66,7 @@ require (
|
||||
github.com/illumos/go-kstat v0.0.0-20210513183136-173c9b0a9973 // indirect
|
||||
github.com/josharian/native v1.1.0 // indirect
|
||||
github.com/jsimonetti/rtnetlink v1.4.2 // indirect
|
||||
github.com/klauspost/compress v1.17.8 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||
@@ -89,33 +89,34 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus-community/go-runit v0.1.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/quic-go/quic-go v0.45.0 // indirect
|
||||
github.com/refraction-networking/utls v1.6.6 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/quic-go v0.45.1 // indirect
|
||||
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/safchain/ethtool v0.3.0 // indirect
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba // indirect
|
||||
github.com/sagernet/sing-dns v0.2.0 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6 // indirect
|
||||
github.com/sagernet/sing-dns v0.2.3 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
||||
github.com/sagernet/sing-tun v0.3.2 // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2.0.20230316163032-ced5aaba43e3 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
|
||||
github.com/xtls/reality v0.0.0-20240429224917-ecc4401070cc // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
|
||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/net v0.27.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
|
||||
82
echo/go.sum
82
echo/go.sum
@@ -143,8 +143,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
||||
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
|
||||
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
|
||||
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -155,6 +155,8 @@ github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
@@ -215,16 +217,16 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/prometheus-community/go-runit v0.1.0 h1:uTWEj/Fn2RoLdfg/etSqwzgYNOYPrARx1BHUN052tGA=
|
||||
github.com/prometheus-community/go-runit v0.1.0/go.mod h1:AvJ9Jo3gAFu2lbM4+qfjdpq30FfiLDJZKbQ015u08IQ=
|
||||
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
|
||||
github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/node_exporter v1.8.1 h1:qYIN+ghn7kEggHe4pcIRp9oXkljU8ARWyEHBr286RPY=
|
||||
github.com/prometheus/node_exporter v1.8.1/go.mod h1:rJMoAQMglUjAZ7nggHnRuwfJ0hKUVW6+Gv+IaMxh6js=
|
||||
github.com/prometheus/node_exporter v1.8.2 h1:G8NryhgftPSXTnD+DuaNZTHDqmHF3zLWgPeG5RUtcHg=
|
||||
github.com/prometheus/node_exporter v1.8.2/go.mod h1:rJMoAQMglUjAZ7nggHnRuwfJ0hKUVW6+Gv+IaMxh6js=
|
||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
@@ -232,10 +234,10 @@ github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
|
||||
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 h1:D33340mCNDAIKBqXuAvexTNMUByrYmFYVfKfDN5nfFs=
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
|
||||
github.com/quic-go/quic-go v0.45.0 h1:OHmkQGM37luZITyTSu6ff03HP/2IrwDX1ZFiNEhSFUE=
|
||||
github.com/quic-go/quic-go v0.45.0/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/refraction-networking/utls v1.6.6 h1:igFsYBUJPYM8Rno9xUuDoM5GQrVEqY4llzEXOkL43Ig=
|
||||
github.com/refraction-networking/utls v1.6.6/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/quic-go/quic-go v0.45.1 h1:tPfeYCk+uZHjmDRwHHQmvHRYL2t44ROTujLeFVBmjCA=
|
||||
github.com/quic-go/quic-go v0.45.1/go.mod h1:1dLehS7TIR64+vxGR70GDcatWTOtMX2PUtnKsjbTurI=
|
||||
github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B2MR1K67ULZM=
|
||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
@@ -249,20 +251,20 @@ github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f h1:NkhuupzH5ch7b/Y
|
||||
github.com/sagernet/gvisor v0.0.0-20240428053021-e691de28565f/go.mod h1:KXmw+ouSJNOsuRpg4wgwwCQuunrGz4yoAqQjsLjc6N0=
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba h1:EY5AS7CCtfmARNv2zXUOrsEMPFDGYxaw65JzA2p51Vk=
|
||||
github.com/sagernet/netlink v0.0.0-20240523065131-45e60152f9ba/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/quic-go v0.43.1-beta.2 h1:6YRCE9t1Q3UbNX1/dJGqpwFQbh6DXC6XBrQr2xp6hXY=
|
||||
github.com/sagernet/quic-go v0.43.1-beta.2/go.mod h1:BkrQYeop7Jx3hN3TW8/76CXcdhYiNPyYEBL/BVJ1ifc=
|
||||
github.com/sagernet/sing v0.4.1 h1:zVlpE+7k7AFoC2pv6ReqLf0PIHjihL/jsBl5k05PQFk=
|
||||
github.com/sagernet/sing v0.4.1/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
|
||||
github.com/sagernet/sing-box v1.9.3 h1:jXiAqQRzBeXCSLTTl0Z92OLs5GkVotsdiNRVATZWpoY=
|
||||
github.com/sagernet/sing-box v1.9.3/go.mod h1:6Rx5nzbqIfN7HlUaHgO/IdkP7fDPPQ/U/TAC5asEjSM=
|
||||
github.com/sagernet/sing-dns v0.2.0 h1:dka3weRX6+CrYO3v+hrTy2z68rCOCZXNBiNXpLZ6JNs=
|
||||
github.com/sagernet/sing-dns v0.2.0/go.mod h1:BJpJv6XLnrUbSyIntOT6DG9FW0f4fETmPAHvNjOprLg=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6 h1:xr7ylAS/q1cQYS8oxKKajhuQcchd5VJJ4K4UZrrpp0s=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.6/go.mod h1:j2YZBIpWIuElPFL/5sJAj470bcn/3QQ5lxZUNKLDNAM=
|
||||
github.com/sagernet/quic-go v0.46.0-beta.4 h1:k9f7VSKaM47AY6MPND0Qf1KRN7HwimPg9zdOFTXTiCk=
|
||||
github.com/sagernet/quic-go v0.46.0-beta.4/go.mod h1:zJmVdJUNqEDXfubf4KtIOUHHerggjBduiGRLNzJspcM=
|
||||
github.com/sagernet/sing v0.4.2 h1:jzGNJdZVRI0xlAfFugsIQUPvyB9SuWvbJK7zQCXc4QM=
|
||||
github.com/sagernet/sing v0.4.2/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls=
|
||||
github.com/sagernet/sing-box v1.9.4 h1:Sf2JffjKvcG2a2+YWPOP0NiCOqpu2iPU12RkpZ0PhaM=
|
||||
github.com/sagernet/sing-box v1.9.4/go.mod h1:DGX0xLYqlQa36DX1PTWJBh6EnChI1hUyzwoJUObhlW4=
|
||||
github.com/sagernet/sing-dns v0.2.3 h1:YzeBUn2tR38F7HtvGEQ0kLRLmZWMEgi/+7wqa4Twb1k=
|
||||
github.com/sagernet/sing-dns v0.2.3/go.mod h1:BJpJv6XLnrUbSyIntOT6DG9FW0f4fETmPAHvNjOprLg=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
github.com/sagernet/sing-tun v0.3.2 h1:z0bLUT/YXH9RrJS9DsIpB0Bb9afl2hVJOmHd0zA3HJY=
|
||||
github.com/sagernet/sing-tun v0.3.2/go.mod h1:DxLIyhjWU/HwGYoX0vNGg2c5QgTQIakphU1MuERR5tQ=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
|
||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
|
||||
@@ -298,8 +300,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
|
||||
github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
|
||||
github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
|
||||
github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8=
|
||||
github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
@@ -315,12 +317,12 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
|
||||
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
|
||||
github.com/xtls/reality v0.0.0-20240429224917-ecc4401070cc h1:0Nj8T1n7F7+v4vRVroaJIvY6R0vNABLfPH+lzPHRJvI=
|
||||
github.com/xtls/reality v0.0.0-20240429224917-ecc4401070cc/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
||||
github.com/xtls/xray-core v1.8.16 h1:PhbpdREAIvDS7xmxR6Sdpkx0h5ugmf6wIoWECWtJ0kE=
|
||||
github.com/xtls/xray-core v1.8.16/go.mod h1:tjzDQQJpFORuhf7fBsiswiexLVEeJpAfMsD0NE5xV7M=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg=
|
||||
github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE=
|
||||
github.com/xtls/xray-core v1.8.23 h1:A8Wr50ildMYLpaNu3EiK+Stg/tps6i0h7z5Hr4f9H2k=
|
||||
github.com/xtls/xray-core v1.8.23/go.mod h1:0CwyMPNA5Cs+ukPXHbYQGgne/ug0PuXOSVqBu7zyXOc=
|
||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
@@ -341,8 +343,8 @@ golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
|
||||
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
@@ -360,8 +362,8 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -372,8 +374,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -388,8 +390,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -398,8 +400,8 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U=
|
||||
golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
||||
@@ -38,8 +38,8 @@ func loadConfig() (cfg *config.Config, err error) {
|
||||
},
|
||||
},
|
||||
}
|
||||
if TCPRemoteAddr != "" {
|
||||
cfg.RelayConfigs[0].TCPRemotes = []string{TCPRemoteAddr}
|
||||
if RemoteAddr != "" {
|
||||
cfg.RelayConfigs[0].Remotes = []string{RemoteAddr}
|
||||
}
|
||||
if err := cfg.Adjust(); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
var (
|
||||
LocalAddr string
|
||||
ListenType constant.RelayType
|
||||
TCPRemoteAddr string
|
||||
RemoteAddr string
|
||||
TransportType constant.RelayType
|
||||
ConfigPath string
|
||||
WebPort int
|
||||
@@ -40,7 +40,7 @@ var RootFlags = []cli.Flag{
|
||||
Name: "r,remote",
|
||||
Usage: "转发地址,例如 0.0.0.0:5201,通过 ws 隧道转发时应为 ws://0.0.0.0:2443",
|
||||
EnvVars: []string{"EHCO_REMOTE_ADDR"},
|
||||
Destination: &TCPRemoteAddr,
|
||||
Destination: &RemoteAddr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tt,transport_type",
|
||||
|
||||
@@ -9,14 +9,22 @@ import (
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/lb"
|
||||
"github.com/Ehco1996/ehco/internal/metrics"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/buffer"
|
||||
"github.com/Ehco1996/ehco/pkg/bytes"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
const (
|
||||
shortHashLength = 7
|
||||
)
|
||||
|
||||
var (
|
||||
ErrIdleTimeout = errors.New("connection closed due to idle timeout")
|
||||
)
|
||||
|
||||
// RelayConn is the interface that represents a relay connection.
|
||||
// it contains two connections: clientConn and remoteConn
|
||||
// clientConn is the connection from the client to the relay server
|
||||
@@ -63,6 +71,7 @@ type relayConnImpl struct {
|
||||
HandshakeDuration time.Duration
|
||||
RelayLabel string `json:"relay_label"`
|
||||
ConnType string `json:"conn_type"`
|
||||
Options *conf.Options
|
||||
}
|
||||
|
||||
func WithRelayLabel(relayLabel string) RelayConnOption {
|
||||
@@ -95,18 +104,31 @@ func WithLogger(l *zap.SugaredLogger) RelayConnOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithRelayOptions(opts *conf.Options) RelayConnOption {
|
||||
return func(rci *relayConnImpl) {
|
||||
rci.Options = opts
|
||||
}
|
||||
}
|
||||
|
||||
func (rc *relayConnImpl) Transport() error {
|
||||
defer rc.Close() // nolint: errcheck
|
||||
cl := rc.l.Named(shortHashSHA256(rc.GetFlow()))
|
||||
cl.Debugf("transport start, stats: %s", rc.Stats.String())
|
||||
defer func() {
|
||||
err := rc.Close()
|
||||
if err != nil {
|
||||
rc.l.Errorf("error closing relay connection: %s", err.Error())
|
||||
}
|
||||
}()
|
||||
rc.l = rc.l.Named(shortHashSHA256(rc.GetFlow()))
|
||||
rc.l.Debugf("transport start")
|
||||
c1 := newInnerConn(rc.clientConn, rc)
|
||||
c1.l = rc.l.Named("client")
|
||||
c2 := newInnerConn(rc.remoteConn, rc)
|
||||
c2.l = rc.l.Named("remote")
|
||||
rc.StartTime = time.Now().Local()
|
||||
err := copyConn(c1, c2)
|
||||
if err != nil {
|
||||
cl.Errorf("transport error: %s", err.Error())
|
||||
rc.l.Errorf("transport error: %s", err.Error())
|
||||
}
|
||||
cl.Debugf("transport end, stats: %s", rc.Stats.String())
|
||||
rc.l.Debugf("transport end: stats: %s", rc.Stats.String())
|
||||
rc.EndTime = time.Now().Local()
|
||||
return err
|
||||
}
|
||||
@@ -115,7 +137,7 @@ func (rc *relayConnImpl) Close() error {
|
||||
err1 := rc.clientConn.Close()
|
||||
err2 := rc.remoteConn.Close()
|
||||
rc.Closed = true
|
||||
return combineErrorsAndMuteEOF(err1, err2)
|
||||
return combineErrorsAndMuteIDLE(err1, err2)
|
||||
}
|
||||
|
||||
// functions that for web ui
|
||||
@@ -142,11 +164,11 @@ func (rc *relayConnImpl) GetConnType() string {
|
||||
return rc.ConnType
|
||||
}
|
||||
|
||||
func combineErrorsAndMuteEOF(err1, err2 error) error {
|
||||
if err1 == io.EOF {
|
||||
func combineErrorsAndMuteIDLE(err1, err2 error) error {
|
||||
if err1 == ErrIdleTimeout {
|
||||
err1 = nil
|
||||
}
|
||||
if err2 == io.EOF {
|
||||
if err2 == ErrIdleTimeout {
|
||||
return nil
|
||||
}
|
||||
if err1 != nil && err2 != nil {
|
||||
@@ -180,13 +202,14 @@ func (s *Stats) String() string {
|
||||
// note that innerConn is a wrapper around net.Conn to allow io.Copy to be used
|
||||
type innerConn struct {
|
||||
net.Conn
|
||||
lastActive time.Time
|
||||
|
||||
rc *relayConnImpl
|
||||
lastActive time.Time
|
||||
rc *relayConnImpl
|
||||
l *zap.SugaredLogger
|
||||
}
|
||||
|
||||
func newInnerConn(conn net.Conn, rc *relayConnImpl) *innerConn {
|
||||
return &innerConn{Conn: conn, rc: rc, lastActive: time.Now()}
|
||||
return &innerConn{Conn: conn, rc: rc, lastActive: time.Now().Local()}
|
||||
}
|
||||
|
||||
func (c *innerConn) recordStats(n int, isRead bool) {
|
||||
@@ -208,37 +231,35 @@ func (c *innerConn) recordStats(n int, isRead bool) {
|
||||
|
||||
func (c *innerConn) Read(p []byte) (n int, err error) {
|
||||
for {
|
||||
deadline := time.Now().Add(constant.ReadTimeOut)
|
||||
deadline := time.Now().Add(c.rc.Options.ReadTimeout)
|
||||
if err := c.Conn.SetReadDeadline(deadline); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
n, err = c.Conn.Read(p)
|
||||
if err == nil {
|
||||
c.recordStats(n, true)
|
||||
c.lastActive = time.Now()
|
||||
return
|
||||
c.lastActive = time.Now().Local()
|
||||
return n, err
|
||||
} else {
|
||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||
if time.Since(c.lastActive) > constant.IdleTimeOut {
|
||||
c.rc.l.Debugf("read idle,close remote: %s", c.rc.remote.Label)
|
||||
return 0, io.EOF
|
||||
since := time.Since(c.lastActive)
|
||||
if since > c.rc.Options.IdleTimeout {
|
||||
c.l.Debugf("Read idle, close remote: %s", c.rc.remote.Label)
|
||||
return 0, ErrIdleTimeout
|
||||
}
|
||||
continue
|
||||
}
|
||||
return n, err
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *innerConn) Write(p []byte) (n int, err error) {
|
||||
if time.Since(c.lastActive) > constant.IdleTimeOut {
|
||||
c.rc.l.Debugf("write idle,close remote: %s", c.rc.remote.Label)
|
||||
return 0, io.EOF
|
||||
}
|
||||
n, err = c.Conn.Write(p)
|
||||
c.recordStats(n, false) // false for write operation
|
||||
if err != nil {
|
||||
c.lastActive = time.Now()
|
||||
if err == nil {
|
||||
c.recordStats(n, false)
|
||||
now := time.Now().Local()
|
||||
c.lastActive = now
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -265,28 +286,29 @@ func shortHashSHA256(input string) string {
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(input))
|
||||
hash := hasher.Sum(nil)
|
||||
return hex.EncodeToString(hash)[:7]
|
||||
return hex.EncodeToString(hash)[:shortHashLength]
|
||||
}
|
||||
|
||||
func copyConn(conn1, conn2 *innerConn) error {
|
||||
buf := buffer.BufferPool.Get()
|
||||
defer buffer.BufferPool.Put(buf)
|
||||
buf1 := buffer.BufferPool.Get()
|
||||
defer buffer.BufferPool.Put(buf1)
|
||||
buf2 := buffer.BufferPool.Get()
|
||||
defer buffer.BufferPool.Put(buf2)
|
||||
|
||||
errCH := make(chan error, 1)
|
||||
// copy conn1 to conn2,read from conn1 and write to conn2
|
||||
go func() {
|
||||
_, err := io.CopyBuffer(conn2, conn1, buf)
|
||||
_, err := io.CopyBuffer(conn2, conn1, buf1)
|
||||
_ = conn2.CloseWrite() // all data is written to conn2 now, so close the write side of conn2 to send eof
|
||||
errCH <- err
|
||||
}()
|
||||
|
||||
// reverse copy conn2 to conn1,read from conn2 and write to conn1
|
||||
buf2 := buffer.BufferPool.Get()
|
||||
defer buffer.BufferPool.Put(buf2)
|
||||
_, err := io.CopyBuffer(conn1, conn2, buf2)
|
||||
_ = conn1.CloseWrite()
|
||||
|
||||
err2 := <-errCH
|
||||
_ = conn1.CloseRead()
|
||||
_ = conn2.CloseRead()
|
||||
return combineErrorsAndMuteEOF(err, err2)
|
||||
return combineErrorsAndMuteIDLE(err, err2)
|
||||
}
|
||||
|
||||
@@ -8,18 +8,23 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/lb"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestInnerConn_ReadWrite(t *testing.T) {
|
||||
testData := []byte("hello")
|
||||
testOptions := conf.Options{
|
||||
IdleTimeout: time.Second,
|
||||
ReadTimeout: time.Second,
|
||||
}
|
||||
|
||||
clientConn, serverConn := net.Pipe()
|
||||
clientConn.SetDeadline(time.Now().Add(1 * time.Second))
|
||||
serverConn.SetDeadline(time.Now().Add(1 * time.Second))
|
||||
defer clientConn.Close()
|
||||
defer serverConn.Close()
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}}
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}, Options: &testOptions}
|
||||
innerC := newInnerConn(clientConn, &rc)
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
@@ -94,8 +99,8 @@ func TestCopyTCPConn(t *testing.T) {
|
||||
remoteConn, err := net.Dial("tcp", echoServer.Addr().String())
|
||||
assert.NoError(t, err)
|
||||
defer remoteConn.Close()
|
||||
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}}
|
||||
testOptions := conf.Options{IdleTimeout: time.Second, ReadTimeout: time.Second}
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}, Options: &testOptions}
|
||||
c1 := newInnerConn(clientConn, &rc)
|
||||
c2 := newInnerConn(remoteConn, &rc)
|
||||
|
||||
@@ -155,7 +160,8 @@ func TestCopyUDPConn(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
defer remoteConn.Close()
|
||||
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}}
|
||||
testOptions := conf.Options{IdleTimeout: time.Second, ReadTimeout: time.Second}
|
||||
rc := relayConnImpl{Stats: &Stats{}, remote: &lb.Node{Label: "client"}, Options: &testOptions}
|
||||
c1 := newInnerConn(clientConn, &rc)
|
||||
c2 := newInnerConn(remoteConn, &rc)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/relay/conf"
|
||||
"github.com/Ehco1996/ehco/pkg/buffer"
|
||||
)
|
||||
|
||||
@@ -33,7 +33,7 @@ func (c *uc) Read(b []byte) (int, error) {
|
||||
c.lastActivity.Store(time.Now())
|
||||
return n, nil
|
||||
default:
|
||||
if time.Since(c.lastActivity.Load().(time.Time)) > constant.IdleTimeOut {
|
||||
if time.Since(c.lastActivity.Load().(time.Time)) > c.listener.cfg.Options.IdleTimeout {
|
||||
return 0, io.EOF
|
||||
}
|
||||
return 0, nil
|
||||
@@ -75,6 +75,7 @@ func (c *uc) SetWriteDeadline(t time.Time) error {
|
||||
}
|
||||
|
||||
type UDPListener struct {
|
||||
cfg *conf.Config
|
||||
listenAddr *net.UDPAddr
|
||||
listenConn *net.UDPConn
|
||||
|
||||
@@ -90,8 +91,8 @@ type UDPListener struct {
|
||||
closed atomic.Bool
|
||||
}
|
||||
|
||||
func NewUDPListener(ctx context.Context, addr string) (*UDPListener, error) {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
||||
func NewUDPListener(ctx context.Context, cfg *conf.Config) (*UDPListener, error) {
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", cfg.Listen)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -104,6 +105,7 @@ func NewUDPListener(ctx context.Context, addr string) (*UDPListener, error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
l := &UDPListener{
|
||||
cfg: cfg,
|
||||
listenConn: conn,
|
||||
listenAddr: udpAddr,
|
||||
|
||||
|
||||
@@ -5,11 +5,6 @@ import "time"
|
||||
type RelayType string
|
||||
|
||||
var (
|
||||
// allow change in test
|
||||
// TODO Set to Relay Config
|
||||
ReadTimeOut = 5 * time.Second
|
||||
IdleTimeOut = 30 * time.Second
|
||||
|
||||
Version = "1.1.5-dev"
|
||||
GitBranch string
|
||||
GitRevision string
|
||||
@@ -18,9 +13,10 @@ var (
|
||||
)
|
||||
|
||||
const (
|
||||
DialTimeOut = 3 * time.Second
|
||||
|
||||
SniffTimeOut = 300 * time.Millisecond
|
||||
DefaultDialTimeOut = 3 * time.Second
|
||||
DefaultReadTimeOut = 5 * time.Second
|
||||
DefaultIdleTimeOut = 10 * time.Second
|
||||
DefaultSniffTimeOut = 300 * time.Millisecond
|
||||
|
||||
// todo,support config in relay config
|
||||
BUFFER_POOL_SIZE = 1024 // support 512 connections
|
||||
|
||||
@@ -64,7 +64,7 @@ func NewPingGroup(cfg *config.Config) *PingGroup {
|
||||
// parse addr from rule
|
||||
for _, relayCfg := range cfg.RelayConfigs {
|
||||
// NOTE for (https/ws/wss)://xxx.com -> xxx.com
|
||||
for _, remote := range relayCfg.TCPRemotes {
|
||||
for _, remote := range relayCfg.Remotes {
|
||||
addr, err := extractHost(remote)
|
||||
if err != nil {
|
||||
pg.logger.Error("try parse host error", zap.Error(err))
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/Ehco1996/ehco/internal/constant"
|
||||
"github.com/Ehco1996/ehco/internal/lb"
|
||||
@@ -31,13 +32,27 @@ func (w *WSConfig) Clone() *WSConfig {
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
WSConfig *WSConfig `json:"ws_config,omitempty"`
|
||||
EnableUDP bool `json:"enable_udp,omitempty"`
|
||||
EnableMultipathTCP bool `json:"enable_multipath_tcp,omitempty"`
|
||||
EnableUDP bool `json:"enable_udp,omitempty"`
|
||||
EnableMultipathTCP bool `json:"enable_multipath_tcp,omitempty"`
|
||||
|
||||
// connection limit
|
||||
MaxConnection int `json:"max_connection,omitempty"`
|
||||
BlockedProtocols []string `json:"blocked_protocols,omitempty"`
|
||||
MaxReadRateKbps int64 `json:"max_read_rate_kbps,omitempty"`
|
||||
|
||||
// ws related
|
||||
WSConfig *WSConfig `json:"ws_config,omitempty"`
|
||||
|
||||
DialTimeoutSec int `json:"dial_timeout_sec,omitempty"`
|
||||
IdleTimeoutSec int `json:"idle_timeout_sec,omitempty"`
|
||||
ReadTimeoutSec int `json:"read_timeout_sec,omitempty"`
|
||||
SniffTimeoutSec int `json:"sniff_timeout_sec,omitempty"`
|
||||
|
||||
// timeout in duration
|
||||
DialTimeout time.Duration
|
||||
IdleTimeout time.Duration
|
||||
ReadTimeout time.Duration
|
||||
SniffTimeout time.Duration
|
||||
}
|
||||
|
||||
func (o *Options) Clone() *Options {
|
||||
@@ -60,9 +75,12 @@ type Config struct {
|
||||
Listen string `json:"listen"`
|
||||
ListenType constant.RelayType `json:"listen_type"`
|
||||
TransportType constant.RelayType `json:"transport_type"`
|
||||
TCPRemotes []string `json:"tcp_remotes"` // TODO rename to remotes
|
||||
Remotes []string `json:"remotes"`
|
||||
|
||||
Options *Options `json:"options,omitempty"`
|
||||
|
||||
// deprecated
|
||||
TCPRemotes []string `json:"tcp_remotes"`
|
||||
}
|
||||
|
||||
func (r *Config) GetWSHandShakePath() string {
|
||||
@@ -83,12 +101,29 @@ func (r *Config) GetWSRemoteAddr(baseAddr string) (string, error) {
|
||||
return addr, nil
|
||||
}
|
||||
|
||||
func (r *Config) GetTCPRemotes() string {
|
||||
return fmt.Sprintf("%v", r.TCPRemotes)
|
||||
func (r *Config) Adjust() error {
|
||||
if r.Label == "" {
|
||||
r.Label = r.DefaultLabel()
|
||||
zap.S().Debugf("label is empty, set default label:%s", r.Label)
|
||||
}
|
||||
if len(r.Remotes) == 0 && len(r.TCPRemotes) != 0 {
|
||||
zap.S().Warnf("tcp remotes is deprecated, use remotes instead")
|
||||
r.Remotes = r.TCPRemotes
|
||||
}
|
||||
|
||||
if r.Options == nil {
|
||||
r.Options = newDefaultOptions()
|
||||
} else {
|
||||
r.Options.DialTimeout = getDuration(r.Options.DialTimeoutSec, r.Options.DialTimeout)
|
||||
r.Options.IdleTimeout = getDuration(r.Options.IdleTimeoutSec, r.Options.IdleTimeout)
|
||||
r.Options.ReadTimeout = getDuration(r.Options.ReadTimeoutSec, r.Options.ReadTimeout)
|
||||
r.Options.SniffTimeout = getDuration(r.Options.SniffTimeoutSec, r.Options.SniffTimeout)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Config) Validate() error {
|
||||
if r.Adjust() != nil {
|
||||
if err := r.Adjust(); err != nil {
|
||||
return errors.New("adjust config failed")
|
||||
}
|
||||
|
||||
@@ -97,18 +132,18 @@ func (r *Config) Validate() error {
|
||||
}
|
||||
|
||||
if r.Listen == "" {
|
||||
return fmt.Errorf("invalid listen:%s", r.Listen)
|
||||
return fmt.Errorf("invalid listen: %s", r.Listen)
|
||||
}
|
||||
|
||||
for _, addr := range r.TCPRemotes {
|
||||
for _, addr := range r.Remotes {
|
||||
if addr == "" {
|
||||
return fmt.Errorf("invalid tcp remote addr:%s", addr)
|
||||
return fmt.Errorf("invalid remote addr: %s", addr)
|
||||
}
|
||||
}
|
||||
|
||||
for _, protocol := range r.Options.BlockedProtocols {
|
||||
if protocol != ProtocolHTTP && protocol != ProtocolTLS {
|
||||
return fmt.Errorf("invalid blocked protocol:%s", protocol)
|
||||
return fmt.Errorf("invalid blocked protocol: %s", protocol)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -122,8 +157,8 @@ func (r *Config) Clone() *Config {
|
||||
Label: r.Label,
|
||||
Options: r.Options.Clone(),
|
||||
}
|
||||
new.TCPRemotes = make([]string, len(r.TCPRemotes))
|
||||
copy(new.TCPRemotes, r.TCPRemotes)
|
||||
new.Remotes = make([]string, len(r.Remotes))
|
||||
copy(new.Remotes, r.Remotes)
|
||||
return new
|
||||
}
|
||||
|
||||
@@ -134,11 +169,11 @@ func (r *Config) Different(new *Config) bool {
|
||||
r.Label != new.Label {
|
||||
return true
|
||||
}
|
||||
if len(r.TCPRemotes) != len(new.TCPRemotes) {
|
||||
if len(r.Remotes) != len(new.Remotes) {
|
||||
return true
|
||||
}
|
||||
for i, addr := range r.TCPRemotes {
|
||||
if addr != new.TCPRemotes[i] {
|
||||
for i, addr := range r.Remotes {
|
||||
if addr != new.Remotes[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -147,28 +182,14 @@ func (r *Config) Different(new *Config) bool {
|
||||
|
||||
// todo make this shorter and more readable
|
||||
func (r *Config) DefaultLabel() string {
|
||||
defaultLabel := fmt.Sprintf("<At=%s To=%s TP=%s>",
|
||||
r.Listen, r.TCPRemotes, r.TransportType)
|
||||
defaultLabel := fmt.Sprintf("<At=%s To=%s By=%s>",
|
||||
r.Listen, r.Remotes, r.TransportType)
|
||||
return defaultLabel
|
||||
}
|
||||
|
||||
func (r *Config) Adjust() error {
|
||||
if r.Label == "" {
|
||||
r.Label = r.DefaultLabel()
|
||||
zap.S().Debugf("label is empty, set default label:%s", r.Label)
|
||||
}
|
||||
if r.Options == nil {
|
||||
r.Options = &Options{
|
||||
WSConfig: &WSConfig{},
|
||||
EnableMultipathTCP: true, // default enable multipath tcp
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Config) ToTCPRemotes() lb.RoundRobin {
|
||||
tcpNodeList := make([]*lb.Node, len(r.TCPRemotes))
|
||||
for idx, addr := range r.TCPRemotes {
|
||||
func (r *Config) ToRemotesLB() lb.RoundRobin {
|
||||
tcpNodeList := make([]*lb.Node, len(r.Remotes))
|
||||
for idx, addr := range r.Remotes {
|
||||
tcpNodeList[idx] = &lb.Node{
|
||||
Address: addr,
|
||||
Label: fmt.Sprintf("%s-%s", r.Label, addr),
|
||||
@@ -195,3 +216,21 @@ func (r *Config) validateType() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getDuration(seconds int, defaultDuration time.Duration) time.Duration {
|
||||
if seconds > 0 {
|
||||
return time.Duration(seconds) * time.Second
|
||||
}
|
||||
return defaultDuration
|
||||
}
|
||||
|
||||
func newDefaultOptions() *Options {
|
||||
return &Options{
|
||||
EnableMultipathTCP: true,
|
||||
WSConfig: &WSConfig{},
|
||||
DialTimeout: constant.DefaultDialTimeOut,
|
||||
IdleTimeout: constant.DefaultIdleTimeOut,
|
||||
ReadTimeout: constant.DefaultReadTimeOut,
|
||||
SniffTimeout: constant.DefaultSniffTimeOut,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,15 +38,12 @@ func NewRelay(cfg *conf.Config, cmgr cmgr.Cmgr) (*Relay, error) {
|
||||
func (r *Relay) ListenAndServe(ctx context.Context) error {
|
||||
errCh := make(chan error)
|
||||
go func() {
|
||||
r.l.Infof("Start Relay Server(%s):%s", r.cfg.ListenType, r.cfg.DefaultLabel())
|
||||
r.l.Infof("Start Relay Server: %s", r.cfg.DefaultLabel())
|
||||
errCh <- r.relayServer.ListenAndServe(ctx)
|
||||
}()
|
||||
return <-errCh
|
||||
}
|
||||
|
||||
func (r *Relay) Close() {
|
||||
r.l.Infof("Close Relay Server:%s", r.cfg.DefaultLabel())
|
||||
if err := r.relayServer.Close(); err != nil {
|
||||
r.l.Errorf(err.Error())
|
||||
}
|
||||
func (r *Relay) Stop() error {
|
||||
return r.relayServer.Close()
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (s *Server) startOneRelay(ctx context.Context, r *Relay) {
|
||||
}
|
||||
|
||||
func (s *Server) stopOneRelay(r *Relay) {
|
||||
r.Close()
|
||||
_ = r.Stop()
|
||||
s.relayM.Delete(r.UniqueID())
|
||||
}
|
||||
|
||||
@@ -85,23 +85,20 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
s.l.Info("ctx cancelled start to stop all relay servers")
|
||||
s.relayM.Range(func(key, value interface{}) bool {
|
||||
r := value.(*Relay)
|
||||
r.Close()
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
return s.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Stop() error {
|
||||
s.l.Info("relay server stop now")
|
||||
var err error
|
||||
s.relayM.Range(func(key, value interface{}) bool {
|
||||
r := value.(*Relay)
|
||||
r.Close()
|
||||
if e := r.Stop(); e != nil {
|
||||
err = errors.Join(err, e)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Server) TriggerReload() {
|
||||
|
||||
@@ -38,7 +38,7 @@ func newBaseRelayServer(cfg *conf.Config, cmgr cmgr.Cmgr) (*BaseRelayServer, err
|
||||
relayer: relayer,
|
||||
cfg: cfg,
|
||||
cmgr: cmgr,
|
||||
remotes: cfg.ToTCPRemotes(),
|
||||
remotes: cfg.ToRemotesLB(),
|
||||
l: zap.S().Named(cfg.GetLoggerName()),
|
||||
}, nil
|
||||
}
|
||||
@@ -98,10 +98,10 @@ func (b *BaseRelayServer) sniffAndBlockProtocol(c net.Conn) (net.Conn, error) {
|
||||
|
||||
buffer := buf.NewPacket()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), constant.SniffTimeOut)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), b.cfg.Options.SniffTimeout)
|
||||
defer cancel()
|
||||
|
||||
sniffMetadata, err := sniff.PeekStream(ctx, c, buffer, constant.SniffTimeOut, sniff.TLSClientHello, sniff.HTTPHost)
|
||||
sniffMetadata, err := sniff.PeekStream(ctx, c, buffer, b.cfg.Options.SniffTimeout, sniff.TLSClientHello, sniff.HTTPHost)
|
||||
if err != nil {
|
||||
b.l.Debugf("sniff error: %s", err)
|
||||
return c, nil
|
||||
@@ -137,6 +137,7 @@ func (b *BaseRelayServer) handleRelayConn(c, rc net.Conn, remote *lb.Node, connT
|
||||
conn.WithRemote(remote),
|
||||
conn.WithConnType(connType),
|
||||
conn.WithRelayLabel(b.cfg.Label),
|
||||
conn.WithRelayOptions(b.cfg.Options),
|
||||
conn.WithHandshakeDuration(remote.HandShakeDuration),
|
||||
}
|
||||
relayConn := conn.NewRelayConn(c, rc, opts...)
|
||||
@@ -161,7 +162,7 @@ func (b *BaseRelayServer) ListenAndServe(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func NewNetDialer(cfg *conf.Config) *net.Dialer {
|
||||
dialer := &net.Dialer{Timeout: constant.DialTimeOut}
|
||||
dialer := &net.Dialer{Timeout: constant.DefaultDialTimeOut}
|
||||
dialer.SetMultipathTCP(cfg.Options.EnableMultipathTCP)
|
||||
return dialer
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func (s *RawServer) ListenAndServe(ctx context.Context) error {
|
||||
s.tcpLis = ts
|
||||
|
||||
if s.cfg.Options != nil && s.cfg.Options.EnableUDP {
|
||||
udpLis, err := conn.NewUDPListener(ctx, s.cfg.Listen)
|
||||
udpLis, err := conn.NewUDPListener(ctx, s.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -107,10 +107,13 @@ func (s *RawServer) ListenAndServe(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (s *RawServer) listenUDP(ctx context.Context) error {
|
||||
s.l.Infof("Start UDP server at %s", s.cfg.Listen)
|
||||
for {
|
||||
c, err := s.udpLis.Accept()
|
||||
if err != nil {
|
||||
// Check if the error is due to context cancellation
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return nil // Return without logging the error
|
||||
}
|
||||
s.l.Errorf("UDP accept error: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -174,10 +174,10 @@ func (c *ClashSub) ToRelayConfigs(listenHost string) ([]*relay_cfg.Config, error
|
||||
// add other proxies address in group to relay config
|
||||
for _, proxy := range proxies[1:] {
|
||||
remote := net.JoinHostPort(proxy.rawServer, proxy.rawPort)
|
||||
if strInArray(remote, rc.TCPRemotes) {
|
||||
if strInArray(remote, rc.Remotes) {
|
||||
continue
|
||||
}
|
||||
rc.TCPRemotes = append(rc.TCPRemotes, remote)
|
||||
rc.Remotes = append(rc.Remotes, remote)
|
||||
if proxy.UDP {
|
||||
rc.Options = &relay_cfg.Options{
|
||||
EnableUDP: true,
|
||||
|
||||
@@ -136,7 +136,7 @@ func (p *Proxies) ToRelayConfig(listenHost string, listenPort string, newName st
|
||||
ListenType: constant.RelayTypeRaw,
|
||||
TransportType: constant.RelayTypeRaw,
|
||||
Listen: net.JoinHostPort(listenHost, listenPort),
|
||||
TCPRemotes: []string{remoteAddr},
|
||||
Remotes: []string{remoteAddr},
|
||||
}
|
||||
if p.UDP {
|
||||
r.Options = &relay_cfg.Options{
|
||||
|
||||
@@ -40,11 +40,6 @@ const (
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// Setup
|
||||
|
||||
// change the idle timeout to 1 second to make connection close faster in test
|
||||
constant.IdleTimeOut = time.Second
|
||||
constant.ReadTimeOut = time.Second
|
||||
|
||||
_ = log.InitGlobalLogger("debug")
|
||||
_ = tls.InitTlsCfg()
|
||||
|
||||
@@ -61,66 +56,67 @@ func TestMain(m *testing.M) {
|
||||
// Cleanup
|
||||
echoServer.Stop()
|
||||
for _, server := range relayServers {
|
||||
server.Close()
|
||||
server.Stop()
|
||||
}
|
||||
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
func startRelayServers() []*relay.Relay {
|
||||
options := conf.Options{
|
||||
EnableUDP: true,
|
||||
IdleTimeoutSec: 1,
|
||||
ReadTimeoutSec: 1,
|
||||
}
|
||||
cfg := config.Config{
|
||||
RelayConfigs: []*conf.Config{
|
||||
// raw
|
||||
{
|
||||
Label: "raw",
|
||||
Listen: RAW_LISTEN,
|
||||
ListenType: constant.RelayTypeRaw,
|
||||
TCPRemotes: []string{ECHO_SERVER},
|
||||
Remotes: []string{ECHO_SERVER},
|
||||
TransportType: constant.RelayTypeRaw,
|
||||
Options: &conf.Options{
|
||||
EnableUDP: true,
|
||||
},
|
||||
Options: &options,
|
||||
},
|
||||
// ws
|
||||
{
|
||||
Label: "ws-in",
|
||||
Listen: WS_LISTEN,
|
||||
ListenType: constant.RelayTypeRaw,
|
||||
TCPRemotes: []string{WS_REMOTE},
|
||||
Remotes: []string{WS_REMOTE},
|
||||
TransportType: constant.RelayTypeWS,
|
||||
Options: &conf.Options{
|
||||
EnableUDP: true,
|
||||
},
|
||||
Options: &options,
|
||||
},
|
||||
{
|
||||
Label: "ws-out",
|
||||
Listen: WS_SERVER,
|
||||
ListenType: constant.RelayTypeWS,
|
||||
TCPRemotes: []string{ECHO_SERVER},
|
||||
Remotes: []string{ECHO_SERVER},
|
||||
TransportType: constant.RelayTypeRaw,
|
||||
Options: &conf.Options{
|
||||
EnableUDP: true,
|
||||
},
|
||||
Options: &options,
|
||||
},
|
||||
|
||||
// wss
|
||||
{
|
||||
Label: "wss-in",
|
||||
Listen: WSS_LISTEN,
|
||||
ListenType: constant.RelayTypeRaw,
|
||||
TCPRemotes: []string{WSS_REMOTE},
|
||||
Remotes: []string{WSS_REMOTE},
|
||||
TransportType: constant.RelayTypeWSS,
|
||||
Options: &conf.Options{
|
||||
EnableUDP: true,
|
||||
},
|
||||
Options: &options,
|
||||
},
|
||||
{
|
||||
Label: "wss-out",
|
||||
Listen: WSS_SERVER,
|
||||
ListenType: constant.RelayTypeWSS,
|
||||
TCPRemotes: []string{ECHO_SERVER},
|
||||
Remotes: []string{ECHO_SERVER},
|
||||
TransportType: constant.RelayTypeRaw,
|
||||
Options: &conf.Options{
|
||||
EnableUDP: true,
|
||||
},
|
||||
Options: &options,
|
||||
},
|
||||
},
|
||||
}
|
||||
cfg.Adjust()
|
||||
|
||||
var servers []*relay.Relay
|
||||
for _, c := range cfg.RelayConfigs {
|
||||
@@ -252,6 +248,6 @@ func testUDPRelay(t *testing.T, address string, concurrent bool, concurrency ...
|
||||
}
|
||||
|
||||
func TestRelayIdleTimeout(t *testing.T) {
|
||||
err := echo.EchoTcpMsgLong([]byte("hello"), time.Second, RAW_LISTEN)
|
||||
err := echo.EchoTcpMsgLong([]byte("hello"), time.Second*2, RAW_LISTEN)
|
||||
require.Error(t, err, "Connection should be rejected")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user