condition.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. // +build !confonly
  2. package router
  3. import (
  4. "context"
  5. "strings"
  6. "v2ray.com/core/app/dispatcher"
  7. "v2ray.com/core/common/net"
  8. "v2ray.com/core/common/session"
  9. "v2ray.com/core/common/strmatcher"
  10. )
  11. type Condition interface {
  12. Apply(ctx context.Context) bool
  13. }
  14. type ConditionChan []Condition
  15. func NewConditionChan() *ConditionChan {
  16. var condChan ConditionChan = make([]Condition, 0, 8)
  17. return &condChan
  18. }
  19. func (v *ConditionChan) Add(cond Condition) *ConditionChan {
  20. *v = append(*v, cond)
  21. return v
  22. }
  23. func (v *ConditionChan) Apply(ctx context.Context) bool {
  24. for _, cond := range *v {
  25. if !cond.Apply(ctx) {
  26. return false
  27. }
  28. }
  29. return true
  30. }
  31. func (v *ConditionChan) Len() int {
  32. return len(*v)
  33. }
  34. var matcherTypeMap = map[Domain_Type]strmatcher.Type{
  35. Domain_Plain: strmatcher.Substr,
  36. Domain_Regex: strmatcher.Regex,
  37. Domain_Domain: strmatcher.Domain,
  38. Domain_Full: strmatcher.Full,
  39. }
  40. func domainToMatcher(domain *Domain) (strmatcher.Matcher, error) {
  41. matcherType, f := matcherTypeMap[domain.Type]
  42. if !f {
  43. return nil, newError("unsupported domain type", domain.Type)
  44. }
  45. matcher, err := matcherType.New(domain.Value)
  46. if err != nil {
  47. return nil, newError("failed to create domain matcher").Base(err)
  48. }
  49. return matcher, nil
  50. }
  51. type DomainMatcher struct {
  52. matchers strmatcher.IndexMatcher
  53. }
  54. func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
  55. g := new(strmatcher.MatcherGroup)
  56. for _, d := range domains {
  57. m, err := domainToMatcher(d)
  58. if err != nil {
  59. return nil, err
  60. }
  61. g.Add(m)
  62. }
  63. return &DomainMatcher{
  64. matchers: g,
  65. }, nil
  66. }
  67. func (m *DomainMatcher) ApplyDomain(domain string) bool {
  68. return m.matchers.Match(domain) > 0
  69. }
  70. func (m *DomainMatcher) Apply(ctx context.Context) bool {
  71. outbound := session.OutboundFromContext(ctx)
  72. if outbound == nil || !outbound.Target.IsValid() {
  73. return false
  74. }
  75. dest := outbound.Target
  76. if !dest.Address.Family().IsDomain() {
  77. return false
  78. }
  79. return m.ApplyDomain(dest.Address.Domain())
  80. }
  81. func sourceFromContext(ctx context.Context) net.Destination {
  82. inbound := session.InboundFromContext(ctx)
  83. if inbound == nil {
  84. return net.Destination{}
  85. }
  86. return inbound.Source
  87. }
  88. func targetFromContent(ctx context.Context) net.Destination {
  89. outbound := session.OutboundFromContext(ctx)
  90. if outbound == nil {
  91. return net.Destination{}
  92. }
  93. return outbound.Target
  94. }
  95. func resolvedIPFromContext(ctx context.Context) []net.IP {
  96. outbound := session.OutboundFromContext(ctx)
  97. if outbound == nil {
  98. return nil
  99. }
  100. return outbound.ResolvedIPs
  101. }
  102. type MultiGeoIPMatcher struct {
  103. matchers []*GeoIPMatcher
  104. destFunc func(context.Context) net.Destination
  105. resolvedIPFunc func(context.Context) []net.IP
  106. }
  107. func NewMultiGeoIPMatcher(geoips []*GeoIP, onSource bool) (*MultiGeoIPMatcher, error) {
  108. var matchers []*GeoIPMatcher
  109. for _, geoip := range geoips {
  110. matcher, err := globalGeoIPContainer.Add(geoip)
  111. if err != nil {
  112. return nil, err
  113. }
  114. matchers = append(matchers, matcher)
  115. }
  116. matcher := &MultiGeoIPMatcher{
  117. matchers: matchers,
  118. }
  119. if onSource {
  120. matcher.destFunc = sourceFromContext
  121. } else {
  122. matcher.destFunc = targetFromContent
  123. matcher.resolvedIPFunc = resolvedIPFromContext
  124. }
  125. return matcher, nil
  126. }
  127. func (m *MultiGeoIPMatcher) Apply(ctx context.Context) bool {
  128. ips := make([]net.IP, 0, 4)
  129. dest := m.destFunc(ctx)
  130. if dest.IsValid() && dest.Address.Family().IsIP() {
  131. ips = append(ips, dest.Address.IP())
  132. }
  133. if m.resolvedIPFunc != nil {
  134. rips := m.resolvedIPFunc(ctx)
  135. if len(rips) > 0 {
  136. ips = append(ips, rips...)
  137. }
  138. }
  139. for _, ip := range ips {
  140. for _, matcher := range m.matchers {
  141. if matcher.Match(ip) {
  142. return true
  143. }
  144. }
  145. }
  146. return false
  147. }
  148. type PortMatcher struct {
  149. port net.PortRange
  150. }
  151. func NewPortMatcher(portRange net.PortRange) *PortMatcher {
  152. return &PortMatcher{
  153. port: portRange,
  154. }
  155. }
  156. func (v *PortMatcher) Apply(ctx context.Context) bool {
  157. outbound := session.OutboundFromContext(ctx)
  158. if outbound == nil || !outbound.Target.IsValid() {
  159. return false
  160. }
  161. return v.port.Contains(outbound.Target.Port)
  162. }
  163. type NetworkMatcher struct {
  164. list [8]bool
  165. }
  166. func NewNetworkMatcher(network []net.Network) NetworkMatcher {
  167. var matcher NetworkMatcher
  168. for _, n := range network {
  169. matcher.list[int(n)] = true
  170. }
  171. return matcher
  172. }
  173. func (v NetworkMatcher) Apply(ctx context.Context) bool {
  174. outbound := session.OutboundFromContext(ctx)
  175. if outbound == nil || !outbound.Target.IsValid() {
  176. return false
  177. }
  178. return v.list[int(outbound.Target.Network)]
  179. }
  180. type UserMatcher struct {
  181. user []string
  182. }
  183. func NewUserMatcher(users []string) *UserMatcher {
  184. usersCopy := make([]string, 0, len(users))
  185. for _, user := range users {
  186. if len(user) > 0 {
  187. usersCopy = append(usersCopy, user)
  188. }
  189. }
  190. return &UserMatcher{
  191. user: usersCopy,
  192. }
  193. }
  194. func (v *UserMatcher) Apply(ctx context.Context) bool {
  195. inbound := session.InboundFromContext(ctx)
  196. if inbound == nil {
  197. return false
  198. }
  199. user := inbound.User
  200. if user == nil {
  201. return false
  202. }
  203. for _, u := range v.user {
  204. if u == user.Email {
  205. return true
  206. }
  207. }
  208. return false
  209. }
  210. type InboundTagMatcher struct {
  211. tags []string
  212. }
  213. func NewInboundTagMatcher(tags []string) *InboundTagMatcher {
  214. tagsCopy := make([]string, 0, len(tags))
  215. for _, tag := range tags {
  216. if len(tag) > 0 {
  217. tagsCopy = append(tagsCopy, tag)
  218. }
  219. }
  220. return &InboundTagMatcher{
  221. tags: tagsCopy,
  222. }
  223. }
  224. func (v *InboundTagMatcher) Apply(ctx context.Context) bool {
  225. inbound := session.InboundFromContext(ctx)
  226. if inbound == nil || len(inbound.Tag) == 0 {
  227. return false
  228. }
  229. tag := inbound.Tag
  230. for _, t := range v.tags {
  231. if t == tag {
  232. return true
  233. }
  234. }
  235. return false
  236. }
  237. type ProtocolMatcher struct {
  238. protocols []string
  239. }
  240. func NewProtocolMatcher(protocols []string) *ProtocolMatcher {
  241. pCopy := make([]string, 0, len(protocols))
  242. for _, p := range protocols {
  243. if len(p) > 0 {
  244. pCopy = append(pCopy, p)
  245. }
  246. }
  247. return &ProtocolMatcher{
  248. protocols: pCopy,
  249. }
  250. }
  251. func (m *ProtocolMatcher) Apply(ctx context.Context) bool {
  252. result := dispatcher.SniffingResultFromContext(ctx)
  253. if result == nil {
  254. return false
  255. }
  256. protocol := result.Protocol()
  257. for _, p := range m.protocols {
  258. if strings.HasPrefix(protocol, p) {
  259. return true
  260. }
  261. }
  262. return false
  263. }