router_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. package router_test
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/golang/mock/gomock"
  6. . "github.com/v2fly/v2ray-core/v5/app/router"
  7. "github.com/v2fly/v2ray-core/v5/app/router/routercommon"
  8. "github.com/v2fly/v2ray-core/v5/common"
  9. "github.com/v2fly/v2ray-core/v5/common/net"
  10. "github.com/v2fly/v2ray-core/v5/common/session"
  11. "github.com/v2fly/v2ray-core/v5/features/outbound"
  12. routing_session "github.com/v2fly/v2ray-core/v5/features/routing/session"
  13. "github.com/v2fly/v2ray-core/v5/testing/mocks"
  14. )
  15. type mockOutboundManager struct {
  16. outbound.Manager
  17. outbound.HandlerSelector
  18. }
  19. func TestSimpleRouter(t *testing.T) {
  20. config := &Config{
  21. Rule: []*RoutingRule{
  22. {
  23. TargetTag: &RoutingRule_Tag{
  24. Tag: "test",
  25. },
  26. Networks: []net.Network{net.Network_TCP},
  27. },
  28. },
  29. }
  30. mockCtl := gomock.NewController(t)
  31. defer mockCtl.Finish()
  32. mockDNS := mocks.NewDNSClient(mockCtl)
  33. mockOhm := mocks.NewOutboundManager(mockCtl)
  34. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  35. r := new(Router)
  36. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  37. Manager: mockOhm,
  38. HandlerSelector: mockHs,
  39. }, nil))
  40. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  41. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  42. common.Must(err)
  43. if tag := route.GetOutboundTag(); tag != "test" {
  44. t.Error("expect tag 'test', bug actually ", tag)
  45. }
  46. }
  47. func TestSimpleBalancer(t *testing.T) {
  48. config := &Config{
  49. Rule: []*RoutingRule{
  50. {
  51. TargetTag: &RoutingRule_BalancingTag{
  52. BalancingTag: "balance",
  53. },
  54. Networks: []net.Network{net.Network_TCP},
  55. },
  56. },
  57. BalancingRule: []*BalancingRule{
  58. {
  59. Tag: "balance",
  60. OutboundSelector: []string{"test-"},
  61. },
  62. },
  63. }
  64. mockCtl := gomock.NewController(t)
  65. defer mockCtl.Finish()
  66. mockDNS := mocks.NewDNSClient(mockCtl)
  67. mockOhm := mocks.NewOutboundManager(mockCtl)
  68. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  69. mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"})
  70. r := new(Router)
  71. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  72. Manager: mockOhm,
  73. HandlerSelector: mockHs,
  74. }, nil))
  75. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  76. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  77. common.Must(err)
  78. if tag := route.GetOutboundTag(); tag != "test" {
  79. t.Error("expect tag 'test', bug actually ", tag)
  80. }
  81. }
  82. /*
  83. Do not work right now: need a full client setup
  84. func TestLeastLoadBalancer(t *testing.T) {
  85. config := &Config{
  86. Rule: []*RoutingRule{
  87. {
  88. TargetTag: &RoutingRule_BalancingTag{
  89. BalancingTag: "balance",
  90. },
  91. Networks: []net.Network{net.Network_TCP},
  92. },
  93. },
  94. BalancingRule: []*BalancingRule{
  95. {
  96. Tag: "balance",
  97. OutboundSelector: []string{"test-"},
  98. Strategy: "leastLoad",
  99. StrategySettings: serial.ToTypedMessage(&StrategyLeastLoadConfig{
  100. Baselines: nil,
  101. Expected: 1,
  102. }),
  103. },
  104. },
  105. }
  106. mockCtl := gomock.NewController(t)
  107. defer mockCtl.Finish()
  108. mockDNS := mocks.NewDNSClient(mockCtl)
  109. mockOhm := mocks.NewOutboundManager(mockCtl)
  110. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  111. mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test1"})
  112. r := new(Router)
  113. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  114. Manager: mockOhm,
  115. HandlerSelector: mockHs,
  116. }, nil))
  117. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)})
  118. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  119. common.Must(err)
  120. if tag := route.GetOutboundTag(); tag != "test1" {
  121. t.Error("expect tag 'test1', bug actually ", tag)
  122. }
  123. }*/
  124. func TestIPOnDemand(t *testing.T) {
  125. config := &Config{
  126. DomainStrategy: DomainStrategy_IpOnDemand,
  127. Rule: []*RoutingRule{
  128. {
  129. TargetTag: &RoutingRule_Tag{
  130. Tag: "test",
  131. },
  132. Cidr: []*routercommon.CIDR{
  133. {
  134. Ip: []byte{192, 168, 0, 0},
  135. Prefix: 16,
  136. },
  137. },
  138. },
  139. },
  140. }
  141. mockCtl := gomock.NewController(t)
  142. defer mockCtl.Finish()
  143. mockDNS := mocks.NewDNSClient(mockCtl)
  144. mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
  145. r := new(Router)
  146. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  147. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  148. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  149. common.Must(err)
  150. if tag := route.GetOutboundTag(); tag != "test" {
  151. t.Error("expect tag 'test', bug actually ", tag)
  152. }
  153. }
  154. func TestIPIfNonMatchDomain(t *testing.T) {
  155. config := &Config{
  156. DomainStrategy: DomainStrategy_IpIfNonMatch,
  157. Rule: []*RoutingRule{
  158. {
  159. TargetTag: &RoutingRule_Tag{
  160. Tag: "test",
  161. },
  162. Cidr: []*routercommon.CIDR{
  163. {
  164. Ip: []byte{192, 168, 0, 0},
  165. Prefix: 16,
  166. },
  167. },
  168. },
  169. },
  170. }
  171. mockCtl := gomock.NewController(t)
  172. defer mockCtl.Finish()
  173. mockDNS := mocks.NewDNSClient(mockCtl)
  174. mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
  175. r := new(Router)
  176. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  177. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  178. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  179. common.Must(err)
  180. if tag := route.GetOutboundTag(); tag != "test" {
  181. t.Error("expect tag 'test', bug actually ", tag)
  182. }
  183. }
  184. func TestIPIfNonMatchIP(t *testing.T) {
  185. config := &Config{
  186. DomainStrategy: DomainStrategy_IpIfNonMatch,
  187. Rule: []*RoutingRule{
  188. {
  189. TargetTag: &RoutingRule_Tag{
  190. Tag: "test",
  191. },
  192. Cidr: []*routercommon.CIDR{
  193. {
  194. Ip: []byte{127, 0, 0, 0},
  195. Prefix: 8,
  196. },
  197. },
  198. },
  199. },
  200. }
  201. mockCtl := gomock.NewController(t)
  202. defer mockCtl.Finish()
  203. mockDNS := mocks.NewDNSClient(mockCtl)
  204. r := new(Router)
  205. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  206. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})
  207. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  208. common.Must(err)
  209. if tag := route.GetOutboundTag(); tag != "test" {
  210. t.Error("expect tag 'test', bug actually ", tag)
  211. }
  212. }