router_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. "github.com/v2fly/v2ray-core/v4/common/session"
  10. "github.com/v2fly/v2ray-core/v4/features/outbound"
  11. routing_session "github.com/v2fly/v2ray-core/v4/features/routing/session"
  12. "github.com/v2fly/v2ray-core/v4/testing/mocks"
  13. )
  14. type mockOutboundManager struct {
  15. outbound.Manager
  16. outbound.HandlerSelector
  17. }
  18. func TestSimpleRouter(t *testing.T) {
  19. config := &Config{
  20. Rule: []*RoutingRule{
  21. {
  22. TargetTag: &RoutingRule_Tag{
  23. Tag: "test",
  24. },
  25. Networks: []net.Network{net.Network_TCP},
  26. },
  27. },
  28. }
  29. mockCtl := gomock.NewController(t)
  30. defer mockCtl.Finish()
  31. mockDNS := mocks.NewDNSClient(mockCtl)
  32. mockOhm := mocks.NewOutboundManager(mockCtl)
  33. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  34. r := new(Router)
  35. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  36. Manager: mockOhm,
  37. HandlerSelector: mockHs,
  38. }, nil))
  39. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  40. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  41. common.Must(err)
  42. if tag := route.GetOutboundTag(); tag != "test" {
  43. t.Error("expect tag 'test', bug actually ", tag)
  44. }
  45. }
  46. func TestSimpleBalancer(t *testing.T) {
  47. config := &Config{
  48. Rule: []*RoutingRule{
  49. {
  50. TargetTag: &RoutingRule_BalancingTag{
  51. BalancingTag: "balance",
  52. },
  53. Networks: []net.Network{net.Network_TCP},
  54. },
  55. },
  56. BalancingRule: []*BalancingRule{
  57. {
  58. Tag: "balance",
  59. OutboundSelector: []string{"test-"},
  60. },
  61. },
  62. }
  63. mockCtl := gomock.NewController(t)
  64. defer mockCtl.Finish()
  65. mockDNS := mocks.NewDNSClient(mockCtl)
  66. mockOhm := mocks.NewOutboundManager(mockCtl)
  67. mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
  68. mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"})
  69. r := new(Router)
  70. common.Must(r.Init(context.TODO(), config, mockDNS, &mockOutboundManager{
  71. Manager: mockOhm,
  72. HandlerSelector: mockHs,
  73. }, nil))
  74. ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("v2fly.org"), 80)})
  75. route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
  76. common.Must(err)
  77. if tag := route.GetOutboundTag(); tag != "test" {
  78. t.Error("expect tag 'test', bug actually ", tag)
  79. }
  80. }
  81. /*
  82. Do not work right now: need a full client setup
  83. func TestLeastLoadBalancer(t *testing.T) {
  84. config := &Config{
  85. Rule: []*RoutingRule{
  86. {
  87. TargetTag: &RoutingRule_BalancingTag{
  88. BalancingTag: "balance",
  89. },
  90. Networks: []net.Network{net.Network_TCP},
  91. },
  92. },
  93. BalancingRule: []*BalancingRule{
  94. {
  95. Tag: "balance",
  96. OutboundSelector: []string{"test-"},
  97. Strategy: "leastLoad",
  98. StrategySettings: serial.ToTypedMessage(&StrategyLeastLoadConfig{
  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. }