mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2025-11-01 20:42:39 +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 {
|
||||||
|
|||||||
128
main.go
128
main.go
@@ -41,11 +41,11 @@ 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)
|
||||||
allClients = make([]proxy.Client, 0, 8)
|
allClients = make([]proxy.Client, 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