Compare commits

...
2 Commits
4 changed files with 30 additions and 74 deletions
+6 -16
View File
@@ -103,7 +103,10 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
ctx = session.ContextWithFullHandler(ctx, h)
newCtx := session.ContextWithStreamSettings(ctx, h.streamSettings)
newCtx := ctx
if h.streamSettings != nil {
newCtx = session.ContextWithStreamSettings(newCtx, h.streamSettings)
}
rawProxyHandler, err := common.CreateObject(newCtx, proxyConfig)
if err != nil {
@@ -263,20 +266,6 @@ func (h *Handler) DestIpAddress() net.IP {
return internet.DestIpAddress()
}
func (h *Handler) ResolveStrategy() internet.DomainStrategy {
if h.senderSettings != nil && h.senderSettings.TargetStrategy.HasStrategy() {
return h.senderSettings.TargetStrategy
}
if h.streamSettings != nil && h.streamSettings.SocketSettings != nil {
return h.streamSettings.SocketSettings.DomainStrategy
}
return internet.DomainStrategy_AS_IS
}
func (h *Handler) UsesDialerProxy() bool {
return h.streamSettings != nil && h.streamSettings.SocketSettings != nil && len(h.streamSettings.SocketSettings.DialerProxy) > 0
}
// Dial implements internet.Dialer.
func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connection, error) {
if h.senderSettings != nil && h.senderSettings.Via != nil {
@@ -298,7 +287,8 @@ func (h *Handler) Dial(ctx context.Context, dest net.Destination) (stat.Connecti
}
func (h *Handler) SetOutboundGateway(ctx context.Context, ob *session.Outbound) {
if ob.Gateway == nil && h.senderSettings != nil && h.senderSettings.Via != nil && !h.UsesDialerProxy() {
if ob.Gateway == nil && h.senderSettings != nil && h.senderSettings.Via != nil &&
(h.streamSettings.SocketSettings == nil || len(h.streamSettings.SocketSettings.DialerProxy) == 0) {
var domain string
addr := h.senderSettings.Via.AsAddress()
domain = h.senderSettings.Via.GetDomain()
-1
View File
@@ -27,7 +27,6 @@ type FreedomConfig struct {
ProxyProtocol uint32 `json:"proxyProtocol"`
IPsBlocked *StringList `json:"ipsBlocked"`
FinalRules []*FreedomFinalRuleConfig `json:"finalRules"`
PrivacyGuard *bool `json:"privacyGuard"`
}
type Fragment struct {
+18 -40
View File
@@ -337,50 +337,28 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
return nil, errors.New("failed to build outbound handler for protocol ", c.Protocol).Base(err)
}
if _, ok := ts.(*freedom.Config); ok &&
senderSettings.StreamSettings != nil &&
senderSettings.StreamSettings.SocketSettings != nil &&
senderSettings.StreamSettings.SocketSettings.AddressPortStrategy != internet.AddressPortStrategy_None {
return nil, errors.New(`freedom outbound does not support "sockopt.addressPortStrategy"`)
}
if fc, ok := ts.(*freedom.Config); ok {
if senderSettings.StreamSettings != nil &&
senderSettings.StreamSettings.SocketSettings != nil &&
senderSettings.StreamSettings.SocketSettings.AddressPortStrategy != internet.AddressPortStrategy_None {
return nil, errors.New(`freedom outbound does not support "sockopt.addressPortStrategy"`)
}
if fc, ok := ts.(*freedom.Config); ok && fc.DomainStrategy != internet.DomainStrategy_AS_IS {
errors.PrintDeprecatedFeatureWarning("freedom.domainStrategy", "sockopt.domainStrategy or targetStrategy")
if senderSettings.StreamSettings == nil {
senderSettings.StreamSettings = &internet.StreamConfig{}
var strategy internet.DomainStrategy
if strategy = senderSettings.TargetStrategy; strategy != internet.DomainStrategy_AS_IS {
errors.LogWarning(context.Background(), `The "outbound.targetStrategy" setting is not supported directly by freedom and has been automatically migrated to "sockopt.domainStrategy" with no behavior change.`)
senderSettings.TargetStrategy = internet.DomainStrategy_AS_IS
} else if strategy = fc.DomainStrategy; strategy != internet.DomainStrategy_AS_IS {
errors.LogWarning(context.Background(), `The "freedom.domainStrategy" setting is deprecated and will be removed. For compatibility, its value has been automatically migrated to "sockopt.domainStrategy". Please update your config before removal.`)
}
if senderSettings.StreamSettings.SocketSettings == nil {
senderSettings.StreamSettings.SocketSettings = &internet.SocketConfig{}
}
senderSettings.StreamSettings.SocketSettings.DomainStrategy = fc.DomainStrategy
}
if fc, ok := rawConfig.(*FreedomConfig); ok && (fc.PrivacyGuard == nil || *fc.PrivacyGuard) {
if senderSettings.StreamSettings == nil {
senderSettings.StreamSettings = &internet.StreamConfig{}
}
if senderSettings.StreamSettings.SocketSettings == nil {
senderSettings.StreamSettings.SocketSettings = &internet.SocketConfig{}
}
if fc.PrivacyGuard == nil {
if senderSettings.TargetStrategy == internet.DomainStrategy_AS_IS &&
senderSettings.StreamSettings.SocketSettings.DomainStrategy == internet.DomainStrategy_AS_IS {
senderSettings.StreamSettings.SocketSettings.DomainStrategy = internet.DomainStrategy_USE_IP46
if strategy != internet.DomainStrategy_AS_IS {
if senderSettings.StreamSettings == nil {
senderSettings.StreamSettings = &internet.StreamConfig{}
}
} else if *fc.PrivacyGuard {
if senderSettings.StreamSettings.SocketSettings.DomainStrategy != internet.DomainStrategy_USE_IP4 &&
senderSettings.StreamSettings.SocketSettings.DomainStrategy != internet.DomainStrategy_USE_IP46 &&
senderSettings.StreamSettings.SocketSettings.DomainStrategy != internet.DomainStrategy_FORCE_IP4 &&
senderSettings.StreamSettings.SocketSettings.DomainStrategy != internet.DomainStrategy_FORCE_IP46 {
if senderSettings.StreamSettings.SocketSettings.DomainStrategy != internet.DomainStrategy_AS_IS {
errors.LogWarning(context.Background(), `The "freedom" outbound "privacyGuard" overrides the existing "sockopt.domainStrategy". Please update your config(s) if this is unintended.`)
}
senderSettings.StreamSettings.SocketSettings.DomainStrategy = internet.DomainStrategy_USE_IP46
}
if senderSettings.TargetStrategy != internet.DomainStrategy_AS_IS {
errors.LogWarning(context.Background(), `The "freedom" outbound "privacyGuard" overrides the existing "targetStrategy". Please update your config(s) if this is unintended.`)
senderSettings.TargetStrategy = internet.DomainStrategy_AS_IS
if senderSettings.StreamSettings.SocketSettings == nil {
senderSettings.StreamSettings.SocketSettings = &internet.SocketConfig{}
}
senderSettings.StreamSettings.SocketSettings.DomainStrategy = strategy
}
}
+6 -17
View File
@@ -40,11 +40,9 @@ var (
func init() {
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) {
h := new(Handler)
if handler, ok := session.FullHandlerFromContext(ctx).(handlerWithResolveStrategy); ok {
h.resolveStrategy = handler.ResolveStrategy()
}
if handler, ok := session.FullHandlerFromContext(ctx).(handlerWithDialerProxy); ok {
h.usesDialerProxy = handler.UsesDialerProxy()
if streamSettings, ok := session.StreamSettingsFromContext(ctx).(*internet.MemoryStreamConfig); ok && streamSettings.SocketSettings != nil {
h.resolveStrategy = streamSettings.SocketSettings.DomainStrategy
h.usesDialerProxy = len(streamSettings.SocketSettings.DialerProxy) > 0
}
if err := core.RequireFeatures(ctx, func(pm policy.Manager) error {
return h.Init(config.(*Config), pm)
@@ -77,14 +75,6 @@ func init() {
}
}
type handlerWithResolveStrategy interface {
ResolveStrategy() internet.DomainStrategy
}
type handlerWithDialerProxy interface {
UsesDialerProxy() bool
}
type FinalRule struct {
action RuleAction
network [8]bool
@@ -288,7 +278,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if defaultRule != nil || len(h.finalRules) > 0 {
if strategy := h.resolveStrategy; strategy.HasStrategy() {
ips, err := internet.LookupForIP(destination.Address.Domain(), strategy, outGateway)
if err != nil { // SRV/TXT
if err != nil { // non-force may still dial with system DNS
errors.LogInfoInner(ctx, err, "failed to get IP address for domain ", destination.Address.Domain())
if strategy.ForceIP() {
return err // retry
@@ -306,7 +296,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
}
} else {
addrs, err := net.DefaultResolver.LookupIPAddr(ctx, destination.Address.Domain())
if err != nil { // SRV/TXT
if err != nil { // dialer may retry DNS
errors.LogInfoInner(ctx, err, "failed to get IP address for domain ", destination.Address.Domain())
}
for _, addr := range addrs {
@@ -347,7 +337,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
if h.usesDialerProxy {
errors.LogInfo(ctx, "skipping final rule check for proxied remote endpoint, original target: ", destination)
} else {
// SRV/TXT, lookup failed
// pre-check may fail or dialer may select another IP
remoteDest := net.DestinationFromAddr(conn.RemoteAddr())
if rule := h.matchFinalRule(remoteDest.Network, remoteDest.Address, remoteDest.Port, defaultRule); rule != nil && rule.action == RuleAction_Block {
conn.Close()
@@ -555,7 +545,6 @@ func NewPacketWriter(conn net.Conn, h *Handler, defaultRule *FinalRule, UDPOverr
ResolvedUDPAddr: resolvedUDPAddr,
OutGateway: outGateway,
}
}
return &buf.SequentialWriter{Writer: conn}
}