mirror of
				https://github.com/e1732a364fed/v2ray_simple.git
				synced 2025-10-31 12:06:21 +08:00 
			
		
		
		
	大范围修订代码,以试图防止内存逃逸到堆;
This commit is contained in:
		
							
								
								
									
										21
									
								
								commands.go
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								commands.go
									
									
									
									
									
								
							| @@ -12,10 +12,6 @@ import ( | |||||||
| 	"github.com/hahahrfool/v2ray_simple/utils" | 	"github.com/hahahrfool/v2ray_simple/utils" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const ( |  | ||||||
| 	mmdbDownloadLink = "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| var ( | var ( | ||||||
| 	cmdPrintSupportedProtocols bool | 	cmdPrintSupportedProtocols bool | ||||||
| 	cmdGenerateUUID            bool | 	cmdGenerateUUID            bool | ||||||
| @@ -39,7 +35,7 @@ func generateAndPrintUUID() { | |||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	log.Println("Your new randomly generated uuid is : ", utils.GenerateUUIDStr()) | 	log.Printf("Your new randomly generated uuid is : %s\n", utils.GenerateUUIDStr()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func mayPrintSupportedProtocols() { | func mayPrintSupportedProtocols() { | ||||||
| @@ -55,33 +51,36 @@ func tryDownloadMMDB() { | |||||||
| 	if utils.FileExist(utils.GetFilePath(netLayer.GeoipFileName)) { | 	if utils.FileExist(utils.GetFilePath(netLayer.GeoipFileName)) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	log.Println("No GeoLite2-Country.mmdb found,start downloading from " + mmdbDownloadLink) |  | ||||||
|  | 	const mmdbDownloadLink = "https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/Country.mmdb" | ||||||
|  |  | ||||||
|  | 	log.Printf("No GeoLite2-Country.mmdb found,start downloading from%s\n", mmdbDownloadLink) | ||||||
|  |  | ||||||
| 	resp, err := http.Get(mmdbDownloadLink) | 	resp, err := http.Get(mmdbDownloadLink) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Println("Download mmdb failed", err) | 		log.Printf("Download mmdb failed%s\n", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	defer resp.Body.Close() | 	defer resp.Body.Close() | ||||||
|  |  | ||||||
| 	out, err := os.Create(netLayer.GeoipFileName) | 	out, err := os.Create(netLayer.GeoipFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Println("Download mmdb but Can't CreateFile,", err) | 		log.Printf("Download mmdb but Can't CreateFile,%s\n", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	defer out.Close() | 	defer out.Close() | ||||||
|  |  | ||||||
| 	if resp.StatusCode != http.StatusOK { | 	if resp.StatusCode != http.StatusOK { | ||||||
| 		log.Println("Download mmdb bad status:", resp.Status) | 		log.Printf("Download mmdb bad status:%s\n", resp.Status) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	_, err = io.Copy(out, resp.Body) | 	_, err = io.Copy(out, resp.Body) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		log.Println("Write downloaded mmdb to file err:", err) | 		log.Printf("Write downloaded mmdb to file err:%s\n", err) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	log.Println("Download mmdb success!") | 	log.Printf("Download mmdb success!\n") | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								configs.go
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								configs.go
									
									
									
									
									
								
							| @@ -33,7 +33,7 @@ func loadConfig() { | |||||||
| 			standardConf, err = proxy.LoadTomlConfFile(fpath) | 			standardConf, err = proxy.LoadTomlConfFile(fpath) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
|  |  | ||||||
| 				log.Fatalln("can not load standard config file: ", err) | 				log.Fatalf("can not load standard config file: %s\n", err) | ||||||
| 			} | 			} | ||||||
| 			//log.Println("standardConf.Fallbacks: ", len(standardConf.Fallbacks)) | 			//log.Println("standardConf.Fallbacks: ", len(standardConf.Fallbacks)) | ||||||
| 			if len(standardConf.Fallbacks) != 0 { | 			if len(standardConf.Fallbacks) != 0 { | ||||||
| @@ -53,10 +53,11 @@ func loadConfig() { | |||||||
| 			//默认认为所有其他后缀的都是json格式,因为有时我会用 server.json.vless 这种写法 | 			//默认认为所有其他后缀的都是json格式,因为有时我会用 server.json.vless 这种写法 | ||||||
| 			// 默认所有json格式的文件都为 极简模式 | 			// 默认所有json格式的文件都为 极简模式 | ||||||
|  |  | ||||||
| 			simpleConf, err = proxy.LoadSimpleConfigFile(fpath) | 			var hasE bool | ||||||
| 			if err != nil { | 			simpleConf, hasE, err = proxy.LoadSimpleConfigFile(fpath) | ||||||
|  | 			if hasE { | ||||||
|  |  | ||||||
| 				log.Fatalln("can not load simple config file: ", err) | 				log.Fatalf("can not load simple config file: %s\n", err) | ||||||
| 			} | 			} | ||||||
| 			if simpleConf.Fallbacks != nil { | 			if simpleConf.Fallbacks != nil { | ||||||
| 				mainFallback = httpLayer.NewClassicFallbackFromConfList(simpleConf.Fallbacks) | 				mainFallback = httpLayer.NewClassicFallbackFromConfList(simpleConf.Fallbacks) | ||||||
| @@ -70,15 +71,15 @@ func loadConfig() { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		log.Println("No Such Config File:", configFileName, ",will try using -L parameter ") | 		log.Printf("No Such Config File:%s,will try using -L parameter \n", configFileName) | ||||||
| 		if listenURL != "" { | 		if listenURL != "" { | ||||||
| 			_, err = url.Parse(listenURL) | 			_, err = url.Parse(listenURL) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Fatalln("listenURL given but invalid ", listenURL, err) | 				log.Fatalf("listenURL given but invalid %s %s\n", listenURL, err) | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			simpleConf = &proxy.Simple{ | 			simpleConf = proxy.Simple{ | ||||||
| 				Server_ThatListenPort_Url: listenURL, | 				Server_ThatListenPort_Url: listenURL, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -86,7 +87,7 @@ func loadConfig() { | |||||||
|  |  | ||||||
| 				_, err = url.Parse(dialURL) | 				_, err = url.Parse(dialURL) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					log.Fatalln("dialURL given but invalid ", dialURL, err) | 					log.Fatalf("dialURL given but invalid %s %s\n", dialURL, err) | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -94,7 +95,7 @@ func loadConfig() { | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		} else { | 		} else { | ||||||
| 			log.Fatalln("no -L listen URL provided ") | 			log.Fatalf("no -L listen URL provided \n") | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ func (c *Conn) Read(b []byte) (n int, err error) { | |||||||
| 	if c.cacheReader == nil { | 	if c.cacheReader == nil { | ||||||
| 		h, err := c.stream.Recv() | 		h, err := c.stream.Recv() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return 0, utils.NewErr("unable to read from gun tunnel", err) | 			return 0, utils.ErrInErr{ErrDesc: "unable to read from gun tunnel", ErrDetail: err} | ||||||
| 		} | 		} | ||||||
| 		c.cacheReader = bytes.NewReader(h.Data) | 		c.cacheReader = bytes.NewReader(h.Data) | ||||||
| 	} | 	} | ||||||
| @@ -47,7 +47,7 @@ func (c *Conn) Read(b []byte) (n int, err error) { | |||||||
| func (c *Conn) Write(b []byte) (n int, err error) { | func (c *Conn) Write(b []byte) (n int, err error) { | ||||||
| 	err = c.stream.Send(&Hunk{Data: b}) | 	err = c.stream.Send(&Hunk{Data: b}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return 0, utils.NewErr("Unable to send data over stream service", err) | 		return 0, utils.ErrInErr{ErrDesc: "Unable to send data over stream service", ErrDetail: err} | ||||||
| 	} | 	} | ||||||
| 	return len(b), nil | 	return len(b), nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -333,14 +333,14 @@ func NewClassicFallbackFromConfList(fcl []*FallbackConf) *ClassicFallback { | |||||||
| 	return cfb | 	return cfb | ||||||
| } | } | ||||||
|  |  | ||||||
| func (cfb *ClassicFallback) InsertFallbackConditionSet(condition FallbackConditionSet, addr *netLayer.Addr) { | func (cfb *ClassicFallback) InsertFallbackConditionSet(condition FallbackConditionSet, addr netLayer.Addr) { | ||||||
|  |  | ||||||
| 	theMap := cfb.Map | 	theMap := cfb.Map | ||||||
|  |  | ||||||
| 	ftype := condition.GetType() | 	ftype := condition.GetType() | ||||||
| 	cfb.supportedTypeMask |= ftype | 	cfb.supportedTypeMask |= ftype | ||||||
|  |  | ||||||
| 	theMap[condition] = addr | 	theMap[condition] = &addr | ||||||
| } | } | ||||||
|  |  | ||||||
| func (cfb *ClassicFallback) FirstBuffer() *bytes.Buffer { | func (cfb *ClassicFallback) FirstBuffer() *bytes.Buffer { | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								main.go
									
									
									
									
									
								
							| @@ -42,9 +42,9 @@ var ( | |||||||
| 	uniqueTestDomain string //有时需要测试到单一网站的流量,此时为了避免其它干扰,需要在这里声明 一下 该域名,然后程序里会进行过滤 | 	uniqueTestDomain string //有时需要测试到单一网站的流量,此时为了避免其它干扰,需要在这里声明 一下 该域名,然后程序里会进行过滤 | ||||||
|  |  | ||||||
| 	confMode           int = -1 //0: simple json, 1: standard toml, 2: v2ray compatible json | 	confMode           int = -1 //0: simple json, 1: standard toml, 2: v2ray compatible json | ||||||
| 	simpleConf      *proxy.Simple | 	simpleConf         proxy.Simple | ||||||
| 	standardConf    *proxy.Standard | 	standardConf       proxy.Standard | ||||||
| 	directClient, _ = proxy.ClientFromURL("direct://") | 	directClient, _, _ = proxy.ClientFromURL("direct://") | ||||||
| 	default_uuid       string | 	default_uuid       string | ||||||
|  |  | ||||||
| 	allServers = make([]proxy.Server, 0, 8) | 	allServers = make([]proxy.Server, 0, 8) | ||||||
| @@ -138,11 +138,9 @@ func main() { | |||||||
| 		netLayer.UseReadv = usereadv_beforeLoadConfigFile | 		netLayer.UseReadv = usereadv_beforeLoadConfigFile | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	fmt.Println("Log Level:", utils.LogLevel) | 	//Printf不会发生 escapes to heap 现象,所以我们统一用 Printf | ||||||
| 	fmt.Println("UseReadv:", netLayer.UseReadv) | 	fmt.Printf("Log Level:%d\n", utils.LogLevel) | ||||||
| 	if utils.CanLogDebug() { | 	fmt.Printf("UseReadv:%t\n", netLayer.UseReadv) | ||||||
| 		fmt.Println("MaxBufSize", utils.MaxBufLen) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	runPreCommands() | 	runPreCommands() | ||||||
|  |  | ||||||
| @@ -153,9 +151,10 @@ func main() { | |||||||
| 	//load server and routePolicy | 	//load server and routePolicy | ||||||
| 	switch confMode { | 	switch confMode { | ||||||
| 	case simpleMode: | 	case simpleMode: | ||||||
| 		defaultInServer, err = proxy.ServerFromURL(simpleConf.Server_ThatListenPort_Url) | 		var hase bool | ||||||
| 		if err != nil { | 		defaultInServer, hase, err = proxy.ServerFromURL(simpleConf.Server_ThatListenPort_Url) | ||||||
| 			log.Fatalln("can not create local server: ", err) | 		if hase { | ||||||
|  | 			log.Fatalf("can not create local server: %s\n", err) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if !defaultInServer.CantRoute() && simpleConf.Route != nil { | 		if !defaultInServer.CantRoute() && simpleConf.Route != nil { | ||||||
| @@ -217,8 +216,9 @@ func main() { | |||||||
| 	// load client | 	// load client | ||||||
| 	switch confMode { | 	switch confMode { | ||||||
| 	case simpleMode: | 	case simpleMode: | ||||||
| 		defaultOutClient, err = proxy.ClientFromURL(simpleConf.Client_ThatDialRemote_Url) | 		var hase bool | ||||||
| 		if err != nil { | 		defaultOutClient, hase, err = proxy.ClientFromURL(simpleConf.Client_ThatDialRemote_Url) | ||||||
|  | 		if hase { | ||||||
| 			log.Fatalln("can not create remote client: ", err) | 			log.Fatalln("can not create remote client: ", err) | ||||||
| 		} | 		} | ||||||
| 	case standardMode: | 	case standardMode: | ||||||
| @@ -274,14 +274,14 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client) { | |||||||
|  |  | ||||||
| 		handleFunc := inServer.HandleInitialLayersFunc() | 		handleFunc := inServer.HandleInitialLayersFunc() | ||||||
| 		if handleFunc == nil { | 		if handleFunc == nil { | ||||||
| 			log.Fatal("inServer.IsHandleInitialLayers but inServer.HandleInitialLayersFunc() returns nil") | 			log.Fatalf("inServer.IsHandleInitialLayers but inServer.HandleInitialLayersFunc() returns nil\n") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		newConnChan, baseConn := handleFunc() | 		newConnChan, baseConn := handleFunc() | ||||||
| 		if newConnChan == nil { | 		if newConnChan == nil { | ||||||
| 			//baseConn可以为nil,quic就是如此 | 			//baseConn可以为nil,quic就是如此 | ||||||
| 			if utils.CanLogErr() { | 			if utils.CanLogErr() { | ||||||
| 				log.Println("StarthandleInitialLayers can't extablish baseConn") | 				log.Printf("StarthandleInitialLayers can't extablish baseConn\n") | ||||||
| 			} | 			} | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| @@ -291,7 +291,7 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client) { | |||||||
| 				newConn, ok := <-newConnChan | 				newConn, ok := <-newConnChan | ||||||
| 				if !ok { | 				if !ok { | ||||||
| 					if utils.CanLogErr() { | 					if utils.CanLogErr() { | ||||||
| 						log.Println("read from SuperProxy not ok") | 						log.Printf("read from SuperProxy not ok\n") | ||||||
|  |  | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -313,7 +313,7 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client) { | |||||||
| 		}() | 		}() | ||||||
|  |  | ||||||
| 		if utils.CanLogInfo() { | 		if utils.CanLogInfo() { | ||||||
| 			log.Println(proxy.GetFullName(inServer), "is listening ", inServer.Network(), "on", inServer.AddrStr()) | 			log.Printf("%s is listening %s on %s\n", proxy.GetFullName(inServer), inServer.Network(), inServer.AddrStr()) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| @@ -328,13 +328,13 @@ func listenSer(inServer proxy.Server, defaultOutClientForThis proxy.Client) { | |||||||
|  |  | ||||||
| 	if err == nil { | 	if err == nil { | ||||||
| 		if utils.CanLogInfo() { | 		if utils.CanLogInfo() { | ||||||
| 			log.Println(proxy.GetFullName(inServer), "is listening ", network, "on", inServer.AddrStr()) | 			log.Printf("%s is listening %s on %s\n", proxy.GetFullName(inServer), network, inServer.AddrStr()) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatalln("can not listen inServer on", inServer.AddrStr(), err) | 			log.Fatalf("can not listen inServer on %s %s\n", inServer.AddrStr(), err) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -392,7 +392,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
|  |  | ||||||
| 	if utils.CanLogInfo() { | 	if utils.CanLogInfo() { | ||||||
| 		str := wrappedConn.RemoteAddr().String() | 		str := wrappedConn.RemoteAddr().String() | ||||||
| 		log.Println("New Accepted Conn from", str, ", being handled by "+proxy.GetVSI_url(inServer)) | 		log.Printf("New Accepted Conn from %s , being handled by %s\n", str, proxy.GetVSI_url(inServer)) | ||||||
|  |  | ||||||
| 		iics.cachedRemoteAddr = str | 		iics.cachedRemoteAddr = str | ||||||
| 	} | 	} | ||||||
| @@ -419,7 +419,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  |  | ||||||
| 			if utils.CanLogErr() { | 			if utils.CanLogErr() { | ||||||
| 				log.Println("failed in inServer tls handshake ", inServer.AddrStr(), err) | 				log.Printf("failed in inServer tls handshake %s %s\n", inServer.AddrStr(), err) | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| 			wrappedConn.Close() | 			wrappedConn.Close() | ||||||
| @@ -450,7 +450,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 			// 我们直接循环监听然后分别用 新goroutine发向 handshakeInserver_and_passToOutClient | 			// 我们直接循环监听然后分别用 新goroutine发向 handshakeInserver_and_passToOutClient | ||||||
|  |  | ||||||
| 			if utils.CanLogDebug() { | 			if utils.CanLogDebug() { | ||||||
| 				log.Println("start upgrade grpc") | 				log.Printf("start upgrade grpc\n") | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			grpcs := inServer.GetGRPC_Server() //这个grpc server是在配置阶段初始化好的. | 			grpcs := inServer.GetGRPC_Server() //这个grpc server是在配置阶段初始化好的. | ||||||
| @@ -464,7 +464,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 				newGConn, ok := <-grpcs.NewConnChan | 				newGConn, ok := <-grpcs.NewConnChan | ||||||
| 				if !ok { | 				if !ok { | ||||||
| 					if utils.CanLogWarn() { | 					if utils.CanLogWarn() { | ||||||
| 						log.Println("grpc getNewSubConn not ok") | 						log.Printf("grpc getNewSubConn not ok\n") | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 					iics.baseLocalConn.Close() | 					iics.baseLocalConn.Close() | ||||||
| @@ -487,12 +487,12 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 			if re != nil { | 			if re != nil { | ||||||
| 				if re == httpLayer.ErrNotHTTP_Request { | 				if re == httpLayer.ErrNotHTTP_Request { | ||||||
| 					if utils.CanLogErr() { | 					if utils.CanLogErr() { | ||||||
| 						log.Println("ws: got not http request ", inServer.AddrStr()) | 						log.Printf("ws: got not http request %s\n", inServer.AddrStr()) | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| 				} else { | 				} else { | ||||||
| 					if utils.CanLogErr() { | 					if utils.CanLogErr() { | ||||||
| 						log.Println("ws: handshake read error ", inServer.AddrStr()) | 						log.Printf("ws: handshake read error %s\n", inServer.AddrStr()) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -507,7 +507,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 				iics.theFallbackFirstBuffer = rp.WholeRequestBuf | 				iics.theFallbackFirstBuffer = rp.WholeRequestBuf | ||||||
|  |  | ||||||
| 				if utils.CanLogDebug() { | 				if utils.CanLogDebug() { | ||||||
| 					log.Println("ws path not match", rp.Method, rp.Path, "should be:", wss.Thepath) | 					log.Printf("ws path not match %s %s should be: %s\n", rp.Method, rp.Path, wss.Thepath) | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -520,7 +520,7 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy | |||||||
| 			wsConn, err := wss.Handshake(rp.WholeRequestBuf, wrappedConn) | 			wsConn, err := wss.Handshake(rp.WholeRequestBuf, wrappedConn) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if utils.CanLogErr() { | 				if utils.CanLogErr() { | ||||||
| 					log.Println("failed in inServer websocket handshake ", inServer.AddrStr(), err) | 					log.Printf("failed in inServer websocket handshake %s %s\n", inServer.AddrStr(), err) | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -550,7 +550,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) { | |||||||
| 	inServer := iics.inServer | 	inServer := iics.inServer | ||||||
|  |  | ||||||
| 	var wlc io.ReadWriteCloser | 	var wlc io.ReadWriteCloser | ||||||
| 	var targetAddr *netLayer.Addr | 	var targetAddr netLayer.Addr | ||||||
| 	var err error | 	var err error | ||||||
|  |  | ||||||
| 	if iics.shouldFallback { | 	if iics.shouldFallback { | ||||||
| @@ -571,7 +571,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) { | |||||||
| 	wlc = nil | 	wlc = nil | ||||||
|  |  | ||||||
| 	if utils.CanLogWarn() { | 	if utils.CanLogWarn() { | ||||||
| 		log.Println("failed in inServer proxy handshake from", inServer.AddrStr(), err) | 		log.Printf("failed in inServer proxy handshake from %s %s\n", inServer.AddrStr(), err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !inServer.CanFallback() { | 	if !inServer.CanFallback() { | ||||||
| @@ -591,7 +591,7 @@ func handshakeInserver_and_passToOutClient(iics incomingInserverConnState) { | |||||||
| 		iics.theFallbackFirstBuffer = fe.First | 		iics.theFallbackFirstBuffer = fe.First | ||||||
| 		if iics.theFallbackFirstBuffer == nil { | 		if iics.theFallbackFirstBuffer == nil { | ||||||
| 			//不应该,至少能读到1字节的。 | 			//不应该,至少能读到1字节的。 | ||||||
| 			log.Fatal("No FirstBuffer") | 			log.Fatalf("No FirstBuffer\n") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -602,7 +602,7 @@ checkFallback: | |||||||
| 	if mainFallback != nil { | 	if mainFallback != nil { | ||||||
|  |  | ||||||
| 		if utils.CanLogDebug() { | 		if utils.CanLogDebug() { | ||||||
| 			log.Println("checkFallback") | 			log.Printf("checkFallback\n") | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var thisFallbackType byte | 		var thisFallbackType byte | ||||||
| @@ -649,10 +649,10 @@ checkFallback: | |||||||
| 		fbAddr := mainFallback.GetFallback(thisFallbackType, fallback_params...) | 		fbAddr := mainFallback.GetFallback(thisFallbackType, fallback_params...) | ||||||
|  |  | ||||||
| 		if utils.CanLogDebug() { | 		if utils.CanLogDebug() { | ||||||
| 			log.Println("checkFallback ,matched fallback:", fbAddr) | 			log.Printf("checkFallback ,matched fallback: %s\n", fbAddr.String()) | ||||||
| 		} | 		} | ||||||
| 		if fbAddr != nil { | 		if fbAddr != nil { | ||||||
| 			targetAddr = fbAddr | 			targetAddr = *fbAddr | ||||||
| 			wlc = wrappedConn | 			wlc = wrappedConn | ||||||
| 			goto afterLocalServerHandshake | 			goto afterLocalServerHandshake | ||||||
| 		} | 		} | ||||||
| @@ -661,7 +661,7 @@ checkFallback: | |||||||
|  |  | ||||||
| 	//默认回落, 每个listen配置 都可 有一个自己独享的默认回落 | 	//默认回落, 每个listen配置 都可 有一个自己独享的默认回落 | ||||||
|  |  | ||||||
| 	if defaultFallbackAddr := inServer.GetFallback(); defaultFallbackAddr != nil { | 	if defaultFallbackAddr := inServer.GetFallback(); !defaultFallbackAddr.IsEmpty() { | ||||||
|  |  | ||||||
| 		targetAddr = defaultFallbackAddr | 		targetAddr = defaultFallbackAddr | ||||||
| 		wlc = wrappedConn | 		wlc = wrappedConn | ||||||
| @@ -673,7 +673,7 @@ afterLocalServerHandshake: | |||||||
| 	if wlc == nil { | 	if wlc == nil { | ||||||
| 		//无wlc证明 inServer 握手失败,且 没有任何回落可用, 直接return | 		//无wlc证明 inServer 握手失败,且 没有任何回落可用, 直接return | ||||||
| 		if utils.CanLogDebug() { | 		if utils.CanLogDebug() { | ||||||
| 			log.Println("invalid request and no matched fallback, hung up.") | 			log.Printf("invalid request and no matched fallback, hung up.\n") | ||||||
| 		} | 		} | ||||||
| 		wrappedConn.Close() | 		wrappedConn.Close() | ||||||
| 		return | 		return | ||||||
| @@ -692,7 +692,7 @@ afterLocalServerHandshake: | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if utils.CanLogDebug() { | 		if utils.CanLogDebug() { | ||||||
| 			log.Println("try routing", desc) | 			log.Printf("try routing %v\n", desc) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		outtag := routePolicy.GetOutTag(desc) | 		outtag := routePolicy.GetOutTag(desc) | ||||||
| @@ -702,7 +702,7 @@ afterLocalServerHandshake: | |||||||
| 			iics.routedToDirect = true | 			iics.routedToDirect = true | ||||||
|  |  | ||||||
| 			if utils.CanLogInfo() { | 			if utils.CanLogInfo() { | ||||||
| 				log.Println("routed to direct", targetAddr.UrlString()) | 				log.Printf("routed to direct %s\n", targetAddr.UrlString()) | ||||||
| 			} | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			//log.Println("outtag", outtag, clientsTagMap) | 			//log.Println("outtag", outtag, clientsTagMap) | ||||||
| @@ -710,7 +710,7 @@ afterLocalServerHandshake: | |||||||
| 			if tagC, ok := clientsTagMap[outtag]; ok { | 			if tagC, ok := clientsTagMap[outtag]; ok { | ||||||
| 				client = tagC | 				client = tagC | ||||||
| 				if utils.CanLogInfo() { | 				if utils.CanLogInfo() { | ||||||
| 					log.Println("routed to", outtag, proxy.GetFullName(client)) | 					log.Printf("routed to %s %s\n", outtag, proxy.GetFullName(client)) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -743,7 +743,7 @@ afterLocalServerHandshake: | |||||||
| 	if isTlsLazy_clientEnd || iics.isTlsLazyServerEnd { | 	if isTlsLazy_clientEnd || iics.isTlsLazyServerEnd { | ||||||
|  |  | ||||||
| 		if tlsLayer.PDD { | 		if tlsLayer.PDD { | ||||||
| 			log.Println("loading TLS SniffConn", isTlsLazy_clientEnd, iics.isTlsLazyServerEnd) | 			log.Printf("loading TLS SniffConn %t %t\n", isTlsLazy_clientEnd, iics.isTlsLazyServerEnd) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		wlc = tlsLayer.NewSniffConn(iics.baseLocalConn, wlc, isTlsLazy_clientEnd, tls_lazy_secure) | 		wlc = tlsLayer.NewSniffConn(iics.baseLocalConn, wlc, isTlsLazy_clientEnd, tls_lazy_secure) | ||||||
| @@ -836,7 +836,7 @@ afterLocalServerHandshake: | |||||||
|  |  | ||||||
| 				unknownRemoteAddrMsgWriter = theCRUMFURS | 				unknownRemoteAddrMsgWriter = theCRUMFURS | ||||||
|  |  | ||||||
| 				uniExtractor := netLayer.NewUniUDP_Extractor(targetAddr.ToUDPAddr(), wlc, unknownRemoteAddrMsgWriter) | 				uniExtractor := netLayer.NewUniUDP_Extractor(*targetAddr.ToUDPAddr(), wlc, unknownRemoteAddrMsgWriter) | ||||||
|  |  | ||||||
| 				netLayer.RelayUDP_to_Direct(uniExtractor) //阻塞 | 				netLayer.RelayUDP_to_Direct(uniExtractor) //阻塞 | ||||||
|  |  | ||||||
| @@ -847,7 +847,7 @@ afterLocalServerHandshake: | |||||||
| 			// 此时socks5包已经帮我们dial好了一个udp连接,即wlc,但是还未读取到客户端想要访问的东西 | 			// 此时socks5包已经帮我们dial好了一个udp连接,即wlc,但是还未读取到客户端想要访问的东西 | ||||||
| 			udpConn := wlc.(*socks5.UDPConn) | 			udpConn := wlc.(*socks5.UDPConn) | ||||||
|  |  | ||||||
| 			dialFunc := func(targetAddr *netLayer.Addr) (io.ReadWriter, error) { | 			dialFunc := func(targetAddr netLayer.Addr) (io.ReadWriter, error) { | ||||||
| 				return dialClient(incomingInserverConnState{}, targetAddr, client, false, nil, true) | 				return dialClient(incomingInserverConnState{}, targetAddr, client, false, nil, true) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -871,7 +871,7 @@ afterLocalServerHandshake: | |||||||
|  |  | ||||||
| 			} else { | 			} else { | ||||||
| 				if utils.CanLogErr() { | 				if utils.CanLogErr() { | ||||||
| 					log.Println("socks5 server -> client for udp, but client didn't implement netLayer.UDP_Putter", client.Name()) | 					log.Printf("socks5 server -> client for udp, but client didn't implement netLayer.UDP_Putter, %s\n", client.Name()) | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			return | 			return | ||||||
| @@ -892,7 +892,7 @@ afterLocalServerHandshake: | |||||||
| //client为真实要拨号的client,可能会与iics里的defaultClient不同。以client为准。 | //client为真实要拨号的client,可能会与iics里的defaultClient不同。以client为准。 | ||||||
| // wlc为调用者所提供的 此请求的 来源 链接。wlc主要用于 Copy阶段. | // wlc为调用者所提供的 此请求的 来源 链接。wlc主要用于 Copy阶段. | ||||||
| // noCopy是为了让其它调用者自行处理 转发 时使用。 | // noCopy是为了让其它调用者自行处理 转发 时使用。 | ||||||
| func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, client proxy.Client, isTlsLazy_clientEnd bool, wlc io.ReadWriteCloser, noCopy bool) (io.ReadWriter, error) { | func dialClient(iics incomingInserverConnState, targetAddr netLayer.Addr, client proxy.Client, isTlsLazy_clientEnd bool, wlc io.ReadWriteCloser, noCopy bool) (io.ReadWriter, error) { | ||||||
|  |  | ||||||
| 	if iics.shouldCloseInSerBaseConnWhenFinish && !noCopy { | 	if iics.shouldCloseInSerBaseConnWhenFinish && !noCopy { | ||||||
| 		if iics.baseLocalConn != nil { | 		if iics.baseLocalConn != nil { | ||||||
| @@ -906,18 +906,18 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
|  |  | ||||||
| 	//direct的话自己是没有目的地址的,直接使用 请求的地址 | 	//direct的话自己是没有目的地址的,直接使用 请求的地址 | ||||||
| 	// 而其它代理的话, realTargetAddr会被设成实际配置的代理的地址 | 	// 而其它代理的话, realTargetAddr会被设成实际配置的代理的地址 | ||||||
| 	var realTargetAddr *netLayer.Addr = targetAddr | 	var realTargetAddr netLayer.Addr = targetAddr | ||||||
|  |  | ||||||
| 	if uniqueTestDomain != "" && uniqueTestDomain != targetAddr.Name { | 	if uniqueTestDomain != "" && uniqueTestDomain != targetAddr.Name { | ||||||
| 		if utils.CanLogDebug() { | 		if utils.CanLogDebug() { | ||||||
| 			log.Println("request isn't the appointed domain", targetAddr, uniqueTestDomain) | 			log.Printf("request isn't the appointed domain, %s, %s\n", targetAddr.String(), uniqueTestDomain) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		return nil, utils.NumErr{N: 1, Prefix: "dialClient err, "} | 		return nil, utils.NumErr{N: 1, Prefix: "dialClient err, "} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if utils.CanLogInfo() { | 	if utils.CanLogInfo() { | ||||||
| 		log.Println(iics.cachedRemoteAddr, " request ", targetAddr.UrlString(), "through", proxy.GetVSI_url(client)) | 		log.Printf("%s request %s through %s\n", iics.cachedRemoteAddr, targetAddr.UrlString(), proxy.GetVSI_url(client)) | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -926,7 +926,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
|  |  | ||||||
| 		realTargetAddr, err = netLayer.NewAddr(client.AddrStr()) | 		realTargetAddr, err = netLayer.NewAddr(client.AddrStr()) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatal("convert addr err:", err) | 			log.Fatalf("convert addr err:%s\n", err) | ||||||
| 		} | 		} | ||||||
| 		realTargetAddr.Network = client.Network() | 		realTargetAddr.Network = client.Network() | ||||||
| 	} | 	} | ||||||
| @@ -943,7 +943,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
| 	switch client.AdvancedLayer() { | 	switch client.AdvancedLayer() { | ||||||
| 	case "grpc": | 	case "grpc": | ||||||
|  |  | ||||||
| 		grpcClientConn = grpc.GetEstablishedConnFor(realTargetAddr) | 		grpcClientConn = grpc.GetEstablishedConnFor(&realTargetAddr) | ||||||
|  |  | ||||||
| 		if grpcClientConn != nil { | 		if grpcClientConn != nil { | ||||||
| 			//如果有已经建立好的连接,则跳过拨号阶段 | 			//如果有已经建立好的连接,则跳过拨号阶段 | ||||||
| @@ -951,7 +951,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
| 		} | 		} | ||||||
| 	case "quic": | 	case "quic": | ||||||
| 		//quic这里并不是在tls层基础上进行dial,而是直接dial | 		//quic这里并不是在tls层基础上进行dial,而是直接dial | ||||||
| 		dailedCommonConn = client.DialCommonInitialLayerConnFunc()(realTargetAddr) | 		dailedCommonConn = client.DialCommonInitialLayerConnFunc()(&realTargetAddr) | ||||||
| 		if dailedCommonConn != nil { | 		if dailedCommonConn != nil { | ||||||
| 			//如果有已经建立好的连接,则跳过拨号阶段 | 			//如果有已经建立好的连接,则跳过拨号阶段 | ||||||
| 			goto advLayerStep | 			goto advLayerStep | ||||||
| @@ -965,7 +965,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
| 	clientConn, err = realTargetAddr.Dial() | 	clientConn, err = realTargetAddr.Dial() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if utils.CanLogErr() { | 		if utils.CanLogErr() { | ||||||
| 			log.Println("failed in dial", realTargetAddr.String(), ", Reason: ", err) | 			log.Printf("failed in dial %s , Reason: , %s\n", realTargetAddr.String(), err) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		return nil, utils.NumErr{N: 2, Prefix: "dialClient err, "} | 		return nil, utils.NumErr{N: 2, Prefix: "dialClient err, "} | ||||||
| @@ -986,7 +986,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
| 				// 而且为了避免黑客攻击或探测,我们要使用uuid作为特殊指令,此时需要 UserServer和 UserClient | 				// 而且为了避免黑客攻击或探测,我们要使用uuid作为特殊指令,此时需要 UserServer和 UserClient | ||||||
|  |  | ||||||
| 				if uc := client.(proxy.UserClient); uc != nil { | 				if uc := client.(proxy.UserClient); uc != nil { | ||||||
| 					tryTlsLazyRawCopy(true, uc, nil, targetAddr, clientConn, wlc, nil, true, nil) | 					tryTlsLazyRawCopy(true, uc, nil, &targetAddr, clientConn, wlc, nil, true, nil) | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -1002,7 +1002,7 @@ func dialClient(iics incomingInserverConnState, targetAddr *netLayer.Addr, clien | |||||||
|  |  | ||||||
| 		tlsConn, err := client.GetTLS_Client().Handshake(clientConn) | 		tlsConn, err := client.GetTLS_Client().Handshake(clientConn) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Println("failed in handshake outClient tls", targetAddr.String(), ", Reason: ", err) | 			log.Printf("failed in handshake outClient tls %s, Reason: %s\n", targetAddr.String(), err) | ||||||
| 			return nil, utils.NumErr{N: 4, Prefix: "dialClient err, "} | 			return nil, utils.NumErr{N: 4, Prefix: "dialClient err, "} | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -1020,16 +1020,16 @@ advLayerStep: | |||||||
| 			clientConn, err = client.DialSubConnFunc()(dailedCommonConn) | 			clientConn, err = client.DialSubConnFunc()(dailedCommonConn) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if utils.CanLogErr() { | 				if utils.CanLogErr() { | ||||||
| 					log.Println("DialSubConnFunc failed,", err) | 					log.Printf("DialSubConnFunc failed, %s\n", err) | ||||||
| 				} | 				} | ||||||
| 				return nil, utils.NumErr{N: 14, Prefix: "DialSubConnFunc err, "} | 				return nil, utils.NumErr{N: 14, Prefix: "DialSubConnFunc err, "} | ||||||
| 			} | 			} | ||||||
| 		case "grpc": | 		case "grpc": | ||||||
| 			if grpcClientConn == nil { | 			if grpcClientConn == nil { | ||||||
| 				grpcClientConn, err = grpc.ClientHandshake(clientConn, realTargetAddr) | 				grpcClientConn, err = grpc.ClientHandshake(clientConn, &realTargetAddr) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					if utils.CanLogErr() { | 					if utils.CanLogErr() { | ||||||
| 						log.Println("grpc.ClientHandshake failed,", err) | 						log.Printf("grpc.ClientHandshake failed, %s\n", err) | ||||||
|  |  | ||||||
| 					} | 					} | ||||||
| 					if iics.baseLocalConn != nil { | 					if iics.baseLocalConn != nil { | ||||||
| @@ -1041,10 +1041,10 @@ advLayerStep: | |||||||
|  |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			clientConn, err = grpc.DialNewSubConn(client.Path(), grpcClientConn, realTargetAddr) | 			clientConn, err = grpc.DialNewSubConn(client.Path(), grpcClientConn, &realTargetAddr) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if utils.CanLogErr() { | 				if utils.CanLogErr() { | ||||||
| 					log.Println("grpc.DialNewSubConn failed,", err) | 					log.Printf("grpc.DialNewSubConn failed,%s\n", err) | ||||||
|  |  | ||||||
| 					//如果底层tcp连接被关闭了的话,错误会是: | 					//如果底层tcp连接被关闭了的话,错误会是: | ||||||
| 					// rpc error: code = Unavailable desc = connection error: desc = "transport: failed to write client preface: tls: use of closed connection" | 					// rpc error: code = Unavailable desc = connection error: desc = "transport: failed to write client preface: tls: use of closed connection" | ||||||
| @@ -1068,7 +1068,7 @@ advLayerStep: | |||||||
| 				n, e := wlc.Read(edBuf) | 				n, e := wlc.Read(edBuf) | ||||||
| 				if e != nil { | 				if e != nil { | ||||||
| 					if utils.CanLogErr() { | 					if utils.CanLogErr() { | ||||||
| 						log.Println("err when reading ws early data", e) | 						log.Printf("err when reading ws early data %s\n", e) | ||||||
| 					} | 					} | ||||||
| 					return nil, utils.NumErr{N: 7, Prefix: "dialClient err, "} | 					return nil, utils.NumErr{N: 7, Prefix: "dialClient err, "} | ||||||
| 				} | 				} | ||||||
| @@ -1093,7 +1093,7 @@ advLayerStep: | |||||||
| 			//wc, err := wsClient.Handshake(clientConn, ed) | 			//wc, err := wsClient.Handshake(clientConn, ed) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				if utils.CanLogErr() { | 				if utils.CanLogErr() { | ||||||
| 					log.Println("failed in handshake ws to", targetAddr.String(), ", Reason: ", err) | 					log.Printf("failed in handshake ws to %s , Reason: %s\n", targetAddr.String(), err) | ||||||
|  |  | ||||||
| 				} | 				} | ||||||
| 				return nil, utils.NumErr{N: 8, Prefix: "dialClient err, "} | 				return nil, utils.NumErr{N: 8, Prefix: "dialClient err, "} | ||||||
| @@ -1105,10 +1105,10 @@ advLayerStep: | |||||||
|  |  | ||||||
| 	////////////////////////////// 代理层 握手阶段 ///////////////////////////////////// | 	////////////////////////////// 代理层 握手阶段 ///////////////////////////////////// | ||||||
|  |  | ||||||
| 	wrc, err := client.Handshake(clientConn, targetAddr) | 	wrc, err := client.Handshake(clientConn, &targetAddr) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if utils.CanLogErr() { | 		if utils.CanLogErr() { | ||||||
| 			log.Println("failed in handshake to", targetAddr.String(), ", Reason: ", err) | 			log.Printf("failed in handshake to %s , Reason: %s\n", targetAddr.String(), err) | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		return nil, utils.NumErr{N: 9, Prefix: "dialClient err, "} | 		return nil, utils.NumErr{N: 9, Prefix: "dialClient err, "} | ||||||
| @@ -1154,7 +1154,7 @@ advLayerStep: | |||||||
| 		utils.PutBytes(iics.theFallbackFirstBuffer.Bytes()) //这个Buf不是从utils.GetBuf创建的,而是从一个 GetBytes的[]byte 包装 的,所以我们要PutBytes,而不是PutBuf | 		utils.PutBytes(iics.theFallbackFirstBuffer.Bytes()) //这个Buf不是从utils.GetBuf创建的,而是从一个 GetBytes的[]byte 包装 的,所以我们要PutBytes,而不是PutBuf | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	netLayer.Relay(realTargetAddr, wlc, wrc) | 	netLayer.Relay(&realTargetAddr, wlc, wrc) | ||||||
|  |  | ||||||
| 	return wrc, nil | 	return wrc, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -48,8 +48,8 @@ func GetRandLocalAddr() string { | |||||||
| 	return "0.0.0.0:" + RandPortStr() | 	return "0.0.0.0:" + RandPortStr() | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewAddrFromUDPAddr(addr *net.UDPAddr) *Addr { | func NewAddrFromUDPAddr(addr *net.UDPAddr) Addr { | ||||||
| 	return &Addr{ | 	return Addr{ | ||||||
| 		IP:      addr.IP, | 		IP:      addr.IP, | ||||||
| 		Port:    addr.Port, | 		Port:    addr.Port, | ||||||
| 		Network: "udp", | 		Network: "udp", | ||||||
| @@ -57,27 +57,27 @@ func NewAddrFromUDPAddr(addr *net.UDPAddr) *Addr { | |||||||
| } | } | ||||||
|  |  | ||||||
| //addrStr格式一般为 host:port ;如果不含冒号,将直接认为该字符串是域名或文件名 | //addrStr格式一般为 host:port ;如果不含冒号,将直接认为该字符串是域名或文件名 | ||||||
| func NewAddr(addrStr string) (*Addr, error) { | func NewAddr(addrStr string) (Addr, error) { | ||||||
| 	if !strings.Contains(addrStr, ":") { | 	if !strings.Contains(addrStr, ":") { | ||||||
| 		//unix domain socket, 或者域名默认端口的情况 | 		//unix domain socket, 或者域名默认端口的情况 | ||||||
| 		return &Addr{Name: addrStr}, nil | 		return Addr{Name: addrStr}, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return NewAddrByHostPort(addrStr) | 	return NewAddrByHostPort(addrStr) | ||||||
| } | } | ||||||
|  |  | ||||||
| //hostPortStr格式 必须为 host:port,本函数不对此检查 | //hostPortStr格式 必须为 host:port,本函数不对此检查 | ||||||
| func NewAddrByHostPort(hostPortStr string) (*Addr, error) { | func NewAddrByHostPort(hostPortStr string) (Addr, error) { | ||||||
| 	host, portStr, err := net.SplitHostPort(hostPortStr) | 	host, portStr, err := net.SplitHostPort(hostPortStr) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return Addr{}, err | ||||||
| 	} | 	} | ||||||
| 	if host == "" { | 	if host == "" { | ||||||
| 		host = "127.0.0.1" | 		host = "127.0.0.1" | ||||||
| 	} | 	} | ||||||
| 	port, err := strconv.Atoi(portStr) | 	port, err := strconv.Atoi(portStr) | ||||||
|  |  | ||||||
| 	a := &Addr{Port: port} | 	a := Addr{Port: port} | ||||||
| 	if ip := net.ParseIP(host); ip != nil { | 	if ip := net.ParseIP(host); ip != nil { | ||||||
| 		a.IP = ip | 		a.IP = ip | ||||||
| 	} else { | 	} else { | ||||||
| @@ -88,27 +88,27 @@ func NewAddrByHostPort(hostPortStr string) (*Addr, error) { | |||||||
|  |  | ||||||
| // 如 tcp://127.0.0.1:443 , tcp://google.com:443 ; | // 如 tcp://127.0.0.1:443 , tcp://google.com:443 ; | ||||||
| // 不支持unix domain socket, 因为它是文件路径, / 还需要转义,太麻烦;不是我们代码麻烦, 而是怕用户嫌麻烦 | // 不支持unix domain socket, 因为它是文件路径, / 还需要转义,太麻烦;不是我们代码麻烦, 而是怕用户嫌麻烦 | ||||||
| func NewAddrByURL(addrStr string) (*Addr, error) { | func NewAddrByURL(addrStr string) (Addr, error) { | ||||||
|  |  | ||||||
| 	u, err := url.Parse(addrStr) | 	u, err := url.Parse(addrStr) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return Addr{}, err | ||||||
| 	} | 	} | ||||||
| 	if u.Scheme == "unix" { | 	if u.Scheme == "unix" { | ||||||
| 		return nil, errors.New("parse unix domain socket by url is not supported") | 		return Addr{}, errors.New("parse unix domain socket by url is not supported") | ||||||
| 	} | 	} | ||||||
| 	addrStr = u.Host | 	addrStr = u.Host | ||||||
|  |  | ||||||
| 	host, portStr, err := net.SplitHostPort(addrStr) | 	host, portStr, err := net.SplitHostPort(addrStr) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return Addr{}, err | ||||||
| 	} | 	} | ||||||
| 	if host == "" { | 	if host == "" { | ||||||
| 		host = "127.0.0.1" | 		host = "127.0.0.1" | ||||||
| 	} | 	} | ||||||
| 	port, err := strconv.Atoi(portStr) | 	port, err := strconv.Atoi(portStr) | ||||||
|  |  | ||||||
| 	a := &Addr{Port: port} | 	a := Addr{Port: port} | ||||||
| 	if ip := net.ParseIP(host); ip != nil { | 	if ip := net.ParseIP(host); ip != nil { | ||||||
| 		a.IP = ip | 		a.IP = ip | ||||||
| 	} else { | 	} else { | ||||||
| @@ -121,7 +121,7 @@ func NewAddrByURL(addrStr string) (*Addr, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| //会根据thing的类型 生成实际addr; 可以为数字端口,或者带冒号的字符串,或者一个 文件路径(unix domain socket) | //会根据thing的类型 生成实际addr; 可以为数字端口,或者带冒号的字符串,或者一个 文件路径(unix domain socket) | ||||||
| func NewAddrFromAny(thing any) (addr *Addr, err error) { | func NewAddrFromAny(thing any) (addr Addr, err error) { | ||||||
| 	var integer int | 	var integer int | ||||||
| 	var dest_type byte = 0 //0: port, 1: ip:port, 2: unix domain socket | 	var dest_type byte = 0 //0: port, 1: ip:port, 2: unix domain socket | ||||||
| 	var dest_string string | 	var dest_string string | ||||||
| @@ -130,7 +130,7 @@ func NewAddrFromAny(thing any) (addr *Addr, err error) { | |||||||
| 	case float64: //json 默认把数字转换成float64,就算是整数也一样 | 	case float64: //json 默认把数字转换成float64,就算是整数也一样 | ||||||
|  |  | ||||||
| 		if value > 65535 || value < 1 { | 		if value > 65535 || value < 1 { | ||||||
| 			err = utils.NewDataErr("int port not valid", nil, value) | 			err = utils.ErrInErr{ErrDesc: "int port not valid", Data: value} | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -152,24 +152,24 @@ func NewAddrFromAny(thing any) (addr *Addr, err error) { | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 		err = utils.NewDataErr("Fallback dest config type err", nil, reflect.TypeOf(thing)) | 		err = utils.ErrInErr{ErrDesc: "Fallback dest config type err", Data: reflect.TypeOf(thing)} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	switch dest_type { | 	switch dest_type { | ||||||
| 	case 0: | 	case 0: | ||||||
| 		addr = &Addr{ | 		addr = Addr{ | ||||||
| 			IP:   net.IPv4(127, 0, 0, 1), | 			IP:   net.IPv4(127, 0, 0, 1), | ||||||
| 			Port: integer, | 			Port: integer, | ||||||
| 		} | 		} | ||||||
| 	case 1: | 	case 1: | ||||||
| 		addr, err = NewAddrByHostPort(dest_string) | 		addr, err = NewAddrByHostPort(dest_string) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			err = utils.NewDataErr("addr create with given string failed", err, dest_string) | 			err = utils.ErrInErr{ErrDesc: "addr create with given string failed", ErrDetail: err, Data: dest_string} | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 	case 2: | 	case 2: | ||||||
| 		addr = &Addr{ | 		addr = Addr{ | ||||||
| 			Network: "unix", | 			Network: "unix", | ||||||
| 			Name:    dest_string, | 			Name:    dest_string, | ||||||
| 		} | 		} | ||||||
| @@ -212,6 +212,10 @@ func (a *Addr) UrlString() string { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (a *Addr) IsEmpty() bool { | ||||||
|  | 	return a.Name == "" && len(a.IP) == 0 && a.Network == "" && a.Port == 0 | ||||||
|  | } | ||||||
|  |  | ||||||
| func (a *Addr) GetNetIPAddr() (na netip.Addr) { | func (a *Addr) GetNetIPAddr() (na netip.Addr) { | ||||||
| 	if len(a.IP) < 1 { | 	if len(a.IP) < 1 { | ||||||
| 		return | 		return | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ func ListenAndAccept(network, addr string, acceptFunc func(net.Conn)) error { | |||||||
| 			} | 			} | ||||||
| 			err := os.Remove(addr) | 			err := os.Remove(addr) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return utils.NewDataErr("Error when deleting previous unix socket file,", err, addr) | 				return utils.ErrInErr{ErrDesc: "Error when deleting previous unix socket file,", ErrDetail: err, Data: addr} | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ import ( | |||||||
| // TargetDescription 可以完整地描述一个网络层/传输层上的一个特定目标, | // TargetDescription 可以完整地描述一个网络层/传输层上的一个特定目标, | ||||||
| // 一般来说,一个具体的监听配置就会分配一个tag | // 一般来说,一个具体的监听配置就会分配一个tag | ||||||
| type TargetDescription struct { | type TargetDescription struct { | ||||||
| 	Addr *Addr | 	Addr Addr | ||||||
| 	Tag  string | 	Tag  string | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -72,7 +72,7 @@ func (sg *RouteSet) IsTransportProtocolAllowed(p uint16) bool { | |||||||
| 	return sg.AllowedTransportLayerProtocols&p > 0 | 	return sg.AllowedTransportLayerProtocols&p > 0 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (sg *RouteSet) IsAddrNetworkAllowed(a *Addr) bool { | func (sg *RouteSet) IsAddrNetworkAllowed(a Addr) bool { | ||||||
|  |  | ||||||
| 	if a.Network == "" { | 	if a.Network == "" { | ||||||
| 		return sg.IsTransportProtocolAllowed(TCP) | 		return sg.IsTransportProtocolAllowed(TCP) | ||||||
| @@ -91,7 +91,7 @@ func (sg *RouteSet) IsTCPAllowed() bool { | |||||||
| 	return sg.IsTransportProtocolAllowed(TCP) | 	return sg.IsTransportProtocolAllowed(TCP) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (sg *RouteSet) IsAddrIn(a *Addr) bool { | func (sg *RouteSet) IsAddrIn(a Addr) bool { | ||||||
| 	//我们先过滤传输层,再过滤网络层 | 	//我们先过滤传输层,再过滤网络层 | ||||||
|  |  | ||||||
| 	if !sg.IsAddrNetworkAllowed(a) { | 	if !sg.IsAddrNetworkAllowed(a) { | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ const ( | |||||||
| //本文件内含 一些 转发 udp 数据的 接口与方法 | //本文件内含 一些 转发 udp 数据的 接口与方法 | ||||||
|  |  | ||||||
| // 阻塞. | // 阻塞. | ||||||
| func RelayUDP(putter UDP_Putter, extractor UDP_Extractor, dialFunc func(targetAddr *Addr) (io.ReadWriter, error)) { | func RelayUDP(putter UDP_Putter, extractor UDP_Extractor, dialFunc func(targetAddr Addr) (io.ReadWriter, error)) { | ||||||
|  |  | ||||||
| 	go func() { | 	go func() { | ||||||
| 		for { | 		for { | ||||||
| @@ -43,11 +43,11 @@ func RelayUDP(putter UDP_Putter, extractor UDP_Extractor, dialFunc func(targetAd | |||||||
| //////////////////// 接口 //////////////////// | //////////////////// 接口 //////////////////// | ||||||
|  |  | ||||||
| type UDPRequestReader interface { | type UDPRequestReader interface { | ||||||
| 	GetNewUDPRequest() (*net.UDPAddr, []byte, error) | 	GetNewUDPRequest() (net.UDPAddr, []byte, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| type UDPResponseWriter interface { | type UDPResponseWriter interface { | ||||||
| 	WriteUDPResponse(*net.UDPAddr, []byte) error | 	WriteUDPResponse(net.UDPAddr, []byte) error | ||||||
| } | } | ||||||
|  |  | ||||||
| // UDP_Extractor, 用于从一个虚拟的协议中提取出 udp请求 | // UDP_Extractor, 用于从一个虚拟的协议中提取出 udp请求 | ||||||
| @@ -61,12 +61,12 @@ type UDP_Extractor interface { | |||||||
| // 写入一个UDP请求; 可以包裹成任意协议。 | // 写入一个UDP请求; 可以包裹成任意协议。 | ||||||
| // 因为有时该地址从来没申请过,所以此时就要用dialFunc创建一个新连接 | // 因为有时该地址从来没申请过,所以此时就要用dialFunc创建一个新连接 | ||||||
| type UDPRequestWriter interface { | type UDPRequestWriter interface { | ||||||
| 	WriteUDPRequest(target *net.UDPAddr, request []byte, dialFunc func(targetAddr *Addr) (io.ReadWriter, error)) error | 	WriteUDPRequest(target net.UDPAddr, request []byte, dialFunc func(targetAddr Addr) (io.ReadWriter, error)) error | ||||||
| } | } | ||||||
|  |  | ||||||
| //拉取一个新的 UDP 响应 | //拉取一个新的 UDP 响应 | ||||||
| type UDPResponseReader interface { | type UDPResponseReader interface { | ||||||
| 	GetNewUDPResponse() (*net.UDPAddr, []byte, error) | 	GetNewUDPResponse() (net.UDPAddr, []byte, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| // UDP_Putter, 用于把 udp请求转换成 虚拟的协议 | // UDP_Putter, 用于把 udp请求转换成 虚拟的协议 | ||||||
| @@ -85,14 +85,14 @@ type UDP_Putter interface { | |||||||
| // 对于 vless v1来说, unknownRemoteAddrMsgWriter 要做的 就是 新建一个与服务端的 请求udp的连接, | // 对于 vless v1来说, unknownRemoteAddrMsgWriter 要做的 就是 新建一个与服务端的 请求udp的连接, | ||||||
| //  然后这个新连接就变成了新的 UniUDP_Putter | //  然后这个新连接就变成了新的 UniUDP_Putter | ||||||
| type UniUDP_Putter struct { | type UniUDP_Putter struct { | ||||||
| 	targetAddr *net.UDPAddr | 	targetAddr net.UDPAddr | ||||||
| 	io.ReadWriter | 	io.ReadWriter | ||||||
|  |  | ||||||
| 	unknownRemoteAddrMsgWriter UDPRequestWriter | 	unknownRemoteAddrMsgWriter UDPRequestWriter | ||||||
| } | } | ||||||
|  |  | ||||||
| // | // | ||||||
| func (e *UniUDP_Putter) GetNewUDPResponse() (*net.UDPAddr, []byte, error) { | func (e *UniUDP_Putter) GetNewUDPResponse() (net.UDPAddr, []byte, error) { | ||||||
| 	bs := make([]byte, MaxUDP_packetLen) | 	bs := make([]byte, MaxUDP_packetLen) | ||||||
| 	n, err := e.ReadWriter.Read(bs) | 	n, err := e.ReadWriter.Read(bs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -101,7 +101,7 @@ func (e *UniUDP_Putter) GetNewUDPResponse() (*net.UDPAddr, []byte, error) { | |||||||
| 	return e.targetAddr, bs[:n], nil | 	return e.targetAddr, bs[:n], nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (e *UniUDP_Putter) WriteUDPRequest(addr *net.UDPAddr, bs []byte, dialFunc func(targetAddr *Addr) (io.ReadWriter, error)) (err error) { | func (e *UniUDP_Putter) WriteUDPRequest(addr net.UDPAddr, bs []byte, dialFunc func(targetAddr Addr) (io.ReadWriter, error)) (err error) { | ||||||
|  |  | ||||||
| 	if addr.String() == e.targetAddr.String() { | 	if addr.String() == e.targetAddr.String() { | ||||||
| 		_, err = e.ReadWriter.Write(bs) | 		_, err = e.ReadWriter.Write(bs) | ||||||
| @@ -122,14 +122,14 @@ func (e *UniUDP_Putter) WriteUDPRequest(addr *net.UDPAddr, bs []byte, dialFunc f | |||||||
| //	收到的响应数据的来源 如果和 targetAddr 相同的话,直接写入传入的 ReadWriter | //	收到的响应数据的来源 如果和 targetAddr 相同的话,直接写入传入的 ReadWriter | ||||||
| //  收到的外界数据的来源 如果和 targetAddr 不同的话,那肯定就是使用了fullcone,那么要传入 unknownRemoteAddrMsgWriter; 如果New时传入unknownRemoteAddrMsgWriter的 是nil的话,那么意思就是不支持fullcone,将直接舍弃这一部分数据。 | //  收到的外界数据的来源 如果和 targetAddr 不同的话,那肯定就是使用了fullcone,那么要传入 unknownRemoteAddrMsgWriter; 如果New时传入unknownRemoteAddrMsgWriter的 是nil的话,那么意思就是不支持fullcone,将直接舍弃这一部分数据。 | ||||||
| type UniUDP_Extractor struct { | type UniUDP_Extractor struct { | ||||||
| 	targetAddr *net.UDPAddr | 	targetAddr net.UDPAddr | ||||||
| 	io.ReadWriter | 	io.ReadWriter | ||||||
|  |  | ||||||
| 	unknownRemoteAddrMsgWriter UDPResponseWriter | 	unknownRemoteAddrMsgWriter UDPResponseWriter | ||||||
| } | } | ||||||
|  |  | ||||||
| // 新建,unknownRemoteAddrMsgWriter 用于写入 未知来源响应,rw 用于普通的客户请求的目标的响应 | // 新建,unknownRemoteAddrMsgWriter 用于写入 未知来源响应,rw 用于普通的客户请求的目标的响应 | ||||||
| func NewUniUDP_Extractor(addr *net.UDPAddr, rw io.ReadWriter, unknownRemoteAddrMsgWriter UDPResponseWriter) *UniUDP_Extractor { | func NewUniUDP_Extractor(addr net.UDPAddr, rw io.ReadWriter, unknownRemoteAddrMsgWriter UDPResponseWriter) *UniUDP_Extractor { | ||||||
| 	return &UniUDP_Extractor{ | 	return &UniUDP_Extractor{ | ||||||
| 		targetAddr:                 addr, | 		targetAddr:                 addr, | ||||||
| 		ReadWriter:                 rw, | 		ReadWriter:                 rw, | ||||||
| @@ -138,7 +138,7 @@ func NewUniUDP_Extractor(addr *net.UDPAddr, rw io.ReadWriter, unknownRemoteAddrM | |||||||
| } | } | ||||||
|  |  | ||||||
| // 从客户端连接中 提取出 它的 UDP请求,就是直接读取数据。然后搭配上之前设置好的地址 | // 从客户端连接中 提取出 它的 UDP请求,就是直接读取数据。然后搭配上之前设置好的地址 | ||||||
| func (e *UniUDP_Extractor) GetNewUDPRequest() (*net.UDPAddr, []byte, error) { | func (e *UniUDP_Extractor) GetNewUDPRequest() (net.UDPAddr, []byte, error) { | ||||||
| 	bs := make([]byte, MaxUDP_packetLen) | 	bs := make([]byte, MaxUDP_packetLen) | ||||||
| 	n, err := e.ReadWriter.Read(bs) | 	n, err := e.ReadWriter.Read(bs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -150,7 +150,7 @@ func (e *UniUDP_Extractor) GetNewUDPRequest() (*net.UDPAddr, []byte, error) { | |||||||
| // WriteUDPResponse 写入远程服务器的响应;要分情况讨论。 | // WriteUDPResponse 写入远程服务器的响应;要分情况讨论。 | ||||||
| // 因为是单一目标extractor,所以正常情况下 传入的response 的源地址 也 应和 e.targetAddr 相同, | // 因为是单一目标extractor,所以正常情况下 传入的response 的源地址 也 应和 e.targetAddr 相同, | ||||||
| //  如果地址不同的话,那肯定就是使用了fullcone,那么要传入 unknownRemoteAddrMsgWriter | //  如果地址不同的话,那肯定就是使用了fullcone,那么要传入 unknownRemoteAddrMsgWriter | ||||||
| func (e *UniUDP_Extractor) WriteUDPResponse(addr *net.UDPAddr, bs []byte) (err error) { | func (e *UniUDP_Extractor) WriteUDPResponse(addr net.UDPAddr, bs []byte) (err error) { | ||||||
|  |  | ||||||
| 	if addr.String() == e.targetAddr.String() { | 	if addr.String() == e.targetAddr.String() { | ||||||
| 		_, err = e.ReadWriter.Write(bs) | 		_, err = e.ReadWriter.Write(bs) | ||||||
| @@ -168,7 +168,7 @@ func (e *UniUDP_Extractor) WriteUDPResponse(addr *net.UDPAddr, bs []byte) (err e | |||||||
| } | } | ||||||
|  |  | ||||||
| type UDPAddrData struct { | type UDPAddrData struct { | ||||||
| 	Addr *net.UDPAddr | 	Addr net.UDPAddr | ||||||
| 	Data []byte | 	Data []byte | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -183,20 +183,20 @@ func NewUDP_Pipe() *UDP_Pipe { | |||||||
| 		responseChan: make(chan UDPAddrData, 10), | 		responseChan: make(chan UDPAddrData, 10), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| func (u *UDP_Pipe) GetNewUDPRequest() (*net.UDPAddr, []byte, error) { | func (u *UDP_Pipe) GetNewUDPRequest() (net.UDPAddr, []byte, error) { | ||||||
| 	d := <-u.requestChan | 	d := <-u.requestChan | ||||||
| 	return d.Addr, d.Data, nil | 	return d.Addr, d.Data, nil | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func (u *UDP_Pipe) GetNewUDPResponse() (*net.UDPAddr, []byte, error) { | func (u *UDP_Pipe) GetNewUDPResponse() (net.UDPAddr, []byte, error) { | ||||||
| 	d := <-u.responseChan | 	d := <-u.responseChan | ||||||
| 	return d.Addr, d.Data, nil | 	return d.Addr, d.Data, nil | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 会保存bs的副本,不必担心数据被改变的问题。 | // 会保存bs的副本,不必担心数据被改变的问题。 | ||||||
| func (u *UDP_Pipe) WriteUDPResponse(addr *net.UDPAddr, bs []byte) error { | func (u *UDP_Pipe) WriteUDPResponse(addr net.UDPAddr, bs []byte) error { | ||||||
| 	bsCopy := make([]byte, len(bs)) | 	bsCopy := make([]byte, len(bs)) | ||||||
| 	copy(bsCopy, bs) | 	copy(bsCopy, bs) | ||||||
|  |  | ||||||
| @@ -208,7 +208,7 @@ func (u *UDP_Pipe) WriteUDPResponse(addr *net.UDPAddr, bs []byte) error { | |||||||
| } | } | ||||||
|  |  | ||||||
| // 会保存bs的副本,不必担心数据被改变的问题。 | // 会保存bs的副本,不必担心数据被改变的问题。 | ||||||
| func (u *UDP_Pipe) WriteUDPRequest(addr *net.UDPAddr, bs []byte, dialFunc func(targetAddr *Addr) (io.ReadWriter, error)) error { | func (u *UDP_Pipe) WriteUDPRequest(addr net.UDPAddr, bs []byte, dialFunc func(targetAddr Addr) (io.ReadWriter, error)) error { | ||||||
| 	bsCopy := make([]byte, len(bs)) | 	bsCopy := make([]byte, len(bs)) | ||||||
| 	copy(bsCopy, bs) | 	copy(bsCopy, bs) | ||||||
|  |  | ||||||
| @@ -254,7 +254,7 @@ func RelayUDP_to_Direct(extractor UDP_Extractor) { | |||||||
|  |  | ||||||
| 		} else { | 		} else { | ||||||
|  |  | ||||||
| 			newConn, err := net.DialUDP("udp", nil, addr) | 			newConn, err := net.DialUDP("udp", nil, &addr) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
| @@ -269,7 +269,7 @@ func RelayUDP_to_Direct(extractor UDP_Extractor) { | |||||||
| 			mutex.Unlock() | 			mutex.Unlock() | ||||||
|  |  | ||||||
| 			//监听所有发往 newConn的 远程任意主机 发来的消息。 | 			//监听所有发往 newConn的 远程任意主机 发来的消息。 | ||||||
| 			go func(thisconn *net.UDPConn, supposedRemoteAddr *net.UDPAddr) { | 			go func(thisconn *net.UDPConn, supposedRemoteAddr net.UDPAddr) { | ||||||
| 				bs := make([]byte, MaxUDP_packetLen) | 				bs := make([]byte, MaxUDP_packetLen) | ||||||
| 				for { | 				for { | ||||||
| 					//log.Println("redirect udp, start read", supposedRemoteAddr) | 					//log.Println("redirect udp, start read", supposedRemoteAddr) | ||||||
| @@ -289,7 +289,7 @@ func RelayUDP_to_Direct(extractor UDP_Extractor) { | |||||||
|  |  | ||||||
| 					//log.Println("redirect udp, will write to extractor", string(bs[:n])) | 					//log.Println("redirect udp, will write to extractor", string(bs[:n])) | ||||||
|  |  | ||||||
| 					err = extractor.WriteUDPResponse(raddr, bs[:n]) | 					err = extractor.WriteUDPResponse(*raddr, bs[:n]) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						break | 						break | ||||||
| 					} | 					} | ||||||
|   | |||||||
| @@ -18,27 +18,35 @@ type Simple struct { | |||||||
| 	MyCountryISO_3166         string                    `toml:"mycountry" json:"mycountry"` | 	MyCountryISO_3166         string                    `toml:"mycountry" json:"mycountry"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func LoadSimpleConfigFile(fileNamePath string) (*Simple, error) { | func LoadSimpleConfigFile(fileNamePath string) (config Simple, hasError bool, E utils.ErrInErr) { | ||||||
|  |  | ||||||
| 	if cf, err := os.Open(fileNamePath); err == nil { | 	if cf, err := os.Open(fileNamePath); err == nil { | ||||||
| 		defer cf.Close() | 		defer cf.Close() | ||||||
| 		bs, _ := ioutil.ReadAll(cf) | 		bs, _ := ioutil.ReadAll(cf) | ||||||
| 		config := &Simple{} | 		if err = json.Unmarshal(bs, &config); err != nil { | ||||||
| 		if err = json.Unmarshal(bs, config); err != nil { | 			hasError = true | ||||||
| 			return nil, utils.NewDataErr("can not parse config file ", err, fileNamePath) | 			E = utils.ErrInErr{ | ||||||
|  | 				ErrDesc:   "can not parse config file ", | ||||||
|  | 				ErrDetail: err, | ||||||
|  | 				Data:      fileNamePath, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 		return config, nil | 		} | ||||||
|  |  | ||||||
|  | 		return | ||||||
| 	} else { | 	} else { | ||||||
| 		return nil, utils.NewErr("can't open config file", err) | 		hasError = true | ||||||
|  | 		E = utils.ErrInErr{ErrDesc: "can't open config file", ErrDetail: err} | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func LoadSimpleConfigFromStr(str string) (*Simple, error) { | func LoadSimpleConfigFromStr(str string) (config Simple, hasE bool, E utils.ErrInErr) { | ||||||
| 	config := &Simple{} |  | ||||||
| 	if err := json.Unmarshal([]byte(str), config); err != nil { | 	if err := json.Unmarshal([]byte(str), &config); err != nil { | ||||||
| 		return nil, utils.NewErr("can not parse config ", err) | 		E = utils.ErrInErr{ErrDesc: "can not parse config ", ErrDetail: err} | ||||||
|  | 		hasE = true | ||||||
| 	} | 	} | ||||||
| 	return config, nil | 	return | ||||||
| } | } | ||||||
|   | |||||||
| @@ -130,21 +130,20 @@ type Standard struct { | |||||||
| 	App *AppConf `toml:"app"` | 	App *AppConf `toml:"app"` | ||||||
| } | } | ||||||
|  |  | ||||||
| func LoadTomlConfStr(str string) (c *Standard, err error) { | func LoadTomlConfStr(str string) (c Standard, err error) { | ||||||
| 	c = &Standard{} | 	_, err = toml.Decode(str, &c) | ||||||
| 	_, err = toml.Decode(str, c) |  | ||||||
|  |  | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func LoadTomlConfFile(fileNamePath string) (*Standard, error) { | func LoadTomlConfFile(fileNamePath string) (Standard, error) { | ||||||
|  |  | ||||||
| 	if cf, err := os.Open(fileNamePath); err == nil { | 	if cf, err := os.Open(fileNamePath); err == nil { | ||||||
| 		defer cf.Close() | 		defer cf.Close() | ||||||
| 		bs, _ := ioutil.ReadAll(cf) | 		bs, _ := ioutil.ReadAll(cf) | ||||||
| 		return LoadTomlConfStr(string(bs)) | 		return LoadTomlConfStr(string(bs)) | ||||||
| 	} else { | 	} else { | ||||||
| 		return nil, utils.NewErr("can't open config file", err) | 		return Standard{}, utils.ErrInErr{ErrDesc: "can't open config file", ErrDetail: err} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -21,8 +21,8 @@ func TestClientSimpleConfig(t *testing.T) { | |||||||
|   ] |   ] | ||||||
| }` | }` | ||||||
|  |  | ||||||
| 	mc, err := proxy.LoadSimpleConfigFromStr(confstr1) | 	mc, hasE, err := proxy.LoadSimpleConfigFromStr(confstr1) | ||||||
| 	if err != nil { | 	if hasE { | ||||||
| 		t.Log("loadConfigFromStr err", err) | 		t.Log("loadConfigFromStr err", err) | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -68,17 +68,17 @@ func NewClient(dc *DialConf) (Client, error) { | |||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil, utils.NewDataErr("unknown client protocol '", nil, protocol) | 	return nil, utils.ErrInErr{ErrDesc: "unknown client protocol ", Data: protocol} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // ClientFromURL calls the registered creator to create client. | // ClientFromURL calls the registered creator to create client. | ||||||
| // dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function. | // dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function. | ||||||
| func ClientFromURL(s string) (Client, error) { | func ClientFromURL(s string) (Client, bool, utils.ErrInErr) { | ||||||
| 	u, err := url.Parse(s) | 	u, err := url.Parse(s) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  |  | ||||||
| 		return nil, utils.NewDataErr("can not parse client url", err, s) | 		return nil, true, utils.ErrInErr{ErrDesc: "can not parse client url", ErrDetail: err, Data: s} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	schemeName := strings.ToLower(u.Scheme) | 	schemeName := strings.ToLower(u.Scheme) | ||||||
| @@ -87,10 +87,10 @@ func ClientFromURL(s string) (Client, error) { | |||||||
| 	if ok { | 	if ok { | ||||||
| 		c, e := creator.NewClientFromURL(u) | 		c, e := creator.NewClientFromURL(u) | ||||||
| 		if e != nil { | 		if e != nil { | ||||||
| 			return nil, e | 			return nil, true, utils.ErrInErr{ErrDesc: "creator.NewClientFromURL err", ErrDetail: e} | ||||||
| 		} | 		} | ||||||
| 		configCommonByURL(c, u) | 		configCommonByURL(c, u) | ||||||
| 		return c, nil | 		return c, false, utils.ErrInErr{} | ||||||
| 	} else { | 	} else { | ||||||
|  |  | ||||||
| 		//尝试判断是否套tls, 比如vlesss实际上是vless+tls,https实际上是http+tls | 		//尝试判断是否套tls, 比如vlesss实际上是vless+tls,https实际上是http+tls | ||||||
| @@ -100,20 +100,20 @@ func ClientFromURL(s string) (Client, error) { | |||||||
| 		if ok { | 		if ok { | ||||||
| 			c, err := creator.NewClientFromURL(u) | 			c, err := creator.NewClientFromURL(u) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return c, err | 				return nil, true, utils.ErrInErr{ErrDesc: "creator.NewClientFromURL err", ErrDetail: err} | ||||||
| 			} | 			} | ||||||
| 			configCommonByURL(c, u) | 			configCommonByURL(c, u) | ||||||
|  |  | ||||||
| 			c.SetUseTLS() | 			c.SetUseTLS() | ||||||
| 			prepareTLS_forProxyCommon_withURL(u, true, c) | 			prepareTLS_forProxyCommon_withURL(u, true, c) | ||||||
|  |  | ||||||
| 			return c, err | 			return c, false, utils.ErrInErr{} | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, utils.NewDataErr("unknown client protocol '", nil, u.Scheme) | 	return nil, false, utils.ErrInErr{ErrDesc: "unknown client protocol ", Data: u.Scheme} | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewServer(lc *ListenConf) (Server, error) { | func NewServer(lc *ListenConf) (Server, error) { | ||||||
| @@ -130,7 +130,7 @@ func NewServer(lc *ListenConf) (Server, error) { | |||||||
| 			ser.SetUseTLS() | 			ser.SetUseTLS() | ||||||
| 			err = prepareTLS_forServer(ser, lc) | 			err = prepareTLS_forServer(ser, lc) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Fatalln("prepareTLS error", err) | 				log.Fatalf("prepareTLS error %s\n", err) | ||||||
| 			} | 			} | ||||||
| 			return ser, nil | 			return ser, nil | ||||||
| 		} | 		} | ||||||
| @@ -149,24 +149,28 @@ func NewServer(lc *ListenConf) (Server, error) { | |||||||
| 			ser.SetUseTLS() | 			ser.SetUseTLS() | ||||||
| 			err = prepareTLS_forServer(ser, lc) | 			err = prepareTLS_forServer(ser, lc) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Fatalln("prepareTLS error", err) | 				log.Fatalf("prepareTLS error %s\n", err) | ||||||
| 			} | 			} | ||||||
| 			return ser, nil | 			return ser, nil | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, utils.NewDataErr("unknown server protocol '", nil, protocol) | 	return nil, utils.ErrInErr{ErrDesc: "unknown server protocol ", Data: protocol} | ||||||
| } | } | ||||||
|  |  | ||||||
| // ServerFromURL calls the registered creator to create proxy servers | // ServerFromURL calls the registered creator to create proxy servers | ||||||
| // dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function | // dialer is the default upstream dialer so cannot be nil, we can use Default when calling this function | ||||||
| // 所有的server都可有 "norule"参数,标明无需路由或者此server不可使用路由,在监听多个ip时是有用的; | // 所有的server都可有 "norule"参数,标明无需路由或者此server不可使用路由,在监听多个ip时是有用的; | ||||||
| // 路由配置可以在json的其他配置里面设置,如 mycountry项 | // 路由配置可以在json的其他配置里面设置,如 mycountry项 | ||||||
| func ServerFromURL(s string) (Server, error) { | func ServerFromURL(s string) (Server, bool, utils.ErrInErr) { | ||||||
| 	u, err := url.Parse(s) | 	u, err := url.Parse(s) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, utils.NewDataErr("can not parse server url ", err, s) | 		return nil, true, utils.ErrInErr{ | ||||||
|  | 			ErrDesc:   "can not parse server url ", | ||||||
|  | 			ErrDetail: err, | ||||||
|  | 			Data:      s, | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	schemeName := strings.ToLower(u.Scheme) | 	schemeName := strings.ToLower(u.Scheme) | ||||||
| @@ -174,29 +178,35 @@ func ServerFromURL(s string) (Server, error) { | |||||||
| 	if ok { | 	if ok { | ||||||
| 		ser, err := creator.NewServerFromURL(u) | 		ser, err := creator.NewServerFromURL(u) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, true, utils.ErrInErr{ | ||||||
|  | 				ErrDesc:   "creator.NewServerFromURL err ", | ||||||
|  | 				ErrDetail: err, | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		configCommonURLQueryForServer(ser, u) | 		configCommonURLQueryForServer(ser, u) | ||||||
|  |  | ||||||
| 		return ser, nil | 		return ser, false, utils.ErrInErr{} | ||||||
| 	} else { | 	} else { | ||||||
| 		realScheme := strings.TrimSuffix(schemeName, "s") | 		realScheme := strings.TrimSuffix(schemeName, "s") | ||||||
| 		creator, ok = serverCreatorMap[realScheme] | 		creator, ok = serverCreatorMap[realScheme] | ||||||
| 		if ok { | 		if ok { | ||||||
| 			server, err := creator.NewServerFromURL(u) | 			server, err := creator.NewServerFromURL(u) | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				return nil, err | 				return nil, true, utils.ErrInErr{ | ||||||
|  | 					ErrDesc:   "creator.NewServerFromURL err ", | ||||||
|  | 					ErrDetail: err, | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			configCommonURLQueryForServer(server, u) | 			configCommonURLQueryForServer(server, u) | ||||||
|  |  | ||||||
| 			server.SetUseTLS() | 			server.SetUseTLS() | ||||||
| 			prepareTLS_forProxyCommon_withURL(u, false, server) | 			prepareTLS_forProxyCommon_withURL(u, false, server) | ||||||
| 			return server, nil | 			return server, false, utils.ErrInErr{} | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil, utils.NewDataErr("unknown server protocol '", nil, u.Scheme) | 	return nil, true, utils.ErrInErr{ErrDesc: "unknown server protocol ", Data: u.Scheme} | ||||||
| } | } | ||||||
|  |  | ||||||
| //setTag, setCantRoute, call configCommonByURL | //setTag, setCantRoute, call configCommonByURL | ||||||
| @@ -218,7 +228,7 @@ func configCommonURLQueryForServer(ser ProxyCommon, u *url.URL) { | |||||||
| 		fa, err := netLayer.NewAddr(fallbackStr) | 		fa, err := netLayer.NewAddr(fallbackStr) | ||||||
|  |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Fatalln("invalid fallback ", fallbackStr) | 			log.Fatalf("invalid fallback %s\n", fallbackStr) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ser.setFallback(fa) | 		ser.setFallback(fa) | ||||||
|   | |||||||
| @@ -73,7 +73,7 @@ func (_ ServerCreator) NewServer(lc *proxy.ListenConf) (proxy.Server, error) { | |||||||
| type Server struct { | type Server struct { | ||||||
| 	proxy.ProxyCommonStruct | 	proxy.ProxyCommonStruct | ||||||
|  |  | ||||||
| 	targetAddr *netLayer.Addr | 	targetAddr netLayer.Addr | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewServer() (proxy.Server, error) { | func NewServer() (proxy.Server, error) { | ||||||
| @@ -82,6 +82,6 @@ func NewServer() (proxy.Server, error) { | |||||||
| } | } | ||||||
| func (d *Server) Name() string { return name } | func (d *Server) Name() string { return name } | ||||||
|  |  | ||||||
| func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Addr, error) { | func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, netLayer.Addr, error) { | ||||||
| 	return underlay, s.targetAddr, nil | 	return underlay, s.targetAddr, nil | ||||||
| } | } | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ func (_ Server) Name() string { | |||||||
| 	return name | 	return name | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *Server) Handshake(underlay net.Conn) (newconn io.ReadWriteCloser, targetAddr *netLayer.Addr, err error) { | func (s *Server) Handshake(underlay net.Conn) (newconn io.ReadWriteCloser, targetAddr netLayer.Addr, err error) { | ||||||
| 	var b = utils.GetMTU() //一般要获取请求信息,不需要那么长; 就算是http,加了path,也不用太长 | 	var b = utils.GetMTU() //一般要获取请求信息,不需要那么长; 就算是http,加了path,也不用太长 | ||||||
| 	//因为要储存为 firstdata,所以也无法直接放回 | 	//因为要储存为 firstdata,所以也无法直接放回 | ||||||
|  |  | ||||||
| @@ -67,7 +67,7 @@ func (s *Server) Handshake(underlay net.Conn) (newconn io.ReadWriteCloser, targe | |||||||
|  |  | ||||||
| 	method, path, failreason := httpLayer.GetRequestMethod_and_PATH_from_Bytes(b[:n], true) | 	method, path, failreason := httpLayer.GetRequestMethod_and_PATH_from_Bytes(b[:n], true) | ||||||
| 	if failreason != 0 { | 	if failreason != 0 { | ||||||
| 		err = utils.NewDataErr("get method/path failed, method:"+method+" ,reason:", nil, failreason) | 		err = utils.ErrInErr{ErrDesc: "get method/path failed, method:" + method + " ,reason:", Data: failreason} | ||||||
|  |  | ||||||
| 		//一个正常的http代理如果遇到了 格式不符的情况的话是要返回 400 等错误代码的 | 		//一个正常的http代理如果遇到了 格式不符的情况的话是要返回 400 等错误代码的 | ||||||
| 		// 但是,也不能说不返回400的就是异常服务器,因为这可能是服务器自己的策略,无视一切错误请求,比如防黑客时就常常会如此. | 		// 但是,也不能说不返回400的就是异常服务器,因为这可能是服务器自己的策略,无视一切错误请求,比如防黑客时就常常会如此. | ||||||
|   | |||||||
| @@ -17,17 +17,19 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func PrintAllServerNames() { | func PrintAllServerNames() { | ||||||
| 	fmt.Println("===============================\nSupported Server protocols:") | 	fmt.Printf("===============================\nSupported Server protocols:\n") | ||||||
| 	for v := range serverCreatorMap { | 	for v := range serverCreatorMap { | ||||||
| 		fmt.Println(v) | 		fmt.Print(v) | ||||||
|  | 		fmt.Print("\n") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func PrintAllClientNames() { | func PrintAllClientNames() { | ||||||
| 	fmt.Println("===============================\nSupported client protocols:") | 	fmt.Printf("===============================\nSupported client protocols:\n") | ||||||
|  |  | ||||||
| 	for v := range clientCreatorMap { | 	for v := range clientCreatorMap { | ||||||
| 		fmt.Println(v) | 		fmt.Print(v) | ||||||
|  | 		fmt.Print("\n") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -50,7 +52,7 @@ type Client interface { | |||||||
| type Server interface { | type Server interface { | ||||||
| 	ProxyCommon | 	ProxyCommon | ||||||
|  |  | ||||||
| 	Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Addr, error) | 	Handshake(underlay net.Conn) (io.ReadWriteCloser, netLayer.Addr, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| // FullName 可以完整表示 一个 代理的 VSI 层级. | // FullName 可以完整表示 一个 代理的 VSI 层级. | ||||||
| @@ -116,8 +118,8 @@ type ProxyCommon interface { | |||||||
|  |  | ||||||
| 	/////////////////// http层 /////////////////// | 	/////////////////// http层 /////////////////// | ||||||
| 	//默认回落地址. | 	//默认回落地址. | ||||||
| 	GetFallback() *netLayer.Addr | 	GetFallback() netLayer.Addr | ||||||
| 	setFallback(*netLayer.Addr) | 	setFallback(netLayer.Addr) | ||||||
|  |  | ||||||
| 	CanFallback() bool //如果能fallback,则handshake失败后,可能会专门返回 FallbackErr,如监测到返回了 FallbackErr, 则main函数会进行 回落处理. | 	CanFallback() bool //如果能fallback,则handshake失败后,可能会专门返回 FallbackErr,如监测到返回了 FallbackErr, 则main函数会进行 回落处理. | ||||||
|  |  | ||||||
| @@ -196,7 +198,7 @@ func prepareTLS_forClient(com ProxyCommon, dc *DialConf) error { | |||||||
| 			if e != nil { | 			if e != nil { | ||||||
| 				log.Fatalln("prepareTLS_forClient,quic,netLayer.NewAddr err: ", e) | 				log.Fatalln("prepareTLS_forClient,quic,netLayer.NewAddr err: ", e) | ||||||
| 			} | 			} | ||||||
| 			return quic.DialCommonInitialLayer(na, &tls.Config{ | 			return quic.DialCommonInitialLayer(&na, tls.Config{ | ||||||
| 				InsecureSkipVerify: dc.Insecure, | 				InsecureSkipVerify: dc.Insecure, | ||||||
| 				ServerName:         dc.Host, | 				ServerName:         dc.Host, | ||||||
| 				NextProtos:         alpnList, | 				NextProtos:         alpnList, | ||||||
| @@ -275,10 +277,10 @@ func prepareTLS_forServer(com ProxyCommon, lc *ListenConf) error { | |||||||
| 			certArray, err := tlsLayer.GetCertArrayFromFile(lc.TLSCert, lc.TLSKey) | 			certArray, err := tlsLayer.GetCertArrayFromFile(lc.TLSCert, lc.TLSKey) | ||||||
|  |  | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
| 				log.Fatalln("can't create tls cert from file:", lc.TLSCert, lc.TLSKey, err) | 				log.Fatalf("can't create tls cert from file: %s, %s, %s\n", lc.TLSCert, lc.TLSKey, err) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			return quic.ListenInitialLayers(com.AddrStr(), &tls.Config{ | 			return quic.ListenInitialLayers(com.AddrStr(), tls.Config{ | ||||||
| 				InsecureSkipVerify: lc.Insecure, | 				InsecureSkipVerify: lc.Insecure, | ||||||
| 				ServerName:         lc.Host, | 				ServerName:         lc.Host, | ||||||
| 				Certificates:       certArray, | 				Certificates:       certArray, | ||||||
| @@ -368,7 +370,7 @@ type ProxyCommonStruct struct { | |||||||
| 	ws_s *ws.Server | 	ws_s *ws.Server | ||||||
|  |  | ||||||
| 	grpc_s       *grpc.Server | 	grpc_s       *grpc.Server | ||||||
| 	FallbackAddr *netLayer.Addr | 	FallbackAddr netLayer.Addr | ||||||
|  |  | ||||||
| 	listenCommonConnFunc func() (newConnChan chan net.Conn, baseConn any) | 	listenCommonConnFunc func() (newConnChan chan net.Conn, baseConn any) | ||||||
| 	dialCommonConnFunc   func(serverAddr *netLayer.Addr) any | 	dialCommonConnFunc   func(serverAddr *netLayer.Addr) any | ||||||
| @@ -386,10 +388,10 @@ func (pcs *ProxyCommonStruct) setPath(a string) { | |||||||
| 	pcs.PATH = a | 	pcs.PATH = a | ||||||
| } | } | ||||||
|  |  | ||||||
| func (pcs *ProxyCommonStruct) GetFallback() *netLayer.Addr { | func (pcs *ProxyCommonStruct) GetFallback() netLayer.Addr { | ||||||
| 	return pcs.FallbackAddr | 	return pcs.FallbackAddr | ||||||
| } | } | ||||||
| func (pcs *ProxyCommonStruct) setFallback(a *netLayer.Addr) { | func (pcs *ProxyCommonStruct) setFallback(a netLayer.Addr) { | ||||||
| 	pcs.FallbackAddr = a | 	pcs.FallbackAddr = a | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ func Client_ReadUDPResponse(udpConn *net.UDPConn, supposedServerAddr *net.UDPAdd | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !(addr.IP.Equal(supposedServerAddr.IP) && addr.Port == supposedServerAddr.Port) { | 	if !(addr.IP.Equal(supposedServerAddr.IP) && addr.Port == supposedServerAddr.Port) { | ||||||
| 		e = utils.NewDataErr("socks5 Client_ReadUDPResponse , got data from unknown source", nil, addr) | 		e = utils.ErrInErr{ErrDesc: "socks5 Client_ReadUDPResponse , got data from unknown source", Data: addr} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	if buf[0] != 0 || buf[1] != 0 || buf[2] != 0 { | 	if buf[0] != 0 || buf[1] != 0 || buf[2] != 0 { | ||||||
|   | |||||||
| @@ -47,10 +47,11 @@ func (s *Server) Name() string { return Name } | |||||||
| // 参考 https://studygolang.com/articles/31404 | // 参考 https://studygolang.com/articles/31404 | ||||||
|  |  | ||||||
| // 处理tcp收到的请求. 注意, udp associate后的 udp请求并不通过此函数处理, 而是由 UDPConn.StartReadRequest 处理 | // 处理tcp收到的请求. 注意, udp associate后的 udp请求并不通过此函数处理, 而是由 UDPConn.StartReadRequest 处理 | ||||||
| func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Addr, error) { | func (s *Server) Handshake(underlay net.Conn) (result io.ReadWriteCloser, targetAddr netLayer.Addr, returnErr error) { | ||||||
| 	// Set handshake timeout 4 seconds | 	// Set handshake timeout 4 seconds | ||||||
| 	if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { | 	if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { | ||||||
| 		return nil, nil, err | 		returnErr = err | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 	defer underlay.SetReadDeadline(time.Time{}) | 	defer underlay.SetReadDeadline(time.Time{}) | ||||||
|  |  | ||||||
| @@ -61,24 +62,28 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
| 	// 一般握手包发来的是 [5 1 0] | 	// 一般握手包发来的是 [5 1 0] | ||||||
| 	n, err := underlay.Read(buf) | 	n, err := underlay.Read(buf) | ||||||
| 	if err != nil || n == 0 { | 	if err != nil || n == 0 { | ||||||
| 		return nil, nil, fmt.Errorf("failed to read hello: %w", err) | 		returnErr = fmt.Errorf("failed to read hello: %w", err) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 	version := buf[0] | 	version := buf[0] | ||||||
| 	if version != Version5 { | 	if version != Version5 { | ||||||
| 		return nil, nil, fmt.Errorf("unsupported socks version %v", version) | 		returnErr = fmt.Errorf("unsupported socks version %v", version) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Write hello response, [5 0] | 	// Write hello response, [5 0] | ||||||
| 	// TODO: Support Auth | 	// TODO: Support Auth | ||||||
| 	_, err = underlay.Write([]byte{Version5, AuthNone}) | 	_, err = underlay.Write([]byte{Version5, AuthNone}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, fmt.Errorf("failed to write hello response: %w", err) | 		returnErr = fmt.Errorf("failed to write hello response: %w", err) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Read command message, | 	// Read command message, | ||||||
| 	n, err = underlay.Read(buf) | 	n, err = underlay.Read(buf) | ||||||
| 	if err != nil || n < 7 { // Shortest length is 7 | 	if err != nil || n < 7 { // Shortest length is 7 | ||||||
| 		return nil, nil, fmt.Errorf("read socks5 failed, msgTooShort: %w", err) | 		returnErr = fmt.Errorf("read socks5 failed, msgTooShort: %w", err) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 一般可以为 5 1 0 3 n,3表示域名,n是域名长度,然后域名很可能是 119 119 119 46 开头,表示 www. | 	// 一般可以为 5 1 0 3 n,3表示域名,n是域名长度,然后域名很可能是 119 119 119 46 开头,表示 www. | ||||||
| @@ -86,7 +91,8 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
|  |  | ||||||
| 	cmd := buf[1] | 	cmd := buf[1] | ||||||
| 	if cmd == CmdBind { | 	if cmd == CmdBind { | ||||||
| 		return nil, nil, fmt.Errorf("unsuppoted command %v", cmd) | 		returnErr = fmt.Errorf("unsuppoted command %v", cmd) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	l := 2 | 	l := 2 | ||||||
| @@ -104,11 +110,13 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
| 		l += int(buf[4]) | 		l += int(buf[4]) | ||||||
| 		off = 5 | 		off = 5 | ||||||
| 	default: | 	default: | ||||||
| 		return nil, nil, fmt.Errorf("unknown address type %v", buf[3]) | 		returnErr = fmt.Errorf("unknown address type %v", buf[3]) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if len(buf[off:]) < l { | 	if len(buf[off:]) < l { | ||||||
| 		return nil, nil, errors.New("short command request") | 		returnErr = errors.New("short command request") | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	var theName string | 	var theName string | ||||||
| @@ -145,7 +153,8 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
|  |  | ||||||
| 		udpRC, err := net.ListenUDP("udp", udpPreparedAddr) | 		udpRC, err := net.ListenUDP("udp", udpPreparedAddr) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, errors.New("UDPAssociate: unable to listen udp") | 			returnErr = errors.New("UDPAssociate: unable to listen udp") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		//ver(5), rep(0,表示成功), rsv(0), atyp(1, 即ipv4), BND.ADDR(4字节的ipv4) , BND.PORT(2字节) | 		//ver(5), rep(0,表示成功), rsv(0), atyp(1, 即ipv4), BND.ADDR(4字节的ipv4) , BND.PORT(2字节) | ||||||
| @@ -154,10 +163,11 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
| 		// Write command response | 		// Write command response | ||||||
| 		_, err = underlay.Write(reply) | 		_, err = underlay.Write(reply) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, fmt.Errorf("failed to write command response: %w", err) | 			returnErr = fmt.Errorf("failed to write command response: %w", err) | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		clientFutureAddr := &netLayer.Addr{ | 		clientFutureAddr := netLayer.Addr{ | ||||||
| 			IP:      theIP, | 			IP:      theIP, | ||||||
| 			Name:    theName, | 			Name:    theName, | ||||||
| 			Port:    thePort, | 			Port:    thePort, | ||||||
| @@ -172,7 +182,7 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
| 		return uc, clientFutureAddr, nil | 		return uc, clientFutureAddr, nil | ||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		addr := &netLayer.Addr{ | 		targetAddr = netLayer.Addr{ | ||||||
| 			IP:   theIP, | 			IP:   theIP, | ||||||
| 			Name: theName, | 			Name: theName, | ||||||
| 			Port: thePort, | 			Port: thePort, | ||||||
| @@ -186,10 +196,11 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
|  |  | ||||||
| 		_, err = underlay.Write(reply) | 		_, err = underlay.Write(reply) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, fmt.Errorf("failed to write command response: %w", err) | 			returnErr = fmt.Errorf("failed to write command response: %w", err) | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		return underlay, addr, nil | 		return underlay, targetAddr, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
| @@ -244,7 +255,7 @@ func (u *UDPConn) StartPushResponse(udpPutter netLayer.UDP_Putter) { | |||||||
| // 然后将该请求 用 udpPutter.WriteUDPRequest 发送给 udpPutter | // 然后将该请求 用 udpPutter.WriteUDPRequest 发送给 udpPutter | ||||||
| //	至于fullcone与否它是不管的。 | //	至于fullcone与否它是不管的。 | ||||||
| // 如果客户端一开始没有指明自己连接本服务端的ip和端口, 则将第一个发来的正确的socks5请求视为该客户端,并记录。 | // 如果客户端一开始没有指明自己连接本服务端的ip和端口, 则将第一个发来的正确的socks5请求视为该客户端,并记录。 | ||||||
| func (u *UDPConn) StartReadRequest(udpPutter netLayer.UDP_Putter, dialFunc func(targetAddr *netLayer.Addr) (io.ReadWriter, error)) { | func (u *UDPConn) StartReadRequest(udpPutter netLayer.UDP_Putter, dialFunc func(targetAddr netLayer.Addr) (io.ReadWriter, error)) { | ||||||
|  |  | ||||||
| 	var clientSupposedAddrIsNothing bool | 	var clientSupposedAddrIsNothing bool | ||||||
| 	if len(u.clientSupposedAddr.IP) < 3 || u.clientSupposedAddr.IP.IsUnspecified() { | 	if len(u.clientSupposedAddr.IP) < 3 || u.clientSupposedAddr.IP.IsUnspecified() { | ||||||
| @@ -341,7 +352,7 @@ func (u *UDPConn) StartReadRequest(udpPutter netLayer.UDP_Putter, dialFunc func( | |||||||
|  |  | ||||||
| 		//log.Println("socks5 server,StartReadRequest, got msg", thisaddr, string(bs[newStart:n])) | 		//log.Println("socks5 server,StartReadRequest, got msg", thisaddr, string(bs[newStart:n])) | ||||||
|  |  | ||||||
| 		udpPutter.WriteUDPRequest(requestAddr.ToUDPAddr(), bs[newStart:n], dialFunc) | 		udpPutter.WriteUDPRequest(*requestAddr.ToUDPAddr(), bs[newStart:n], dialFunc) | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -54,7 +54,7 @@ func TestUDP(t *testing.T) { | |||||||
|  |  | ||||||
| 				go udpConn.StartPushResponse(putter) | 				go udpConn.StartPushResponse(putter) | ||||||
|  |  | ||||||
| 				dialFunc := func(targetAddr *netLayer.Addr) (io.ReadWriter, error) { | 				dialFunc := func(targetAddr netLayer.Addr) (io.ReadWriter, error) { | ||||||
| 					return targetAddr.Dial() | 					return targetAddr.Dial() | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| @@ -142,7 +142,7 @@ func TestUDP(t *testing.T) { | |||||||
|  |  | ||||||
| 	t.Log("call Client_RequestUDP") | 	t.Log("call Client_RequestUDP") | ||||||
|  |  | ||||||
| 	socks5.Client_RequestUDP(urc, raFake, []byte("hello")) | 	socks5.Client_RequestUDP(urc, &raFake, []byte("hello")) | ||||||
|  |  | ||||||
| 	t.Log("call Client_ReadUDPResponse") | 	t.Log("call Client_ReadUDPResponse") | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ package vless | |||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"encoding/binary" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"log" | 	"log" | ||||||
| 	"net" | 	"net" | ||||||
| @@ -17,14 +16,14 @@ import ( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| func init() { | func init() { | ||||||
| 	proxy.RegisterClient(Name, &ClientCreator{}) | 	proxy.RegisterClient(Name, ClientCreator{}) | ||||||
| } | } | ||||||
|  |  | ||||||
| //实现 proxy.UserClient,以及 netLayer.UDP_Putter | //实现 proxy.UserClient,以及 netLayer.UDP_Putter | ||||||
| type Client struct { | type Client struct { | ||||||
| 	proxy.ProxyCommonStruct | 	proxy.ProxyCommonStruct | ||||||
|  |  | ||||||
| 	udpResponseChan chan *netLayer.UDPAddrData | 	udpResponseChan chan netLayer.UDPAddrData | ||||||
|  |  | ||||||
| 	version int | 	version int | ||||||
|  |  | ||||||
| @@ -52,12 +51,12 @@ func (_ ClientCreator) NewClient(dc *proxy.DialConf) (proxy.Client, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	c := &Client{ | 	c := Client{ | ||||||
| 		user: id, | 		user: id, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	c.knownUDPDestinations = make(map[string]io.ReadWriter) | 	c.knownUDPDestinations = make(map[string]io.ReadWriter) | ||||||
| 	c.udpResponseChan = make(chan *netLayer.UDPAddrData, 20) | 	c.udpResponseChan = make(chan netLayer.UDPAddrData, 20) | ||||||
|  |  | ||||||
| 	v := dc.Version | 	v := dc.Version | ||||||
| 	if v >= 0 { | 	if v >= 0 { | ||||||
| @@ -68,7 +67,7 @@ func (_ ClientCreator) NewClient(dc *proxy.DialConf) (proxy.Client, error) { | |||||||
|  |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return c, nil | 	return &c, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewClientByURL(url *url.URL) (proxy.Client, error) { | func NewClientByURL(url *url.URL) (proxy.Client, error) { | ||||||
| @@ -78,11 +77,11 @@ func NewClientByURL(url *url.URL) (proxy.Client, error) { | |||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	c := &Client{ | 	c := Client{ | ||||||
| 		user: id, | 		user: id, | ||||||
| 	} | 	} | ||||||
| 	c.knownUDPDestinations = make(map[string]io.ReadWriter) | 	c.knownUDPDestinations = make(map[string]io.ReadWriter) | ||||||
| 	c.udpResponseChan = make(chan *netLayer.UDPAddrData, 20) | 	c.udpResponseChan = make(chan netLayer.UDPAddrData, 20) | ||||||
|  |  | ||||||
| 	vStr := url.Query().Get("version") | 	vStr := url.Query().Get("version") | ||||||
| 	if vStr != "" { | 	if vStr != "" { | ||||||
| @@ -94,7 +93,7 @@ func NewClientByURL(url *url.URL) (proxy.Client, error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return c, nil | 	return &c, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Client) Name() string { return Name } | func (c *Client) Name() string { return Name } | ||||||
| @@ -158,10 +157,10 @@ func (c *Client) Handshake(underlay net.Conn, target *netLayer.Addr) (io.ReadWri | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	buf := c.getBufWithCmd(cmd) | 	buf := c.getBufWithCmd(cmd) | ||||||
| 	err = binary.Write(buf, binary.BigEndian, uint16(port)) // port |  | ||||||
| 	if err != nil { | 	buf.WriteByte(byte(uint16(port) >> 8)) | ||||||
| 		return nil, err | 	buf.WriteByte(byte(uint16(port) << 8 >> 8)) | ||||||
| 	} |  | ||||||
| 	buf.WriteByte(atyp) | 	buf.WriteByte(atyp) | ||||||
| 	buf.Write(addr) | 	buf.Write(addr) | ||||||
|  |  | ||||||
| @@ -178,13 +177,13 @@ func (c *Client) Handshake(underlay net.Conn, target *netLayer.Addr) (io.ReadWri | |||||||
| 	}, err | 	}, err | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *Client) GetNewUDPResponse() (*net.UDPAddr, []byte, error) { | func (c *Client) GetNewUDPResponse() (net.UDPAddr, []byte, error) { | ||||||
| 	x := <-c.udpResponseChan //v1的话,由 handle_CRUMFURS 以及 WriteUDPRequest 中的 goroutine 填充;v0的话,由 WriteUDPRequest 填充 | 	x := <-c.udpResponseChan //v1的话,由 handle_CRUMFURS 以及 WriteUDPRequest 中的 goroutine 填充;v0的话,由 WriteUDPRequest 填充 | ||||||
| 	return x.Addr, x.Data, nil | 	return x.Addr, x.Data, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| //一般由socks5或者透明代理等地方 获取到 udp请求后,被传入这里 | //一般由socks5或者透明代理等地方 获取到 udp请求后,被传入这里 | ||||||
| func (c *Client) WriteUDPRequest(a *net.UDPAddr, b []byte, dialFunc func(targetAddr *netLayer.Addr) (io.ReadWriter, error)) (err error) { | func (c *Client) WriteUDPRequest(a net.UDPAddr, b []byte, dialFunc func(targetAddr netLayer.Addr) (io.ReadWriter, error)) (err error) { | ||||||
|  |  | ||||||
| 	astr := a.String() | 	astr := a.String() | ||||||
|  |  | ||||||
| @@ -194,9 +193,9 @@ func (c *Client) WriteUDPRequest(a *net.UDPAddr, b []byte, dialFunc func(targetA | |||||||
|  |  | ||||||
| 	if knownConn == nil { | 	if knownConn == nil { | ||||||
|  |  | ||||||
| 		knownConn, err = dialFunc(netLayer.NewAddrFromUDPAddr(a)) | 		knownConn, err = dialFunc(netLayer.NewAddrFromUDPAddr(&a)) | ||||||
| 		if err != nil || knownConn == nil { | 		if err != nil || knownConn == nil { | ||||||
| 			return utils.NewErr("vless WriteUDPRequest, err when creating an underlay", err) | 			return utils.ErrInErr{ErrDesc: "vless WriteUDPRequest, err when creating an underlay", ErrDetail: err} | ||||||
| 		} | 		} | ||||||
| 		//这里原来的代码是调用 c.Handshake,会自动帮我们拨号代理节点CmdUDP | 		//这里原来的代码是调用 c.Handshake,会自动帮我们拨号代理节点CmdUDP | ||||||
| 		// 但是似乎有问题,因为不应该由client自己拨号vless,因为我们还有上层的tls; | 		// 但是似乎有问题,因为不应该由client自己拨号vless,因为我们还有上层的tls; | ||||||
| @@ -221,7 +220,7 @@ func (c *Client) WriteUDPRequest(a *net.UDPAddr, b []byte, dialFunc func(targetA | |||||||
| 				msg := make([]byte, n) | 				msg := make([]byte, n) | ||||||
| 				copy(msg, bs[:n]) | 				copy(msg, bs[:n]) | ||||||
|  |  | ||||||
| 				c.udpResponseChan <- &netLayer.UDPAddrData{ | 				c.udpResponseChan <- netLayer.UDPAddrData{ | ||||||
| 					Addr: a, | 					Addr: a, | ||||||
| 					Data: msg, | 					Data: msg, | ||||||
| 				} | 				} | ||||||
| @@ -283,8 +282,8 @@ func (c *Client) handle_CRUMFURS(UMFURS_conn net.Conn) { | |||||||
|  |  | ||||||
| 			port := int16(msg[portIndex])<<8 + int16(msg[portIndex+1]) | 			port := int16(msg[portIndex])<<8 + int16(msg[portIndex+1]) | ||||||
|  |  | ||||||
| 			c.udpResponseChan <- &netLayer.UDPAddrData{ | 			c.udpResponseChan <- netLayer.UDPAddrData{ | ||||||
| 				Addr: &net.UDPAddr{ | 				Addr: net.UDPAddr{ | ||||||
| 					IP:   theIP, | 					IP:   theIP, | ||||||
| 					Port: int(port), | 					Port: int(port), | ||||||
| 				}, | 				}, | ||||||
| @@ -339,8 +338,8 @@ func (c *Client) handle_CRUMFURS(UMFURS_conn net.Conn) { | |||||||
| 				break | 				break | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			c.udpResponseChan <- &netLayer.UDPAddrData{ | 			c.udpResponseChan <- netLayer.UDPAddrData{ | ||||||
| 				Addr: &net.UDPAddr{ | 				Addr: net.UDPAddr{ | ||||||
| 					IP:   theIP, | 					IP:   theIP, | ||||||
| 					Port: port, | 					Port: port, | ||||||
| 				}, | 				}, | ||||||
|   | |||||||
| @@ -133,10 +133,11 @@ func (s *Server) GetUserByStr(str string) proxy.User { | |||||||
| func (s *Server) Name() string { return Name } | func (s *Server) Name() string { return Name } | ||||||
|  |  | ||||||
| // 返回的bytes.Buffer 是用于 回落使用的,内含了整个读取的数据;不回落时不要使用该Buffer | // 返回的bytes.Buffer 是用于 回落使用的,内含了整个读取的数据;不回落时不要使用该Buffer | ||||||
| func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Addr, error) { | func (s *Server) Handshake(underlay net.Conn) (result io.ReadWriteCloser, targetAddr netLayer.Addr, returnErr error) { | ||||||
|  |  | ||||||
| 	if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { | 	if err := underlay.SetReadDeadline(time.Now().Add(time.Second * 4)); err != nil { | ||||||
| 		return nil, nil, err | 		returnErr = err | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 	defer underlay.SetReadDeadline(time.Time{}) | 	defer underlay.SetReadDeadline(time.Time{}) | ||||||
|  |  | ||||||
| @@ -149,30 +150,30 @@ func (s *Server) Handshake(underlay net.Conn) (io.ReadWriteCloser, *netLayer.Add | |||||||
| 	//var auth [17]byte | 	//var auth [17]byte | ||||||
| 	wholeReadLen, err := underlay.Read(readbs) | 	wholeReadLen, err := underlay.Read(readbs) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, nil, utils.NewDataErr("read err", err, wholeReadLen) | 		returnErr = utils.ErrInErr{ErrDesc: "read err", ErrDetail: err, Data: wholeReadLen} | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if wholeReadLen < 17 { | 	if wholeReadLen < 17 { | ||||||
| 		//根据下面回答,HTTP的最小长度恰好是16字节,但是是0.9版本。1.0是18字节,1.1还要更长。总之我们可以直接不返回fallback地址 | 		//根据下面回答,HTTP的最小长度恰好是16字节,但是是0.9版本。1.0是18字节,1.1还要更长。总之我们可以直接不返回fallback地址 | ||||||
| 		//https://stackoverflow.com/questions/25047905/http-request-minimum-size-in-bytes/25065089 | 		//https://stackoverflow.com/questions/25047905/http-request-minimum-size-in-bytes/25065089 | ||||||
|  |  | ||||||
| 		return nil, nil, utils.NewDataErr("fallback, msg too short", nil, wholeReadLen) | 		returnErr = utils.ErrInErr{ErrDesc: "fallback, msg too short", Data: wholeReadLen} | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	readbuf := bytes.NewBuffer(readbs[:wholeReadLen]) | 	readbuf := bytes.NewBuffer(readbs[:wholeReadLen]) | ||||||
|  |  | ||||||
| 	var returnErr error |  | ||||||
|  |  | ||||||
| 	goto realPart | 	goto realPart | ||||||
|  |  | ||||||
| errorPart: | errorPart: | ||||||
|  |  | ||||||
| 	//所返回的buffer必须包含所有数据,而Buffer不支持回退,所以只能重新New | 	//所返回的buffer必须包含所有数据,而Buffer不支持回退,所以只能重新New | ||||||
| 	return nil, nil, &utils.ErrFirstBuffer{ | 	returnErr = &utils.ErrFirstBuffer{ | ||||||
| 		Err:   returnErr, | 		Err:   returnErr, | ||||||
| 		First: bytes.NewBuffer(readbs[:wholeReadLen]), | 		First: bytes.NewBuffer(readbs[:wholeReadLen]), | ||||||
| 	} | 	} | ||||||
|  | 	return | ||||||
|  |  | ||||||
| realPart: | realPart: | ||||||
| 	//这部分过程可以参照 v2ray的 proxy/vless/encoding/encoding.go DecodeRequestHeader 方法 | 	//这部分过程可以参照 v2ray的 proxy/vless/encoding/encoding.go DecodeRequestHeader 方法 | ||||||
| @@ -183,7 +184,7 @@ realPart: | |||||||
| 	version := auth[0] | 	version := auth[0] | ||||||
| 	if version > 1 { | 	if version > 1 { | ||||||
|  |  | ||||||
| 		returnErr = utils.NewDataErr("Vless invalid version ", nil, version) | 		returnErr = utils.ErrInErr{ErrDesc: "Vless invalid version ", Data: version} | ||||||
| 		goto errorPart | 		goto errorPart | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| @@ -206,7 +207,8 @@ realPart: | |||||||
|  |  | ||||||
| 		addonLenByte, err := readbuf.ReadByte() | 		addonLenByte, err := readbuf.ReadByte() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, err //凡是和的层Read相关的错误,一律不再返回Fallback信息,因为连接已然不可用 | 			returnErr = err //凡是和的层Read相关的错误,一律不再返回Fallback信息,因为连接已然不可用 | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
| 		if addonLenByte != 0 { | 		if addonLenByte != 0 { | ||||||
| 			//v2ray的vless中没有对应的任何处理。 | 			//v2ray的vless中没有对应的任何处理。 | ||||||
| @@ -223,7 +225,8 @@ realPart: | |||||||
| 				utils.PutBytes(tmpBuf) | 				utils.PutBytes(tmpBuf) | ||||||
| 			*/ | 			*/ | ||||||
| 			if tmpbs := readbuf.Next(int(addonLenByte)); len(tmpbs) != int(addonLenByte) { | 			if tmpbs := readbuf.Next(int(addonLenByte)); len(tmpbs) != int(addonLenByte) { | ||||||
| 				return nil, nil, errors.New("vless short read in addon") | 				returnErr = errors.New("vless short read in addon") | ||||||
|  | 				return | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -236,13 +239,11 @@ realPart: | |||||||
| 		goto errorPart | 		goto errorPart | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	addr := &netLayer.Addr{} |  | ||||||
|  |  | ||||||
| 	switch commandByte { | 	switch commandByte { | ||||||
| 	case CmdMux: //实际目前verysimple 暂时还未实现mux,先这么写 | 	case CmdMux: //实际目前verysimple 暂时还未实现mux,先这么写 | ||||||
|  |  | ||||||
| 		addr.Port = 0 | 		targetAddr.Port = 0 | ||||||
| 		addr.Name = "v1.mux.cool" | 		targetAddr.Name = "v1.mux.cool" | ||||||
|  |  | ||||||
| 	case Cmd_CRUMFURS: | 	case Cmd_CRUMFURS: | ||||||
| 		if version != 1 { | 		if version != 1 { | ||||||
| @@ -255,11 +256,11 @@ realPart: | |||||||
| 		_, err = underlay.Write([]byte{CRUMFURS_ESTABLISHED}) | 		_, err = underlay.Write([]byte{CRUMFURS_ESTABLISHED}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  |  | ||||||
| 			returnErr = utils.NewErr("write to crumfurs err", err) | 			returnErr = utils.ErrInErr{ErrDesc: "write to crumfurs err", ErrDetail: err} | ||||||
| 			goto errorPart | 			goto errorPart | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		addr.Name = CRUMFURS_Established_Str // 使用这个特殊的办法来告诉调用者,预留了 CRUMFURS 信道,防止其关闭上层连接导致 CRUMFURS 信道 被关闭。 | 		targetAddr.Name = CRUMFURS_Established_Str // 使用这个特殊的办法来告诉调用者,预留了 CRUMFURS 信道,防止其关闭上层连接导致 CRUMFURS 信道 被关闭。 | ||||||
|  |  | ||||||
| 		theCRUMFURS := &CRUMFURS{ | 		theCRUMFURS := &CRUMFURS{ | ||||||
| 			Conn: underlay, | 			Conn: underlay, | ||||||
| @@ -271,7 +272,7 @@ realPart: | |||||||
|  |  | ||||||
| 		s.mux4Hashes.Unlock() | 		s.mux4Hashes.Unlock() | ||||||
|  |  | ||||||
| 		return nil, addr, nil | 		return | ||||||
|  |  | ||||||
| 	case CmdTCP, CmdUDP: | 	case CmdTCP, CmdUDP: | ||||||
|  |  | ||||||
| @@ -283,10 +284,10 @@ realPart: | |||||||
| 			goto errorPart | 			goto errorPart | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		addr.Port = int(binary.BigEndian.Uint16(portbs)) | 		targetAddr.Port = int(binary.BigEndian.Uint16(portbs)) | ||||||
|  |  | ||||||
| 		if commandByte == CmdUDP { | 		if commandByte == CmdUDP { | ||||||
| 			addr.Network = "udp" | 			targetAddr.Network = "udp" | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		var ip_or_domain_bytesLength byte = 0 | 		var ip_or_domain_bytesLength byte = 0 | ||||||
| @@ -303,7 +304,7 @@ realPart: | |||||||
| 		case netLayer.AtypIP4: | 		case netLayer.AtypIP4: | ||||||
|  |  | ||||||
| 			ip_or_domain_bytesLength = net.IPv4len | 			ip_or_domain_bytesLength = net.IPv4len | ||||||
| 			addr.IP = utils.GetBytes(net.IPv4len) | 			targetAddr.IP = utils.GetBytes(net.IPv4len) | ||||||
|  |  | ||||||
| 		case netLayer.AtypDomain: | 		case netLayer.AtypDomain: | ||||||
| 			// 解码域名的长度 | 			// 解码域名的长度 | ||||||
| @@ -320,7 +321,7 @@ realPart: | |||||||
| 		case netLayer.AtypIP6: | 		case netLayer.AtypIP6: | ||||||
|  |  | ||||||
| 			ip_or_domain_bytesLength = net.IPv6len | 			ip_or_domain_bytesLength = net.IPv6len | ||||||
| 			addr.IP = utils.GetBytes(net.IPv6len) | 			targetAddr.IP = utils.GetBytes(net.IPv6len) | ||||||
| 		default: | 		default: | ||||||
|  |  | ||||||
| 			returnErr = fmt.Errorf("unknown address type %v", addrTypeByte) | 			returnErr = fmt.Errorf("unknown address type %v", addrTypeByte) | ||||||
| @@ -332,13 +333,14 @@ realPart: | |||||||
| 		_, err = readbuf.Read(ip_or_domain) | 		_, err = readbuf.Read(ip_or_domain) | ||||||
|  |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, nil, errors.New("fallback, reason 6") | 			returnErr = errors.New("fallback, reason 6") | ||||||
|  | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if addr.IP != nil { | 		if targetAddr.IP != nil { | ||||||
| 			copy(addr.IP, ip_or_domain) | 			copy(targetAddr.IP, ip_or_domain) | ||||||
| 		} else { | 		} else { | ||||||
| 			addr.Name = string(ip_or_domain) | 			targetAddr.Name = string(ip_or_domain) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		utils.PutBytes(ip_or_domain) | 		utils.PutBytes(ip_or_domain) | ||||||
| @@ -355,10 +357,10 @@ realPart: | |||||||
| 		remainFirstBufLen: readbuf.Len(), | 		remainFirstBufLen: readbuf.Len(), | ||||||
| 		uuid:              thisUUIDBytes, | 		uuid:              thisUUIDBytes, | ||||||
| 		version:           int(version), | 		version:           int(version), | ||||||
| 		isUDP:             addr.IsUDP(), | 		isUDP:             targetAddr.IsUDP(), | ||||||
| 		underlayIsBasic:   netLayer.IsBasicConn(underlay), | 		underlayIsBasic:   netLayer.IsBasicConn(underlay), | ||||||
| 		isServerEnd:       true, | 		isServerEnd:       true, | ||||||
| 	}, addr, nil | 	}, targetAddr, nil | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -375,7 +377,7 @@ type CRUMFURS struct { | |||||||
| 	hasAdvancedLayer bool //在用ws或grpc时,这个开关保持打开 | 	hasAdvancedLayer bool //在用ws或grpc时,这个开关保持打开 | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *CRUMFURS) WriteUDPResponse(a *net.UDPAddr, b []byte) (err error) { | func (c *CRUMFURS) WriteUDPResponse(a net.UDPAddr, b []byte) (err error) { | ||||||
| 	atype := netLayer.AtypIP4 | 	atype := netLayer.AtypIP4 | ||||||
| 	if len(a.IP) > 4 { | 	if len(a.IP) > 4 { | ||||||
| 		atype = netLayer.AtypIP6 | 		atype = netLayer.AtypIP6 | ||||||
|   | |||||||
| @@ -24,13 +24,13 @@ func TestVLess1(t *testing.T) { | |||||||
|  |  | ||||||
| func testVLess(version int, port string, t *testing.T) { | func testVLess(version int, port string, t *testing.T) { | ||||||
| 	url := "vless://a684455c-b14f-11ea-bf0d-42010aaa0003@127.0.0.1:" + port + "?version=" + strconv.Itoa(version) | 	url := "vless://a684455c-b14f-11ea-bf0d-42010aaa0003@127.0.0.1:" + port + "?version=" + strconv.Itoa(version) | ||||||
| 	server, err := proxy.ServerFromURL(url) | 	server, hase, _ := proxy.ServerFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
| 	defer server.Stop() | 	defer server.Stop() | ||||||
| 	client, err := proxy.ClientFromURL(url) | 	client, hase, _ := proxy.ClientFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -127,15 +127,15 @@ func TestVLess0_udp(t *testing.T) { | |||||||
| //  不过实测,这个test暂时只能使用v0版本,因为 v1版本具有 独特信道,不能直接使用下面代码。 | //  不过实测,这个test暂时只能使用v0版本,因为 v1版本具有 独特信道,不能直接使用下面代码。 | ||||||
| func testVLessUDP(version int, port string, t *testing.T) { | func testVLessUDP(version int, port string, t *testing.T) { | ||||||
| 	url := "vless://a684455c-b14f-11ea-bf0d-42010aaa0003@127.0.0.1:" + port + "?version=" + strconv.Itoa(version) | 	url := "vless://a684455c-b14f-11ea-bf0d-42010aaa0003@127.0.0.1:" + port + "?version=" + strconv.Itoa(version) | ||||||
| 	fakeServerEndLocalServer, err := proxy.ServerFromURL(url) | 	fakeServerEndLocalServer, hase, errx := proxy.ServerFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.Log("fakeClientEndLocalServer parse err", err) | 		t.Log("fakeClientEndLocalServer parse err", errx) | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
| 	defer fakeServerEndLocalServer.Stop() | 	defer fakeServerEndLocalServer.Stop() | ||||||
| 	fakeClientEndRemoteClient, err := proxy.ClientFromURL(url) | 	fakeClientEndRemoteClient, hase, errx := proxy.ClientFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.Log("fakeClientEndRemoteClient parse err", err) | 		t.Log("fakeClientEndRemoteClient parse err", errx) | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -76,9 +76,9 @@ var ( | |||||||
| 	} | 	} | ||||||
| ) | ) | ||||||
|  |  | ||||||
| func ListenInitialLayers(addr string, tlsConf *tls.Config, useHysteria bool, hysteriaMaxByteCount int) (newConnChan chan net.Conn, baseConn any) { | func ListenInitialLayers(addr string, tlsConf tls.Config, useHysteria bool, hysteriaMaxByteCount int) (newConnChan chan net.Conn, baseConn any) { | ||||||
|  |  | ||||||
| 	listener, err := quic.ListenAddr(addr, tlsConf, &our_ListenConfig) | 	listener, err := quic.ListenAddr(addr, &tlsConf, &our_ListenConfig) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if utils.CanLogErr() { | 		if utils.CanLogErr() { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
| @@ -140,8 +140,8 @@ func ListenInitialLayers(addr string, tlsConf *tls.Config, useHysteria bool, hys | |||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  |  | ||||||
| func DialCommonInitialLayer(serverAddr *netLayer.Addr, tlsConf *tls.Config, useHysteria bool, hysteriaMaxByteCount int) any { | func DialCommonInitialLayer(serverAddr *netLayer.Addr, tlsConf tls.Config, useHysteria bool, hysteriaMaxByteCount int) any { | ||||||
| 	session, err := quic.DialAddr(serverAddr.String(), tlsConf, &our_DialConfig) | 	session, err := quic.DialAddr(serverAddr.String(), &tlsConf, &our_DialConfig) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if utils.CanLogErr() { | 		if utils.CanLogErr() { | ||||||
| 			log.Println(err) | 			log.Println(err) | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ func (s *Server) Handshake(underlay net.Conn) (tlsConn *Conn, err error) { | |||||||
| 	rawTlsConn := tls.Server(underlay, s.tlsConfig) | 	rawTlsConn := tls.Server(underlay, s.tlsConfig) | ||||||
| 	err = rawTlsConn.Handshake() | 	err = rawTlsConn.Handshake() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		err = utils.NewErr("tlsLayer: tls握手失败", err) | 		err = utils.ErrInErr{ErrDesc: "tlsLayer: tls握手失败", ErrDetail: err} | ||||||
|  |  | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -27,15 +27,15 @@ func testTls(protocol string, port string, t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	url := protocol + "://a684455c-b14f-11ea-bf0d-42010aaa0003@localhost:" + port + "?alterID=4&cert=../cert.pem&key=../cert.key&insecure=1" | 	url := protocol + "://a684455c-b14f-11ea-bf0d-42010aaa0003@localhost:" + port + "?alterID=4&cert=../cert.pem&key=../cert.key&insecure=1" | ||||||
| 	server, err := proxy.ServerFromURL(url) | 	server, hase, errx := proxy.ServerFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.Log("fail1", err) | 		t.Log("fail1", errx) | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
| 	defer server.Stop() | 	defer server.Stop() | ||||||
| 	client, err := proxy.ClientFromURL(url) | 	client, hase, errx := proxy.ClientFromURL(url) | ||||||
| 	if err != nil { | 	if hase { | ||||||
| 		t.Log("fail2", err) | 		t.Log("fail2", errx) | ||||||
| 		t.FailNow() | 		t.FailNow() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -136,6 +136,8 @@ func MergeBuffers(bs [][]byte) (result []byte, duplicate bool) { | |||||||
|  |  | ||||||
| 	} else { | 	} else { | ||||||
| 		result = make([]byte, allLen) //实际目前的readv实现也很难出现这种情况 | 		result = make([]byte, allLen) //实际目前的readv实现也很难出现这种情况 | ||||||
|  | 		// 一定要尽量避免这种情况,如果 MaxBufLen小于readv buf总长度,会导致严重的内存泄漏问题, | ||||||
|  | 		// 见github issue #24 | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cursor := 0 | 	cursor := 0 | ||||||
|   | |||||||
| @@ -34,7 +34,8 @@ func (ef ErrFirstBuffer) Error() string { | |||||||
| } | } | ||||||
|  |  | ||||||
| // 返回结构体,而不是指针, 这样可以避免内存逃逸到堆 | // 返回结构体,而不是指针, 这样可以避免内存逃逸到堆 | ||||||
| func NewErr(desc string, e error) ErrInErr { | // 发现只要是函数就会逃逸到堆,自己初始化就没事。那就不提供初始化函数了。 | ||||||
|  | /*func NewErr(desc string, e error) ErrInErr { | ||||||
| 	return ErrInErr{ | 	return ErrInErr{ | ||||||
| 		ErrDesc:   desc, | 		ErrDesc:   desc, | ||||||
| 		ErrDetail: e, | 		ErrDetail: e, | ||||||
| @@ -42,6 +43,7 @@ func NewErr(desc string, e error) ErrInErr { | |||||||
| } | } | ||||||
|  |  | ||||||
| // 返回结构体,而不是指针, 这样可以避免内存逃逸到堆 | // 返回结构体,而不是指针, 这样可以避免内存逃逸到堆 | ||||||
|  |  | ||||||
| func NewDataErr(desc string, e error, data interface{}) ErrInErr { | func NewDataErr(desc string, e error, data interface{}) ErrInErr { | ||||||
| 	return ErrInErr{ | 	return ErrInErr{ | ||||||
| 		ErrDesc:   desc, | 		ErrDesc:   desc, | ||||||
| @@ -49,6 +51,7 @@ func NewDataErr(desc string, e error, data interface{}) ErrInErr { | |||||||
| 		Data:      data, | 		Data:      data, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | */ | ||||||
|  |  | ||||||
| // ErrInErr 很适合一个err包含另一个err,并且提供附带数据的情况. | // ErrInErr 很适合一个err包含另一个err,并且提供附带数据的情况. | ||||||
| type ErrInErr struct { | type ErrInErr struct { | ||||||
|   | |||||||
| @@ -50,10 +50,10 @@ var Version string //版本号由 Makefile 里的 BUILD_VERSION 指定 | |||||||
| func printVersion() { | func printVersion() { | ||||||
| 	const desc = "verysimple, a very simple implementation of V2Ray with some innovation" | 	const desc = "verysimple, a very simple implementation of V2Ray with some innovation" | ||||||
|  |  | ||||||
| 	fmt.Printf("===============================\nverysimple %v (%v), %v %v %v\n", Version, desc, runtime.Version(), runtime.GOOS, runtime.GOARCH) | 	fmt.Printf("===============================\nverysimple %s (%s), %s %s %s\n", Version, desc, runtime.Version(), runtime.GOOS, runtime.GOARCH) | ||||||
| 	fmt.Println("Support tls and websocket for all protocols.") | 	fmt.Printf("Support tls and websocket for all protocols.\n") | ||||||
| 	if netLayer.HasEmbedGeoip() { | 	if netLayer.HasEmbedGeoip() { | ||||||
| 		fmt.Println("Contains embeded Geoip file") | 		fmt.Printf("Contains embeded Geoip file\n") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -137,7 +137,7 @@ func (edc *EarlyDataConn) Write(p []byte) (int, error) { | |||||||
| 		_, encerr := io.Copy(encoder, multiReader) | 		_, encerr := io.Copy(encoder, multiReader) | ||||||
| 		if encerr != nil { | 		if encerr != nil { | ||||||
| 			close(edc.firstHandshakeOkChan) | 			close(edc.firstHandshakeOkChan) | ||||||
| 			return 0, utils.NewErr("encode early data err", encerr) | 			return 0, utils.ErrInErr{ErrDesc: "encode early data err", ErrDetail: encerr} | ||||||
| 		} | 		} | ||||||
| 		encoder.Close() | 		encoder.Close() | ||||||
|  |  | ||||||
|   | |||||||
| @@ -89,7 +89,7 @@ func (c *Conn) Read(p []byte) (int, error) { | |||||||
| 		*/ | 		*/ | ||||||
|  |  | ||||||
| 		//log.Println("OpCode not Binary", h.OpCode) | 		//log.Println("OpCode not Binary", h.OpCode) | ||||||
| 		return 0, utils.NewDataErr("ws OpCode not Binary", nil, h.OpCode) | 		return 0, utils.ErrInErr{ErrDesc: "ws OpCode not Binary", Data: h.OpCode} | ||||||
| 	} | 	} | ||||||
| 	//log.Println("Read next frame header ok,", h.Length, c.r.State.Fragmented(), "givenbuf len", len(p)) | 	//log.Println("Read next frame header ok,", h.Length, c.r.State.Fragmented(), "givenbuf len", len(p)) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 hahahrfool
					hahahrfool