mirror of https://github.com/cbeuw/Cloak
Merge branch 'master' into notsure2
This commit is contained in:
commit
edb18d5b4c
|
|
@ -73,6 +73,9 @@ func main() {
|
||||||
log.Info("Starting standalone mode")
|
log.Info("Starting standalone mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.SetFormatter(&log.TextFormatter{
|
||||||
|
FullTimestamp: true,
|
||||||
|
})
|
||||||
lvl, err := log.ParseLevel(*verbosity)
|
lvl, err := log.ParseLevel(*verbosity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,10 @@ func main() {
|
||||||
|
|
||||||
var pluginMode bool
|
var pluginMode bool
|
||||||
|
|
||||||
|
log.SetFormatter(&log.TextFormatter{
|
||||||
|
FullTimestamp: true,
|
||||||
|
})
|
||||||
|
|
||||||
if os.Getenv("SS_LOCAL_HOST") != "" && os.Getenv("SS_LOCAL_PORT") != "" {
|
if os.Getenv("SS_LOCAL_HOST") != "" && os.Getenv("SS_LOCAL_PORT") != "" {
|
||||||
pluginMode = true
|
pluginMode = true
|
||||||
config = os.Getenv("SS_PLUGIN_OPTIONS")
|
config = os.Getenv("SS_PLUGIN_OPTIONS")
|
||||||
|
|
|
||||||
|
|
@ -65,14 +65,15 @@ func makeSessionPair(numConn int) (*Session, *Session, []*connPair) {
|
||||||
|
|
||||||
func runEchoTest(t *testing.T, conns []net.Conn, msgLen int) {
|
func runEchoTest(t *testing.T, conns []net.Conn, msgLen int) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
testData := make([]byte, msgLen)
|
|
||||||
rand.Read(testData)
|
|
||||||
|
|
||||||
for _, conn := range conns {
|
for _, conn := range conns {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(conn net.Conn) {
|
go func(conn net.Conn) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
|
testData := make([]byte, msgLen)
|
||||||
|
rand.Read(testData)
|
||||||
|
|
||||||
// we cannot call t.Fatalf in concurrent contexts
|
// we cannot call t.Fatalf in concurrent contexts
|
||||||
n, err := conn.Write(testData)
|
n, err := conn.Write(testData)
|
||||||
if n != msgLen {
|
if n != msgLen {
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,6 @@ import (
|
||||||
"golang.org/x/crypto/salsa20"
|
"golang.org/x/crypto/salsa20"
|
||||||
)
|
)
|
||||||
|
|
||||||
var u32 = binary.BigEndian.Uint32
|
|
||||||
var u64 = binary.BigEndian.Uint64
|
|
||||||
var putU32 = binary.BigEndian.PutUint32
|
|
||||||
var putU64 = binary.BigEndian.PutUint64
|
|
||||||
|
|
||||||
const frameHeaderLength = 14
|
const frameHeaderLength = 14
|
||||||
const salsa20NonceSize = 8
|
const salsa20NonceSize = 8
|
||||||
|
|
||||||
|
|
@ -98,8 +93,8 @@ func (o *Obfuscator) obfuscate(f *Frame, buf []byte, payloadOffsetInBuf int) (in
|
||||||
}
|
}
|
||||||
|
|
||||||
header := buf[:frameHeaderLength]
|
header := buf[:frameHeaderLength]
|
||||||
putU32(header[0:4], f.StreamID)
|
binary.BigEndian.PutUint32(header[0:4], f.StreamID)
|
||||||
putU64(header[4:12], f.Seq)
|
binary.BigEndian.PutUint64(header[4:12], f.Seq)
|
||||||
header[12] = f.Closing
|
header[12] = f.Closing
|
||||||
header[13] = byte(extraLen)
|
header[13] = byte(extraLen)
|
||||||
|
|
||||||
|
|
@ -130,8 +125,8 @@ func (o *Obfuscator) deobfuscate(f *Frame, in []byte) error {
|
||||||
nonce := in[len(in)-salsa20NonceSize:]
|
nonce := in[len(in)-salsa20NonceSize:]
|
||||||
salsa20.XORKeyStream(header, header, nonce, &o.SessionKey)
|
salsa20.XORKeyStream(header, header, nonce, &o.SessionKey)
|
||||||
|
|
||||||
streamID := u32(header[0:4])
|
streamID := binary.BigEndian.Uint32(header[0:4])
|
||||||
seq := u64(header[4:12])
|
seq := binary.BigEndian.Uint64(header[4:12])
|
||||||
closing := header[12]
|
closing := header[12]
|
||||||
extraLen := header[13]
|
extraLen := header[13]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/cbeuw/connutil"
|
"github.com/cbeuw/connutil"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -16,73 +19,188 @@ var seshConfigs = map[string]SessionConfig{
|
||||||
"ordered": {},
|
"ordered": {},
|
||||||
"unordered": {Unordered: true},
|
"unordered": {Unordered: true},
|
||||||
}
|
}
|
||||||
|
var encryptionMethods = map[string]byte{
|
||||||
|
"plain": EncryptionMethodPlain,
|
||||||
|
"aes-256-gcm": EncryptionMethodAES256GCM,
|
||||||
|
"aes-128-gcm": EncryptionMethodAES128GCM,
|
||||||
|
"chacha20poly1305": EncryptionMethodChaha20Poly1305,
|
||||||
|
}
|
||||||
|
|
||||||
const testPayloadLen = 1024
|
const testPayloadLen = 1024
|
||||||
const obfsBufLen = testPayloadLen * 2
|
const obfsBufLen = testPayloadLen * 2
|
||||||
|
|
||||||
func TestRecvDataFromRemote(t *testing.T) {
|
func TestRecvDataFromRemote(t *testing.T) {
|
||||||
testPayload := make([]byte, testPayloadLen)
|
|
||||||
rand.Read(testPayload)
|
|
||||||
f := &Frame{
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
testPayload,
|
|
||||||
}
|
|
||||||
obfsBuf := make([]byte, obfsBufLen)
|
|
||||||
|
|
||||||
var sessionKey [32]byte
|
var sessionKey [32]byte
|
||||||
rand.Read(sessionKey[:])
|
rand.Read(sessionKey[:])
|
||||||
|
|
||||||
MakeObfuscatorUnwrap := func(method byte, sessionKey [32]byte) Obfuscator {
|
|
||||||
ret, err := MakeObfuscator(method, sessionKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to make an obfuscator: %v", err)
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
encryptionMethods := map[string]Obfuscator{
|
|
||||||
"plain": MakeObfuscatorUnwrap(EncryptionMethodPlain, sessionKey),
|
|
||||||
"aes-gcm": MakeObfuscatorUnwrap(EncryptionMethodAES256GCM, sessionKey),
|
|
||||||
"chacha20-poly1305": MakeObfuscatorUnwrap(EncryptionMethodChaha20Poly1305, sessionKey),
|
|
||||||
}
|
|
||||||
|
|
||||||
for seshType, seshConfig := range seshConfigs {
|
for seshType, seshConfig := range seshConfigs {
|
||||||
seshConfig := seshConfig
|
seshConfig := seshConfig
|
||||||
t.Run(seshType, func(t *testing.T) {
|
t.Run(seshType, func(t *testing.T) {
|
||||||
for method, obfuscator := range encryptionMethods {
|
var err error
|
||||||
obfuscator := obfuscator
|
seshConfig.Obfuscator, err = MakeObfuscator(EncryptionMethodPlain, sessionKey)
|
||||||
t.Run(method, func(t *testing.T) {
|
if err != nil {
|
||||||
seshConfig.Obfuscator = obfuscator
|
t.Fatalf("failed to make obfuscator: %v", err)
|
||||||
|
}
|
||||||
|
t.Run("initial frame", func(t *testing.T) {
|
||||||
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
obfsBuf := make([]byte, obfsBufLen)
|
||||||
|
f := Frame{
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
make([]byte, testPayloadLen),
|
||||||
|
}
|
||||||
|
rand.Read(f.Payload)
|
||||||
|
n, err := sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
stream, err := sesh.Accept()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
resultPayload := make([]byte, testPayloadLen)
|
||||||
|
_, err = stream.Read(resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, f.Payload, resultPayload)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("two frames in order", func(t *testing.T) {
|
||||||
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
obfsBuf := make([]byte, obfsBufLen)
|
||||||
|
f := Frame{
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
make([]byte, testPayloadLen),
|
||||||
|
}
|
||||||
|
rand.Read(f.Payload)
|
||||||
|
n, err := sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
stream, err := sesh.Accept()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
resultPayload := make([]byte, testPayloadLen)
|
||||||
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, f.Payload, resultPayload)
|
||||||
|
|
||||||
|
f.Seq += 1
|
||||||
|
rand.Read(f.Payload)
|
||||||
|
n, err = sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, f.Payload, resultPayload)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("two frames in order", func(t *testing.T) {
|
||||||
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
obfsBuf := make([]byte, obfsBufLen)
|
||||||
|
f := Frame{
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
make([]byte, testPayloadLen),
|
||||||
|
}
|
||||||
|
rand.Read(f.Payload)
|
||||||
|
n, err := sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
stream, err := sesh.Accept()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
resultPayload := make([]byte, testPayloadLen)
|
||||||
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, f.Payload, resultPayload)
|
||||||
|
|
||||||
|
f.Seq += 1
|
||||||
|
rand.Read(f.Payload)
|
||||||
|
n, err = sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.EqualValues(t, f.Payload, resultPayload)
|
||||||
|
})
|
||||||
|
|
||||||
|
if seshType == "ordered" {
|
||||||
|
t.Run("frames out of order", func(t *testing.T) {
|
||||||
sesh := MakeSession(0, seshConfig)
|
sesh := MakeSession(0, seshConfig)
|
||||||
n, err := sesh.obfuscate(f, obfsBuf, 0)
|
obfsBuf := make([]byte, obfsBufLen)
|
||||||
if err != nil {
|
f := Frame{
|
||||||
t.Error(err)
|
1,
|
||||||
return
|
0,
|
||||||
}
|
0,
|
||||||
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
nil,
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
stream, err := sesh.Accept()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First frame
|
||||||
|
seq0 := make([]byte, testPayloadLen)
|
||||||
|
rand.Read(seq0)
|
||||||
|
f.Seq = 0
|
||||||
|
f.Payload = seq0
|
||||||
|
n, err := sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Third frame
|
||||||
|
seq2 := make([]byte, testPayloadLen)
|
||||||
|
rand.Read(seq2)
|
||||||
|
f.Seq = 2
|
||||||
|
f.Payload = seq2
|
||||||
|
n, err = sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Second frame
|
||||||
|
seq1 := make([]byte, testPayloadLen)
|
||||||
|
rand.Read(seq1)
|
||||||
|
f.Seq = 1
|
||||||
|
f.Payload = seq1
|
||||||
|
n, err = sesh.obfuscate(&f, obfsBuf, 0)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
err = sesh.recvDataFromRemote(obfsBuf[:n])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Expect things to receive in order
|
||||||
|
stream, err := sesh.Accept()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
resultPayload := make([]byte, testPayloadLen)
|
resultPayload := make([]byte, testPayloadLen)
|
||||||
_, err = stream.Read(resultPayload)
|
|
||||||
if err != nil {
|
// First
|
||||||
t.Error(err)
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
return
|
assert.NoError(t, err)
|
||||||
}
|
assert.EqualValues(t, seq0, resultPayload)
|
||||||
if !bytes.Equal(testPayload, resultPayload) {
|
|
||||||
t.Errorf("Expecting %x, got %x", testPayload, resultPayload)
|
// Second
|
||||||
}
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, seq1, resultPayload)
|
||||||
|
|
||||||
|
// Third
|
||||||
|
_, err = io.ReadFull(stream, resultPayload)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.EqualValues(t, seq2, resultPayload)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,10 +212,9 @@ func TestRecvDataFromRemote_Closing_InOrder(t *testing.T) {
|
||||||
|
|
||||||
var sessionKey [32]byte
|
var sessionKey [32]byte
|
||||||
rand.Read(sessionKey[:])
|
rand.Read(sessionKey[:])
|
||||||
obfuscator, _ := MakeObfuscator(EncryptionMethodPlain, sessionKey)
|
|
||||||
|
|
||||||
seshConfig := seshConfigs["ordered"]
|
seshConfig := seshConfigs["ordered"]
|
||||||
seshConfig.Obfuscator = obfuscator
|
seshConfig.Obfuscator, _ = MakeObfuscator(EncryptionMethodPlain, sessionKey)
|
||||||
sesh := MakeSession(0, seshConfig)
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
|
||||||
f1 := &Frame{
|
f1 := &Frame{
|
||||||
|
|
@ -233,10 +350,9 @@ func TestRecvDataFromRemote_Closing_OutOfOrder(t *testing.T) {
|
||||||
|
|
||||||
var sessionKey [32]byte
|
var sessionKey [32]byte
|
||||||
rand.Read(sessionKey[:])
|
rand.Read(sessionKey[:])
|
||||||
obfuscator, _ := MakeObfuscator(EncryptionMethodPlain, sessionKey)
|
|
||||||
|
|
||||||
seshConfig := seshConfigs["ordered"]
|
seshConfig := seshConfigs["ordered"]
|
||||||
seshConfig.Obfuscator = obfuscator
|
seshConfig.Obfuscator, _ = MakeObfuscator(EncryptionMethodPlain, sessionKey)
|
||||||
sesh := MakeSession(0, seshConfig)
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
|
||||||
// receive stream 1 closing first
|
// receive stream 1 closing first
|
||||||
|
|
@ -415,7 +531,7 @@ func TestSession_timeoutAfter(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRecvDataFromRemote_Ordered(b *testing.B) {
|
func BenchmarkRecvDataFromRemote(b *testing.B) {
|
||||||
testPayload := make([]byte, testPayloadLen)
|
testPayload := make([]byte, testPayloadLen)
|
||||||
rand.Read(testPayload)
|
rand.Read(testPayload)
|
||||||
f := &Frame{
|
f := &Frame{
|
||||||
|
|
@ -428,34 +544,34 @@ func BenchmarkRecvDataFromRemote_Ordered(b *testing.B) {
|
||||||
var sessionKey [32]byte
|
var sessionKey [32]byte
|
||||||
rand.Read(sessionKey[:])
|
rand.Read(sessionKey[:])
|
||||||
|
|
||||||
table := map[string]byte{
|
|
||||||
"plain": EncryptionMethodPlain,
|
|
||||||
"aes-256-gcm": EncryptionMethodAES256GCM,
|
|
||||||
"aes-128-gcm": EncryptionMethodAES128GCM,
|
|
||||||
"chacha20poly1305": EncryptionMethodChaha20Poly1305,
|
|
||||||
}
|
|
||||||
|
|
||||||
const maxIter = 100_000 // run with -benchtime 100000x to avoid index out of bounds panic
|
const maxIter = 100_000 // run with -benchtime 100000x to avoid index out of bounds panic
|
||||||
for name, ep := range table {
|
for name, ep := range encryptionMethods {
|
||||||
ep := ep
|
ep := ep
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
seshConfig := seshConfigs["ordered"]
|
for seshType, seshConfig := range seshConfigs {
|
||||||
obfuscator, _ := MakeObfuscator(ep, sessionKey)
|
b.Run(seshType, func(b *testing.B) {
|
||||||
seshConfig.Obfuscator = obfuscator
|
seshConfig.Obfuscator, _ = MakeObfuscator(ep, sessionKey)
|
||||||
sesh := MakeSession(0, seshConfig)
|
sesh := MakeSession(0, seshConfig)
|
||||||
|
|
||||||
binaryFrames := [maxIter][]byte{}
|
go func() {
|
||||||
for i := 0; i < maxIter; i++ {
|
stream, _ := sesh.Accept()
|
||||||
obfsBuf := make([]byte, obfsBufLen)
|
stream.(*Stream).WriteTo(ioutil.Discard)
|
||||||
n, _ := sesh.obfuscate(f, obfsBuf, 0)
|
}()
|
||||||
binaryFrames[i] = obfsBuf[:n]
|
|
||||||
f.Seq++
|
|
||||||
}
|
|
||||||
|
|
||||||
b.SetBytes(int64(len(f.Payload)))
|
binaryFrames := [maxIter][]byte{}
|
||||||
b.ResetTimer()
|
for i := 0; i < maxIter; i++ {
|
||||||
for i := 0; i < b.N; i++ {
|
obfsBuf := make([]byte, obfsBufLen)
|
||||||
sesh.recvDataFromRemote(binaryFrames[i])
|
n, _ := sesh.obfuscate(f, obfsBuf, 0)
|
||||||
|
binaryFrames[i] = obfsBuf[:n]
|
||||||
|
f.Seq++
|
||||||
|
}
|
||||||
|
|
||||||
|
b.SetBytes(int64(len(f.Payload)))
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
sesh.recvDataFromRemote(binaryFrames[i])
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -465,22 +581,13 @@ func BenchmarkMultiStreamWrite(b *testing.B) {
|
||||||
var sessionKey [32]byte
|
var sessionKey [32]byte
|
||||||
rand.Read(sessionKey[:])
|
rand.Read(sessionKey[:])
|
||||||
|
|
||||||
table := map[string]byte{
|
|
||||||
"plain": EncryptionMethodPlain,
|
|
||||||
"aes-256-gcm": EncryptionMethodAES256GCM,
|
|
||||||
"aes-128-gcm": EncryptionMethodAES128GCM,
|
|
||||||
"chacha20poly1305": EncryptionMethodChaha20Poly1305,
|
|
||||||
}
|
|
||||||
|
|
||||||
testPayload := make([]byte, testPayloadLen)
|
testPayload := make([]byte, testPayloadLen)
|
||||||
|
|
||||||
for name, ep := range table {
|
for name, ep := range encryptionMethods {
|
||||||
b.Run(name, func(b *testing.B) {
|
b.Run(name, func(b *testing.B) {
|
||||||
for seshType, seshConfig := range seshConfigs {
|
for seshType, seshConfig := range seshConfigs {
|
||||||
seshConfig := seshConfig
|
|
||||||
b.Run(seshType, func(b *testing.B) {
|
b.Run(seshType, func(b *testing.B) {
|
||||||
obfuscator, _ := MakeObfuscator(ep, sessionKey)
|
seshConfig.Obfuscator, _ = MakeObfuscator(ep, sessionKey)
|
||||||
seshConfig.Obfuscator = obfuscator
|
|
||||||
sesh := MakeSession(0, seshConfig)
|
sesh := MakeSession(0, seshConfig)
|
||||||
sesh.AddConnection(connutil.Discard())
|
sesh.AddConnection(connutil.Discard())
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
@ -496,3 +603,36 @@ func BenchmarkMultiStreamWrite(b *testing.B) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkLatency(b *testing.B) {
|
||||||
|
var sessionKey [32]byte
|
||||||
|
rand.Read(sessionKey[:])
|
||||||
|
|
||||||
|
for name, ep := range encryptionMethods {
|
||||||
|
b.Run(name, func(b *testing.B) {
|
||||||
|
for seshType, seshConfig := range seshConfigs {
|
||||||
|
b.Run(seshType, func(b *testing.B) {
|
||||||
|
seshConfig.Obfuscator, _ = MakeObfuscator(ep, sessionKey)
|
||||||
|
clientSesh := MakeSession(0, seshConfig)
|
||||||
|
serverSesh := MakeSession(0, seshConfig)
|
||||||
|
|
||||||
|
c, s := net.Pipe()
|
||||||
|
clientSesh.AddConnection(c)
|
||||||
|
serverSesh.AddConnection(s)
|
||||||
|
|
||||||
|
buf := make([]byte, 64)
|
||||||
|
clientStream, _ := clientSesh.OpenStream()
|
||||||
|
clientStream.Write(buf)
|
||||||
|
serverStream, _ := serverSesh.Accept()
|
||||||
|
io.ReadFull(serverStream, buf)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
clientStream.Write(buf)
|
||||||
|
io.ReadFull(serverStream, buf)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,8 @@ func (sb *streamBuffer) Write(f *Frame) (toBeClosed bool, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
saved := *f
|
saved := *f
|
||||||
|
saved.Payload = make([]byte, len(f.Payload))
|
||||||
|
copy(saved.Payload, f.Payload)
|
||||||
heap.Push(&sb.sh, &saved)
|
heap.Push(&sb.sh, &saved)
|
||||||
// Keep popping from the heap until empty or to the point that the wanted seq was not received
|
// Keep popping from the heap until empty or to the point that the wanted seq was not received
|
||||||
for len(sb.sh) > 0 && sb.sh[0].Seq == sb.nextRecvSeq {
|
for len(sb.sh) > 0 && sb.sh[0].Seq == sb.nextRecvSeq {
|
||||||
|
|
|
||||||
|
|
@ -222,14 +222,15 @@ func establishSession(lcc client.LocalConnConfig, rcc client.RemoteConnConfig, a
|
||||||
|
|
||||||
func runEchoTest(t *testing.T, conns []net.Conn, msgLen int) {
|
func runEchoTest(t *testing.T, conns []net.Conn, msgLen int) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
testData := make([]byte, msgLen)
|
|
||||||
rand.Read(testData)
|
|
||||||
|
|
||||||
for _, conn := range conns {
|
for _, conn := range conns {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func(conn net.Conn) {
|
go func(conn net.Conn) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
|
testData := make([]byte, msgLen)
|
||||||
|
rand.Read(testData)
|
||||||
|
|
||||||
// we cannot call t.Fatalf in concurrent contexts
|
// we cannot call t.Fatalf in concurrent contexts
|
||||||
n, err := conn.Write(testData)
|
n, err := conn.Write(testData)
|
||||||
if n != msgLen {
|
if n != msgLen {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue