2016-10-12 16:46:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								package  core  
						 
					
						
							
								
									
										
										
										
											2015-09-05 17:48:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2017-01-13 00:56:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"sync" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 00:56:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:54:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"v2ray.com/core/common" 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"v2ray.com/core/common/serial" 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-17 19:09:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"v2ray.com/core/common/uuid" 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-05 17:48:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:25:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Server is an instance of V2Ray. At any time, there must be at most one Server instance running.  
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Deprecated. Use Instance directly.  
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:25:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								type  Server  interface  {  
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									common . Runnable 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:25:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Feature is the interface for V2Ray features. All features must implement this interface.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// All existing features have an implementation in app directory. These features can be replaced by third-party ones.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Feature  interface  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									common . Runnable 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-22 11:30:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Instance combines all functionalities in V2Ray.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Instance  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dnsClient      syncDNSClient 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyManager  syncPolicyManager 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dispatcher     syncDispatcher 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									router         syncRouter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ihm            syncInboundHandlerManager 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ohm            syncOutboundHandlerManager 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stats          syncStatManager 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									access    sync . Mutex 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									features  [ ] Feature 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-17 19:09:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									id        uuid . UUID 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									running   bool 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:25:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// New returns a new V2Ray instance based on given configuration.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The instance is not started at this point.  
						 
					
						
							
								
									
										
										
										
											2018-04-03 17:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// To ensure V2Ray instance works properly, the config must contain one Dispatcher, one InboundHandlerManager and one OutboundHandlerManager. Other features are optional.  
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  New ( config  * Config )  ( * Instance ,  error )  {  
						 
					
						
							
								
									
										
										
										
											2018-01-17 19:09:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  server  =  & Instance { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-18 23:25:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										id :  uuid . New ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-17 19:09:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-12 11:51:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 23:05:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  config . Transport . Apply ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-14 22:21:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-02 01:49:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 23:05:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  appSettings  :=  range  config . App  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 21:35:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										settings ,  err  :=  appSettings . GetInstance ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  err  :=  CreateObject ( server ,  settings ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-01 21:35:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  inbound  :=  range  config . Inbound  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rawHandler ,  err  :=  CreateObject ( server ,  inbound ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 13:41:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 15:32:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										handler ,  ok  :=  rawHandler . ( InboundHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  newError ( "not an InboundHandler" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-10 16:54:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-05 23:38:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  server . InboundHandlerManager ( ) . AddHandler ( context . Background ( ) ,  handler ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 13:41:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 15:32:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 23:41:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  outbound  :=  range  config . Outbound  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rawHandler ,  err  :=  CreateObject ( server ,  outbound ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-13 13:41:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-06 15:32:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										handler ,  ok  :=  rawHandler . ( OutboundHandler ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  newError ( "not an OutboundHandler" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-05 23:38:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  server . OutboundHandlerManager ( ) . AddHandler ( context . Background ( ) ,  handler ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-27 22:09:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-16 15:39:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-05 22:55:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  server ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-02 15:52:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ID returns a unique ID for this V2Ray instance.  
						 
					
						
							
								
									
										
										
										
											2018-01-17 19:09:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  ID ( )  uuid . UUID  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s . id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Close shutdown the V2Ray instance.  
						 
					
						
							
								
									
										
										
										
											2018-02-08 15:39:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  Close ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . access . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . access . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . running  =  false 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  errors  [ ] interface { } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  s . allFeatures ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-31 11:55:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  f . Close ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											errors  =  append ( errors ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( errors )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  newError ( "failed to close all features" ) . Base ( newError ( serial . Concat ( errors ... ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-01 00:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-08 15:39:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-11-01 00:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Start starts the V2Ray instance, including all registered features. When Start returns error, the state of the instance is unknown.  
						 
					
						
							
								
									
										
										
										
											2018-02-10 11:17:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// A V2Ray instance can be started only once. Upon closing, the instance is not guaranteed to start again.  
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  Start ( )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									s . access . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  s . access . Unlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s . running  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  s . allFeatures ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  :=  f . Start ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 14:47:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-16 00:46:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2015-11-22 17:41:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-01 21:16:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newError ( "V2Ray " ,  Version ( ) ,  " started" ) . AtWarning ( ) . WriteToLog ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// RegisterFeature registers the given feature into V2Ray.  
						 
					
						
							
								
									
										
										
										
											2018-03-15 10:32:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If feature is one of the following types, the corresponding feature in this Instance  
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// will be replaced: DNSClient, PolicyManager, Router, Dispatcher, InboundHandlerManager, OutboundHandlerManager.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  RegisterFeature ( feature  interface { } ,  instance  Feature )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									running  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  feature . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  DNSClient ,  * DNSClient : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . dnsClient . Set ( instance . ( DNSClient ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  PolicyManager ,  * PolicyManager : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . policyManager . Set ( instance . ( PolicyManager ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  Router ,  * Router : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . router . Set ( instance . ( Router ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  Dispatcher ,  * Dispatcher : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . dispatcher . Set ( instance . ( Dispatcher ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  InboundHandlerManager ,  * InboundHandlerManager : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . ihm . Set ( instance . ( InboundHandlerManager ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  OutboundHandlerManager ,  * OutboundHandlerManager : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . ohm . Set ( instance . ( OutboundHandlerManager ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  StatManager ,  * StatManager : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . stats . Set ( instance . ( StatManager ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . access . Lock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . features  =  append ( s . features ,  instance ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										running  =  s . running 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s . access . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-18 08:12:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  running  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 12:34:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  instance . Start ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-05-18 08:12:04 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  allFeatures ( )  [ ] Feature  {  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  append ( [ ] Feature { s . DNSClient ( ) ,  s . PolicyManager ( ) ,  s . Dispatcher ( ) ,  s . Router ( ) ,  s . InboundHandlerManager ( ) ,  s . OutboundHandlerManager ( ) ,  s . Stats ( ) } ,  s . features ... ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-20 21:19:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-14 17:35:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetFeature returns a feature that was registered in this Instance. Nil if not found.  
						 
					
						
							
								
									
										
										
										
											2018-04-03 17:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// The returned Feature must implement common.HasType and whose type equals to the given feature type.  
						 
					
						
							
								
									
										
										
										
											2018-02-14 17:35:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  GetFeature ( featureType  interface { } )  Feature  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  f  :=  range  s . features  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  hasType ,  ok  :=  f . ( common . HasType ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  hasType . Type ( )  ==  featureType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// DNSClient returns the DNSClient used by this Instance. The returned DNSClient is always functional.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  DNSClient ( )  DNSClient  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . dnsClient ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-05 17:48:38 +02:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// PolicyManager returns the PolicyManager used by this Instance. The returned PolicyManager is always functional.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  PolicyManager ( )  PolicyManager  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . policyManager ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-04 00:33:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Router returns the Router used by this Instance. The returned Router is always functional.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  Router ( )  Router  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . router ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-11-01 00:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-10 12:22:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Dispatcher returns the Dispatcher used by this Instance. If Dispatcher was not registered before, the returned value doesn't work, although it is not nil.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  Dispatcher ( )  Dispatcher  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . dispatcher ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// InboundHandlerManager returns the InboundHandlerManager used by this Instance. If InboundHandlerManager was not registered before, the returned value doesn't work.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  InboundHandlerManager ( )  InboundHandlerManager  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . ihm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// OutboundHandlerManager returns the OutboundHandlerManager used by this Instance. If OutboundHandlerManager was not registered before, the returned value doesn't work.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( s  * Instance )  OutboundHandlerManager ( )  OutboundHandlerManager  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . ohm ) 
							 
						 
					
						
							
								
									
										
										
										
											2015-09-06 22:10:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-04 00:57:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Stats returns the StatManager used by this Instance. If StatManager was not registered before, the returned value doesn't work.  
						 
					
						
							
								
									
										
										
										
											2018-03-30 19:56:59 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( s  * Instance )  Stats ( )  StatManager  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & ( s . stats ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}