telebit/mplexer/packer/parser_test.go

265 lines
4.9 KiB
Go
Raw Normal View History

2020-05-18 08:43:06 +00:00
package packer
import (
2020-05-19 07:06:10 +00:00
"math/rand"
2020-05-18 08:43:06 +00:00
"net"
"testing"
"time"
)
2020-05-19 04:36:20 +00:00
var src = Addr{
family: "IPv4",
addr: "192.168.1.101",
port: 6743,
}
var dst = Addr{
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
}
func (th *testHandler) WriteMessage(a Addr, b []byte) {
2020-05-19 07:06:10 +00:00
th.chunksParsed++
2020-05-18 08:43:06 +00:00
addr := &a
_, ok := th.conns[addr.Network()]
if !ok {
rconn, wconn := net.Pipe()
conn := &Conn{
updated: time.Now(),
relayRemoteAddr: *addr,
relay: rconn,
local: wconn,
}
th.conns[addr.Network()] = conn
}
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-18 09:30:22 +00:00
h, b, err := Encode(src, dst, domain, payload)
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
h, b, err := Encode(src, dst, domain, payload)
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
h, b, err := Encode(src, dst, domain, payload)
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 {
copied := src
src = copied
src.port += i
}
h, b, err := Encode(src, dst, domain, payload)
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)
}
}