github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/sdk/android-ios/sdk.go (about)

     1  package proxy
     2  
     3  import (
     4  	"crypto/sha1"
     5  	"fmt"
     6  	"io/ioutil"
     7  	logger "log"
     8  	"os"
     9  	"path"
    10  	"path/filepath"
    11  	"runtime/pprof"
    12  	"strings"
    13  	"sync"
    14  
    15  	"github.com/AntonOrnatskyi/goproxy/core/lib/kcpcfg"
    16  	encryptconn "github.com/AntonOrnatskyi/goproxy/core/lib/transport/encrypt"
    17  	"github.com/AntonOrnatskyi/goproxy/services"
    18  	httpx "github.com/AntonOrnatskyi/goproxy/services/http"
    19  	keygenx "github.com/AntonOrnatskyi/goproxy/services/keygen"
    20  	mux "github.com/AntonOrnatskyi/goproxy/services/mux"
    21  	socksx "github.com/AntonOrnatskyi/goproxy/services/socks"
    22  	spsx "github.com/AntonOrnatskyi/goproxy/services/sps"
    23  	tcpx "github.com/AntonOrnatskyi/goproxy/services/tcp"
    24  	tunnelx "github.com/AntonOrnatskyi/goproxy/services/tunnel"
    25  	udpx "github.com/AntonOrnatskyi/goproxy/services/udp"
    26  
    27  	kcp "github.com/xtaci/kcp-go"
    28  	"golang.org/x/crypto/pbkdf2"
    29  	kingpin "gopkg.in/alecthomas/kingpin.v2"
    30  )
    31  
    32  var SDK_VERSION = "No Version Provided"
    33  
    34  var (
    35  	app *kingpin.Application
    36  	cpuProfilingFile, memProfilingFile, blockProfilingFile,
    37  	goroutineProfilingFile, threadcreateProfilingFile *os.File
    38  	isProfiling   bool
    39  	profilingLock = &sync.Mutex{}
    40  )
    41  
    42  type LogCallback interface {
    43  	Write(line string)
    44  }
    45  type logCallback interface {
    46  	Write(line string)
    47  }
    48  type logWriter struct {
    49  	callback LogCallback
    50  }
    51  
    52  func (s *logWriter) Write(p []byte) (n int, err error) {
    53  	s.callback.Write(string(p))
    54  	return
    55  }
    56  
    57  func Start(serviceID, serviceArgsStr string) (errStr string) {
    58  	return StartWithLog(serviceID, serviceArgsStr, nil)
    59  }
    60  
    61  //Start
    62  //serviceID : is service identify id,different service's id should be difference
    63  //serviceArgsStr: is the whole command line args string
    64  //such as :
    65  //1."http -t tcp -p :8989"
    66  //2."socks -t tcp -p :8989"
    67  //and so on.
    68  //if an error occured , errStr will be the error reason
    69  //if start success, errStr is empty.
    70  func StartWithLog(serviceID, serviceArgsStr string, loggerCallback LogCallback) (errStr string) {
    71  	//define  args
    72  	tcpArgs := tcpx.TCPArgs{}
    73  	httpArgs := httpx.HTTPArgs{}
    74  	tunnelServerArgs := tunnelx.TunnelServerArgs{}
    75  	tunnelClientArgs := tunnelx.TunnelClientArgs{}
    76  	tunnelBridgeArgs := tunnelx.TunnelBridgeArgs{}
    77  	muxServerArgs := mux.MuxServerArgs{}
    78  	muxClientArgs := mux.MuxClientArgs{}
    79  	muxBridgeArgs := mux.MuxBridgeArgs{}
    80  	udpArgs := udpx.UDPArgs{}
    81  	socksArgs := socksx.SocksArgs{}
    82  	spsArgs := spsx.SPSArgs{}
    83  	dnsArgs := DNSArgs{}
    84  	keygenArgs := keygenx.KeygenArgs{}
    85  	kcpArgs := kcpcfg.KCPConfigArgs{}
    86  	//build srvice args
    87  	app = kingpin.New("proxy", "happy with proxy")
    88  	app.Author("snail").Version(SDK_VERSION)
    89  	debug := app.Flag("debug", "debug log output").Default("false").Bool()
    90  	logfile := app.Flag("log", "log file path").Default("").String()
    91  	nolog := app.Flag("nolog", "turn off logging").Default("false").Bool()
    92  	kcpArgs.Key = app.Flag("kcp-key", "pre-shared secret between client and server").Default("secrect").String()
    93  	kcpArgs.Crypt = app.Flag("kcp-method", "encrypt/decrypt method, can be: aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none").Default("aes").Enum("aes", "aes-128", "aes-192", "salsa20", "blowfish", "twofish", "cast5", "3des", "tea", "xtea", "xor", "sm4", "none")
    94  	kcpArgs.Mode = app.Flag("kcp-mode", "profiles: fast3, fast2, fast, normal, manual").Default("fast3").Enum("fast3", "fast2", "fast", "normal", "manual")
    95  	kcpArgs.MTU = app.Flag("kcp-mtu", "set maximum transmission unit for UDP packets").Default("1350").Int()
    96  	kcpArgs.SndWnd = app.Flag("kcp-sndwnd", "set send window size(num of packets)").Default("1024").Int()
    97  	kcpArgs.RcvWnd = app.Flag("kcp-rcvwnd", "set receive window size(num of packets)").Default("1024").Int()
    98  	kcpArgs.DataShard = app.Flag("kcp-ds", "set reed-solomon erasure coding - datashard").Default("10").Int()
    99  	kcpArgs.ParityShard = app.Flag("kcp-ps", "set reed-solomon erasure coding - parityshard").Default("3").Int()
   100  	kcpArgs.DSCP = app.Flag("kcp-dscp", "set DSCP(6bit)").Default("0").Int()
   101  	kcpArgs.NoComp = app.Flag("kcp-nocomp", "disable compression").Default("false").Bool()
   102  	kcpArgs.AckNodelay = app.Flag("kcp-acknodelay", "be carefull! flush ack immediately when a packet is received").Default("true").Bool()
   103  	kcpArgs.NoDelay = app.Flag("kcp-nodelay", "be carefull!").Default("0").Int()
   104  	kcpArgs.Interval = app.Flag("kcp-interval", "be carefull!").Default("50").Int()
   105  	kcpArgs.Resend = app.Flag("kcp-resend", "be carefull!").Default("0").Int()
   106  	kcpArgs.NoCongestion = app.Flag("kcp-nc", "be carefull! no congestion").Default("0").Int()
   107  	kcpArgs.SockBuf = app.Flag("kcp-sockbuf", "be carefull!").Default("4194304").Int()
   108  	kcpArgs.KeepAlive = app.Flag("kcp-keepalive", "be carefull!").Default("10").Int()
   109  
   110  	//########http#########
   111  	http := app.Command("http", "proxy on http mode")
   112  	httpArgs.Parent = http.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').Strings()
   113  	httpArgs.CaCertFile = http.Flag("ca", "ca cert file for tls").Default("").String()
   114  	httpArgs.CertFile = http.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   115  	httpArgs.KeyFile = http.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   116  	httpArgs.LocalType = http.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
   117  	httpArgs.ParentType = http.Flag("parent-type", "parent protocol type <tls|tcp|ssh|kcp>").Short('T').Enum("tls", "tcp", "ssh", "kcp")
   118  	httpArgs.Always = http.Flag("always", "always use parent proxy").Default("false").Bool()
   119  	httpArgs.Timeout = http.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("2000").Int()
   120  	httpArgs.HTTPTimeout = http.Flag("http-timeout", "check domain if blocked , http request timeout milliseconds when connect to host").Default("3000").Int()
   121  	httpArgs.Interval = http.Flag("interval", "check domain if blocked every interval seconds").Default("10").Int()
   122  	httpArgs.Blocked = http.Flag("blocked", "blocked domain file , one domain each line").Default("blocked").Short('b').String()
   123  	httpArgs.Direct = http.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
   124  	httpArgs.AuthFile = http.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
   125  	httpArgs.Auth = http.Flag("auth", "http basic auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
   126  	httpArgs.CheckParentInterval = http.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
   127  	httpArgs.Local = http.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":33080").String()
   128  	httpArgs.SSHUser = http.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
   129  	httpArgs.SSHKeyFile = http.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
   130  	httpArgs.SSHKeyFileSalt = http.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
   131  	httpArgs.SSHPassword = http.Flag("ssh-password", "password for ssh").Short('A').Default("").String()
   132  	httpArgs.LocalIPS = http.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
   133  	httpArgs.AuthURL = http.Flag("auth-url", "http basic auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
   134  	httpArgs.AuthURLTimeout = http.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
   135  	httpArgs.AuthURLOkCode = http.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int()
   136  	httpArgs.AuthURLRetry = http.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("1").Int()
   137  	httpArgs.DNSAddress = http.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
   138  	httpArgs.DNSTTL = http.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
   139  	httpArgs.LocalKey = http.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String()
   140  	httpArgs.ParentKey = http.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
   141  	httpArgs.LocalCompress = http.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
   142  	httpArgs.ParentCompress = http.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
   143  	httpArgs.Intelligent = http.Flag("intelligent", "settting intelligent HTTP, SOCKS5 proxy mode, can be <intelligent|direct|parent>").Default("intelligent").Enum("intelligent", "direct", "parent")
   144  	httpArgs.LoadBalanceMethod = http.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
   145  	httpArgs.LoadBalanceTimeout = http.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
   146  	httpArgs.LoadBalanceRetryTime = http.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
   147  	httpArgs.LoadBalanceHashTarget = http.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
   148  	httpArgs.LoadBalanceOnlyHA = http.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
   149  	httpArgs.RateLimit = http.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
   150  	httpArgs.BindListen = http.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
   151  	httpArgs.Jumper = http.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   152  	httpArgs.Debug = debug
   153  	//########tcp#########
   154  	tcp := app.Command("tcp", "proxy on tcp mode")
   155  	tcpArgs.Parent = tcp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   156  	tcpArgs.CertFile = tcp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   157  	tcpArgs.KeyFile = tcp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   158  	tcpArgs.Timeout = tcp.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('e').Default("2000").Int()
   159  	tcpArgs.ParentType = tcp.Flag("parent-type", "parent protocol type <tls|tcp|kcp|udp>").Short('T').Enum("tls", "tcp", "udp", "kcp")
   160  	tcpArgs.LocalType = tcp.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
   161  	tcpArgs.CheckParentInterval = tcp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
   162  	tcpArgs.Local = tcp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
   163  	tcpArgs.Jumper = tcp.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   164  
   165  	//########udp#########
   166  	udp := app.Command("udp", "proxy on udp mode")
   167  	udpArgs.Parent = udp.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   168  	udpArgs.CertFile = udp.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   169  	udpArgs.KeyFile = udp.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   170  	udpArgs.Timeout = udp.Flag("timeout", "tcp timeout milliseconds when connect to parent proxy").Short('t').Default("2000").Int()
   171  	udpArgs.ParentType = udp.Flag("parent-type", "parent protocol type <tls|tcp|udp>").Short('T').Enum("tls", "tcp", "udp")
   172  	udpArgs.CheckParentInterval = udp.Flag("check-parent-interval", "check if proxy is okay every interval seconds,zero: means no check").Short('I').Default("3").Int()
   173  	udpArgs.Local = udp.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
   174  
   175  	//########mux-server#########
   176  	muxServer := app.Command("server", "proxy on mux server mode")
   177  	muxServerArgs.Parent = muxServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   178  	muxServerArgs.ParentType = muxServer.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
   179  	muxServerArgs.CertFile = muxServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   180  	muxServerArgs.KeyFile = muxServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   181  	muxServerArgs.Timeout = muxServer.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
   182  	muxServerArgs.IsUDP = muxServer.Flag("udp", "proxy on udp mux server mode").Default("false").Bool()
   183  	muxServerArgs.Key = muxServer.Flag("k", "client key").Default("default").String()
   184  	muxServerArgs.Route = muxServer.Flag("route", "local route to client's network, such as: PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings()
   185  	muxServerArgs.IsCompress = muxServer.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
   186  	muxServerArgs.SessionCount = muxServer.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
   187  	muxServerArgs.Jumper = muxServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   188  	muxServerArgs.TCPSMethod = muxServer.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   189  	muxServerArgs.TCPSPassword = muxServer.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
   190  	muxServerArgs.TOUMethod = muxServer.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   191  	muxServerArgs.TOUPassword = muxServer.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
   192  
   193  	//########mux-client#########
   194  	muxClient := app.Command("client", "proxy on mux client mode")
   195  	muxClientArgs.Parent = muxClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   196  	muxClientArgs.ParentType = muxClient.Flag("parent-type", "parent protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('T').Enum("tls", "tcp", "tcps", "kcp", "tou")
   197  	muxClientArgs.CertFile = muxClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   198  	muxClientArgs.KeyFile = muxClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   199  	muxClientArgs.Timeout = muxClient.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
   200  	muxClientArgs.Key = muxClient.Flag("k", "key same with server").Default("default").String()
   201  	muxClientArgs.IsCompress = muxClient.Flag("c", "compress data when tcp|tls mode").Default("false").Bool()
   202  	muxClientArgs.SessionCount = muxClient.Flag("session-count", "session count which connect to bridge").Short('n').Default("10").Int()
   203  	muxClientArgs.Jumper = muxClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   204  	muxClientArgs.TCPSMethod = muxClient.Flag("tcps-method", "method of parent tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   205  	muxClientArgs.TCPSPassword = muxClient.Flag("tcps-password", "password of parent tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
   206  	muxClientArgs.TOUMethod = muxClient.Flag("tou-method", "method of parent tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   207  	muxClientArgs.TOUPassword = muxClient.Flag("tou-password", "password of parent tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
   208  
   209  	//########mux-bridge#########
   210  	muxBridge := app.Command("bridge", "proxy on mux bridge mode")
   211  	muxBridgeArgs.CertFile = muxBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   212  	muxBridgeArgs.KeyFile = muxBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   213  	muxBridgeArgs.Timeout = muxBridge.Flag("timeout", "tcp timeout with milliseconds").Short('i').Default("2000").Int()
   214  	muxBridgeArgs.Local = muxBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
   215  	muxBridgeArgs.LocalType = muxBridge.Flag("local-type", "local protocol type <tls|tcp|tcps|kcp|tou>").Default("tls").Short('t').Enum("tls", "tcp", "tcps", "kcp", "tou")
   216  	muxBridgeArgs.TCPSMethod = muxBridge.Flag("tcps-method", "method of local tcps's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   217  	muxBridgeArgs.TCPSPassword = muxBridge.Flag("tcps-password", "password of local tcps's encrpyt/decrypt").Default("snail007's_goproxy").String()
   218  	muxBridgeArgs.TOUMethod = muxBridge.Flag("tou-method", "method of local tou's encrpyt/decrypt, these below are supported :\n"+strings.Join(encryptconn.GetCipherMethods(), ",")).Default("aes-192-cfb").String()
   219  	muxBridgeArgs.TOUPassword = muxBridge.Flag("tou-password", "password of local tou's encrpyt/decrypt").Default("snail007's_goproxy").String()
   220  
   221  	//########tunnel-server#########
   222  	tunnelServer := app.Command("tserver", "proxy on tunnel server mode")
   223  	tunnelServerArgs.Parent = tunnelServer.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   224  	tunnelServerArgs.CertFile = tunnelServer.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   225  	tunnelServerArgs.KeyFile = tunnelServer.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   226  	tunnelServerArgs.Timeout = tunnelServer.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
   227  	tunnelServerArgs.IsUDP = tunnelServer.Flag("udp", "proxy on udp tunnel server mode").Default("false").Bool()
   228  	tunnelServerArgs.Key = tunnelServer.Flag("k", "client key").Default("default").String()
   229  	tunnelServerArgs.Route = tunnelServer.Flag("route", "local route to client's network, such as: PROTOCOL://LOCAL_IP:LOCAL_PORT@[CLIENT_KEY]CLIENT_LOCAL_HOST:CLIENT_LOCAL_PORT").Short('r').Default("").Strings()
   230  	tunnelServerArgs.Jumper = tunnelServer.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   231  
   232  	//########tunnel-client#########
   233  	tunnelClient := app.Command("tclient", "proxy on tunnel client mode")
   234  	tunnelClientArgs.Parent = tunnelClient.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   235  	tunnelClientArgs.CertFile = tunnelClient.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   236  	tunnelClientArgs.KeyFile = tunnelClient.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   237  	tunnelClientArgs.Timeout = tunnelClient.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
   238  	tunnelClientArgs.Key = tunnelClient.Flag("k", "key same with server").Default("default").String()
   239  	tunnelClientArgs.Jumper = tunnelClient.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Short('J').Default("").String()
   240  
   241  	//########tunnel-bridge#########
   242  	tunnelBridge := app.Command("tbridge", "proxy on tunnel bridge mode")
   243  	tunnelBridgeArgs.CertFile = tunnelBridge.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   244  	tunnelBridgeArgs.KeyFile = tunnelBridge.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   245  	tunnelBridgeArgs.Timeout = tunnelBridge.Flag("timeout", "tcp timeout with milliseconds").Short('t').Default("2000").Int()
   246  	tunnelBridgeArgs.Local = tunnelBridge.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
   247  
   248  	//########ssh#########
   249  	socks := app.Command("socks", "proxy on ssh mode")
   250  	socksArgs.Parent = socks.Flag("parent", "parent ssh address, such as: \"23.32.32.19:22\"").Default("").Short('P').Strings()
   251  	socksArgs.ParentType = socks.Flag("parent-type", "parent protocol type <tls|tcp|kcp|ssh>").Default("tcp").Short('T').Enum("tls", "tcp", "kcp", "ssh")
   252  	socksArgs.LocalType = socks.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
   253  	socksArgs.Local = socks.Flag("local", "local ip:port to listen").Short('p').Default(":33080").String()
   254  	socksArgs.CertFile = socks.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   255  	socksArgs.CaCertFile = socks.Flag("ca", "ca cert file for tls").Default("").String()
   256  	socksArgs.KeyFile = socks.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   257  	socksArgs.SSHUser = socks.Flag("ssh-user", "user for ssh").Short('u').Default("").String()
   258  	socksArgs.SSHKeyFile = socks.Flag("ssh-key", "private key file for ssh").Short('S').Default("").String()
   259  	socksArgs.SSHKeyFileSalt = socks.Flag("ssh-keysalt", "salt of ssh private key").Short('s').Default("").String()
   260  	socksArgs.SSHPassword = socks.Flag("ssh-password", "password for ssh").Short('D').Default("").String()
   261  	socksArgs.Always = socks.Flag("always", "always use parent proxy").Default("false").Bool()
   262  	socksArgs.Timeout = socks.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Default("5000").Int()
   263  	socksArgs.Interval = socks.Flag("interval", "check domain if blocked every interval seconds").Default("10").Int()
   264  	socksArgs.Blocked = socks.Flag("blocked", "blocked domain file , one domain each line").Default("blocked").Short('b').String()
   265  	socksArgs.Direct = socks.Flag("direct", "direct domain file , one domain each line").Default("direct").Short('d').String()
   266  	socksArgs.AuthFile = socks.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
   267  	socksArgs.Auth = socks.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
   268  	socksArgs.LocalIPS = socks.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
   269  	socksArgs.AuthURL = socks.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
   270  	socksArgs.AuthURLTimeout = socks.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
   271  	socksArgs.AuthURLOkCode = socks.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int()
   272  	socksArgs.AuthURLRetry = socks.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
   273  	socksArgs.ParentAuth = socks.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
   274  	socksArgs.DNSAddress = socks.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
   275  	socksArgs.DNSTTL = socks.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
   276  	socksArgs.LocalKey = socks.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String()
   277  	socksArgs.ParentKey = socks.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
   278  	socksArgs.LocalCompress = socks.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
   279  	socksArgs.ParentCompress = socks.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
   280  	socksArgs.Intelligent = socks.Flag("intelligent", "settting intelligent HTTP, SOCKS5 proxy mode, can be <intelligent|direct|parent>").Default("intelligent").Enum("intelligent", "direct", "parent")
   281  	socksArgs.LoadBalanceMethod = socks.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("roundrobin").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
   282  	socksArgs.LoadBalanceTimeout = socks.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
   283  	socksArgs.LoadBalanceRetryTime = socks.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
   284  	socksArgs.LoadBalanceHashTarget = socks.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
   285  	socksArgs.LoadBalanceOnlyHA = socks.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
   286  	socksArgs.RateLimit = socks.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
   287  	socksArgs.BindListen = socks.Flag("bind-listen", "using listener binding IP when connect to target").Short('B').Default("false").Bool()
   288  	socksArgs.Debug = debug
   289  
   290  	//########socks+http(s)#########
   291  	sps := app.Command("sps", "proxy on socks+http(s) mode")
   292  	spsArgs.Parent = sps.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').Strings()
   293  	spsArgs.CertFile = sps.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   294  	spsArgs.KeyFile = sps.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   295  	spsArgs.CaCertFile = sps.Flag("ca", "ca cert file for tls").Default("").String()
   296  	spsArgs.Timeout = sps.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int()
   297  	spsArgs.ParentType = sps.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
   298  	spsArgs.LocalType = sps.Flag("local-type", "local protocol type <tls|tcp|kcp>").Default("tcp").Short('t').Enum("tls", "tcp", "kcp")
   299  	spsArgs.Local = sps.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":33080").String()
   300  	spsArgs.ParentServiceType = sps.Flag("parent-service-type", "parent service type <http|socks|ss>").Short('S').Enum("http", "socks", "ss")
   301  	spsArgs.DNSAddress = sps.Flag("dns-address", "if set this, proxy will use this dns for resolve doamin").Short('q').Default("").String()
   302  	spsArgs.DNSTTL = sps.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
   303  	spsArgs.AuthFile = sps.Flag("auth-file", "http basic auth file,\"username:password\" each line in file").Short('F').String()
   304  	spsArgs.Auth = sps.Flag("auth", "socks auth username and password, mutiple user repeat -a ,such as: -a user1:pass1 -a user2:pass2").Short('a').Strings()
   305  	spsArgs.LocalIPS = sps.Flag("local-bind-ips", "if your host behind a nat,set your public ip here avoid dead loop").Short('g').Strings()
   306  	spsArgs.AuthURL = sps.Flag("auth-url", "auth username and password will send to this url,response http code equal to 'auth-code' means ok,others means fail.").Default("").String()
   307  	spsArgs.AuthURLTimeout = sps.Flag("auth-timeout", "access 'auth-url' timeout milliseconds").Default("3000").Int()
   308  	spsArgs.AuthURLOkCode = sps.Flag("auth-code", "access 'auth-url' success http code").Default("204").Int()
   309  	spsArgs.AuthURLRetry = sps.Flag("auth-retry", "access 'auth-url' fail and retry count").Default("0").Int()
   310  	spsArgs.ParentAuth = sps.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
   311  	spsArgs.LocalKey = sps.Flag("local-key", "the password for auto encrypt/decrypt local connection data").Short('z').Default("").String()
   312  	spsArgs.ParentKey = sps.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
   313  	spsArgs.LocalCompress = sps.Flag("local-compress", "auto compress/decompress data on local connection").Short('m').Default("false").Bool()
   314  	spsArgs.ParentCompress = sps.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
   315  	spsArgs.SSMethod = sps.Flag("ss-method", "the following methods are supported: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, rc4-md5-6, chacha20, salsa20, rc4, table, des-cfb, chacha20-ietf; if you use ss client , \"-t tcp\" is required").Short('h').Default("aes-256-cfb").String()
   316  	spsArgs.SSKey = sps.Flag("ss-key", "if you use ss client , \"-t tcp\" is required").Short('j').Default("sspassword").String()
   317  	spsArgs.ParentSSMethod = sps.Flag("parent-ss-method", "the following methods are supported: aes-128-cfb, aes-192-cfb, aes-256-cfb, bf-cfb, cast5-cfb, des-cfb, rc4-md5, rc4-md5-6, chacha20, salsa20, rc4, table, des-cfb, chacha20-ietf; if you use ss server as parent, \"-T tcp\" is required").Short('H').Default("aes-256-cfb").String()
   318  	spsArgs.ParentSSKey = sps.Flag("parent-ss-key", "if you use ss server as parent, \"-T tcp\" is required").Short('J').Default("sspassword").String()
   319  	spsArgs.DisableHTTP = sps.Flag("disable-http", "disable http(s) proxy").Default("false").Bool()
   320  	spsArgs.DisableSocks5 = sps.Flag("disable-socks", "disable socks proxy").Default("false").Bool()
   321  	spsArgs.DisableSS = sps.Flag("disable-ss", "disable ss proxy").Default("false").Bool()
   322  	spsArgs.LoadBalanceMethod = sps.Flag("lb-method", "load balance method when use multiple parent,can be <roundrobin|leastconn|leasttime|hash|weight>").Default("hash").Enum("roundrobin", "weight", "leastconn", "leasttime", "hash")
   323  	spsArgs.LoadBalanceTimeout = sps.Flag("lb-timeout", "tcp milliseconds timeout of connecting to parent").Default("500").Int()
   324  	spsArgs.LoadBalanceRetryTime = sps.Flag("lb-retrytime", "sleep time milliseconds after checking").Default("1000").Int()
   325  	spsArgs.LoadBalanceHashTarget = sps.Flag("lb-hashtarget", "use target address to choose parent for LB").Default("false").Bool()
   326  	spsArgs.LoadBalanceOnlyHA = sps.Flag("lb-onlyha", "use only `high availability mode` to choose parent for LB").Default("false").Bool()
   327  	spsArgs.RateLimit = sps.Flag("rate-limit", "rate limit (bytes/second) of each connection, such as: 100K 1.5M . 0 means no limitation").Short('l').Default("0").String()
   328  	spsArgs.Jumper = sps.Flag("jumper", "https or socks5 proxies used when connecting to parent, only worked of -T is tls or tcp, format is https://username:password@host:port https://host:port or socks5://username:password@host:port socks5://host:port").Default("").String()
   329  	spsArgs.ParentTLSSingle = sps.Flag("parent-tls-single", "conntect to parent insecure skip verify").Default("false").Bool()
   330  	spsArgs.Debug = debug
   331  
   332  	//########dns#########
   333  	dns := app.Command("dns", "proxy on dns server mode")
   334  	dnsArgs.Parent = dns.Flag("parent", "parent address, such as: \"23.32.32.19:28008\"").Default("").Short('P').String()
   335  	dnsArgs.CertFile = dns.Flag("cert", "cert file for tls").Short('C').Default("proxy.crt").String()
   336  	dnsArgs.KeyFile = dns.Flag("key", "key file for tls").Short('K').Default("proxy.key").String()
   337  	dnsArgs.CaCertFile = dns.Flag("ca", "ca cert file for tls").Default("").String()
   338  	dnsArgs.Timeout = dns.Flag("timeout", "tcp timeout milliseconds when connect to real server or parent proxy").Short('i').Default("2000").Int()
   339  	dnsArgs.ParentType = dns.Flag("parent-type", "parent protocol type <tls|tcp|kcp>").Short('T').Enum("tls", "tcp", "kcp")
   340  	dnsArgs.Local = dns.Flag("local", "local ip:port to listen,multiple address use comma split,such as: 0.0.0.0:80,0.0.0.0:443").Short('p').Default(":53").String()
   341  	dnsArgs.ParentServiceType = dns.Flag("parent-service-type", "parent service type <http|socks>").Short('S').Enum("http", "socks")
   342  	dnsArgs.RemoteDNSAddress = dns.Flag("dns-address", "remote dns for resolve doamin").Short('q').Default("8.8.8.8:53").String()
   343  	dnsArgs.DNSTTL = dns.Flag("dns-ttl", "caching seconds of dns query result").Short('e').Default("300").Int()
   344  	dnsArgs.ParentAuth = dns.Flag("parent-auth", "parent socks auth username and password, such as: -A user1:pass1").Short('A').String()
   345  	dnsArgs.ParentKey = dns.Flag("parent-key", "the password for auto encrypt/decrypt parent connection data").Short('Z').Default("").String()
   346  	dnsArgs.ParentCompress = dns.Flag("parent-compress", "auto compress/decompress data on parent connection").Short('M').Default("false").Bool()
   347  	dnsArgs.CacheFile = dns.Flag("cache-file", "dns result cached file").Short('f').Default(filepath.Join(path.Dir(os.Args[0]), "cache.dat")).String()
   348  	dnsArgs.LocalSocks5Port = dns.Flag("socks-port", "local socks5 port").Short('s').Default("65501").String()
   349  
   350  	//########keygen#########
   351  	keygen := app.Command("keygen", "create certificate for proxy")
   352  	keygenArgs.CommonName = keygen.Flag("cn", "common name").Short('n').Default("").String()
   353  	keygenArgs.CaName = keygen.Flag("ca", "ca name").Short('C').Default("").String()
   354  	keygenArgs.CertName = keygen.Flag("cert", "cert name of sign to create").Short('c').Default("").String()
   355  	keygenArgs.SignDays = keygen.Flag("days", "days of sign").Short('d').Default("365").Int()
   356  	keygenArgs.Sign = keygen.Flag("sign", "cert is to signin").Short('s').Default("false").Bool()
   357  
   358  	//parse args
   359  	_args := strings.Fields(strings.Trim(serviceArgsStr, " "))
   360  	args := []string{}
   361  	for _, a := range _args {
   362  		args = append(args, strings.Trim(a, "\""))
   363  	}
   364  	serviceName, err := app.Parse(args)
   365  	if err != nil {
   366  		return fmt.Sprintf("parse args fail,err: %s", err)
   367  	}
   368  	//set kcp config
   369  
   370  	switch *kcpArgs.Mode {
   371  	case "normal":
   372  		*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 40, 2, 1
   373  	case "fast":
   374  		*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 0, 30, 2, 1
   375  	case "fast2":
   376  		*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 20, 2, 1
   377  	case "fast3":
   378  		*kcpArgs.NoDelay, *kcpArgs.Interval, *kcpArgs.Resend, *kcpArgs.NoCongestion = 1, 10, 2, 1
   379  	}
   380  	pass := pbkdf2.Key([]byte(*kcpArgs.Key), []byte("snail007-goproxy"), 4096, 32, sha1.New)
   381  
   382  	switch *kcpArgs.Crypt {
   383  	case "sm4":
   384  		kcpArgs.Block, _ = kcp.NewSM4BlockCrypt(pass[:16])
   385  	case "tea":
   386  		kcpArgs.Block, _ = kcp.NewTEABlockCrypt(pass[:16])
   387  	case "xor":
   388  		kcpArgs.Block, _ = kcp.NewSimpleXORBlockCrypt(pass)
   389  	case "none":
   390  		kcpArgs.Block, _ = kcp.NewNoneBlockCrypt(pass)
   391  	case "aes-128":
   392  		kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:16])
   393  	case "aes-192":
   394  		kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass[:24])
   395  	case "blowfish":
   396  		kcpArgs.Block, _ = kcp.NewBlowfishBlockCrypt(pass)
   397  	case "twofish":
   398  		kcpArgs.Block, _ = kcp.NewTwofishBlockCrypt(pass)
   399  	case "cast5":
   400  		kcpArgs.Block, _ = kcp.NewCast5BlockCrypt(pass[:16])
   401  	case "3des":
   402  		kcpArgs.Block, _ = kcp.NewTripleDESBlockCrypt(pass[:24])
   403  	case "xtea":
   404  		kcpArgs.Block, _ = kcp.NewXTEABlockCrypt(pass[:16])
   405  	case "salsa20":
   406  		kcpArgs.Block, _ = kcp.NewSalsa20BlockCrypt(pass)
   407  	default:
   408  		*kcpArgs.Crypt = "aes"
   409  		kcpArgs.Block, _ = kcp.NewAESBlockCrypt(pass)
   410  	}
   411  	//attach kcp config
   412  	tcpArgs.KCP = kcpArgs
   413  	httpArgs.KCP = kcpArgs
   414  	socksArgs.KCP = kcpArgs
   415  	spsArgs.KCP = kcpArgs
   416  	muxBridgeArgs.KCP = kcpArgs
   417  	muxServerArgs.KCP = kcpArgs
   418  	muxClientArgs.KCP = kcpArgs
   419  	dnsArgs.KCP = kcpArgs
   420  
   421  	log := logger.New(os.Stdout, "", logger.Ldate|logger.Ltime)
   422  	flags := logger.Ldate
   423  	if *debug {
   424  		flags |= logger.Lshortfile | logger.Lmicroseconds
   425  	} else {
   426  		flags |= logger.Ltime
   427  	}
   428  	log.SetFlags(flags)
   429  
   430  	if loggerCallback == nil {
   431  		if *nolog {
   432  			log.SetOutput(ioutil.Discard)
   433  		} else if *logfile != "" {
   434  			f, e := os.OpenFile(*logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
   435  			if e != nil {
   436  				log.Fatal(e)
   437  			}
   438  			log.SetOutput(f)
   439  		}
   440  	} else {
   441  		log.SetOutput(&logWriter{
   442  			callback: loggerCallback,
   443  		})
   444  	}
   445  
   446  	//regist services and run service
   447  	switch serviceName {
   448  	case "http":
   449  		services.Regist(serviceID, httpx.NewHTTP(), httpArgs, log)
   450  	case "tcp":
   451  		services.Regist(serviceID, tcpx.NewTCP(), tcpArgs, log)
   452  	case "udp":
   453  		services.Regist(serviceID, udpx.NewUDP(), udpArgs, log)
   454  	case "tserver":
   455  		services.Regist(serviceID, tunnelx.NewTunnelServerManager(), tunnelServerArgs, log)
   456  	case "tclient":
   457  		services.Regist(serviceID, tunnelx.NewTunnelClient(), tunnelClientArgs, log)
   458  	case "tbridge":
   459  		services.Regist(serviceID, tunnelx.NewTunnelBridge(), tunnelBridgeArgs, log)
   460  	case "server":
   461  		services.Regist(serviceID, mux.NewMuxServerManager(), muxServerArgs, log)
   462  	case "client":
   463  		services.Regist(serviceID, mux.NewMuxClient(), muxClientArgs, log)
   464  	case "bridge":
   465  		services.Regist(serviceID, mux.NewMuxBridge(), muxBridgeArgs, log)
   466  	case "socks":
   467  		services.Regist(serviceID, socksx.NewSocks(), socksArgs, log)
   468  	case "sps":
   469  		services.Regist(serviceID, spsx.NewSPS(), spsArgs, log)
   470  	case "dns":
   471  		services.Regist(serviceID, NewDNS(), dnsArgs, log)
   472  	}
   473  	_, err = services.Run(serviceID, nil)
   474  	if err != nil {
   475  		return fmt.Sprintf("run service [%s:%s] fail, ERR:%s", serviceID, serviceName, err)
   476  	}
   477  	return
   478  }
   479  
   480  func Stop(serviceID string) {
   481  	services.Stop(serviceID)
   482  }
   483  
   484  func Version() string {
   485  	return SDK_VERSION
   486  }
   487  func StartProfiling(storePath string) {
   488  	profilingLock.Lock()
   489  	defer profilingLock.Unlock()
   490  	if !isProfiling {
   491  		isProfiling = true
   492  		if storePath == "" {
   493  			storePath = "."
   494  		}
   495  		cpuProfilingFile, _ = os.Create(filepath.Join(storePath, "cpu.prof"))
   496  		memProfilingFile, _ = os.Create(filepath.Join(storePath, "memory.prof"))
   497  		blockProfilingFile, _ = os.Create(filepath.Join(storePath, "block.prof"))
   498  		goroutineProfilingFile, _ = os.Create(filepath.Join(storePath, "goroutine.prof"))
   499  		threadcreateProfilingFile, _ = os.Create(filepath.Join(storePath, "threadcreate.prof"))
   500  		pprof.StartCPUProfile(cpuProfilingFile)
   501  	}
   502  }
   503  func StopProfiling() {
   504  	profilingLock.Lock()
   505  	defer profilingLock.Unlock()
   506  	if isProfiling {
   507  		isProfiling = false
   508  		pprof.StopCPUProfile()
   509  		goroutine := pprof.Lookup("goroutine")
   510  		goroutine.WriteTo(goroutineProfilingFile, 1)
   511  		heap := pprof.Lookup("heap")
   512  		heap.WriteTo(memProfilingFile, 1)
   513  		block := pprof.Lookup("block")
   514  		block.WriteTo(blockProfilingFile, 1)
   515  		threadcreate := pprof.Lookup("threadcreate")
   516  		threadcreate.WriteTo(threadcreateProfilingFile, 1)
   517  		//close
   518  		goroutineProfilingFile.Close()
   519  		memProfilingFile.Close()
   520  		blockProfilingFile.Close()
   521  		threadcreateProfilingFile.Close()
   522  	}
   523  
   524  }