2020-05-22 10:41:24 +00:00
|
|
|
package telebit
|
2020-05-18 08:43:06 +00:00
|
|
|
|
|
|
|
import (
|
2020-05-19 07:06:10 +00:00
|
|
|
"math/rand"
|
2020-05-18 08:43:06 +00:00
|
|
|
"net"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
2020-05-21 10:29:05 +00:00
|
|
|
var srcTestAddr = Addr{
|
2020-05-19 04:36:20 +00:00
|
|
|
family: "IPv4",
|
|
|
|
addr: "192.168.1.101",
|
|
|
|
port: 6743,
|
|
|
|
}
|
2020-05-21 10:29:05 +00:00
|
|
|
var dstTestAddr = Addr{
|
2020-05-19 04:36:20 +00:00
|
|
|
family: "IPv4",
|
|
|
|
port: 80,
|
|
|
|
scheme: "http",
|
|
|
|
}
|
|
|
|
var domain = "ex1.telebit.io"
|
|
|
|
var payload = []byte("Hello, World!")
|
|
|
|
|
2020-05-18 08:43:06 +00:00
|
|
|
type testHandler struct {
|
|
|
|
conns map[string]*Conn
|
|
|
|
chunksParsed int
|
|
|
|
bytesRead int
|
|
|
|
}
|
|
|
|
|
2020-05-21 10:29:05 +00:00
|
|
|
func (th *testHandler) RouteBytes(srcAddr, dstAddr Addr, b []byte) {
|
2020-05-19 07:06:10 +00:00
|
|
|
th.chunksParsed++
|
2020-05-21 10:29:05 +00:00
|
|
|
src := &srcAddr
|
|
|
|
dst := &dstAddr
|
|
|
|
_, ok := th.conns[src.Network()]
|
2020-05-18 08:43:06 +00:00
|
|
|
if !ok {
|
|
|
|
rconn, wconn := net.Pipe()
|
|
|
|
conn := &Conn{
|
2020-05-21 10:29:05 +00:00
|
|
|
//updated: time.Now(),
|
|
|
|
relaySourceAddr: *src,
|
2020-05-22 10:07:35 +00:00
|
|
|
relayTargetAddr: *dst,
|
2020-05-18 08:43:06 +00:00
|
|
|
relay: rconn,
|
|
|
|
local: wconn,
|
|
|
|
}
|
2020-05-21 10:29:05 +00:00
|
|
|
th.conns[src.Network()] = conn
|
2020-05-18 08:43:06 +00:00
|
|
|
}
|
|
|
|
th.bytesRead += len(b)
|
|
|
|
}
|
|
|
|
|
2020-05-19 04:36:20 +00:00
|
|
|
func TestParse1WholeBlock(t *testing.T) {
|
|
|
|
testParseNBlocks(t, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParse2WholeBlocks(t *testing.T) {
|
|
|
|
testParseNBlocks(t, 2)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParse3WholeBlocks(t *testing.T) {
|
|
|
|
testParseNBlocks(t, 3)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParse2Addrs(t *testing.T) {
|
|
|
|
testParseNBlocks(t, 4)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParse3Addrs(t *testing.T) {
|
|
|
|
testParseNBlocks(t, 5)
|
|
|
|
}
|
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
func TestParseBy1(t *testing.T) {
|
|
|
|
testParseByN(t, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParseByPrimes(t *testing.T) {
|
|
|
|
testParseByN(t, 2)
|
|
|
|
testParseByN(t, 3)
|
|
|
|
testParseByN(t, 5)
|
|
|
|
testParseByN(t, 7)
|
|
|
|
testParseByN(t, 11)
|
|
|
|
testParseByN(t, 13)
|
|
|
|
testParseByN(t, 17)
|
|
|
|
testParseByN(t, 19)
|
|
|
|
testParseByN(t, 23)
|
|
|
|
testParseByN(t, 29)
|
|
|
|
testParseByN(t, 31)
|
|
|
|
testParseByN(t, 37)
|
|
|
|
testParseByN(t, 41)
|
|
|
|
testParseByN(t, 43)
|
|
|
|
testParseByN(t, 47)
|
|
|
|
}
|
2020-05-18 08:43:06 +00:00
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
func TestParseByRand(t *testing.T) {
|
|
|
|
testParseByN(t, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParse1AndRest(t *testing.T) {
|
2020-05-18 08:43:06 +00:00
|
|
|
th := &testHandler{
|
|
|
|
conns: map[string]*Conn{},
|
|
|
|
}
|
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
p := NewParser(th)
|
2020-05-19 04:36:20 +00:00
|
|
|
|
2020-05-21 10:29:05 +00:00
|
|
|
h, b, err := Encode(payload, srcTestAddr, dstTestAddr)
|
2020-05-18 09:30:22 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
raw := append(h, b...)
|
2020-05-19 04:36:20 +00:00
|
|
|
n, err := p.Write(raw[:1])
|
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
m, err := p.Write(raw[1:])
|
2020-05-18 08:43:06 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if 1 != len(th.conns) {
|
|
|
|
t.Fatal("should have parsed one connection")
|
|
|
|
}
|
|
|
|
if 1 != th.chunksParsed {
|
2020-05-19 04:36:20 +00:00
|
|
|
t.Fatal("should have parsed 1 chunck(s)")
|
2020-05-18 08:43:06 +00:00
|
|
|
}
|
2020-05-18 09:30:22 +00:00
|
|
|
if len(payload) != th.bytesRead {
|
|
|
|
t.Fatalf("should have parsed a payload of %d bytes, but saw %d\n", len(payload), th.bytesRead)
|
2020-05-18 08:43:06 +00:00
|
|
|
}
|
2020-05-19 04:36:20 +00:00
|
|
|
if n+m != len(raw) {
|
|
|
|
t.Fatalf("should have parsed all %d bytes, not just %d\n", n, len(raw))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParseRestAnd1(t *testing.T) {
|
|
|
|
th := &testHandler{
|
|
|
|
conns: map[string]*Conn{},
|
|
|
|
}
|
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
p := NewParser(th)
|
2020-05-19 04:36:20 +00:00
|
|
|
|
2020-05-21 10:29:05 +00:00
|
|
|
h, b, err := Encode(payload, srcTestAddr, dstTestAddr)
|
2020-05-19 04:36:20 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
raw := append(h, b...)
|
|
|
|
i := len(raw)
|
|
|
|
n, err := p.Write(raw[:i-1])
|
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
m, err := p.Write(raw[i-1:])
|
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if 1 != len(th.conns) {
|
|
|
|
t.Fatal("should have parsed one connection")
|
|
|
|
}
|
|
|
|
if 2 != th.chunksParsed {
|
|
|
|
t.Fatal("should have parsed 2 chunck(s)")
|
|
|
|
}
|
|
|
|
if len(payload) != th.bytesRead {
|
|
|
|
t.Fatalf("should have parsed a payload of %d bytes, but saw %d\n", len(payload), th.bytesRead)
|
|
|
|
}
|
|
|
|
if n+m != len(raw) {
|
2020-05-18 08:43:06 +00:00
|
|
|
t.Fatalf("should have parsed all %d bytes, not just %d\n", n, len(raw))
|
|
|
|
}
|
|
|
|
}
|
2020-05-19 04:36:20 +00:00
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
func testParseByN(t *testing.T, n int) {
|
|
|
|
//fmt.Printf("[debug] parse by %d\n", n)
|
2020-05-19 04:36:20 +00:00
|
|
|
th := &testHandler{
|
|
|
|
conns: map[string]*Conn{},
|
|
|
|
}
|
|
|
|
|
2020-05-19 07:06:10 +00:00
|
|
|
p := NewParser(th)
|
2020-05-19 04:36:20 +00:00
|
|
|
|
2020-05-21 10:29:05 +00:00
|
|
|
h, b, err := Encode(payload, srcTestAddr, dstTestAddr)
|
2020-05-19 04:36:20 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
raw := append(h, b...)
|
|
|
|
count := 0
|
2020-05-19 07:06:10 +00:00
|
|
|
nChunk := 0
|
|
|
|
b = raw
|
|
|
|
for {
|
|
|
|
r := 24
|
|
|
|
c := len(b)
|
|
|
|
if 0 == c {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
i := n
|
|
|
|
if 0 == n {
|
|
|
|
if c < r {
|
|
|
|
r = c
|
|
|
|
}
|
|
|
|
i = 1 + rand.Intn(r+1)
|
|
|
|
}
|
|
|
|
if c < i {
|
|
|
|
i = c
|
|
|
|
}
|
|
|
|
// TODO shouldn't this cause an error?
|
|
|
|
//a := b[:i][0]
|
|
|
|
a := b[:i]
|
|
|
|
b = b[i:]
|
|
|
|
nw, err := p.Write(a)
|
2020-05-19 04:36:20 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2020-05-19 07:06:10 +00:00
|
|
|
count += nw
|
|
|
|
if count > len(h) {
|
|
|
|
nChunk++
|
|
|
|
}
|
2020-05-19 04:36:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if 1 != len(th.conns) {
|
2020-05-19 07:06:10 +00:00
|
|
|
t.Fatalf("should have parsed one connection, not %d", len(th.conns))
|
2020-05-19 04:36:20 +00:00
|
|
|
}
|
2020-05-19 07:06:10 +00:00
|
|
|
if nChunk != th.chunksParsed {
|
|
|
|
t.Fatalf("should have parsed %d chunk(s), not %d", nChunk, th.chunksParsed)
|
2020-05-19 04:36:20 +00:00
|
|
|
}
|
|
|
|
if len(payload) != th.bytesRead {
|
|
|
|
t.Fatalf("should have parsed a payload of %d bytes, but saw %d\n", len(payload), th.bytesRead)
|
|
|
|
}
|
|
|
|
if count != len(raw) {
|
|
|
|
t.Fatalf("should have parsed all %d bytes, not just %d\n", len(raw), count)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testParseNBlocks(t *testing.T, count int) {
|
|
|
|
th := &testHandler{
|
|
|
|
conns: map[string]*Conn{},
|
|
|
|
}
|
|
|
|
|
|
|
|
nAddr := 1
|
|
|
|
if count > 2 {
|
|
|
|
nAddr = count - 2
|
|
|
|
}
|
2020-05-19 07:06:10 +00:00
|
|
|
p := NewParser(th)
|
2020-05-19 04:36:20 +00:00
|
|
|
raw := []byte{}
|
|
|
|
for i := 0; i < count; i++ {
|
|
|
|
if i > 2 {
|
2020-05-21 10:29:05 +00:00
|
|
|
copied := srcTestAddr
|
|
|
|
srcTestAddr = copied
|
|
|
|
srcTestAddr.port += i
|
2020-05-19 04:36:20 +00:00
|
|
|
}
|
2020-05-21 10:29:05 +00:00
|
|
|
h, b, err := Encode(payload, srcTestAddr, dstTestAddr)
|
2020-05-19 04:36:20 +00:00
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
raw = append(raw, h...)
|
|
|
|
raw = append(raw, b...)
|
|
|
|
}
|
|
|
|
n, err := p.Write(raw)
|
|
|
|
if nil != err {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if nAddr != len(th.conns) {
|
|
|
|
t.Fatalf("should have parsed %d connection(s)", nAddr)
|
|
|
|
}
|
|
|
|
if count != th.chunksParsed {
|
|
|
|
t.Fatalf("should have parsed %d chunk(s)", count)
|
|
|
|
}
|
|
|
|
if count*len(payload) != th.bytesRead {
|
|
|
|
t.Fatalf("should have parsed a payload of %d bytes, but saw %d\n", count*len(payload), th.bytesRead)
|
|
|
|
}
|
|
|
|
if n != len(raw) {
|
|
|
|
t.Fatalf("should have parsed all %d bytes, not just %d\n", len(raw), n)
|
|
|
|
}
|
|
|
|
}
|