v2ray.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package core
  2. import (
  3. "context"
  4. "sync"
  5. "v2ray.com/core/common"
  6. "v2ray.com/core/common/serial"
  7. "v2ray.com/core/features"
  8. "v2ray.com/core/features/dns"
  9. "v2ray.com/core/features/inbound"
  10. "v2ray.com/core/features/outbound"
  11. "v2ray.com/core/features/policy"
  12. "v2ray.com/core/features/routing"
  13. )
  14. // Server is an instance of V2Ray. At any time, there must be at most one Server instance running.
  15. type Server interface {
  16. common.Runnable
  17. }
  18. // ServerType returns the type of the server.
  19. func ServerType() interface{} {
  20. return (*Instance)(nil)
  21. }
  22. type resolution struct {
  23. deps []interface{}
  24. callback func([]features.Feature)
  25. }
  26. func getFeature(allFeatures []features.Feature, t interface{}) features.Feature {
  27. for _, f := range allFeatures {
  28. if f.Type() == t {
  29. return f
  30. }
  31. }
  32. return nil
  33. }
  34. func (r *resolution) resolve(allFeatures []features.Feature) bool {
  35. var fs []features.Feature
  36. for _, d := range r.deps {
  37. f := getFeature(allFeatures, d)
  38. if f == nil {
  39. return false
  40. }
  41. fs = append(fs, f)
  42. }
  43. r.callback(fs)
  44. return true
  45. }
  46. // Instance combines all functionalities in V2Ray.
  47. type Instance struct {
  48. access sync.Mutex
  49. features []features.Feature
  50. featureResolutions []resolution
  51. running bool
  52. }
  53. // New returns a new V2Ray instance based on given configuration.
  54. // The instance is not started at this point.
  55. // To ensure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.
  56. func New(config *Config) (*Instance, error) {
  57. var server = &Instance{}
  58. if config.Transport != nil {
  59. features.PrintDeprecatedFeatureWarning("global transport settings")
  60. }
  61. if err := config.Transport.Apply(); err != nil {
  62. return nil, err
  63. }
  64. for _, appSettings := range config.App {
  65. settings, err := appSettings.GetInstance()
  66. if err != nil {
  67. return nil, err
  68. }
  69. obj, err := CreateObject(server, settings)
  70. if err != nil {
  71. return nil, err
  72. }
  73. if feature, ok := obj.(features.Feature); ok {
  74. server.AddFeature(feature)
  75. }
  76. }
  77. if server.GetFeature(dns.ClientType()) == nil {
  78. server.AddFeature(dns.LocalClient{})
  79. }
  80. if server.GetFeature(policy.ManagerType()) == nil {
  81. server.AddFeature(policy.DefaultManager{})
  82. }
  83. if server.GetFeature(routing.RouterType()) == nil {
  84. server.AddFeature(routing.DefaultRouter{})
  85. }
  86. // Add an empty instance at the end, for optional feature requirement.
  87. server.AddFeature(&Instance{})
  88. if server.featureResolutions != nil {
  89. return nil, newError("not all dependency are resolved.")
  90. }
  91. if len(config.Inbound) > 0 {
  92. inboundManager := server.GetFeature(inbound.ManagerType()).(inbound.Manager)
  93. for _, inboundConfig := range config.Inbound {
  94. rawHandler, err := CreateObject(server, inboundConfig)
  95. if err != nil {
  96. return nil, err
  97. }
  98. handler, ok := rawHandler.(inbound.Handler)
  99. if !ok {
  100. return nil, newError("not an InboundHandler")
  101. }
  102. if err := inboundManager.AddHandler(context.Background(), handler); err != nil {
  103. return nil, err
  104. }
  105. }
  106. }
  107. if len(config.Outbound) > 0 {
  108. outboundManager := server.GetFeature(outbound.ManagerType()).(outbound.Manager)
  109. for _, outboundConfig := range config.Outbound {
  110. rawHandler, err := CreateObject(server, outboundConfig)
  111. if err != nil {
  112. return nil, err
  113. }
  114. handler, ok := rawHandler.(outbound.Handler)
  115. if !ok {
  116. return nil, newError("not an OutboundHandler")
  117. }
  118. if err := outboundManager.AddHandler(context.Background(), handler); err != nil {
  119. return nil, err
  120. }
  121. }
  122. }
  123. return server, nil
  124. }
  125. // Type implements common.HasType.
  126. func (s *Instance) Type() interface{} {
  127. return ServerType()
  128. }
  129. // Close shutdown the V2Ray instance.
  130. func (s *Instance) Close() error {
  131. s.access.Lock()
  132. defer s.access.Unlock()
  133. s.running = false
  134. var errors []interface{}
  135. for _, f := range s.features {
  136. if err := f.Close(); err != nil {
  137. errors = append(errors, err)
  138. }
  139. }
  140. if len(errors) > 0 {
  141. return newError("failed to close all features").Base(newError(serial.Concat(errors...)))
  142. }
  143. return nil
  144. }
  145. // RequireFeatures registers a callback, which will be called when all dependent features are registered.
  146. func (s *Instance) RequireFeatures(featureTypes []interface{}, callback func([]features.Feature)) {
  147. r := resolution{
  148. deps: featureTypes,
  149. callback: callback,
  150. }
  151. if r.resolve(s.features) {
  152. return
  153. }
  154. s.featureResolutions = append(s.featureResolutions, r)
  155. }
  156. // AddFeature registers a feature into current Instance.
  157. func (s *Instance) AddFeature(feature features.Feature) {
  158. s.features = append(s.features, feature)
  159. if s.running {
  160. if err := feature.Start(); err != nil {
  161. newError("failed to start feature").Base(err).WriteToLog()
  162. }
  163. return
  164. }
  165. if s.featureResolutions == nil {
  166. return
  167. }
  168. var pendingResolutions []resolution
  169. for _, r := range s.featureResolutions {
  170. if !r.resolve(s.features) {
  171. pendingResolutions = append(pendingResolutions, r)
  172. }
  173. }
  174. if len(pendingResolutions) == 0 {
  175. s.featureResolutions = nil
  176. } else if len(pendingResolutions) < len(s.featureResolutions) {
  177. s.featureResolutions = pendingResolutions
  178. }
  179. }
  180. // GetFeature returns a feature of the given type, or nil if such feature is not registered.
  181. func (s *Instance) GetFeature(featureType interface{}) features.Feature {
  182. return getFeature(s.features, featureType)
  183. }
  184. // Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.
  185. // A V2Ray instance can be started only once. Upon closing, the instance is not guaranteed to start again.
  186. func (s *Instance) Start() error {
  187. s.access.Lock()
  188. defer s.access.Unlock()
  189. s.running = true
  190. for _, f := range s.features {
  191. if err := f.Start(); err != nil {
  192. return err
  193. }
  194. }
  195. newError("V2Ray ", Version(), " started").AtWarning().WriteToLog()
  196. return nil
  197. }