router_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package router_test
  2. import (
  3. "context"
  4. "testing"
  5. "github.com/golang/mock/gomock"
  6. . "github.com/v2fly/v2ray-core/v4/app/router"
  7. "github.com/v2fly/v2ray-core/v4/common"
  8. "github.com/v2fly/v2ray-core/v4/common/net"
  9. serial "github.com/v2fly/v2ray-core/v4/common/serial"
  10. "github.com/v2fly/v2ray-core/v4/common/session"
  11. "github.com/v2fly/v2ray-core/v4/features/outbound"
  12. routing_session "github.com/v2fly/v2ray-core/v4/features/routing/session"
  13. "github.com/v2fly/v2ray-core/v4/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. func TestLeastLoadBalancer(t *testing.T) {
  83. config := &Config{
  84. Rule: []*RoutingRule{
  85. {
  86. TargetTag: &RoutingRule_BalancingTag{
  87. BalancingTag: "balance",
  88. },
  89. Networks: []net.Network{net.Network_TCP},
  90. },
  91. },
  92. BalancingRule: []*BalancingRule{
  93. {
  94. Tag: "balance",
  95. OutboundSelector: []string{"test-"},
  96. Strategy: "leastLoad",
  97. StrategySettings: serial.ToTypedMessage(&StrategyLeastLoadConfig{
  98. HealthCheck: nil,
  99. Baselines: nil,
  100. Expected: 1,
  101. }),
  102. },
  103. },
  104. }
  105. mockCtl := gomock.NewController(t)
  106. defer mockCtl.Finish()
  107. mockDNS := mocks.NewDNSClient(mockCtl)
  108. mockOhm := mocks.NewOutboundManager(mockCtl)
  109. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  110. mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test1"})
  111. r := new(Router)
  112. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  113. Manager: mockOhm,
  114. HandlerSelector: mockHs,
  115. }, nil))
  116. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2ray.com"), 80)})
  117. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  118. common.Must(err)
  119. if tag := route.GetOutboundTag(); tag != "test1" {
  120. t.Error("expect tag 'test1', bug actually ", tag)
  121. }
  122. }
  123. func TestIPOnDemand(t *testing.T) {
  124. config := &Config{
  125. DomainStrategy: Config_IpOnDemand,
  126. Rule: []*RoutingRule{
  127. {
  128. TargetTag: &RoutingRule_Tag{
  129. Tag: "test",
  130. },
  131. Cidr: []*CIDR{
  132. {
  133. Ip: []byte{192, 168, 0, 0},
  134. Prefix: 16,
  135. },
  136. },
  137. },
  138. },
  139. }
  140. mockCtl := gomock.NewController(t)
  141. defer mockCtl.Finish()
  142. mockDNS := mocks.NewDNSClient(mockCtl)
  143. mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
  144. r := new(Router)
  145. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  146. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  147. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  148. common.Must(err)
  149. if tag := route.GetOutboundTag(); tag != "test" {
  150. t.Error("expect tag 'test', bug actually ", tag)
  151. }
  152. }
  153. func TestIPIfNonMatchDomain(t *testing.T) {
  154. config := &Config{
  155. DomainStrategy: Config_IpIfNonMatch,
  156. Rule: []*RoutingRule{
  157. {
  158. TargetTag: &RoutingRule_Tag{
  159. Tag: "test",
  160. },
  161. Cidr: []*CIDR{
  162. {
  163. Ip: []byte{192, 168, 0, 0},
  164. Prefix: 16,
  165. },
  166. },
  167. },
  168. },
  169. }
  170. mockCtl := gomock.NewController(t)
  171. defer mockCtl.Finish()
  172. mockDNS := mocks.NewDNSClient(mockCtl)
  173. mockDNS.EXPECT().LookupIP(gomock.Eq("v2fly.org")).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
  174. r := new(Router)
  175. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  176. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  177. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  178. common.Must(err)
  179. if tag := route.GetOutboundTag(); tag != "test" {
  180. t.Error("expect tag 'test', bug actually ", tag)
  181. }
  182. }
  183. func TestIPIfNonMatchIP(t *testing.T) {
  184. config := &Config{
  185. DomainStrategy: Config_IpIfNonMatch,
  186. Rule: []*RoutingRule{
  187. {
  188. TargetTag: &RoutingRule_Tag{
  189. Tag: "test",
  190. },
  191. Cidr: []*CIDR{
  192. {
  193. Ip: []byte{127, 0, 0, 0},
  194. Prefix: 8,
  195. },
  196. },
  197. },
  198. },
  199. }
  200. mockCtl := gomock.NewController(t)
  201. defer mockCtl.Finish()
  202. mockDNS := mocks.NewDNSClient(mockCtl)
  203. r := new(Router)
  204. common.Must(r.Init(context.TODO(), config, mockDNS, nil, nil))
  205. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})
  206. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  207. common.Must(err)
  208. if tag := route.GetOutboundTag(); tag != "test" {
  209. t.Error("expect tag 'test', bug actually ", tag)
  210. }
  211. }