@@ -95,7 +95,7 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
9595 if deadline .NeedAdditionalReadDeadline (conn ) {
9696 conn = deadline .NewConn (conn )
9797 }
98- selectedRule , _ , buffers , _ , err := r .matchRule (ctx , & metadata , false , conn , nil )
98+ selectedRule , _ , buffers , _ , err := r .matchRule (ctx , & metadata , false , false , conn , nil )
9999 if err != nil {
100100 return err
101101 }
@@ -114,6 +114,9 @@ func (r *Router) routeConnection(ctx context.Context, conn net.Conn, metadata ad
114114 return E .New ("TCP is not supported by outbound: " , selectedOutbound .Tag ())
115115 }
116116 case * R.RuleActionBypass :
117+ if action .Outbound == "" {
118+ break
119+ }
117120 var loaded bool
118121 selectedOutbound , loaded = r .outbound .Outbound (action .Outbound )
119122 if ! loaded {
@@ -223,7 +226,7 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
223226 conn = deadline.NewPacketConn(bufio.NewNetPacketConn(conn))
224227 }*/
225228
226- selectedRule , _ , _ , packetBuffers , err := r .matchRule (ctx , & metadata , false , nil , conn )
229+ selectedRule , _ , _ , packetBuffers , err := r .matchRule (ctx , & metadata , false , false , nil , conn )
227230 if err != nil {
228231 return err
229232 }
@@ -243,6 +246,9 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
243246 return E .New ("UDP is not supported by outbound: " , selectedOutbound .Tag ())
244247 }
245248 case * R.RuleActionBypass :
249+ if action .Outbound == "" {
250+ break
251+ }
246252 var loaded bool
247253 selectedOutbound , loaded = r .outbound .Outbound (action .Outbound )
248254 if ! loaded {
@@ -289,8 +295,8 @@ func (r *Router) routePacketConnection(ctx context.Context, conn N.PacketConn, m
289295 return nil
290296}
291297
292- func (r * Router ) PreMatch (metadata adapter.InboundContext , routeContext tun.DirectRouteContext , timeout time.Duration ) (tun.DirectRouteDestination , error ) {
293- selectedRule , _ , _ , _ , err := r .matchRule (r .ctx , & metadata , true , nil , nil )
298+ func (r * Router ) PreMatch (metadata adapter.InboundContext , routeContext tun.DirectRouteContext , timeout time.Duration , supportBypass bool ) (tun.DirectRouteDestination , error ) {
299+ selectedRule , _ , _ , _ , err := r .matchRule (r .ctx , & metadata , true , supportBypass , nil , nil )
294300 if err != nil {
295301 return nil , err
296302 }
@@ -310,7 +316,20 @@ func (r *Router) PreMatch(metadata adapter.InboundContext, routeContext tun.Dire
310316 }
311317 return nil , action .Error (context .Background ())
312318 case * R.RuleActionBypass :
313- return nil , & R.BypassedError {Cause : tun .ErrBypass }
319+ if supportBypass {
320+ return nil , & R.BypassedError {Cause : tun .ErrBypass }
321+ }
322+ if routeContext == nil {
323+ return nil , nil
324+ }
325+ outbound , loaded := r .outbound .Outbound (action .Outbound )
326+ if ! loaded {
327+ return nil , E .New ("outbound not found: " , action .Outbound )
328+ }
329+ if ! common .Contains (outbound .Network (), metadata .Network ) {
330+ return nil , E .New (metadata .Network , " is not supported by outbound: " , action .Outbound )
331+ }
332+ directRouteOutbound = outbound .(adapter.DirectRouteOutbound )
314333 case * R.RuleActionRoute :
315334 if routeContext == nil {
316335 return nil , nil
@@ -388,7 +407,7 @@ func (r *Router) PreMatch(metadata adapter.InboundContext, routeContext tun.Dire
388407}
389408
390409func (r * Router ) matchRule (
391- ctx context.Context , metadata * adapter.InboundContext , preMatch bool ,
410+ ctx context.Context , metadata * adapter.InboundContext , preMatch bool , supportBypass bool ,
392411 inputConn net.Conn , inputPacketConn N.PacketConn ,
393412) (
394413 selectedRule adapter.Rule , selectedRuleIndex int ,
@@ -591,8 +610,16 @@ match:
591610 actionType := currentRule .Action ().Type ()
592611 if actionType == C .RuleActionTypeRoute ||
593612 actionType == C .RuleActionTypeReject ||
594- actionType == C .RuleActionTypeHijackDNS ||
595- actionType == C .RuleActionTypeBypass {
613+ actionType == C .RuleActionTypeHijackDNS {
614+ selectedRule = currentRule
615+ selectedRuleIndex = currentRuleIndex
616+ break match
617+ }
618+ if actionType == C .RuleActionTypeBypass {
619+ bypassAction := currentRule .Action ().(* R.RuleActionBypass )
620+ if ! supportBypass && bypassAction .Outbound == "" {
621+ continue match
622+ }
596623 selectedRule = currentRule
597624 selectedRuleIndex = currentRuleIndex
598625 break match
0 commit comments