| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | package core | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"v2ray.com/core/common" | 
					
						
							|  |  |  | 	"v2ray.com/core/common/net" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // InboundHandler is the interface for handlers that process inbound connections. | 
					
						
							|  |  |  | type InboundHandler interface { | 
					
						
							|  |  |  | 	common.Runnable | 
					
						
							|  |  |  | 	// The tag of this handler. | 
					
						
							|  |  |  | 	Tag() string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Deprecated. Do not use in new code. | 
					
						
							|  |  |  | 	GetRandomInboundProxy() (interface{}, net.Port, int) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // OutboundHandler is the interface for handlers that process outbound connections. | 
					
						
							|  |  |  | type OutboundHandler interface { | 
					
						
							| 
									
										
										
										
											2018-02-08 15:39:46 +01:00
										 |  |  | 	common.Runnable | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	Tag() string | 
					
						
							| 
									
										
										
										
											2018-04-17 00:31:10 +02:00
										 |  |  | 	Dispatch(ctx context.Context, link *Link) | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-03 17:11:54 +08:00
										 |  |  | // InboundHandlerManager is a feature that manages InboundHandlers. | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | type InboundHandlerManager interface { | 
					
						
							|  |  |  | 	Feature | 
					
						
							|  |  |  | 	// GetHandlers returns an InboundHandler for the given tag. | 
					
						
							|  |  |  | 	GetHandler(ctx context.Context, tag string) (InboundHandler, error) | 
					
						
							|  |  |  | 	// AddHandler adds the given handler into this InboundHandlerManager. | 
					
						
							|  |  |  | 	AddHandler(ctx context.Context, handler InboundHandler) error | 
					
						
							| 
									
										
										
										
											2018-02-05 23:38:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// RemoveHandler removes a handler from InboundHandlerManager. | 
					
						
							|  |  |  | 	RemoveHandler(ctx context.Context, tag string) error | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type syncInboundHandlerManager struct { | 
					
						
							|  |  |  | 	sync.RWMutex | 
					
						
							|  |  |  | 	InboundHandlerManager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncInboundHandlerManager) GetHandler(ctx context.Context, tag string) (InboundHandler, error) { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.InboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return nil, newError("InboundHandlerManager not set.").AtError() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.InboundHandlerManager.GetHandler(ctx, tag) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncInboundHandlerManager) AddHandler(ctx context.Context, handler InboundHandler) error { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.InboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return newError("InboundHandlerManager not set.").AtError() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.InboundHandlerManager.AddHandler(ctx, handler) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncInboundHandlerManager) Start() error { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.InboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return newError("InboundHandlerManager not set.").AtError() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.InboundHandlerManager.Start() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 15:39:46 +01:00
										 |  |  | func (m *syncInboundHandlerManager) Close() error { | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 15:39:46 +01:00
										 |  |  | 	return common.Close(m.InboundHandlerManager) | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncInboundHandlerManager) Set(manager InboundHandlerManager) { | 
					
						
							| 
									
										
										
										
											2018-02-20 21:22:41 +01:00
										 |  |  | 	if manager == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.Lock() | 
					
						
							|  |  |  | 	defer m.Unlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 11:55:11 +02:00
										 |  |  | 	common.Close(m.InboundHandlerManager) // nolint: errcheck | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.InboundHandlerManager = manager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // OutboundHandlerManager is a feature that manages OutboundHandlers. | 
					
						
							|  |  |  | type OutboundHandlerManager interface { | 
					
						
							|  |  |  | 	Feature | 
					
						
							| 
									
										
										
										
											2018-04-03 17:11:54 +08:00
										 |  |  | 	// GetHandler returns an OutboundHandler for the given tag. | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	GetHandler(tag string) OutboundHandler | 
					
						
							|  |  |  | 	// GetDefaultHandler returns the default OutboundHandler. It is usually the first OutboundHandler specified in the configuration. | 
					
						
							|  |  |  | 	GetDefaultHandler() OutboundHandler | 
					
						
							|  |  |  | 	// AddHandler adds a handler into this OutboundHandlerManager. | 
					
						
							|  |  |  | 	AddHandler(ctx context.Context, handler OutboundHandler) error | 
					
						
							| 
									
										
										
										
											2018-02-05 23:38:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// RemoveHandler removes a handler from OutboundHandlerManager. | 
					
						
							|  |  |  | 	RemoveHandler(ctx context.Context, tag string) error | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type syncOutboundHandlerManager struct { | 
					
						
							|  |  |  | 	sync.RWMutex | 
					
						
							|  |  |  | 	OutboundHandlerManager | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncOutboundHandlerManager) GetHandler(tag string) OutboundHandler { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.OutboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.OutboundHandlerManager.GetHandler(tag) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncOutboundHandlerManager) GetDefaultHandler() OutboundHandler { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.OutboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.OutboundHandlerManager.GetDefaultHandler() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncOutboundHandlerManager) AddHandler(ctx context.Context, handler OutboundHandler) error { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.OutboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return newError("OutboundHandlerManager not set.").AtError() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.OutboundHandlerManager.AddHandler(ctx, handler) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncOutboundHandlerManager) Start() error { | 
					
						
							|  |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if m.OutboundHandlerManager == nil { | 
					
						
							|  |  |  | 		return newError("OutboundHandlerManager not set.").AtError() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return m.OutboundHandlerManager.Start() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 15:39:46 +01:00
										 |  |  | func (m *syncOutboundHandlerManager) Close() error { | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.RLock() | 
					
						
							|  |  |  | 	defer m.RUnlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-08 15:39:46 +01:00
										 |  |  | 	return common.Close(m.OutboundHandlerManager) | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (m *syncOutboundHandlerManager) Set(manager OutboundHandlerManager) { | 
					
						
							| 
									
										
										
										
											2018-02-20 21:22:41 +01:00
										 |  |  | 	if manager == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.Lock() | 
					
						
							|  |  |  | 	defer m.Unlock() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 11:55:11 +02:00
										 |  |  | 	common.Close(m.OutboundHandlerManager) // nolint: errcheck | 
					
						
							| 
									
										
										
										
											2018-01-10 12:22:37 +01:00
										 |  |  | 	m.OutboundHandlerManager = manager | 
					
						
							|  |  |  | } |