2019-08-08 14:08:16 +00:00
|
|
|
package multiplex
|
|
|
|
|
|
|
|
import (
|
2019-08-14 09:44:50 +00:00
|
|
|
"github.com/cbeuw/Cloak/internal/util"
|
2020-04-07 19:59:32 +00:00
|
|
|
"github.com/cbeuw/connutil"
|
2019-08-08 14:08:16 +00:00
|
|
|
"math/rand"
|
2019-10-16 22:00:11 +00:00
|
|
|
"net"
|
2019-08-08 14:08:16 +00:00
|
|
|
"testing"
|
2019-10-16 22:00:11 +00:00
|
|
|
"time"
|
2019-08-08 14:08:16 +00:00
|
|
|
)
|
|
|
|
|
2019-09-22 09:44:16 +00:00
|
|
|
func TestSwitchboard_Send(t *testing.T) {
|
2019-10-20 14:21:31 +00:00
|
|
|
getHole := func() net.Conn {
|
|
|
|
l, _ := net.Listen("tcp", "127.0.0.1:0")
|
|
|
|
go func() {
|
|
|
|
net.Dial("tcp", l.Addr().String())
|
|
|
|
}()
|
|
|
|
hole, _ := l.Accept()
|
|
|
|
return hole
|
|
|
|
}
|
2019-09-22 09:44:16 +00:00
|
|
|
doTest := func(seshConfig *SessionConfig) {
|
|
|
|
sesh := MakeSession(0, seshConfig)
|
2019-10-20 14:21:31 +00:00
|
|
|
hole0 := getHole()
|
2019-09-22 09:44:16 +00:00
|
|
|
sesh.sb.addConn(hole0)
|
2019-11-03 12:22:12 +00:00
|
|
|
connId, _, err := sesh.sb.pickRandConn()
|
2019-09-22 09:44:16 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("failed to get a random conn", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
data := make([]byte, 1000)
|
|
|
|
rand.Read(data)
|
|
|
|
_, err = sesh.sb.send(data, &connId)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-10-20 14:21:31 +00:00
|
|
|
hole1 := getHole()
|
2019-09-22 09:44:16 +00:00
|
|
|
sesh.sb.addConn(hole1)
|
2019-11-03 12:22:12 +00:00
|
|
|
connId, _, err = sesh.sb.pickRandConn()
|
2019-09-22 09:44:16 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("failed to get a random conn", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_, err = sesh.sb.send(data, &connId)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-11-03 12:22:12 +00:00
|
|
|
connId, _, err = sesh.sb.pickRandConn()
|
2019-09-22 09:44:16 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("failed to get a random conn", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
_, err = sesh.sb.send(data, &connId)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("Ordered", func(t *testing.T) {
|
|
|
|
seshConfig := &SessionConfig{
|
|
|
|
Obfuscator: nil,
|
|
|
|
Valve: nil,
|
|
|
|
UnitRead: util.ReadTLS,
|
|
|
|
Unordered: false,
|
|
|
|
}
|
|
|
|
doTest(seshConfig)
|
|
|
|
})
|
|
|
|
t.Run("Unordered", func(t *testing.T) {
|
|
|
|
seshConfig := &SessionConfig{
|
|
|
|
Obfuscator: nil,
|
|
|
|
Valve: nil,
|
|
|
|
UnitRead: util.ReadTLS,
|
|
|
|
Unordered: true,
|
|
|
|
}
|
|
|
|
doTest(seshConfig)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-08-08 14:08:16 +00:00
|
|
|
func BenchmarkSwitchboard_Send(b *testing.B) {
|
2020-04-07 19:59:32 +00:00
|
|
|
hole := connutil.Discard()
|
2019-08-11 23:22:15 +00:00
|
|
|
seshConfig := &SessionConfig{
|
|
|
|
Obfuscator: nil,
|
|
|
|
Valve: nil,
|
2019-08-14 09:44:50 +00:00
|
|
|
UnitRead: util.ReadTLS,
|
2019-08-11 23:22:15 +00:00
|
|
|
}
|
|
|
|
sesh := MakeSession(0, seshConfig)
|
2019-08-14 09:44:50 +00:00
|
|
|
sesh.sb.addConn(hole)
|
2019-11-03 12:22:12 +00:00
|
|
|
connId, _, err := sesh.sb.pickRandConn()
|
2019-08-08 14:08:16 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Error("failed to get a random conn", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
data := make([]byte, 1000)
|
|
|
|
rand.Read(data)
|
|
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
2019-08-14 09:44:50 +00:00
|
|
|
n, err := sesh.sb.send(data, &connId)
|
2019-08-08 14:08:16 +00:00
|
|
|
if err != nil {
|
|
|
|
b.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
b.SetBytes(int64(n))
|
|
|
|
}
|
|
|
|
}
|
2019-08-14 09:44:50 +00:00
|
|
|
|
|
|
|
func TestSwitchboard_TxCredit(t *testing.T) {
|
|
|
|
seshConfig := &SessionConfig{
|
|
|
|
Obfuscator: nil,
|
|
|
|
Valve: MakeValve(1<<20, 1<<20),
|
|
|
|
UnitRead: util.ReadTLS,
|
|
|
|
}
|
|
|
|
sesh := MakeSession(0, seshConfig)
|
2020-04-07 19:59:32 +00:00
|
|
|
hole := connutil.Discard()
|
2019-08-14 09:44:50 +00:00
|
|
|
sesh.sb.addConn(hole)
|
2019-11-03 12:22:12 +00:00
|
|
|
connId, _, err := sesh.sb.pickRandConn()
|
2019-08-14 09:44:50 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error("failed to get a random conn", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
data := make([]byte, 1000)
|
|
|
|
rand.Read(data)
|
|
|
|
|
|
|
|
t.Run("FIXED CONN MAPPING", func(t *testing.T) {
|
|
|
|
*sesh.sb.Valve.(*LimitedValve).tx = 0
|
|
|
|
sesh.sb.strategy = FIXED_CONN_MAPPING
|
|
|
|
n, err := sesh.sb.send(data[:10], &connId)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if n != 10 {
|
|
|
|
t.Errorf("wanted to send %v, got %v", 10, n)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if *sesh.sb.Valve.(*LimitedValve).tx != 10 {
|
|
|
|
t.Error("tx credit didn't increase by 10")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
t.Run("UNIFORM", func(t *testing.T) {
|
|
|
|
*sesh.sb.Valve.(*LimitedValve).tx = 0
|
|
|
|
sesh.sb.strategy = UNIFORM_SPREAD
|
|
|
|
n, err := sesh.sb.send(data[:10], &connId)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if n != 10 {
|
|
|
|
t.Errorf("wanted to send %v, got %v", 10, n)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if *sesh.sb.Valve.(*LimitedValve).tx != 10 {
|
|
|
|
t.Error("tx credit didn't increase by 10")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2019-10-16 22:00:11 +00:00
|
|
|
|
|
|
|
func TestSwitchboard_CloseOnOneDisconn(t *testing.T) {
|
|
|
|
sesh := setupSesh(false)
|
|
|
|
|
|
|
|
l, _ := net.Listen("tcp", "127.0.0.1:0")
|
|
|
|
addRemoteConn := func(close chan struct{}) {
|
|
|
|
conn, _ := net.Dial("tcp", l.Addr().String())
|
|
|
|
for {
|
|
|
|
conn.Write([]byte{0x00})
|
|
|
|
<-close
|
|
|
|
conn.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close0 := make(chan struct{})
|
|
|
|
go addRemoteConn(close0)
|
|
|
|
conn0, _ := l.Accept()
|
|
|
|
sesh.AddConnection(conn0)
|
|
|
|
|
|
|
|
close1 := make(chan struct{})
|
|
|
|
go addRemoteConn(close1)
|
|
|
|
conn1, _ := l.Accept()
|
|
|
|
sesh.AddConnection(conn1)
|
|
|
|
|
|
|
|
close0 <- struct{}{}
|
|
|
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
if !sesh.IsClosed() {
|
|
|
|
t.Error("session not closed after one conn is disconnected")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if _, err := conn1.Write([]byte{0x00}); err == nil {
|
|
|
|
t.Error("the other conn is still connected")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|