mirror of https://github.com/cbeuw/Cloak
Improve logging
This commit is contained in:
parent
c2c7c54761
commit
33f232475d
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -20,6 +19,7 @@ import (
|
||||||
"github.com/cbeuw/Cloak/internal/client/TLS"
|
"github.com/cbeuw/Cloak/internal/client/TLS"
|
||||||
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
||||||
"github.com/cbeuw/Cloak/internal/util"
|
"github.com/cbeuw/Cloak/internal/util"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var version string
|
var version string
|
||||||
|
|
@ -51,7 +51,7 @@ func makeRemoteConn(sta *client.State) (net.Conn, []byte, error) {
|
||||||
// For android
|
// For android
|
||||||
d := net.Dialer{Control: protector}
|
d := net.Dialer{Control: protector}
|
||||||
|
|
||||||
clientHello, sharedSecret := TLS.ComposeInitHandshake(sta)
|
clientHello, sharedSecret := TLS.ComposeClientHello(sta)
|
||||||
connectingIP := sta.RemoteHost
|
connectingIP := sta.RemoteHost
|
||||||
if net.ParseIP(connectingIP).To4() == nil {
|
if net.ParseIP(connectingIP).To4() == nil {
|
||||||
// IPv6 needs square brackets
|
// IPv6 needs square brackets
|
||||||
|
|
@ -59,25 +59,25 @@ func makeRemoteConn(sta *client.State) (net.Conn, []byte, error) {
|
||||||
}
|
}
|
||||||
remoteConn, err := d.Dial("tcp", connectingIP+":"+sta.RemotePort)
|
remoteConn, err := d.Dial("tcp", connectingIP+":"+sta.RemotePort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Connecting to remote: %v\n", err)
|
log.WithField("error", err).Error("Failed to connect to remote")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
_, err = remoteConn.Write(clientHello)
|
_, err = remoteConn.Write(clientHello)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Sending ClientHello: %v\n", err)
|
log.WithField("error", err).Error("Failed to send ClientHello")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
_, err = util.ReadTLS(remoteConn, buf)
|
_, err = util.ReadTLS(remoteConn, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Reading ServerHello: %v\n", err)
|
log.WithField("error", err).Error("Failed to read ServerHello")
|
||||||
}
|
}
|
||||||
serverRandom := buf[11:43]
|
serverRandom := buf[11:43]
|
||||||
sessionKey := client.DecryptSessionKey(serverRandom, sharedSecret)
|
sessionKey := client.DecryptSessionKey(serverRandom, sharedSecret)
|
||||||
_, err = util.ReadTLS(remoteConn, buf)
|
_, err = util.ReadTLS(remoteConn, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Reading Change Cipher Spec %v\n", err)
|
log.WithField("error", err).Error("Failed to read ChangeCipherSpec")
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ func makeRemoteConn(sta *client.State) (net.Conn, []byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSession(sta *client.State) *mux.Session {
|
func makeSession(sta *client.State) *mux.Session {
|
||||||
log.Println("Attemtping to start a new session")
|
log.Info("Attemtping to start a new session")
|
||||||
if !sta.IsAdmin {
|
if !sta.IsAdmin {
|
||||||
// sessionID is usergenerated. There shouldn't be a security concern because the scope of
|
// sessionID is usergenerated. There shouldn't be a security concern because the scope of
|
||||||
// sessionID is limited to its UID.
|
// sessionID is limited to its UID.
|
||||||
|
|
@ -105,7 +105,8 @@ func makeSession(sta *client.State) *mux.Session {
|
||||||
conn, sk, err := makeRemoteConn(sta)
|
conn, sk, err := makeRemoteConn(sta)
|
||||||
_sessionKey.Store(sk)
|
_sessionKey.Store(sk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to establish new connections to remote: %v\n", err)
|
log.Errorf("Failed to establish new connections to remote: %v", err)
|
||||||
|
// TODO increase the interval if failed multiple times
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
goto makeconn
|
goto makeconn
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +128,7 @@ func makeSession(sta *client.State) *mux.Session {
|
||||||
sesh.AddConnection(conn)
|
sesh.AddConnection(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Session %v established", sta.SessionID)
|
log.Infof("Session %v established", sta.SessionID)
|
||||||
return sesh
|
return sesh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -143,9 +144,8 @@ func main() {
|
||||||
var config string
|
var config string
|
||||||
var b64AdminUID string
|
var b64AdminUID string
|
||||||
|
|
||||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
|
||||||
|
|
||||||
log_init()
|
log_init()
|
||||||
|
log.SetLevel(log.DebugLevel)
|
||||||
|
|
||||||
if os.Getenv("SS_LOCAL_HOST") != "" {
|
if os.Getenv("SS_LOCAL_HOST") != "" {
|
||||||
localHost = os.Getenv("SS_LOCAL_HOST")
|
localHost = os.Getenv("SS_LOCAL_HOST")
|
||||||
|
|
@ -165,7 +165,7 @@ func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *askVersion {
|
if *askVersion {
|
||||||
fmt.Printf("ck-client %s\n", version)
|
fmt.Printf("ck-client %s", version)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Starting standalone mode")
|
log.Info("Starting standalone mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
sta := client.InitState(localHost, localPort, remoteHost, remotePort, time.Now)
|
sta := client.InitState(localHost, localPort, remoteHost, remotePort, time.Now)
|
||||||
|
|
@ -200,7 +200,6 @@ func main() {
|
||||||
listeningIP = "[" + listeningIP + "]"
|
listeningIP = "[" + listeningIP + "]"
|
||||||
}
|
}
|
||||||
listener, err := net.Listen("tcp", listeningIP+":"+sta.LocalPort)
|
listener, err := net.Listen("tcp", listeningIP+":"+sta.LocalPort)
|
||||||
log.Println("Listening on " + listeningIP + ":" + sta.LocalPort)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -214,10 +213,13 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if adminUID != nil {
|
if adminUID != nil {
|
||||||
|
log.Infof("API base is %v:%v", listeningIP, sta.LocalPort)
|
||||||
sta.IsAdmin = true
|
sta.IsAdmin = true
|
||||||
sta.SessionID = 0
|
sta.SessionID = 0
|
||||||
sta.UID = adminUID
|
sta.UID = adminUID
|
||||||
sta.NumConn = 1
|
sta.NumConn = 1
|
||||||
|
} else {
|
||||||
|
log.Infof("Listening on %v:%v for proxy clients", listeningIP, sta.LocalPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
var sesh *mux.Session
|
var sesh *mux.Session
|
||||||
|
|
@ -225,7 +227,7 @@ func main() {
|
||||||
for {
|
for {
|
||||||
localConn, err := listener.Accept()
|
localConn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if sesh == nil || sesh.IsClosed() {
|
if sesh == nil || sesh.IsClosed() {
|
||||||
|
|
@ -235,19 +237,19 @@ func main() {
|
||||||
data := make([]byte, 10240)
|
data := make([]byte, 10240)
|
||||||
i, err := io.ReadAtLeast(localConn, data, 1)
|
i, err := io.ReadAtLeast(localConn, data, 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Errorf("Failed to read first packet from proxy client: %v", err)
|
||||||
localConn.Close()
|
localConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
stream, err := sesh.OpenStream()
|
stream, err := sesh.OpenStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Errorf("Failed to open stream: %v", err)
|
||||||
localConn.Close()
|
localConn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = stream.Write(data[:i])
|
_, err = stream.Write(data[:i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Errorf("Failed to write to stream: %v", err)
|
||||||
localConn.Close()
|
localConn.Close()
|
||||||
stream.Close()
|
stream.Close()
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
"os"
|
"os"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -66,8 +66,6 @@ func lineLog(f *os.File, priority C.int) {
|
||||||
|
|
||||||
func log_init() {
|
func log_init() {
|
||||||
log.SetOutput(infoWriter{})
|
log.SetOutput(infoWriter{})
|
||||||
// android logcat includes all of log.LstdFlags
|
|
||||||
log.SetFlags(log.Flags() &^ log.LstdFlags)
|
|
||||||
|
|
||||||
r, w, err := os.Pipe()
|
r, w, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ package main
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
|
|
@ -19,9 +18,10 @@ import (
|
||||||
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
||||||
"github.com/cbeuw/Cloak/internal/server"
|
"github.com/cbeuw/Cloak/internal/server"
|
||||||
"github.com/cbeuw/Cloak/internal/util"
|
"github.com/cbeuw/Cloak/internal/util"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var b64 = base64.StdEncoding
|
var b64 = base64.StdEncoding.EncodeToString
|
||||||
var version string
|
var version string
|
||||||
|
|
||||||
func pipe(dst io.ReadWriteCloser, src io.ReadWriteCloser) {
|
func pipe(dst io.ReadWriteCloser, src io.ReadWriteCloser) {
|
||||||
|
|
@ -46,6 +46,12 @@ func pipe(dst io.ReadWriteCloser, src io.ReadWriteCloser) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dispatchConnection(conn net.Conn, sta *server.State) {
|
func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
|
remoteAddr := conn.RemoteAddr()
|
||||||
|
var err error
|
||||||
|
rejectLogger := log.WithFields(log.Fields{
|
||||||
|
"remoteAddr": remoteAddr,
|
||||||
|
"error": err,
|
||||||
|
})
|
||||||
buf := make([]byte, 1500)
|
buf := make([]byte, 1500)
|
||||||
|
|
||||||
conn.SetReadDeadline(time.Now().Add(3 * time.Second))
|
conn.SetReadDeadline(time.Now().Add(3 * time.Second))
|
||||||
|
|
@ -60,7 +66,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
goWeb := func() {
|
goWeb := func() {
|
||||||
webConn, err := net.Dial("tcp", sta.RedirAddr)
|
webConn, err := net.Dial("tcp", sta.RedirAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Making connection to redirection server: %v\n", err)
|
log.Errorf("Making connection to redirection server: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
webConn.Write(data)
|
webConn.Write(data)
|
||||||
|
|
@ -70,26 +76,33 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
|
|
||||||
ch, err := server.ParseClientHello(data)
|
ch, err := server.ParseClientHello(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("+1 non Cloak non (or malformed) TLS traffic from %v\n", conn.RemoteAddr())
|
rejectLogger.Warn("+1 non Cloak non (or malformed) TLS traffic")
|
||||||
goWeb()
|
goWeb()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isCloak, UID, sessionID, proxyMethod, encryptionMethod, sharedSecret := server.TouchStone(ch, sta)
|
UID, sessionID, proxyMethod, encryptionMethod, sharedSecret, err := server.TouchStone(ch, sta)
|
||||||
if !isCloak {
|
if err != nil {
|
||||||
log.Printf("+1 non Cloak TLS traffic from %v\n", conn.RemoteAddr())
|
rejectLogger.Warn("+1 non Cloak TLS traffic")
|
||||||
goWeb()
|
goWeb()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, ok := sta.ProxyBook[proxyMethod]; !ok {
|
if _, ok := sta.ProxyBook[proxyMethod]; !ok {
|
||||||
log.Printf("+1 Cloak TLS traffic with invalid proxy method `%v` from %v\n", proxyMethod, conn.RemoteAddr())
|
log.WithFields(log.Fields{
|
||||||
|
"UID": UID,
|
||||||
|
"proxyMethod": proxyMethod,
|
||||||
|
}).Warn("+1 Cloak TLS traffic with invalid proxy method")
|
||||||
goWeb()
|
goWeb()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := sta.Panel.GetUser(UID)
|
user, err := sta.Panel.GetUser(UID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("+1 unauthorised user from %v, uid: %v\n", conn.RemoteAddr(), base64.StdEncoding.EncodeToString(UID))
|
log.WithFields(log.Fields{
|
||||||
|
"UID": b64(UID),
|
||||||
|
"remoteAddr": remoteAddr,
|
||||||
|
"error": err,
|
||||||
|
}).Warn("+1 unauthorised UID")
|
||||||
goWeb()
|
goWeb()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -108,21 +121,21 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
rand.Read(sessionKey)
|
rand.Read(sessionKey)
|
||||||
obfs, deobfs, err := util.GenerateObfs(encryptionMethod, sessionKey)
|
obfs, deobfs, err := util.GenerateObfs(encryptionMethod, sessionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
goWeb()
|
goWeb()
|
||||||
}
|
}
|
||||||
|
|
||||||
sesh, existing, err := user.GetSession(sessionID, obfs, deobfs, sessionKey, util.ReadTLS)
|
sesh, existing, err := user.GetSession(sessionID, obfs, deobfs, sessionKey, util.ReadTLS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
user.DelSession(sessionID)
|
user.DelSession(sessionID)
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing {
|
if existing {
|
||||||
err = finishHandshake(sesh.SessionKey)
|
err = finishHandshake(sesh.SessionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sesh.AddConnection(conn)
|
sesh.AddConnection(conn)
|
||||||
|
|
@ -135,7 +148,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
if bytes.Equal(UID, sta.AdminUID) && sessionID == 0 {
|
if bytes.Equal(UID, sta.AdminUID) && sessionID == 0 {
|
||||||
err = finishHandshake(sessionKey)
|
err = finishHandshake(sessionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sesh := mux.MakeSession(0, mux.UNLIMITED_VALVE, obfs, deobfs, sessionKey, util.ReadTLS)
|
sesh := mux.MakeSession(0, mux.UNLIMITED_VALVE, obfs, deobfs, sessionKey, util.ReadTLS)
|
||||||
|
|
@ -143,25 +156,32 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
//TODO: Router could be nil in cnc mode
|
//TODO: Router could be nil in cnc mode
|
||||||
err = http.Serve(sesh, sta.LocalAPIRouter)
|
err = http.Serve(sesh, sta.LocalAPIRouter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = finishHandshake(sessionKey)
|
err = finishHandshake(sessionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("New session from UID:%v, sessionID:%v\n", b64.EncodeToString(UID), sessionID)
|
log.WithFields(log.Fields{
|
||||||
|
"UID": b64(UID),
|
||||||
|
"sessionID": sessionID,
|
||||||
|
}).Info("New session")
|
||||||
sesh.AddConnection(conn)
|
sesh.AddConnection(conn)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
newStream, err := sesh.Accept()
|
newStream, err := sesh.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == mux.ErrBrokenSession {
|
if err == mux.ErrBrokenSession {
|
||||||
log.Printf("Session closed for UID:%v, sessionID:%v, reason:%v\n", b64.EncodeToString(UID), sessionID, sesh.TerminalMsg())
|
log.WithFields(log.Fields{
|
||||||
|
"UID": b64(UID),
|
||||||
|
"sessionID": sessionID,
|
||||||
|
"reason": sesh.TerminalMsg(),
|
||||||
|
}).Info("Session closed")
|
||||||
user.DelSession(sessionID)
|
user.DelSession(sessionID)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -170,7 +190,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) {
|
||||||
}
|
}
|
||||||
localConn, err := net.Dial("tcp", sta.ProxyBook[proxyMethod])
|
localConn, err := net.Dial("tcp", sta.ProxyBook[proxyMethod])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to connect to %v: %v\n", proxyMethod, err)
|
log.Errorf("Failed to connect to %v: %v", proxyMethod, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go pipe(localConn, newStream)
|
go pipe(localConn, newStream)
|
||||||
|
|
@ -186,7 +206,7 @@ func main() {
|
||||||
var bindPort string
|
var bindPort string
|
||||||
var config string
|
var config string
|
||||||
|
|
||||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
log.SetLevel(log.DebugLevel)
|
||||||
|
|
||||||
if os.Getenv("SS_LOCAL_HOST") != "" {
|
if os.Getenv("SS_LOCAL_HOST") != "" {
|
||||||
bindHost = os.Getenv("SS_REMOTE_HOST")
|
bindHost = os.Getenv("SS_REMOTE_HOST")
|
||||||
|
|
@ -207,7 +227,7 @@ func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *askVersion {
|
if *askVersion {
|
||||||
fmt.Printf("ck-server %s\n", version)
|
fmt.Printf("ck-server %s", version)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if *printUsage {
|
if *printUsage {
|
||||||
|
|
@ -227,13 +247,13 @@ func main() {
|
||||||
if *pprofAddr != "" {
|
if *pprofAddr != "" {
|
||||||
runtime.SetBlockProfileRate(5)
|
runtime.SetBlockProfileRate(5)
|
||||||
go func() {
|
go func() {
|
||||||
log.Println(http.ListenAndServe(*pprofAddr, nil))
|
log.Info(http.ListenAndServe(*pprofAddr, nil))
|
||||||
}()
|
}()
|
||||||
log.Println("pprof listening on " + *pprofAddr)
|
log.Infof("pprof listening on %v", *pprofAddr)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Starting standalone mode, listening on %v:%v", bindHost, bindPort)
|
log.Infof("Starting standalone mode, listening on %v:%v", bindHost, bindPort)
|
||||||
}
|
}
|
||||||
sta, _ := server.InitState(bindHost, bindPort, time.Now)
|
sta, _ := server.InitState(bindHost, bindPort, time.Now)
|
||||||
|
|
||||||
|
|
@ -254,14 +274,14 @@ func main() {
|
||||||
|
|
||||||
listen := func(addr, port string) {
|
listen := func(addr, port string) {
|
||||||
listener, err := net.Listen("tcp", addr+":"+port)
|
listener, err := net.Listen("tcp", addr+":"+port)
|
||||||
log.Println("Listening on " + addr + ":" + port)
|
log.Infof("Listening on " + addr + ":" + port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
for {
|
for {
|
||||||
conn, err := listener.Accept()
|
conn, err := listener.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%v", err)
|
log.Errorf("%v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go dispatchConnection(conn, sta)
|
go dispatchConnection(conn, sta)
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,12 @@ import (
|
||||||
func generateUID() string {
|
func generateUID() string {
|
||||||
UID := make([]byte, 16)
|
UID := make([]byte, 16)
|
||||||
rand.Read(UID)
|
rand.Read(UID)
|
||||||
return b64.EncodeToString(UID)
|
return b64(UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateKeyPair() (string, string) {
|
func generateKeyPair() (string, string) {
|
||||||
staticPv, staticPub, _ := ecdh.GenerateKey(rand.Reader)
|
staticPv, staticPub, _ := ecdh.GenerateKey(rand.Reader)
|
||||||
marshPub := ecdh.Marshal(staticPub)
|
marshPub := ecdh.Marshal(staticPub)
|
||||||
marshPv := staticPv.(*[32]byte)[:]
|
marshPv := staticPv.(*[32]byte)[:]
|
||||||
return b64.EncodeToString(marshPub), b64.EncodeToString(marshPv)
|
return b64(marshPub), b64(marshPv)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -5,7 +5,7 @@ require (
|
||||||
github.com/gorilla/mux v1.7.3
|
github.com/gorilla/mux v1.7.3
|
||||||
github.com/juju/ratelimit v1.0.1
|
github.com/juju/ratelimit v1.0.1
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.4.2
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b
|
||||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e // indirect
|
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
15
go.sum
15
go.sum
|
|
@ -1,17 +1,28 @@
|
||||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=
|
github.com/juju/ratelimit v1.0.1 h1:+7AIFJVQ0EQgq/K9+0Krm7m530Du7tIz0METWzN0RgY=
|
||||||
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE=
|
||||||
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package multiplex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
//"log"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -122,7 +121,6 @@ func (sesh *Session) getStream(id uint32, closingFrame bool) *Stream {
|
||||||
stream = makeStream(id, sesh)
|
stream = makeStream(id, sesh)
|
||||||
sesh.streams[id] = stream
|
sesh.streams[id] = stream
|
||||||
sesh.acceptCh <- stream
|
sesh.acceptCh <- stream
|
||||||
//log.Printf("Adding stream %v\n", id)
|
|
||||||
return stream
|
return stream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
//"log"
|
log "github.com/sirupsen/logrus"
|
||||||
"math"
|
"math"
|
||||||
prand "math/rand"
|
prand "math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -48,6 +48,7 @@ func makeStream(id uint32, sesh *Session) *Stream {
|
||||||
sortedBuf: NewBufferedPipe(),
|
sortedBuf: NewBufferedPipe(),
|
||||||
}
|
}
|
||||||
go stream.recvNewFrame()
|
go stream.recvNewFrame()
|
||||||
|
log.Tracef("stream %v opened", id)
|
||||||
return stream
|
return stream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +113,7 @@ func (s *Stream) _close() {
|
||||||
func (s *Stream) passiveClose() {
|
func (s *Stream) passiveClose() {
|
||||||
s._close()
|
s._close()
|
||||||
s.session.delStream(s.id)
|
s.session.delStream(s.id)
|
||||||
//log.Printf("%v passive closing\n", stream.id)
|
log.WithField("streamId", s.id).Trace("stream passively closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// active close. Close locally and tell the remote that this stream is being closed
|
// active close. Close locally and tell the remote that this stream is being closed
|
||||||
|
|
@ -140,7 +141,7 @@ func (s *Stream) Close() error {
|
||||||
|
|
||||||
s._close()
|
s._close()
|
||||||
s.session.delStream(s.id)
|
s.session.delStream(s.id)
|
||||||
//log.Printf("%v actively closed\n", stream.id)
|
log.WithField("streamId", s.id).Trace("stream actively closed")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,6 +150,7 @@ func (s *Stream) Close() error {
|
||||||
// We don't notify the remote because session.Close() is always
|
// We don't notify the remote because session.Close() is always
|
||||||
// called when the session is passively closed
|
// called when the session is passively closed
|
||||||
func (s *Stream) closeNoDelMap() {
|
func (s *Stream) closeNoDelMap() {
|
||||||
|
log.WithField("streamId", s.id).Trace("stream closed by session")
|
||||||
s._close()
|
s._close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package multiplex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -129,7 +129,7 @@ func (sb *switchboard) deplex(ce *connEnclave) {
|
||||||
sb.rxWait(n)
|
sb.rxWait(n)
|
||||||
sb.Valve.AddRx(int64(n))
|
sb.Valve.AddRx(int64(n))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//log.Println(err)
|
log.Tracef("a connection for session %v has closed: %v", sb.session.id, err)
|
||||||
go ce.remoteConn.Close()
|
go ce.remoteConn.Close()
|
||||||
sb.removeConn(ce)
|
sb.removeConn(ce)
|
||||||
return
|
return
|
||||||
|
|
@ -137,7 +137,7 @@ func (sb *switchboard) deplex(ce *connEnclave) {
|
||||||
|
|
||||||
frame, err := sb.session.deobfs(buf[:n])
|
frame, err := sb.session.deobfs(buf[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Debugf("Failed to decrypt a frame for session %v: %v", sb.session.id, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,18 @@ package server
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/cbeuw/Cloak/internal/ecdh"
|
"github.com/cbeuw/Cloak/internal/ecdh"
|
||||||
"github.com/cbeuw/Cloak/internal/util"
|
"github.com/cbeuw/Cloak/internal/util"
|
||||||
"log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TouchStone(ch *ClientHello, sta *State) (isCK bool, UID []byte, sessionID uint32, proxyMethod string, encryptionMethod byte, sharedSecret []byte) {
|
var ErrReplay = errors.New("duplicate random")
|
||||||
|
var ErrInvalidPubKey = errors.New("public key has invalid format")
|
||||||
|
var ErrCiphertextLength = errors.New("ciphertext has the wrong length")
|
||||||
|
var ErrTimestampOutOfWindow = errors.New("timestamp is outside of the accepting window")
|
||||||
|
|
||||||
|
func TouchStone(ch *ClientHello, sta *State) (UID []byte, sessionID uint32, proxyMethod string, encryptionMethod byte, sharedSecret []byte, err error) {
|
||||||
var random [32]byte
|
var random [32]byte
|
||||||
copy(random[:], ch.random)
|
copy(random[:], ch.random)
|
||||||
|
|
||||||
|
|
@ -18,27 +24,31 @@ func TouchStone(ch *ClientHello, sta *State) (isCK bool, UID []byte, sessionID u
|
||||||
sta.usedRandomM.Unlock()
|
sta.usedRandomM.Unlock()
|
||||||
|
|
||||||
if used != 0 {
|
if used != 0 {
|
||||||
log.Println("Replay! Duplicate random")
|
err = ErrReplay
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ephPub, ok := ecdh.Unmarshal(random[:])
|
ephPub, ok := ecdh.Unmarshal(random[:])
|
||||||
if !ok {
|
if !ok {
|
||||||
|
err = ErrInvalidPubKey
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sharedSecret = ecdh.GenerateSharedSecret(sta.staticPv, ephPub)
|
sharedSecret = ecdh.GenerateSharedSecret(sta.staticPv, ephPub)
|
||||||
keyShare, err := parseKeyShare(ch.extensions[[2]byte{0x00, 0x33}])
|
var keyShare []byte
|
||||||
|
keyShare, err = parseKeyShare(ch.extensions[[2]byte{0x00, 0x33}])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ciphertext := append(ch.sessionId, keyShare...)
|
|
||||||
|
|
||||||
|
ciphertext := append(ch.sessionId, keyShare...)
|
||||||
if len(ciphertext) != 64 {
|
if len(ciphertext) != 64 {
|
||||||
|
err = fmt.Errorf("%v: %v", ErrCiphertextLength, len(ciphertext))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
plaintext, err := util.AESGCMDecrypt(random[0:12], sharedSecret, ciphertext)
|
var plaintext []byte
|
||||||
|
plaintext, err = util.AESGCMDecrypt(random[0:12], sharedSecret, ciphertext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -48,11 +58,9 @@ func TouchStone(ch *ClientHello, sta *State) (isCK bool, UID []byte, sessionID u
|
||||||
encryptionMethod = plaintext[28]
|
encryptionMethod = plaintext[28]
|
||||||
timestamp := int64(binary.BigEndian.Uint64(plaintext[29:37]))
|
timestamp := int64(binary.BigEndian.Uint64(plaintext[29:37]))
|
||||||
if timestamp/int64(TIMESTAMP_WINDOW.Seconds()) != sta.Now().Unix()/int64(TIMESTAMP_WINDOW.Seconds()) {
|
if timestamp/int64(TIMESTAMP_WINDOW.Seconds()) != sta.Now().Unix()/int64(TIMESTAMP_WINDOW.Seconds()) {
|
||||||
isCK = false
|
err = fmt.Errorf("%v: received timestamp %v", ErrTimestampOutOfWindow, timestamp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sessionID = binary.BigEndian.Uint32(plaintext[37:41])
|
sessionID = binary.BigEndian.Uint32(plaintext[37:41])
|
||||||
|
|
||||||
isCK = true
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"log"
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -157,7 +157,7 @@ func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusRespo
|
||||||
}
|
}
|
||||||
err := bucket.Put([]byte("UpCredit"), i64ToB(newUp))
|
err := bucket.Put([]byte("UpCredit"), i64ToB(newUp))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ func (manager *localManager) uploadStatus(uploads []statusUpdate) ([]statusRespo
|
||||||
}
|
}
|
||||||
err = bucket.Put([]byte("DownCredit"), i64ToB(newDown))
|
err = bucket.Put([]byte("DownCredit"), i64ToB(newDown))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Error(err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type userPanel struct {
|
type userPanel struct {
|
||||||
|
|
@ -101,7 +101,7 @@ func (panel *userPanel) updateUsageQueueForOne(user *ActiveUser) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (panel *userPanel) commitUpdate() {
|
func (panel *userPanel) commitUpdate() error {
|
||||||
panel.usageUpdateQueueM.Lock()
|
panel.usageUpdateQueueM.Lock()
|
||||||
statuses := make([]statusUpdate, 0, len(panel.usageUpdateQueue))
|
statuses := make([]statusUpdate, 0, len(panel.usageUpdateQueue))
|
||||||
for arrUID, usage := range panel.usageUpdateQueue {
|
for arrUID, usage := range panel.usageUpdateQueue {
|
||||||
|
|
@ -125,7 +125,7 @@ func (panel *userPanel) commitUpdate() {
|
||||||
|
|
||||||
responses, err := panel.Manager.uploadStatus(statuses)
|
responses, err := panel.Manager.uploadStatus(statuses)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
return err
|
||||||
}
|
}
|
||||||
for _, resp := range responses {
|
for _, resp := range responses {
|
||||||
var arrUID [16]byte
|
var arrUID [16]byte
|
||||||
|
|
@ -142,6 +142,7 @@ func (panel *userPanel) commitUpdate() {
|
||||||
}
|
}
|
||||||
panel.usageUpdateQueue = make(map[[16]byte]*usagePair)
|
panel.usageUpdateQueue = make(map[[16]byte]*usagePair)
|
||||||
panel.usageUpdateQueueM.Unlock()
|
panel.usageUpdateQueueM.Unlock()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (panel *userPanel) regularQueueUpload() {
|
func (panel *userPanel) regularQueueUpload() {
|
||||||
|
|
@ -149,7 +150,10 @@ func (panel *userPanel) regularQueueUpload() {
|
||||||
time.Sleep(1 * time.Minute)
|
time.Sleep(1 * time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
panel.updateUsageQueue()
|
panel.updateUsageQueue()
|
||||||
panel.commitUpdate()
|
err := panel.commitUpdate()
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
mux "github.com/cbeuw/Cloak/internal/multiplex"
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
"io"
|
"io"
|
||||||
prand "math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
@ -41,14 +40,6 @@ func AESGCMDecrypt(nonce []byte, key []byte, ciphertext []byte) ([]byte, error)
|
||||||
return plain, nil
|
return plain, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PsudoRandBytes returns a byte slice filled with psudorandom bytes generated by the seed
|
|
||||||
func PsudoRandBytes(length int, seed int64) []byte {
|
|
||||||
r := prand.New(prand.NewSource(seed))
|
|
||||||
ret := make([]byte, length)
|
|
||||||
r.Read(ret)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadTLS reads TLS data according to its record layer
|
// ReadTLS reads TLS data according to its record layer
|
||||||
func ReadTLS(conn net.Conn, buffer []byte) (n int, err error) {
|
func ReadTLS(conn net.Conn, buffer []byte) (n int, err error) {
|
||||||
// TCP is a stream. Multiple TLS messages can arrive at the same time,
|
// TCP is a stream. Multiple TLS messages can arrive at the same time,
|
||||||
|
|
@ -130,9 +121,3 @@ func AddRecordLayer(input []byte, typ []byte, ver []byte) []byte {
|
||||||
copy(ret[5:], input)
|
copy(ret[5:], input)
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeelRecordLayer peels off the record layer
|
|
||||||
func PeelRecordLayer(data []byte) []byte {
|
|
||||||
ret := data[5:]
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue