| 
									
										
										
										
											2015-12-04 22:53:31 +01:00
										 |  |  | // Package point is a shell of V2Ray to run on various of systems. | 
					
						
							|  |  |  | // Point server is a full functionality proxying system. It consists of an inbound and an outbound | 
					
						
							|  |  |  | // connection, as well as any number of inbound and outbound detours. It provides a way internally | 
					
						
							|  |  |  | // to route network packets. | 
					
						
							| 
									
										
										
										
											2015-10-14 14:51:19 +02:00
										 |  |  | package point | 
					
						
							| 
									
										
										
										
											2015-09-05 17:48:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-12-05 22:55:45 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/app" | 
					
						
							| 
									
										
										
										
											2016-01-31 17:01:28 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/app/dispatcher" | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 	dispatchers "github.com/v2ray/v2ray-core/app/dispatcher/impl" | 
					
						
							| 
									
										
										
										
											2016-05-16 00:25:34 -07:00
										 |  |  | 	"github.com/v2ray/v2ray-core/app/dns" | 
					
						
							| 
									
										
										
										
											2016-01-31 17:01:28 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/app/proxyman" | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/app/router" | 
					
						
							| 
									
										
										
										
											2015-09-20 00:50:21 +02:00
										 |  |  | 	"github.com/v2ray/v2ray-core/common/log" | 
					
						
							| 
									
										
										
										
											2015-09-19 23:54:36 +02:00
										 |  |  | 	v2net "github.com/v2ray/v2ray-core/common/net" | 
					
						
							| 
									
										
										
										
											2015-10-13 12:27:50 +02:00
										 |  |  | 	"github.com/v2ray/v2ray-core/common/retry" | 
					
						
							| 
									
										
										
										
											2016-01-01 23:44:11 +01:00
										 |  |  | 	"github.com/v2ray/v2ray-core/proxy" | 
					
						
							| 
									
										
										
										
											2016-01-02 23:32:18 +01:00
										 |  |  | 	proxyrepo "github.com/v2ray/v2ray-core/proxy/repo" | 
					
						
							| 
									
										
										
										
											2015-09-05 17:48:38 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-04 22:53:31 +01:00
										 |  |  | // Point shell of V2Ray. | 
					
						
							| 
									
										
										
										
											2015-09-12 22:11:54 +02:00
										 |  |  | type Point struct { | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 	port      v2net.Port | 
					
						
							| 
									
										
										
										
											2016-05-29 16:37:52 +02:00
										 |  |  | 	listen    v2net.Address | 
					
						
							| 
									
										
										
										
											2016-01-25 17:18:24 +01:00
										 |  |  | 	ich       proxy.InboundHandler | 
					
						
							|  |  |  | 	och       proxy.OutboundHandler | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 	idh       []InboundDetourHandler | 
					
						
							|  |  |  | 	taggedIdh map[string]InboundDetourHandler | 
					
						
							| 
									
										
										
										
											2016-01-25 17:18:24 +01:00
										 |  |  | 	odh       map[string]proxy.OutboundHandler | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 	router    router.Router | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 	space     app.Space | 
					
						
							| 
									
										
										
										
											2015-09-05 17:48:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-12 22:11:54 +02:00
										 |  |  | // NewPoint returns a new Point server based on given configuration. | 
					
						
							| 
									
										
										
										
											2015-09-07 12:00:46 +02:00
										 |  |  | // The server is not started at this point. | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | func NewPoint(pConfig *Config) (*Point, error) { | 
					
						
							| 
									
										
										
										
											2015-09-12 22:11:54 +02:00
										 |  |  | 	var vpoint = new(Point) | 
					
						
							| 
									
										
										
										
											2016-06-04 00:38:22 +02:00
										 |  |  | 	vpoint.port = pConfig.InboundConfig.Port | 
					
						
							|  |  |  | 	if vpoint.port == 0 { | 
					
						
							|  |  |  | 		vpoint.port = pConfig.Port // Backward compatibility | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vpoint.listen = pConfig.InboundConfig.ListenOn | 
					
						
							| 
									
										
										
										
											2015-09-12 11:51:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:25 +02:00
										 |  |  | 	if pConfig.TransportConfig != nil { | 
					
						
							| 
									
										
										
										
											2016-06-02 20:52:52 +02:00
										 |  |  | 		pConfig.TransportConfig.Apply() | 
					
						
							| 
									
										
										
										
											2016-06-02 01:49:25 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 	if pConfig.LogConfig != nil { | 
					
						
							|  |  |  | 		logConfig := pConfig.LogConfig | 
					
						
							|  |  |  | 		if len(logConfig.AccessLog) > 0 { | 
					
						
							|  |  |  | 			err := log.InitAccessLogger(logConfig.AccessLog) | 
					
						
							| 
									
										
										
										
											2015-12-05 21:10:14 +01:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 		if len(logConfig.ErrorLog) > 0 { | 
					
						
							|  |  |  | 			err := log.InitErrorLogger(logConfig.ErrorLog) | 
					
						
							| 
									
										
										
										
											2015-12-05 21:10:14 +01:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 		log.SetLogLevel(logConfig.LogLevel) | 
					
						
							| 
									
										
										
										
											2015-12-05 21:10:14 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 	vpoint.space = app.NewSpace() | 
					
						
							|  |  |  | 	vpoint.space.BindApp(proxyman.APP_ID_INBOUND_MANAGER, vpoint) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:12:04 -07:00
										 |  |  | 	outboundHandlerManager := proxyman.NewDefaultOutboundHandlerManager() | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 	vpoint.space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dnsConfig := pConfig.DNSConfig | 
					
						
							|  |  |  | 	if dnsConfig != nil { | 
					
						
							|  |  |  | 		dnsServer := dns.NewCacheServer(vpoint.space, dnsConfig) | 
					
						
							|  |  |  | 		vpoint.space.BindApp(dns.APP_ID, dnsServer) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	routerConfig := pConfig.RouterConfig | 
					
						
							|  |  |  | 	if routerConfig != nil { | 
					
						
							|  |  |  | 		r, err := router.CreateRouter(routerConfig.Strategy, routerConfig.Settings, vpoint.space) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			log.Error("Failed to create router: ", err) | 
					
						
							|  |  |  | 			return nil, ErrorBadConfiguration | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		vpoint.space.BindApp(router.APP_ID, r) | 
					
						
							|  |  |  | 		vpoint.router = r | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vpoint.space.BindApp(dispatcher.APP_ID, dispatchers.NewDefaultDispatcher(vpoint.space)) | 
					
						
							| 
									
										
										
										
											2015-12-05 22:55:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 	ichConfig := pConfig.InboundConfig.Settings | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 	ich, err := proxyrepo.CreateInboundHandler( | 
					
						
							|  |  |  | 		pConfig.InboundConfig.Protocol, vpoint.space, ichConfig, &proxy.InboundHandlerMeta{ | 
					
						
							|  |  |  | 			Tag:     "system.inbound", | 
					
						
							|  |  |  | 			Address: pConfig.InboundConfig.ListenOn, | 
					
						
							|  |  |  | 			Port:    vpoint.port}) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:30:44 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-01-18 12:24:33 +01:00
										 |  |  | 		log.Error("Failed to create inbound connection handler: ", err) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:30:44 +02:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	vpoint.ich = ich | 
					
						
							| 
									
										
										
										
											2015-09-12 11:51:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 	ochConfig := pConfig.OutboundConfig.Settings | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 	och, err := proxyrepo.CreateOutboundHandler( | 
					
						
							|  |  |  | 		pConfig.OutboundConfig.Protocol, vpoint.space, ochConfig, &proxy.OutboundHandlerMeta{ | 
					
						
							|  |  |  | 			Tag:     "system.outbound", | 
					
						
							|  |  |  | 			Address: pConfig.OutboundConfig.SendThrough}) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:30:44 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-01-18 12:24:33 +01:00
										 |  |  | 		log.Error("Failed to create outbound connection handler: ", err) | 
					
						
							| 
									
										
										
										
											2015-10-07 00:30:44 +02:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	vpoint.och = och | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 	outboundHandlerManager.SetDefaultHandler(och) | 
					
						
							| 
									
										
										
										
											2015-09-11 00:24:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 	vpoint.taggedIdh = make(map[string]InboundDetourHandler) | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 	detours := pConfig.InboundDetours | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 	if len(detours) > 0 { | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 		vpoint.idh = make([]InboundDetourHandler, len(detours)) | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 		for idx, detourConfig := range detours { | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 			allocConfig := detourConfig.Allocation | 
					
						
							|  |  |  | 			var detourHandler InboundDetourHandler | 
					
						
							|  |  |  | 			switch allocConfig.Strategy { | 
					
						
							|  |  |  | 			case AllocationStrategyAlways: | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 				dh, err := NewInboundDetourHandlerAlways(vpoint.space, detourConfig) | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					log.Error("Point: Failed to create detour handler: ", err) | 
					
						
							| 
									
										
										
										
											2016-01-30 12:12:57 +01:00
										 |  |  | 					return nil, ErrorBadConfiguration | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				detourHandler = dh | 
					
						
							| 
									
										
										
										
											2016-01-22 16:25:01 +01:00
										 |  |  | 			case AllocationStrategyRandom: | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 				dh, err := NewInboundDetourHandlerDynamic(vpoint.space, detourConfig) | 
					
						
							| 
									
										
										
										
											2016-01-22 16:25:01 +01:00
										 |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					log.Error("Point: Failed to create detour handler: ", err) | 
					
						
							| 
									
										
										
										
											2016-01-30 12:12:57 +01:00
										 |  |  | 					return nil, ErrorBadConfiguration | 
					
						
							| 
									
										
										
										
											2016-01-22 16:25:01 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				detourHandler = dh | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 			default: | 
					
						
							|  |  |  | 				log.Error("Point: Unknown allocation strategy: ", allocConfig.Strategy) | 
					
						
							| 
									
										
										
										
											2016-01-30 12:12:57 +01:00
										 |  |  | 				return nil, ErrorBadConfiguration | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			vpoint.idh[idx] = detourHandler | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | 			if len(detourConfig.Tag) > 0 { | 
					
						
							|  |  |  | 				vpoint.taggedIdh[detourConfig.Tag] = detourHandler | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 	outboundDetours := pConfig.OutboundDetours | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 	if len(outboundDetours) > 0 { | 
					
						
							| 
									
										
										
										
											2016-01-25 17:18:24 +01:00
										 |  |  | 		vpoint.odh = make(map[string]proxy.OutboundHandler) | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 		for _, detourConfig := range outboundDetours { | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 			detourHandler, err := proxyrepo.CreateOutboundHandler( | 
					
						
							|  |  |  | 				detourConfig.Protocol, vpoint.space, detourConfig.Settings, &proxy.OutboundHandlerMeta{ | 
					
						
							|  |  |  | 					Tag:     detourConfig.Tag, | 
					
						
							|  |  |  | 					Address: detourConfig.SendThrough}) | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2016-06-01 22:45:12 +02:00
										 |  |  | 				log.Error("Point: Failed to create detour outbound connection handler: ", err) | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-01-17 21:43:10 +01:00
										 |  |  | 			vpoint.odh[detourConfig.Tag] = detourHandler | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | 			outboundHandlerManager.SetHandler(detourConfig.Tag, detourHandler) | 
					
						
							| 
									
										
										
										
											2015-11-22 17:41:52 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-18 08:12:04 -07:00
										 |  |  | 	if err := vpoint.space.Initialize(); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-06 22:10:42 +02:00
										 |  |  | 	return vpoint, nil | 
					
						
							| 
									
										
										
										
											2015-09-05 17:48:38 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-04 00:33:25 +01:00
										 |  |  | func (this *Point) Close() { | 
					
						
							|  |  |  | 	this.ich.Close() | 
					
						
							|  |  |  | 	for _, idh := range this.idh { | 
					
						
							|  |  |  | 		idh.Close() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-12 22:11:54 +02:00
										 |  |  | // Start starts the Point server, and return any error during the process. | 
					
						
							| 
									
										
										
										
											2015-09-07 12:00:46 +02:00
										 |  |  | // In the case of any errors, the state of the server is unpredicatable. | 
					
						
							| 
									
										
										
										
											2015-11-27 12:29:20 +01:00
										 |  |  | func (this *Point) Start() error { | 
					
						
							|  |  |  | 	if this.port <= 0 { | 
					
						
							| 
									
										
										
										
											2016-06-01 22:45:12 +02:00
										 |  |  | 		log.Error("Point: Invalid port ", this.port) | 
					
						
							| 
									
										
										
										
											2016-01-30 12:12:57 +01:00
										 |  |  | 		return ErrorBadConfiguration | 
					
						
							| 
									
										
										
										
											2015-09-06 22:10:42 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-09-22 18:11:55 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 	err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error { | 
					
						
							| 
									
										
										
										
											2016-06-04 00:38:22 +02:00
										 |  |  | 		err := this.ich.Start() | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2015-10-14 01:15:29 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-01 22:45:12 +02:00
										 |  |  | 		log.Warning("Point: started on port ", this.port) | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2015-10-13 12:27:50 +02:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-27 12:29:20 +01:00
										 |  |  | 	for _, detourHandler := range this.idh { | 
					
						
							| 
									
										
										
										
											2015-11-01 00:11:41 +01:00
										 |  |  | 		err := detourHandler.Start() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-09-06 22:10:42 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-09-11 00:24:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-17 23:05:52 -07:00
										 |  |  | func (this *Point) GetHandler(tag string) (proxy.InboundHandler, int) { | 
					
						
							| 
									
										
										
										
											2016-01-21 16:22:56 +00:00
										 |  |  | 	handler, found := this.taggedIdh[tag] | 
					
						
							|  |  |  | 	if !found { | 
					
						
							| 
									
										
										
										
											2016-01-30 11:45:33 +01:00
										 |  |  | 		log.Warning("Point: Unable to find an inbound handler with tag: ", tag) | 
					
						
							| 
									
										
										
										
											2016-01-21 16:22:56 +00:00
										 |  |  | 		return nil, 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return handler.GetConnectionHandler() | 
					
						
							| 
									
										
										
										
											2016-01-21 01:40:52 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-18 08:12:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | func (this *Point) Release() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |