mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-11-06 10:12:40 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42e162b095 | ||
|
|
a52db8f6ed | ||
|
|
858c44f410 | ||
|
|
fff4acac52 | ||
|
|
ad98ffd42b | ||
|
|
63ca2e0c1d | ||
|
|
ab88e0118f |
@@ -20,7 +20,7 @@ RUN cat <<EOF >/tmp/usr/local/etc/xray/00_log.json
|
|||||||
{
|
{
|
||||||
"log": {
|
"log": {
|
||||||
"error": "/var/log/xray/error.log",
|
"error": "/var/log/xray/error.log",
|
||||||
"loglevel": "warning",
|
"logLevel": "warning",
|
||||||
"access": "none",
|
"access": "none",
|
||||||
"dnsLog": false
|
"dnsLog": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ RUN cat <<EOF >/tmp/usr/local/etc/xray/00_log.json
|
|||||||
{
|
{
|
||||||
"log": {
|
"log": {
|
||||||
"error": "/var/log/xray/error.log",
|
"error": "/var/log/xray/error.log",
|
||||||
"loglevel": "warning",
|
"logLevel": "warning",
|
||||||
"access": "none",
|
"access": "none",
|
||||||
"dnsLog": false
|
"dnsLog": false
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -73,7 +73,7 @@ func (r *TimeoutWrapperReader) ReadMultiBufferTimeout(duration time.Duration) (M
|
|||||||
}
|
}
|
||||||
return r.mb, r.err
|
return r.mb, r.err
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
return nil, nil
|
return nil, ErrReadTimeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ func TestMarshalConfigJson(t *testing.T) {
|
|||||||
func getConfig() string {
|
func getConfig() string {
|
||||||
return `{
|
return `{
|
||||||
"log": {
|
"log": {
|
||||||
"loglevel": "debug"
|
"logLevel": "debug"
|
||||||
},
|
},
|
||||||
"stats": {},
|
"stats": {},
|
||||||
"policy": {
|
"policy": {
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ require (
|
|||||||
github.com/google/go-cmp v0.7.0
|
github.com/google/go-cmp v0.7.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
github.com/klauspost/cpuid/v2 v2.4.1
|
github.com/klauspost/cpuid/v2 v2.4.2
|
||||||
github.com/libp2p/go-nat v1.0.1-0.20250821073202-01afc089f138
|
github.com/libp2p/go-nat v1.0.1-0.20250821073202-01afc089f138
|
||||||
github.com/miekg/dns v1.1.73
|
github.com/miekg/dns v1.1.73
|
||||||
github.com/pelletier/go-toml v1.9.5
|
github.com/pelletier/go-toml v1.9.5
|
||||||
github.com/pion/stun/v3 v3.1.7
|
github.com/pion/stun/v3 v3.1.7
|
||||||
github.com/pires/go-proxyproto v0.16.0
|
github.com/pires/go-proxyproto v0.16.0
|
||||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af
|
github.com/refraction-networking/utls v1.8.3-0.20261014003643-b2e5ff8060be
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/stretchr/testify v1.12.1
|
github.com/stretchr/testify v1.12.1
|
||||||
github.com/vishvananda/netlink v1.3.1
|
github.com/vishvananda/netlink v1.3.1
|
||||||
@@ -41,14 +41,14 @@ require (
|
|||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.2.3 // indirect
|
|
||||||
github.com/google/gopacket v1.1.19 // indirect
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
github.com/huin/goupnp v1.2.0 // indirect
|
github.com/huin/goupnp v1.2.0 // indirect
|
||||||
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
|
||||||
github.com/juju/ratelimit v1.0.2 // indirect
|
github.com/juju/ratelimit v1.0.2 // indirect
|
||||||
github.com/klauspost/compress v1.20.0 // indirect
|
github.com/klauspost/compress v1.20.1 // indirect
|
||||||
github.com/koron/go-ssdp v0.0.4 // indirect
|
github.com/koron/go-ssdp v0.0.4 // indirect
|
||||||
github.com/libp2p/go-netroute v0.2.1 // indirect
|
github.com/libp2p/go-netroute v0.2.1 // indirect
|
||||||
|
github.com/molecule-man/go-brrr v1.2.0 // indirect
|
||||||
github.com/pion/dtls/v3 v3.1.5 // indirect
|
github.com/pion/dtls/v3 v3.1.5 // indirect
|
||||||
github.com/pion/logging v0.2.4 // indirect
|
github.com/pion/logging v0.2.4 // indirect
|
||||||
github.com/pion/transport/v4 v4.1.0 // indirect
|
github.com/pion/transport/v4 v4.1.0 // indirect
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
github.com/andybalholm/brotli v1.2.3 h1:8H1qwOkl2LPfjf3YezB90JnCliZb6SInJ/OJkEbA5NQ=
|
|
||||||
github.com/andybalholm/brotli v1.2.3/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
|
||||||
github.com/apernet/quic-go v0.61.1-0.20260806010916-184d081eef3e h1:5mgtR5gwIgBKMiGI1QdXldZZ+SNor06Nbu1wCBulQBg=
|
github.com/apernet/quic-go v0.61.1-0.20260806010916-184d081eef3e h1:5mgtR5gwIgBKMiGI1QdXldZZ+SNor06Nbu1wCBulQBg=
|
||||||
github.com/apernet/quic-go v0.61.1-0.20260806010916-184d081eef3e/go.mod h1:x7qxEvX6MCVtDuBKHj3E+88+BtrbEMuAL5qGUKItjW8=
|
github.com/apernet/quic-go v0.61.1-0.20260806010916-184d081eef3e/go.mod h1:x7qxEvX6MCVtDuBKHj3E+88+BtrbEMuAL5qGUKItjW8=
|
||||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||||
@@ -33,10 +31,10 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd
|
|||||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||||
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
|
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/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||||
github.com/klauspost/compress v1.20.0 h1:a3C1ke2ohxFymNlb2HWAHjDeKCI90scRskErZkR0ezA=
|
github.com/klauspost/compress v1.20.1 h1:T7kKElXUMXrUJ2E9QhQhxFtcK5rPyLdsGZvdbLMPdiQ=
|
||||||
github.com/klauspost/compress v1.20.0/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
|
github.com/klauspost/compress v1.20.1/go.mod h1:LUdAzn7YLVvxLpc7y3V1m40wESHTgc1422pwwBSKYuI=
|
||||||
github.com/klauspost/cpuid/v2 v2.4.1 h1:I9KxadAkvo+QjtcEE2f2tyfEvmIla/T0m+14PrZNl0U=
|
github.com/klauspost/cpuid/v2 v2.4.2 h1:xRw7IZEsAgVCp6trS/DgWbTAqpixhmywgVgBjYGg1bQ=
|
||||||
github.com/klauspost/cpuid/v2 v2.4.1/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
|
github.com/klauspost/cpuid/v2 v2.4.2/go.mod h1:19jmZ9mjzoF//ddRSUsv0zfBTJWh3QJh9FNxZTMrGxU=
|
||||||
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
|
github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0=
|
||||||
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
|
github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
@@ -49,6 +47,8 @@ github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9t
|
|||||||
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
|
github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ=
|
||||||
github.com/miekg/dns v1.1.73 h1:uhT8nJxmTrPJYClxVxTCX+CVn6qnzSiybRk72Z6DgrE=
|
github.com/miekg/dns v1.1.73 h1:uhT8nJxmTrPJYClxVxTCX+CVn6qnzSiybRk72Z6DgrE=
|
||||||
github.com/miekg/dns v1.1.73/go.mod h1:RW2Obtfd5NZHvOFe3zYG0W8koWOQtAzyHaLo8vASBuQ=
|
github.com/miekg/dns v1.1.73/go.mod h1:RW2Obtfd5NZHvOFe3zYG0W8koWOQtAzyHaLo8vASBuQ=
|
||||||
|
github.com/molecule-man/go-brrr v1.2.0 h1:dOJU45BC3Gc2WXoxAW0rgCAgVuu2gruAOGncfieA0Jw=
|
||||||
|
github.com/molecule-man/go-brrr v1.2.0/go.mod h1:7ybW6/7gA3oKY45jOfVNjSJDtrr6ea4tzbsTkjmQDC4=
|
||||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
|
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
|
||||||
@@ -67,8 +67,8 @@ github.com/quic-go/go-ossfuzz-seeds v0.1.0 h1:APacT+iIaNF6fd8AGEiN3bT/Jtkd2jz4v4
|
|||||||
github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk=
|
github.com/quic-go/go-ossfuzz-seeds v0.1.0/go.mod h1:3IOHRbJIc+L6YKMwfDtJAM9Vj9k0YY4muhuyUYk5tbk=
|
||||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af h1:er2acxbi3N1nvEq6HXHUAR1nTWEJmQfqiGR8EVT9rfs=
|
github.com/refraction-networking/utls v1.8.3-0.20261014003643-b2e5ff8060be h1:gpxlwEH6mzilrkEdDRoW5Gw6nuHFjie0xnf2cbtdW+E=
|
||||||
github.com/refraction-networking/utls v1.8.3-0.20260301010127-aa6edf4b11af/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
|
github.com/refraction-networking/utls v1.8.3-0.20261014003643-b2e5ff8060be/go.mod h1:rc/ctWeKlh9LSk5k90KlSPcwF7P6D31mn/9GI2NAfBI=
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g=
|
github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g=
|
||||||
@@ -83,8 +83,6 @@ github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
|||||||
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||||
github.com/xtls/reality v0.0.0-20261014101318-83f621788ca8 h1:RjLnVvlzK4q6zWaSBPNRGsrgx2fbJDeUWffjw574uzs=
|
github.com/xtls/reality v0.0.0-20261014101318-83f621788ca8 h1:RjLnVvlzK4q6zWaSBPNRGsrgx2fbJDeUWffjw574uzs=
|
||||||
github.com/xtls/reality v0.0.0-20261014101318-83f621788ca8/go.mod h1:ptlSkJ8k/7IDauNH0SA96JPOo+nYGLTv2Y3UMpwvAsY=
|
github.com/xtls/reality v0.0.0-20261014101318-83f621788ca8/go.mod h1:ptlSkJ8k/7IDauNH0SA96JPOo+nYGLTv2Y3UMpwvAsY=
|
||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ=
|
||||||
github.com/yuin/gopher-lua v1.1.2 h1:yF/FjE3hD65tBbt0VXLE13HWS9h34fdzJmrWRXwobGA=
|
github.com/yuin/gopher-lua v1.1.2 h1:yF/FjE3hD65tBbt0VXLE13HWS9h34fdzJmrWRXwobGA=
|
||||||
|
|||||||
+33
-3
@@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/geodata"
|
"github.com/xtls/xray-core/common/geodata"
|
||||||
|
"github.com/xtls/xray-core/common/log"
|
||||||
xnet "github.com/xtls/xray-core/common/net"
|
xnet "github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/protocol"
|
"github.com/xtls/xray-core/common/protocol"
|
||||||
"github.com/xtls/xray-core/proxy/freedom"
|
"github.com/xtls/xray-core/proxy/freedom"
|
||||||
@@ -48,6 +49,8 @@ type FreedomFinalRuleConfig struct {
|
|||||||
Network *NetworkList `json:"network"`
|
Network *NetworkList `json:"network"`
|
||||||
Port *PortList `json:"port"`
|
Port *PortList `json:"port"`
|
||||||
IP *StringList `json:"ip"`
|
IP *StringList `json:"ip"`
|
||||||
|
Delay *Int32Range `json:"delay"`
|
||||||
|
LogLevel string `json:"logLevel"`
|
||||||
BlockDelay *Int32Range `json:"blockDelay"`
|
BlockDelay *Int32Range `json:"blockDelay"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,10 +283,37 @@ func (c *FreedomFinalRuleConfig) Build() (*freedom.FinalRuleConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if c.BlockDelay != nil {
|
if c.BlockDelay != nil {
|
||||||
rule.BlockDelay = &freedom.Range{
|
errors.PrintDeprecatedFeatureWarning("finalRules.blockDelay", "finalRules.delay")
|
||||||
Min: uint64(c.BlockDelay.From),
|
c.Delay = c.BlockDelay
|
||||||
Max: uint64(c.BlockDelay.To),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if rule.Action != freedom.RuleAction_Block {
|
||||||
|
if c.Delay != nil || c.LogLevel != "" {
|
||||||
|
return nil, errors.New("delay and logLevel are only supported for block finalRules")
|
||||||
|
}
|
||||||
|
return rule, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Delay != nil {
|
||||||
|
rule.Delay = &freedom.Range{
|
||||||
|
Min: uint64(c.Delay.From),
|
||||||
|
Max: uint64(c.Delay.To),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch strings.ToLower(c.LogLevel) {
|
||||||
|
case "", "info":
|
||||||
|
rule.LogLevel = log.Severity_Info.Enum()
|
||||||
|
case "none":
|
||||||
|
rule.LogLevel = log.Severity_Unknown.Enum()
|
||||||
|
case "debug":
|
||||||
|
rule.LogLevel = log.Severity_Debug.Enum()
|
||||||
|
case "warning":
|
||||||
|
rule.LogLevel = log.Severity_Warning.Enum()
|
||||||
|
case "error":
|
||||||
|
rule.LogLevel = log.Severity_Error.Enum()
|
||||||
|
default:
|
||||||
|
return nil, errors.New("unknown finalRules.logLevel: ", c.LogLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rule, nil
|
return rule, nil
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/geodata"
|
"github.com/xtls/xray-core/common/geodata"
|
||||||
|
"github.com/xtls/xray-core/common/log"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/protocol"
|
"github.com/xtls/xray-core/common/protocol"
|
||||||
. "github.com/xtls/xray-core/infra/conf"
|
. "github.com/xtls/xray-core/infra/conf"
|
||||||
@@ -46,7 +47,8 @@ func TestFreedomConfig(t *testing.T) {
|
|||||||
"network": "tcp,udp",
|
"network": "tcp,udp",
|
||||||
"port": "53,443",
|
"port": "53,443",
|
||||||
"ip": ["10.0.0.0/8", "2001:db8::/32"],
|
"ip": ["10.0.0.0/8", "2001:db8::/32"],
|
||||||
"blockDelay": "30-60"
|
"delay": "30-60",
|
||||||
|
"logLevel": "debug"
|
||||||
}, {
|
}, {
|
||||||
"action": "allow",
|
"action": "allow",
|
||||||
"network": ["udp"]
|
"network": ["udp"]
|
||||||
@@ -86,10 +88,8 @@ func TestFreedomConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
BlockDelay: &freedom.Range{
|
Delay: &freedom.Range{Min: 30, Max: 60},
|
||||||
Min: 30,
|
LogLevel: log.Severity_Debug.Enum(),
|
||||||
Max: 60,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Action: freedom.RuleAction_Allow,
|
Action: freedom.RuleAction_Allow,
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ func DefaultLogConfig() *log.Config {
|
|||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
AccessLog string `json:"access"`
|
AccessLog string `json:"access"`
|
||||||
ErrorLog string `json:"error"`
|
ErrorLog string `json:"error"`
|
||||||
LogLevel string `json:"loglevel"`
|
LogLevel string `json:"logLevel"`
|
||||||
DNSLog bool `json:"dnsLog"`
|
DNSLog bool `json:"dnsLog"`
|
||||||
MaskAddress string `json:"maskAddress"`
|
MaskAddress string `json:"maskAddress"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ func TestLoaderError(t *testing.T) {
|
|||||||
"log": {
|
"log": {
|
||||||
// abcd
|
// abcd
|
||||||
0,
|
0,
|
||||||
"loglevel": "info"
|
"logLevel": "info"
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
Output: "line 4 char 6",
|
Output: "line 4 char 6",
|
||||||
@@ -27,7 +27,7 @@ func TestLoaderError(t *testing.T) {
|
|||||||
Input: `{
|
Input: `{
|
||||||
"log": {
|
"log": {
|
||||||
// abcd
|
// abcd
|
||||||
"loglevel": "info",
|
"logLevel": "info",
|
||||||
}
|
}
|
||||||
}`,
|
}`,
|
||||||
Output: "line 5 char 5",
|
Output: "line 5 char 5",
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ func TestXrayConfig(t *testing.T) {
|
|||||||
Input: `{
|
Input: `{
|
||||||
"log": {
|
"log": {
|
||||||
"access": "/var/log/xray/access.log",
|
"access": "/var/log/xray/access.log",
|
||||||
"loglevel": "error",
|
"logLevel": "error",
|
||||||
"error": "/var/log/xray/error.log"
|
"error": "/var/log/xray/error.log"
|
||||||
},
|
},
|
||||||
"inbounds": [{
|
"inbounds": [{
|
||||||
|
|||||||
+34
-20
@@ -8,6 +8,7 @@ package freedom
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
geodata "github.com/xtls/xray-core/common/geodata"
|
geodata "github.com/xtls/xray-core/common/geodata"
|
||||||
|
log "github.com/xtls/xray-core/common/log"
|
||||||
net "github.com/xtls/xray-core/common/net"
|
net "github.com/xtls/xray-core/common/net"
|
||||||
protocol "github.com/xtls/xray-core/common/protocol"
|
protocol "github.com/xtls/xray-core/common/protocol"
|
||||||
internet "github.com/xtls/xray-core/transport/internet"
|
internet "github.com/xtls/xray-core/transport/internet"
|
||||||
@@ -357,7 +358,8 @@ type FinalRuleConfig struct {
|
|||||||
Networks []net.Network `protobuf:"varint,2,rep,packed,name=networks,proto3,enum=xray.common.net.Network" json:"networks,omitempty"`
|
Networks []net.Network `protobuf:"varint,2,rep,packed,name=networks,proto3,enum=xray.common.net.Network" json:"networks,omitempty"`
|
||||||
PortList *net.PortList `protobuf:"bytes,3,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
|
PortList *net.PortList `protobuf:"bytes,3,opt,name=port_list,json=portList,proto3" json:"port_list,omitempty"`
|
||||||
Ip []*geodata.IPRule `protobuf:"bytes,4,rep,name=ip,proto3" json:"ip,omitempty"`
|
Ip []*geodata.IPRule `protobuf:"bytes,4,rep,name=ip,proto3" json:"ip,omitempty"`
|
||||||
BlockDelay *Range `protobuf:"bytes,5,opt,name=block_delay,json=blockDelay,proto3" json:"block_delay,omitempty"`
|
Delay *Range `protobuf:"bytes,5,opt,name=delay,proto3" json:"delay,omitempty"`
|
||||||
|
LogLevel *log.Severity `protobuf:"varint,6,opt,name=log_level,json=logLevel,proto3,enum=xray.common.log.Severity,oneof" json:"log_level,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
@@ -420,13 +422,20 @@ func (x *FinalRuleConfig) GetIp() []*geodata.IPRule {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *FinalRuleConfig) GetBlockDelay() *Range {
|
func (x *FinalRuleConfig) GetDelay() *Range {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.BlockDelay
|
return x.Delay
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *FinalRuleConfig) GetLogLevel() log.Severity {
|
||||||
|
if x != nil && x.LogLevel != nil {
|
||||||
|
return *x.LogLevel
|
||||||
|
}
|
||||||
|
return log.Severity(0)
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
DomainStrategy internet.DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.transport.internet.DomainStrategy" json:"domain_strategy,omitempty"`
|
DomainStrategy internet.DomainStrategy `protobuf:"varint,1,opt,name=domain_strategy,json=domainStrategy,proto3,enum=xray.transport.internet.DomainStrategy" json:"domain_strategy,omitempty"`
|
||||||
@@ -523,7 +532,7 @@ var File_proxy_freedom_config_proto protoreflect.FileDescriptor
|
|||||||
|
|
||||||
const file_proxy_freedom_config_proto_rawDesc = "" +
|
const file_proxy_freedom_config_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x15common/net/port.proto\x1a\x18common/net/network.proto\x1a\x1bcommon/geodata/geodat.proto\"S\n" +
|
"\x1aproxy/freedom/config.proto\x12\x12xray.proxy.freedom\x1a!common/protocol/server_spec.proto\x1a\x1ftransport/internet/config.proto\x1a\x15common/net/port.proto\x1a\x18common/net/network.proto\x1a\x1bcommon/geodata/geodat.proto\x1a\x14common/log/log.proto\"S\n" +
|
||||||
"\x13DestinationOverride\x12<\n" +
|
"\x13DestinationOverride\x12<\n" +
|
||||||
"\x06server\x18\x01 \x01(\v2$.xray.common.protocol.ServerEndpointR\x06server\"\x98\x02\n" +
|
"\x06server\x18\x01 \x01(\v2$.xray.common.protocol.ServerEndpointR\x06server\"\x98\x02\n" +
|
||||||
"\bFragment\x12!\n" +
|
"\bFragment\x12!\n" +
|
||||||
@@ -549,14 +558,16 @@ const file_proxy_freedom_config_proto_rawDesc = "" +
|
|||||||
"\bapply_to\x18\x06 \x01(\tR\aapplyTo\"+\n" +
|
"\bapply_to\x18\x06 \x01(\tR\aapplyTo\"+\n" +
|
||||||
"\x05Range\x12\x10\n" +
|
"\x05Range\x12\x10\n" +
|
||||||
"\x03min\x18\x01 \x01(\x04R\x03min\x12\x10\n" +
|
"\x03min\x18\x01 \x01(\x04R\x03min\x12\x10\n" +
|
||||||
"\x03max\x18\x02 \x01(\x04R\x03max\"\xa0\x02\n" +
|
"\x03max\x18\x02 \x01(\x04R\x03max\"\xe0\x02\n" +
|
||||||
"\x0fFinalRuleConfig\x126\n" +
|
"\x0fFinalRuleConfig\x126\n" +
|
||||||
"\x06action\x18\x01 \x01(\x0e2\x1e.xray.proxy.freedom.RuleActionR\x06action\x124\n" +
|
"\x06action\x18\x01 \x01(\x0e2\x1e.xray.proxy.freedom.RuleActionR\x06action\x124\n" +
|
||||||
"\bnetworks\x18\x02 \x03(\x0e2\x18.xray.common.net.NetworkR\bnetworks\x126\n" +
|
"\bnetworks\x18\x02 \x03(\x0e2\x18.xray.common.net.NetworkR\bnetworks\x126\n" +
|
||||||
"\tport_list\x18\x03 \x01(\v2\x19.xray.common.net.PortListR\bportList\x12+\n" +
|
"\tport_list\x18\x03 \x01(\v2\x19.xray.common.net.PortListR\bportList\x12+\n" +
|
||||||
"\x02ip\x18\x04 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x02ip\x12:\n" +
|
"\x02ip\x18\x04 \x03(\v2\x1b.xray.common.geodata.IPRuleR\x02ip\x12/\n" +
|
||||||
"\vblock_delay\x18\x05 \x01(\v2\x19.xray.proxy.freedom.RangeR\n" +
|
"\x05delay\x18\x05 \x01(\v2\x19.xray.proxy.freedom.RangeR\x05delay\x12;\n" +
|
||||||
"blockDelay\"\xaf\x03\n" +
|
"\tlog_level\x18\x06 \x01(\x0e2\x19.xray.common.log.SeverityH\x00R\blogLevel\x88\x01\x01B\f\n" +
|
||||||
|
"\n" +
|
||||||
|
"_log_level\"\xaf\x03\n" +
|
||||||
"\x06Config\x12P\n" +
|
"\x06Config\x12P\n" +
|
||||||
"\x0fdomain_strategy\x18\x01 \x01(\x0e2'.xray.transport.internet.DomainStrategyR\x0edomainStrategy\x12Z\n" +
|
"\x0fdomain_strategy\x18\x01 \x01(\x0e2'.xray.transport.internet.DomainStrategyR\x0edomainStrategy\x12Z\n" +
|
||||||
"\x14destination_override\x18\x03 \x01(\v2'.xray.proxy.freedom.DestinationOverrideR\x13destinationOverride\x12\x1d\n" +
|
"\x14destination_override\x18\x03 \x01(\v2'.xray.proxy.freedom.DestinationOverrideR\x13destinationOverride\x12\x1d\n" +
|
||||||
@@ -599,7 +610,8 @@ var file_proxy_freedom_config_proto_goTypes = []any{
|
|||||||
(net.Network)(0), // 8: xray.common.net.Network
|
(net.Network)(0), // 8: xray.common.net.Network
|
||||||
(*net.PortList)(nil), // 9: xray.common.net.PortList
|
(*net.PortList)(nil), // 9: xray.common.net.PortList
|
||||||
(*geodata.IPRule)(nil), // 10: xray.common.geodata.IPRule
|
(*geodata.IPRule)(nil), // 10: xray.common.geodata.IPRule
|
||||||
(internet.DomainStrategy)(0), // 11: xray.transport.internet.DomainStrategy
|
(log.Severity)(0), // 11: xray.common.log.Severity
|
||||||
|
(internet.DomainStrategy)(0), // 12: xray.transport.internet.DomainStrategy
|
||||||
}
|
}
|
||||||
var file_proxy_freedom_config_proto_depIdxs = []int32{
|
var file_proxy_freedom_config_proto_depIdxs = []int32{
|
||||||
7, // 0: xray.proxy.freedom.DestinationOverride.server:type_name -> xray.common.protocol.ServerEndpoint
|
7, // 0: xray.proxy.freedom.DestinationOverride.server:type_name -> xray.common.protocol.ServerEndpoint
|
||||||
@@ -607,17 +619,18 @@ var file_proxy_freedom_config_proto_depIdxs = []int32{
|
|||||||
8, // 2: xray.proxy.freedom.FinalRuleConfig.networks:type_name -> xray.common.net.Network
|
8, // 2: xray.proxy.freedom.FinalRuleConfig.networks:type_name -> xray.common.net.Network
|
||||||
9, // 3: xray.proxy.freedom.FinalRuleConfig.port_list:type_name -> xray.common.net.PortList
|
9, // 3: xray.proxy.freedom.FinalRuleConfig.port_list:type_name -> xray.common.net.PortList
|
||||||
10, // 4: xray.proxy.freedom.FinalRuleConfig.ip:type_name -> xray.common.geodata.IPRule
|
10, // 4: xray.proxy.freedom.FinalRuleConfig.ip:type_name -> xray.common.geodata.IPRule
|
||||||
4, // 5: xray.proxy.freedom.FinalRuleConfig.block_delay:type_name -> xray.proxy.freedom.Range
|
4, // 5: xray.proxy.freedom.FinalRuleConfig.delay:type_name -> xray.proxy.freedom.Range
|
||||||
11, // 6: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
|
11, // 6: xray.proxy.freedom.FinalRuleConfig.log_level:type_name -> xray.common.log.Severity
|
||||||
1, // 7: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride
|
12, // 7: xray.proxy.freedom.Config.domain_strategy:type_name -> xray.transport.internet.DomainStrategy
|
||||||
2, // 8: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment
|
1, // 8: xray.proxy.freedom.Config.destination_override:type_name -> xray.proxy.freedom.DestinationOverride
|
||||||
3, // 9: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise
|
2, // 9: xray.proxy.freedom.Config.fragment:type_name -> xray.proxy.freedom.Fragment
|
||||||
5, // 10: xray.proxy.freedom.Config.final_rules:type_name -> xray.proxy.freedom.FinalRuleConfig
|
3, // 10: xray.proxy.freedom.Config.noises:type_name -> xray.proxy.freedom.Noise
|
||||||
11, // [11:11] is the sub-list for method output_type
|
5, // 11: xray.proxy.freedom.Config.final_rules:type_name -> xray.proxy.freedom.FinalRuleConfig
|
||||||
11, // [11:11] is the sub-list for method input_type
|
12, // [12:12] is the sub-list for method output_type
|
||||||
11, // [11:11] is the sub-list for extension type_name
|
12, // [12:12] is the sub-list for method input_type
|
||||||
11, // [11:11] is the sub-list for extension extendee
|
12, // [12:12] is the sub-list for extension type_name
|
||||||
0, // [0:11] is the sub-list for field type_name
|
12, // [12:12] is the sub-list for extension extendee
|
||||||
|
0, // [0:12] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_proxy_freedom_config_proto_init() }
|
func init() { file_proxy_freedom_config_proto_init() }
|
||||||
@@ -625,6 +638,7 @@ func file_proxy_freedom_config_proto_init() {
|
|||||||
if File_proxy_freedom_config_proto != nil {
|
if File_proxy_freedom_config_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
file_proxy_freedom_config_proto_msgTypes[4].OneofWrappers = []any{}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import "transport/internet/config.proto";
|
|||||||
import "common/net/port.proto";
|
import "common/net/port.proto";
|
||||||
import "common/net/network.proto";
|
import "common/net/network.proto";
|
||||||
import "common/geodata/geodat.proto";
|
import "common/geodata/geodat.proto";
|
||||||
|
import "common/log/log.proto";
|
||||||
|
|
||||||
message DestinationOverride {
|
message DestinationOverride {
|
||||||
xray.common.protocol.ServerEndpoint server = 1;
|
xray.common.protocol.ServerEndpoint server = 1;
|
||||||
@@ -51,7 +52,8 @@ message FinalRuleConfig {
|
|||||||
repeated xray.common.net.Network networks = 2;
|
repeated xray.common.net.Network networks = 2;
|
||||||
xray.common.net.PortList port_list = 3;
|
xray.common.net.PortList port_list = 3;
|
||||||
repeated xray.common.geodata.IPRule ip = 4;
|
repeated xray.common.geodata.IPRule ip = 4;
|
||||||
Range block_delay = 5;
|
Range delay = 5;
|
||||||
|
optional xray.common.log.Severity log_level = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Config {
|
message Config {
|
||||||
|
|||||||
+32
-10
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/xtls/xray-core/common/dice"
|
"github.com/xtls/xray-core/common/dice"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/geodata"
|
"github.com/xtls/xray-core/common/geodata"
|
||||||
|
"github.com/xtls/xray-core/common/log"
|
||||||
"github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/platform"
|
"github.com/xtls/xray-core/common/platform"
|
||||||
"github.com/xtls/xray-core/common/retry"
|
"github.com/xtls/xray-core/common/retry"
|
||||||
@@ -75,11 +76,13 @@ func init() {
|
|||||||
action: RuleAction_Block,
|
action: RuleAction_Block,
|
||||||
network: allNetworks,
|
network: allNetworks,
|
||||||
ip: geodata.GetPrivateIPMatcher(),
|
ip: geodata.GetPrivateIPMatcher(),
|
||||||
|
logLevel: log.Severity_Warning.Enum(),
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultBlockAllRule = &FinalRule{
|
defaultBlockAllRule = &FinalRule{
|
||||||
action: RuleAction_Block,
|
action: RuleAction_Block,
|
||||||
network: allNetworks,
|
network: allNetworks,
|
||||||
|
logLevel: log.Severity_Warning.Enum(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +91,8 @@ type FinalRule struct {
|
|||||||
network [8]bool
|
network [8]bool
|
||||||
port net.MemoryPortList
|
port net.MemoryPortList
|
||||||
ip geodata.IPMatcher
|
ip geodata.IPMatcher
|
||||||
blockDelay *Range
|
delay *Range
|
||||||
|
logLevel *log.Severity
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler handles Freedom connections.
|
// Handler handles Freedom connections.
|
||||||
@@ -103,7 +107,8 @@ type Handler struct {
|
|||||||
func buildFinalRule(config *FinalRuleConfig) (*FinalRule, error) {
|
func buildFinalRule(config *FinalRuleConfig) (*FinalRule, error) {
|
||||||
rule := &FinalRule{
|
rule := &FinalRule{
|
||||||
action: config.GetAction(),
|
action: config.GetAction(),
|
||||||
blockDelay: config.GetBlockDelay(),
|
delay: config.GetDelay(),
|
||||||
|
logLevel: config.LogLevel,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(config.Networks) == 0 {
|
if len(config.Networks) == 0 {
|
||||||
@@ -164,7 +169,7 @@ func getDefaultFinalRule(inbound *session.Inbound) *FinalRule {
|
|||||||
switch inbound.Name {
|
switch inbound.Name {
|
||||||
case "vless-reverse":
|
case "vless-reverse":
|
||||||
return defaultBlockAllRule
|
return defaultBlockAllRule
|
||||||
case "vless", "vmess", "trojan", "hysteria", "wireguard":
|
case "vless", "vmess", "trojan", "hysteria", "wireguard", "masque":
|
||||||
return defaultBlockPrivateRule
|
return defaultBlockPrivateRule
|
||||||
default:
|
default:
|
||||||
if strings.HasPrefix(inbound.Name, "shadowsocks") {
|
if strings.HasPrefix(inbound.Name, "shadowsocks") {
|
||||||
@@ -212,12 +217,12 @@ func (h *Handler) policy() policy.Session {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) blockDelay(rule *FinalRule) time.Duration {
|
func (r *FinalRule) blockDuration() time.Duration {
|
||||||
min := uint64(30)
|
min := uint64(30)
|
||||||
max := uint64(90)
|
max := uint64(90)
|
||||||
if rule.blockDelay != nil {
|
if r.delay != nil {
|
||||||
min = rule.blockDelay.Min
|
min = r.delay.Min
|
||||||
max = rule.blockDelay.Max
|
max = r.delay.Max
|
||||||
}
|
}
|
||||||
span := max - min
|
span := max - min
|
||||||
if max < min {
|
if max < min {
|
||||||
@@ -226,9 +231,26 @@ func (h *Handler) blockDelay(rule *FinalRule) time.Duration {
|
|||||||
return time.Duration(min+uint64(dice.Roll(int(span+1)))) * time.Second
|
return time.Duration(min+uint64(dice.Roll(int(span+1)))) * time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *FinalRule) log(ctx context.Context, msg ...interface{}) {
|
||||||
|
level := log.Severity_Info
|
||||||
|
if r.logLevel != nil {
|
||||||
|
level = *r.logLevel
|
||||||
|
}
|
||||||
|
switch level {
|
||||||
|
case log.Severity_Debug:
|
||||||
|
errors.LogDebug(ctx, msg...)
|
||||||
|
case log.Severity_Info:
|
||||||
|
errors.LogInfo(ctx, msg...)
|
||||||
|
case log.Severity_Warning:
|
||||||
|
errors.LogWarning(ctx, msg...)
|
||||||
|
case log.Severity_Error:
|
||||||
|
errors.LogError(ctx, msg...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handler) blackhole(ctx context.Context, input buf.Reader, output buf.Writer, rule *FinalRule, dest *net.Destination) error {
|
func (h *Handler) blackhole(ctx context.Context, input buf.Reader, output buf.Writer, rule *FinalRule, dest *net.Destination) error {
|
||||||
delay := h.blockDelay(rule)
|
delay := rule.blockDuration()
|
||||||
errors.LogInfo(ctx, "blocked target: ", *dest, ", blackholing connection for ", delay)
|
rule.log(ctx, "target blocked by a finalrule: ", *dest, ", blackholing connection for ", delay)
|
||||||
defer common.Close(output)
|
defer common.Close(output)
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
go func() { // a DispatchLink inbound's reader ignores Interrupt, so don't wait for this copy
|
go func() { // a DispatchLink inbound's reader ignores Interrupt, so don't wait for this copy
|
||||||
@@ -240,7 +262,7 @@ func (h *Handler) blackhole(ctx context.Context, input buf.Reader, output buf.Wr
|
|||||||
case <-time.After(delay):
|
case <-time.After(delay):
|
||||||
common.Interrupt(input)
|
common.Interrupt(input)
|
||||||
common.Interrupt(output)
|
common.Interrupt(output)
|
||||||
errors.LogInfo(ctx, "closed blackholed connection to blocked target: ", *dest)
|
rule.log(ctx, "closed blackholed connection to blocked target: ", *dest)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,12 @@ startOver:
|
|||||||
}
|
}
|
||||||
err = t.luid.SetDNS(family, dns, nil)
|
err = t.luid.SetDNS(family, dns, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// Skip IPv6 the config does not ask for also when setting its DNS
|
||||||
|
// servers fails, as reported on Windows 11 24H2 with IPv6 disabled
|
||||||
|
// (Access is denied).
|
||||||
|
if family == windows.AF_INET6 && !address6 && !route6 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
firstErr = errors.New("unable to set DNS").Base(err)
|
firstErr = errors.New("unable to set DNS").Base(err)
|
||||||
if err == windows.ERROR_NOT_FOUND {
|
if err == windows.ERROR_NOT_FOUND {
|
||||||
goto startOver
|
goto startOver
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import (
|
|||||||
|
|
||||||
type bind struct {
|
type bind struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
resolveFunc func(host string) (net.IP, error)
|
resolveFunc func(ctx context.Context, host string) (net.IP, error)
|
||||||
listenFunc func(ctx context.Context) (net.PacketConn, error)
|
listenFunc func(ctx context.Context) (net.PacketConn, error)
|
||||||
downFunc func() error
|
downFunc func() error
|
||||||
reserved []byte
|
reserved []byte
|
||||||
@@ -143,7 +143,11 @@ func (b *bind) ParseEndpoint(s string) (conn.Endpoint, error) {
|
|||||||
if port < 0 || port > 65535 {
|
if port < 0 || port > 65535 {
|
||||||
return nil, errors.New("invalid port " + sport)
|
return nil, errors.New("invalid port " + sport)
|
||||||
}
|
}
|
||||||
ip, err := b.resolveFunc(host)
|
// up sets the connection's context right before it hands over the endpoint
|
||||||
|
b.mu.Lock()
|
||||||
|
ctx := b.ctx
|
||||||
|
b.mu.Unlock()
|
||||||
|
ip, err := b.resolveFunc(ctx, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,12 +323,12 @@ func (h *Handler) up(ctx context.Context) error {
|
|||||||
return h.dev.Up()
|
return h.dev.Up()
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeResolveLocal(d dns.Client, streamSettings *internet.MemoryStreamConfig) func(host string) (net.IP, error) {
|
func MakeResolveLocal(d dns.Client, streamSettings *internet.MemoryStreamConfig) func(ctx context.Context, host string) (net.IP, error) {
|
||||||
return func(host string) (net.IP, error) {
|
return func(ctx context.Context, host string) (net.IP, error) {
|
||||||
if ip := net.ParseIP(host); ip != nil {
|
if ip := net.ParseIP(host); ip != nil {
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
ips, _, err := d.LookupIP(host, dns.IPOption{IPv4Enable: true, IPv6Enable: true})
|
ips, err := lookupIPContext(ctx, d, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -368,6 +368,27 @@ func MakeResolveLocal(d dns.Client, streamSettings *internet.MemoryStreamConfig)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lookupIPContext(ctx context.Context, d dns.Client, host string) ([]net.IP, error) {
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
type result struct {
|
||||||
|
ips []net.IP
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
done := make(chan result, 1)
|
||||||
|
go func() {
|
||||||
|
ips, _, err := d.LookupIP(host, dns.IPOption{IPv4Enable: true, IPv6Enable: true})
|
||||||
|
done <- result{ips, err}
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case r := <-done:
|
||||||
|
return r.ips, r.err
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type UDPConnClient struct {
|
type UDPConnClient struct {
|
||||||
net.PacketConn
|
net.PacketConn
|
||||||
Dest *net.UDPAddr
|
Dest *net.UDPAddr
|
||||||
|
|||||||
@@ -661,7 +661,7 @@ func TestVlessRealityFingerprints(t *testing.T) {
|
|||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A blocked connection must be closed after blockDelay even while the client keeps it open and sends nothing.
|
// A blocked connection must close after finalRules.delay even while the client keeps it open and sends nothing.
|
||||||
func TestVlessBlockDelay(t *testing.T) {
|
func TestVlessBlockDelay(t *testing.T) {
|
||||||
tcpServer := tcp.Server{
|
tcpServer := tcp.Server{
|
||||||
MsgProcessor: xor,
|
MsgProcessor: xor,
|
||||||
@@ -671,7 +671,7 @@ func TestVlessBlockDelay(t *testing.T) {
|
|||||||
defer tcpServer.Close()
|
defer tcpServer.Close()
|
||||||
|
|
||||||
for _, delay := range []uint64{0, 1} {
|
for _, delay := range []uint64{0, 1} {
|
||||||
t.Run(fmt.Sprint("blockDelay=", delay), func(t *testing.T) {
|
t.Run(fmt.Sprint("delay=", delay), func(t *testing.T) {
|
||||||
userID := protocol.NewID(uuid.New())
|
userID := protocol.NewID(uuid.New())
|
||||||
serverPort := tcp.PickPort()
|
serverPort := tcp.PickPort()
|
||||||
serverConfig := &core.Config{
|
serverConfig := &core.Config{
|
||||||
@@ -698,7 +698,7 @@ func TestVlessBlockDelay(t *testing.T) {
|
|||||||
FinalRules: []*freedom.FinalRuleConfig{
|
FinalRules: []*freedom.FinalRuleConfig{
|
||||||
{
|
{
|
||||||
Action: freedom.RuleAction_Block,
|
Action: freedom.RuleAction_Block,
|
||||||
BlockDelay: &freedom.Range{Min: delay, Max: delay},
|
Delay: &freedom.Range{Min: delay, Max: delay},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
@@ -726,15 +726,15 @@ func TestVlessBlockDelay(t *testing.T) {
|
|||||||
Port: dest.Port,
|
Port: dest.Port,
|
||||||
}, &encoding.Addons{}))
|
}, &encoding.Addons{}))
|
||||||
|
|
||||||
blockDelay := time.Duration(delay) * time.Second
|
blockDuration := time.Duration(delay) * time.Second
|
||||||
common.Must(conn.SetReadDeadline(time.Now().Add(blockDelay + 5*time.Second)))
|
common.Must(conn.SetReadDeadline(time.Now().Add(blockDuration + 5*time.Second)))
|
||||||
_, err = io.Copy(io.Discard, conn)
|
_, err = io.Copy(io.Discard, conn)
|
||||||
elapsed := time.Since(start)
|
elapsed := time.Since(start)
|
||||||
if err, ok := err.(net.Error); ok && err.Timeout() {
|
if err, ok := err.(net.Error); ok && err.Timeout() {
|
||||||
t.Fatalf("connection is still open after %v", elapsed)
|
t.Fatalf("connection is still open after %v", elapsed)
|
||||||
}
|
}
|
||||||
if elapsed < blockDelay {
|
if elapsed < blockDuration {
|
||||||
t.Fatalf("connection is closed after %v, before blockDelay", elapsed)
|
t.Fatalf("connection is closed after %v, before finalRules.delay", elapsed)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
goerrors "errors"
|
goerrors "errors"
|
||||||
"io"
|
"io"
|
||||||
mrand "math/rand"
|
mrand "math/rand"
|
||||||
|
stdnet "net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -164,7 +165,7 @@ func (c *udpHopConn) recv(conn net.PacketConn) {
|
|||||||
n, addr, err := conn.ReadFrom(p)
|
n, addr, err := conn.ReadFrom(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pool.Put(p[:cap(p)])
|
pool.Put(p[:cap(p)])
|
||||||
if c.closed() {
|
if c.closed() || goerrors.Is(err, stdnet.ErrClosed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var netErr net.Error
|
var netErr net.Error
|
||||||
|
|||||||
Reference in New Issue
Block a user