telebit/parser.go

96 lines
1.7 KiB
Go
Raw Normal View History

2020-05-22 10:41:24 +00:00
package telebit
2020-05-18 08:43:06 +00:00
import (
"errors"
2020-07-15 10:46:02 +00:00
"fmt"
2020-07-21 06:35:45 +00:00
"os"
2020-07-20 22:20:59 +00:00
"git.rootprojects.org/root/telebit/dbg"
2020-05-18 08:43:06 +00:00
)
type Parser struct {
2020-05-21 05:30:24 +00:00
handler Router
2020-05-18 08:43:06 +00:00
newConns chan *Conn
conns map[string]*Conn
state ParserState
parseState State
dataReady chan struct{}
data []byte
2020-05-19 04:36:20 +00:00
consumed int
2020-05-18 08:43:06 +00:00
}
type ParserState struct {
2020-05-19 04:36:20 +00:00
consumed int
2020-05-18 08:43:06 +00:00
version byte
headerLen int
header []byte
payloadLen int
2020-05-21 10:29:05 +00:00
srcAddr Addr
dstAddr Addr
2020-05-18 08:43:06 +00:00
payloadWritten int
}
type State int
const (
V1 byte = 255 - (1 + iota)
V2
)
const (
VersionState State = 0
)
2020-05-21 05:30:24 +00:00
func NewParser(handler Router) *Parser {
2020-05-18 08:43:06 +00:00
return &Parser{
conns: make(map[string]*Conn),
newConns: make(chan *Conn, 2), // Buffered to make testing easier
dataReady: make(chan struct{}, 2),
data: []byte{},
handler: handler,
}
}
2020-05-21 05:30:24 +00:00
type Router interface {
2020-05-21 10:29:05 +00:00
RouteBytes(src, dst Addr, payload []byte)
2020-05-18 08:43:06 +00:00
}
// Write receives tunnel data and creates or writes to connections
func (p *Parser) Write(b []byte) (int, error) {
if len(b) < 1 {
return 0, errors.New("developer error: wrote 0 bytes")
}
2020-05-19 04:36:20 +00:00
/*
// so that we can overwrite the main state
// as soon as a full message has completed
// but still keep the number of bytes written
if 0 == p.state.written {
p.written = 0
}
*/
2020-05-18 08:43:06 +00:00
switch p.parseState {
case VersionState:
if dbg.Debug {
2020-07-21 06:35:45 +00:00
fmt.Fprintf(os.Stderr, "[debug] MPLEXY version byte %v %s", b[0], string(b))
}
2020-05-18 08:43:06 +00:00
p.state.version = b[0]
b = b[1:]
2020-05-19 07:06:10 +00:00
p.consumed++
p.parseState++
2020-05-18 08:43:06 +00:00
default:
// do nothing
}
switch p.state.version {
case V1:
if dbg.Debug {
2020-07-21 06:35:45 +00:00
fmt.Fprintf(os.Stderr, "[debug] MPLEXY packet is of type v1\n")
}
2020-05-19 04:36:20 +00:00
return p.unpackV1(b)
2020-05-18 08:43:06 +00:00
default:
return 0, errors.New("incorrect version or version not implemented")
}
}