mirror of
https://github.com/net-byte/vtun
synced 2024-03-14 10:50:03 +08:00
optimise code.
This commit is contained in:
parent
b9f0c3fc25
commit
414869fd96
@ -5,6 +5,7 @@ import (
|
||||
"crypto/cipher"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"hash/fnv"
|
||||
)
|
||||
|
||||
type XCrypto struct {
|
||||
@ -25,10 +26,21 @@ func (x *XCrypto) LoadKey(key string) {
|
||||
}
|
||||
|
||||
func (x *XCrypto) LoadNonce(key string) {
|
||||
n := 2 * 2 * 3
|
||||
h := sha1.New()
|
||||
h.Write([]byte(key))
|
||||
b := h.Sum(nil)
|
||||
x.Nonce = b[:12]
|
||||
ia := int(String2Int64(key) % int64(len(b)-n))
|
||||
x.Nonce = b[ia : ia+n]
|
||||
}
|
||||
|
||||
func String2Int64(s string) int64 {
|
||||
h := fnv.New32a()
|
||||
_, err := h.Write([]byte(s))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int64(h.Sum32())
|
||||
}
|
||||
|
||||
func (x *XCrypto) Init(key string) error {
|
||||
|
11
h1/conn.go
11
h1/conn.go
@ -3,7 +3,6 @@ package h1
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
@ -117,13 +116,3 @@ func mkConnAddr(p1 net.Conn, address string) net.Conn {
|
||||
}
|
||||
return p1
|
||||
}
|
||||
|
||||
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/-_"
|
||||
|
||||
func randStringBytes(n int) string {
|
||||
b := make([]byte, n)
|
||||
for i := range b {
|
||||
b[i] = letterBytes[rand.Intn(len(letterBytes))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
@ -22,6 +22,10 @@ import (
|
||||
func StartClient(iFace *water.Interface, config config.Config) {
|
||||
log.Println("vtun h1 client started")
|
||||
var cl *Client
|
||||
tcA := RandomStringByStringNonce(16, config.Key, 123)
|
||||
tcB := RandomStringByStringNonce(32, config.Key, 456)
|
||||
tcC := RandomStringByStringNonce(64, config.Key, 789)
|
||||
ua := RandomUserAgent(config.Key)
|
||||
go tunToH1(config, iFace)
|
||||
for {
|
||||
if config.Protocol == "https" {
|
||||
@ -29,6 +33,12 @@ func StartClient(iFace *water.Interface, config config.Config) {
|
||||
} else {
|
||||
cl = NewClient(config.ServerAddr)
|
||||
}
|
||||
cl.TokenCookieA = tcA
|
||||
cl.TokenCookieB = tcB
|
||||
cl.TokenCookieC = tcC
|
||||
cl.Url = "/" + RandomStringByInt64(64, time.Now().UnixMilli())
|
||||
cl.Host = "www.microsoft.com"
|
||||
cl.UserAgent = ua
|
||||
conn, err := cl.Dial()
|
||||
if err != nil {
|
||||
time.Sleep(3 * time.Second)
|
||||
|
@ -23,13 +23,16 @@ import (
|
||||
func StartServer(iFace *water.Interface, config config.Config) {
|
||||
log.Printf("vtun h1 server started on %v", config.LocalAddr)
|
||||
webSrv := NewHandle(netutil.GetDefaultHttpHandleFunc())
|
||||
webSrv.TokenCookieA = RandomStringByStringNonce(16, config.Key, 123)
|
||||
webSrv.TokenCookieB = RandomStringByStringNonce(32, config.Key, 456)
|
||||
webSrv.TokenCookieC = RandomStringByStringNonce(64, config.Key, 789)
|
||||
http.Handle("/", webSrv)
|
||||
srv := &http.Server{Addr: config.LocalAddr, Handler: nil}
|
||||
go func(srv *http.Server) {
|
||||
var err error
|
||||
if config.Protocol == "https" {
|
||||
tlsConfig := &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
MinVersion: tls.VersionTLS13,
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
@ -45,7 +48,7 @@ func StartServer(iFace *water.Interface, config config.Config) {
|
||||
} else {
|
||||
err = srv.ListenAndServe()
|
||||
}
|
||||
if err != ErrServerClose {
|
||||
if err != http.ErrServerClosed {
|
||||
panic(err)
|
||||
}
|
||||
}(srv)
|
||||
|
@ -38,6 +38,16 @@ func NewTLSClient(config config.Config) *Client {
|
||||
cl := NewClient(config.ServerAddr)
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
MinVersion: tls.VersionTLS13,
|
||||
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
InsecureSkipVerify: config.TLSInsecureSkipVerify,
|
||||
}
|
||||
|
||||
|
47
h1/httpd.go
47
h1/httpd.go
@ -80,9 +80,7 @@ func NewHandle(handler http.Handler) *Server {
|
||||
HttpHandler: handler,
|
||||
TokenTTL: tokenTTL,
|
||||
}
|
||||
|
||||
srv.startTokenCleaner()
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
@ -97,9 +95,7 @@ func (srv *Server) StartServer() {
|
||||
if srv.lis == nil {
|
||||
return
|
||||
}
|
||||
|
||||
srv.startTokenCleaner()
|
||||
|
||||
http.HandleFunc("/", srv.ServeHTTP)
|
||||
go http.Serve(srv.lis, nil)
|
||||
}
|
||||
@ -122,7 +118,6 @@ func (srv *Server) Addr() net.Addr {
|
||||
|
||||
func (srv *Server) Close() error {
|
||||
srv.dieLock.Lock()
|
||||
|
||||
select {
|
||||
case <-srv.die:
|
||||
srv.dieLock.Unlock()
|
||||
@ -137,38 +132,28 @@ func (srv *Server) Close() error {
|
||||
}
|
||||
}
|
||||
|
||||
// set cookie: TokenCookieA = XXXX
|
||||
// try get cookie: TokenCookieB = XXXX
|
||||
func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
var cc *state
|
||||
var ok bool
|
||||
var err error
|
||||
var c, ct *http.Cookie
|
||||
|
||||
c, err = r.Cookie(srv.TokenCookieB) // token
|
||||
c, err = r.Cookie(srv.TokenCookieB)
|
||||
if err != nil {
|
||||
|
||||
goto FILE
|
||||
}
|
||||
|
||||
ct, err = r.Cookie(srv.TokenCookieC) // flag
|
||||
ct, err = r.Cookie(srv.TokenCookieC)
|
||||
if err != nil {
|
||||
|
||||
goto FILE
|
||||
}
|
||||
|
||||
cc, ok = srv.checkToken(c.Value)
|
||||
if ok {
|
||||
if r.Method == srv.RxMethod || r.Method == srv.TxMethod {
|
||||
|
||||
} else {
|
||||
goto FILE
|
||||
}
|
||||
|
||||
srv.handleNonWs(w, r, c.Value, ct.Value, cc)
|
||||
return
|
||||
}
|
||||
|
||||
FILE:
|
||||
srv.handleBase(w, r)
|
||||
}
|
||||
@ -176,42 +161,33 @@ FILE:
|
||||
func (srv *Server) handleBase(w http.ResponseWriter, r *http.Request) {
|
||||
header := w.Header()
|
||||
header.Set("Server", srv.HeaderServer)
|
||||
token := randStringBytes(16)
|
||||
token := RandomString(16)
|
||||
expiration := time.Now().AddDate(0, 0, 3)
|
||||
cookie := http.Cookie{Name: srv.TokenCookieA, Value: token, Expires: expiration}
|
||||
http.SetCookie(w, &cookie)
|
||||
srv.regToken(token)
|
||||
|
||||
srv.HttpHandler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (srv *Server) handleWs(w http.ResponseWriter, r *http.Request, token string, flag string, cc *state) {
|
||||
|
||||
ip := r.Header.Get("Cf-Connecting-Ip")
|
||||
|
||||
hj, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
conn, bufRW, err := hj.Hijack()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
bufRW.Flush()
|
||||
|
||||
conn.Write([]byte("HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: " + token + "\r\n\r\n"))
|
||||
|
||||
cc.mx.Lock()
|
||||
defer cc.mx.Unlock()
|
||||
if r.Method == srv.RxMethod && flag == srv.RxFlag {
|
||||
|
||||
srv.rmToken(token)
|
||||
srv.accepts <- mkConnAddr(conn, ip)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (srv *Server) handleNonWs(w http.ResponseWriter, r *http.Request, token string, flag string, cc *state) {
|
||||
@ -224,19 +200,15 @@ func (srv *Server) handleNonWs(w http.ResponseWriter, r *http.Request, token str
|
||||
header.Set("Cache-Control", "private, no-store, no-cache, max-age=0")
|
||||
header.Set("Content-Encoding", "gzip")
|
||||
flusher.Flush()
|
||||
|
||||
hj, ok := w.(http.Hijacker)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
conn, bufRW, err := hj.Hijack()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
bufRW.Flush()
|
||||
|
||||
cc.mx.Lock()
|
||||
defer cc.mx.Unlock()
|
||||
if r.Method == srv.RxMethod && flag == srv.RxFlag {
|
||||
@ -254,25 +226,22 @@ func (srv *Server) handleNonWs(w http.ResponseWriter, r *http.Request, token str
|
||||
cc.bufR.Reader.Read(buf[:n])
|
||||
srv.accepts <- mkConn(cc.connR, cc.connW, buf[:n])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (srv *Server) regToken(token string) {
|
||||
srv.mx.Lock()
|
||||
defer srv.mx.Unlock()
|
||||
|
||||
_, ok := srv.states[token]
|
||||
if ok {
|
||||
|
||||
}
|
||||
srv.states[token] = &state{
|
||||
ttl: time.Now().Add(srv.TokenTTL),
|
||||
}
|
||||
}
|
||||
|
||||
func (srv *Server) checkToken(token string) (*state, bool) {
|
||||
srv.mx.Lock()
|
||||
defer srv.mx.Unlock()
|
||||
|
||||
c, ok := srv.states[token]
|
||||
if !ok {
|
||||
return nil, false
|
||||
@ -283,17 +252,15 @@ func (srv *Server) checkToken(token string) (*state, bool) {
|
||||
}
|
||||
return c, true
|
||||
}
|
||||
|
||||
func (srv *Server) rmToken(token string) {
|
||||
srv.mx.Lock()
|
||||
defer srv.mx.Unlock()
|
||||
|
||||
_, ok := srv.states[token]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
delete(srv.states, token)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -306,9 +273,7 @@ func (srv *Server) tokenCleaner() {
|
||||
return
|
||||
case <-ticker.C:
|
||||
}
|
||||
|
||||
list := make([]*state, 0)
|
||||
|
||||
srv.mx.Lock()
|
||||
for idx, c := range srv.states {
|
||||
if time.Now().After(c.ttl) {
|
||||
@ -318,8 +283,6 @@ func (srv *Server) tokenCleaner() {
|
||||
}
|
||||
}
|
||||
srv.mx.Unlock()
|
||||
|
||||
// check and close half open connection
|
||||
for _, cc := range list {
|
||||
cc.mx.Lock()
|
||||
if cc.connR == nil && cc.connW != nil {
|
||||
|
83
h1/utils.go
Normal file
83
h1/utils.go
Normal file
@ -0,0 +1,83 @@
|
||||
package h1
|
||||
|
||||
import (
|
||||
"hash/fnv"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var letter = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||
|
||||
func RandomString(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letter[rand.Intn(len(letter))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func RandomStringByInt64(n int, seed int64) string {
|
||||
r := rand.New(rand.NewSource(seed))
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letter[r.Intn(len(letter))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func String2Int64(s string) int64 {
|
||||
h := fnv.New32a()
|
||||
_, err := h.Write([]byte(s))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int64(h.Sum32())
|
||||
}
|
||||
|
||||
func RandomStringByStringNonce(n int, seed string, nonce int64) string {
|
||||
return RandomStringByInt64(n, String2Int64(seed)*nonce)
|
||||
}
|
||||
|
||||
func RandomStringByString(n int, seed string) string {
|
||||
return RandomStringByInt64(n, String2Int64(seed))
|
||||
}
|
||||
|
||||
var userAgentList = []string{
|
||||
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;",
|
||||
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv,2.0.1) Gecko/20100101 Firefox/4.0.1",
|
||||
"Mozilla/5.0 (Windows NT 6.1; rv,2.0.1) Gecko/20100101 Firefox/4.0.1",
|
||||
"Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11",
|
||||
"Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X…TML, like Gecko) Chrome/17.0.963.56 Safari/535.11",
|
||||
"Mozilla/5.0 (Macintosh; U; Intel Mac OS….50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
|
||||
"Mozilla/5.0 (Windows; U; Windows NT 6.1….50 (KHTML, like Gecko) Version/5.1 Safari/534.50",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Win…etaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)",
|
||||
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)",
|
||||
"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4… Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
|
||||
"Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3… Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
|
||||
"Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like… Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5",
|
||||
"Mozilla/5.0 (Linux; U; Android 2.3.7; …HTML, like Gecko) Version/4.0 Mobile Safari/533.1",
|
||||
"MQQBrowser/26 Mozilla/5.0 (Linux; U; A…HTML, like Gecko) Version/4.0 Mobile Safari/533.1",
|
||||
"Opera/9.80 (Android 2.3.4; Linux; Oper…107180945; U; en-GB) Presto/2.8.149 Version/11.10",
|
||||
"Mozilla/5.0 (Linux; U; Android 3.0; en….13 (KHTML, like Gecko) Version/4.0 Safari/534.13",
|
||||
"Mozilla/5.0 (BlackBerry; U; BlackBerry…ike Gecko) Version/6.0.0.337 Mobile Safari/534.1+",
|
||||
"Mozilla/5.0 (hp-tablet; Linux; hpwOS/3…ecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0",
|
||||
"Mozilla/5.0 (SymbianOS/9.4; Series60/5…ebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124",
|
||||
"Mozilla/5.0 (compatible; MSIE 9.0; Win…ne OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Titan)",
|
||||
"UCWEB7.0.2.37/28/999",
|
||||
"NOKIA5700/ UCWEB7.0.2.37/28/999",
|
||||
"Openwave/ UCWEB7.0.2.37/28/999",
|
||||
"Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999",
|
||||
}
|
||||
|
||||
func RandomUserAgent(seed string) string {
|
||||
return userAgentList[rand.New(rand.NewSource(String2Int64(seed))).Intn(len(userAgentList))]
|
||||
}
|
Loading…
Reference in New Issue
Block a user