package main import ( "net/netip" "testing" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-shadowsocks/shadowaead_2022" ) func TestChainedInbound(t *testing.T) { method := shadowaead_2022.List[0] password := mkBase64(t, 16) startInstance(t, option.Options{ Inbounds: []option.LegacyInbound{ { Type: C.TypeMixed, Tag: "mixed-in", MixedOptions: option.HTTPMixedInboundOptions{ ListenOptions: option.ListenOptions{ Listen: option.NewListenAddress(netip.IPv4Unspecified()), ListenPort: clientPort, }, }, }, { Type: C.TypeShadowsocks, ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ Listen: option.NewListenAddress(netip.IPv4Unspecified()), ListenPort: serverPort, Detour: "detour", }, Method: method, Password: password, }, }, { Type: C.TypeShadowsocks, Tag: "detour", ShadowsocksOptions: option.ShadowsocksInboundOptions{ ListenOptions: option.ListenOptions{ Listen: option.NewListenAddress(netip.IPv4Unspecified()), ListenPort: otherPort, }, Method: method, Password: password, }, }, }, LegacyOutbounds: []option.LegacyOutbound{ { Type: C.TypeDirect, }, { Type: C.TypeShadowsocks, Tag: "ss-out", ShadowsocksOptions: option.ShadowsocksOutboundOptions{ Method: method, Password: password, DialerOptions: option.DialerOptions{ Detour: "detour-out", }, }, }, { Type: C.TypeShadowsocks, Tag: "detour-out", ShadowsocksOptions: option.ShadowsocksOutboundOptions{ ServerOptions: option.ServerOptions{ Server: "127.0.0.1", ServerPort: serverPort, }, Method: method, Password: password, }, }, }, Route: &option.RouteOptions{ Rules: []option.Rule{ { Type: C.RuleTypeDefault, DefaultOptions: option.DefaultRule{ RawDefaultRule: option.RawDefaultRule{ Inbound: []string{"mixed-in"}, }, RuleAction: option.RuleAction{ Action: C.RuleActionTypeRoute, RouteOptions: option.RouteActionOptions{ Outbound: "ss-out", }, }, }, }, }, }, }) testTCP(t, clientPort, testPort) }