Просмотр исходного кода

Add more detail to fragmentor notices

Rod Hynes 7 лет назад
Родитель
Сommit
a090df6a38
1 измененных файлов с 31 добавлено и 14 удалено
  1. 31 14
      psiphon/fragmentor.go

+ 31 - 14
psiphon/fragmentor.go

@@ -20,6 +20,7 @@
 package psiphon
 
 import (
+	"bytes"
 	"context"
 	"fmt"
 	"net"
@@ -32,7 +33,8 @@ import (
 )
 
 const (
-	NUM_FRAGMENTOR_NOTICES = 3
+	MAX_FRAGMENTOR_NOTICES               = 3
+	MAX_FRAGMENTOR_ITERATIONS_PER_NOTICE = 5
 )
 
 // NewTCPFragmentorDialer creates a TCP dialer that wraps dialed conns in
@@ -120,8 +122,8 @@ type FragmentorConn struct {
 	runCtx          context.Context
 	stopRunning     context.CancelFunc
 	isClosed        int32
-	numNotices      int32
 	writeMutex      sync.Mutex
+	numNotices      int
 	bytesToFragment int
 	bytesFragmented int
 	minWriteBytes   int
@@ -141,7 +143,23 @@ func (fragmentor *FragmentorConn) Write(buffer []byte) (int, error) {
 
 	totalBytesWritten := 0
 
-	for len(buffer) > 0 {
+	emitNotice := fragmentor.numNotices < MAX_FRAGMENTOR_NOTICES
+
+	// TODO: use strings.Builder in Go 1.10
+	var notice bytes.Buffer
+
+	if emitNotice {
+		remoteAddrStr := "(nil)"
+		remoteAddr := fragmentor.Conn.RemoteAddr()
+		if remoteAddr != nil {
+			remoteAddrStr = remoteAddr.String()
+		}
+		fmt.Fprintf(&notice,
+			"fragment %s %d bytes:",
+			remoteAddrStr, len(buffer))
+	}
+
+	for iterations := 0; len(buffer) > 0; iterations += 1 {
 
 		delay, err := common.MakeSecureRandomPeriod(
 			fragmentor.minDelay, fragmentor.maxDelay)
@@ -187,23 +205,22 @@ func (fragmentor *FragmentorConn) Write(buffer []byte) (int, error) {
 			return totalBytesWritten, err
 		}
 
-		numNotices := atomic.LoadInt32(&fragmentor.numNotices)
-		if numNotices < NUM_FRAGMENTOR_NOTICES &&
-			atomic.AddInt32(&fragmentor.numNotices, 1) <= NUM_FRAGMENTOR_NOTICES {
-
-			remoteAddrStr := "(nil)"
-			remoteAddr := fragmentor.Conn.RemoteAddr()
-			if remoteAddr != nil {
-				remoteAddrStr = remoteAddr.String()
+		if emitNotice {
+			if iterations < MAX_FRAGMENTOR_ITERATIONS_PER_NOTICE {
+				fmt.Fprintf(&notice, " [%s] %d", delay, bytesWritten)
+			} else if iterations == MAX_FRAGMENTOR_ITERATIONS_PER_NOTICE {
+				fmt.Fprintf(&notice, "...")
 			}
-
-			NoticeInfo("fragmentor %s: %s delay, %d bytes",
-				remoteAddrStr, delay, bytesWritten)
 		}
 
 		buffer = buffer[writeBytes:]
 	}
 
+	if emitNotice {
+		NoticeInfo(notice.String())
+		fragmentor.numNotices += 1
+	}
+
 	return totalBytesWritten, nil
 }