From bd6978444345a5a80b7b4c8683e7aa912d4e77c0 Mon Sep 17 00:00:00 2001 From: Qian Wang Date: Sat, 20 Oct 2018 17:03:39 +0100 Subject: [PATCH] optimisations --- cmd/ck-client/ck-client.go | 4 ++-- cmd/ck-server/ck-server.go | 5 ++--- internal/multiplex/frameSorter.go | 12 ++++++++++++ internal/multiplex/switchboard.go | 26 +++++++++++++------------- internal/util/obfs.go | 22 ++++++++++++++-------- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/cmd/ck-client/ck-client.go b/cmd/ck-client/ck-client.go index 75ee00e..b63cf7c 100644 --- a/cmd/ck-client/ck-client.go +++ b/cmd/ck-client/ck-client.go @@ -142,8 +142,8 @@ func main() { log.Fatalf("Failed to establish connection to remote: %v\n", err) } - obfs := util.MakeObfs(sta.SID) - deobfs := util.MakeDeobfs(sta.SID) + obfs := util.MakeObfs(sta.SID[:16]) + deobfs := util.MakeDeobfs(sta.SID[:16]) // TODO: where to put obfs deobfs and rtd? sesh := mux.MakeSession(0, initRemoteConn, obfs, deobfs, util.ReadTillDrain) diff --git a/cmd/ck-server/ck-server.go b/cmd/ck-server/ck-server.go index 953b356..1653445 100644 --- a/cmd/ck-server/ck-server.go +++ b/cmd/ck-server/ck-server.go @@ -9,7 +9,7 @@ import ( "net/http" _ "net/http/pprof" "os" - "runtime" + //"runtime" "strings" "time" @@ -105,7 +105,7 @@ func dispatchConnection(conn net.Conn, sta *server.State) { if sesh = sta.GetSession(arrSID); sesh != nil { sesh.AddConnection(conn) } else { - sesh = mux.MakeSession(0, conn, util.MakeObfs(SID), util.MakeDeobfs(SID), util.ReadTillDrain) + sesh = mux.MakeSession(0, conn, util.MakeObfs(SID[:16]), util.MakeDeobfs(SID[:16]), util.ReadTillDrain) sta.PutSession(arrSID, sesh) } go func() { @@ -129,7 +129,6 @@ func dispatchConnection(conn net.Conn, sta *server.State) { } func main() { - runtime.SetBlockProfileRate(2) go func() { log.Println(http.ListenAndServe("0.0.0.0:8001", nil)) }() diff --git a/internal/multiplex/frameSorter.go b/internal/multiplex/frameSorter.go index 9f71c6a..d2084d3 100644 --- a/internal/multiplex/frameSorter.go +++ b/internal/multiplex/frameSorter.go @@ -62,6 +62,18 @@ func (s *Stream) recvNewFrame() { continue } + if len(s.sh) == 0 && f.Seq == s.nextRecvSeq { + s.sortedBufCh <- f.Payload + + s.nextRecvSeq += 1 + if s.nextRecvSeq == 0 { + // when nextN is wrapped, wrapMode becomes false and rev+1 + s.rev += 1 + s.wrapMode = false + } + continue + } + // For the ease of demonstration, assume seq is uint8, i.e. it wraps around after 255 fs := &frameNode{ f.Seq, diff --git a/internal/multiplex/switchboard.go b/internal/multiplex/switchboard.go index 9477e71..c198410 100644 --- a/internal/multiplex/switchboard.go +++ b/internal/multiplex/switchboard.go @@ -3,7 +3,7 @@ package multiplex import ( "log" "net" - //"sort" + "sort" ) const ( @@ -79,18 +79,18 @@ type sentNotifier struct { func (ce *connEnclave) send(data []byte) { // TODO: error handling - _, err := ce.remoteConn.Write(data) + n, err := ce.remoteConn.Write(data) if err != nil { ce.sb.closingCECh <- ce log.Println(err) } - /* - sn := &sentNotifier{ - ce, - n, - } - ce.sb.sentNotifyCh <- sn - */ + + sn := &sentNotifier{ + ce, + n, + } + ce.sb.sentNotifyCh <- sn + } // Dispatcher sends data coming from a stream to a remote connection @@ -102,11 +102,11 @@ func (sb *switchboard) dispatch() { // dispatCh receives data from stream.Write case data := <-sb.dispatCh: go sb.ces[nextCE%len(sb.ces)].send(data) - //sb.ces[0].sendQueue += len(data) + sb.ces[0].sendQueue += len(data) nextCE += 1 - /*case notified := <-sb.sentNotifyCh: - notified.ce.sendQueue -= notified.sent - sort.Sort(byQ(sb.ces))*/ + case notified := <-sb.sentNotifyCh: + notified.ce.sendQueue -= notified.sent + sort.Sort(byQ(sb.ces)) case conn := <-sb.newConnCh: log.Println("newConn") newCe := &connEnclave{ diff --git a/internal/util/obfs.go b/internal/util/obfs.go index 2232945..b28031b 100644 --- a/internal/util/obfs.go +++ b/internal/util/obfs.go @@ -37,20 +37,26 @@ func MakeObfs(key []byte) func(*mux.Frame) []byte { iv := make([]byte, 16) io.ReadFull(rand.Reader, iv) cipherheader := AESEncrypt(iv, key, header) - obfsed := make([]byte, len(f.Payload)+12+16) - copy(obfsed[0:16], iv) - copy(obfsed[16:28], cipherheader) - copy(obfsed[28:], f.Payload) - // obfsed: [iv 16 bytes][cipherheader 12 bytes][payload] - ret := AddRecordLayer(obfsed, []byte{0x17}, []byte{0x03, 0x03}) - return ret + + // Composing final obfsed message + // We don't use util.AddRecordLayer here to avoid unnecessary malloc + obfsed := make([]byte, 5+16+12+len(f.Payload)) + obfsed[0] = 0x17 + obfsed[1] = 0x03 + obfsed[2] = 0x03 + binary.BigEndian.PutUint16(obfsed[3:5], uint16(16+12+len(f.Payload))) + copy(obfsed[5:21], iv) + copy(obfsed[21:33], cipherheader) + copy(obfsed[33:], f.Payload) + // obfsed: [record layer 5 bytes][iv 16 bytes][cipherheader 12 bytes][payload] + return obfsed } return obfs } func MakeDeobfs(key []byte) func([]byte) *mux.Frame { deobfs := func(in []byte) *mux.Frame { - peeled := PeelRecordLayer(in) + peeled := in[5:] header := AESDecrypt(peeled[0:16], key, peeled[16:28]) streamID := binary.BigEndian.Uint32(header[0:4]) seq := binary.BigEndian.Uint32(header[4:8])