optimise code.

This commit is contained in:
NNdroid 2023-07-14 18:37:46 +08:00
parent b9f0c3fc25
commit 414869fd96
7 changed files with 126 additions and 56 deletions

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)

View File

@ -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)

View File

@ -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,
}

View File

@ -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
View 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))]
}