for test use

This commit is contained in:
Sense T 2022-09-09 06:05:20 +00:00
parent aa3ccbbfee
commit 94b80580fa
6 changed files with 160 additions and 0 deletions

34
connection.go Normal file
View File

@ -0,0 +1,34 @@
package tunnel
type Connection struct {
RX <-chan *DataFrame
TX chan<- *DataFrame
ID ID
}
func (c *Connection) Read(p []byte) (int, error) {
df, ok := <-c.RX
if !ok {
return 0, c.Close()
}
return df.Read(p)
}
func (c *Connection) Write(p []byte) (int, error) {
defer recover()
df := &DataFrame{
ID: c.ID,
Type: TypeNormal,
}
n, err := df.Write(p)
if err != nil {
return 0, err
}
c.TX <- df
return n, nil
}
func (c *Connection) Close() error {
defer close(c.TX)
return nil
}

9
consts.go Normal file
View File

@ -0,0 +1,9 @@
package tunnel
const (
TypeNormal Type = iota
TypeRequest
TypeConnected
TypeClosed
TypeInvalid Type = 0xff
)

38
dataframe.go Normal file
View File

@ -0,0 +1,38 @@
package tunnel
import (
"compress/gzip"
"encoding/gob"
"io"
)
type DataFrame struct {
ID ID
Type Type
Payload []byte
}
func (d *DataFrame) Encode(w io.Writer) error {
gz := gzip.NewWriter(w)
defer gz.Close()
gob := gob.NewEncoder(gz)
return gob.Encode(d)
}
func (d *DataFrame) Decode(r io.Reader) error {
gz, err := gzip.NewReader(r)
if err != nil {
return err
}
defer gz.Close()
gob := gob.NewDecoder(gz)
return gob.Decode(d)
}
func (d *DataFrame) Read(p []byte) (int, error) {
return copy(p, d.Payload), nil
}
func (d *DataFrame) Write(p []byte) (int, error) {
return copy(d.Payload, p), nil
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module git.sense-t.eu.org/senset/tunnel
go 1.19

72
manager.go Normal file
View File

@ -0,0 +1,72 @@
package tunnel
import (
"io"
)
type Manager struct {
Tunnel io.ReadWriter
Connections map[ID]*Connection
incoming chan *DataFrame
outgoing chan *DataFrame
accept chan *DataFrame
closed chan bool
}
func NewManager(tun io.ReadWriter) *Manager {
return &Manager{
Tunnel: tun,
Connections: make(map[ID]*Connection),
incoming: make(chan *DataFrame, 1024),
outgoing: make(chan *DataFrame, 1024),
accept: make(chan *DataFrame, 1024),
}
}
func (m *Manager) Run() {
for {
select {
case <-m.closed:
return
case df := <-m.incoming:
go df.Encode(m.Tunnel)
default:
go func() {
df := new(DataFrame)
df.Decode(m.Tunnel)
switch df.Type {
case TypeRequest:
m.accept <- df
case TypeClosed:
connection, ok := m.Connections[df.ID]
if ok {
connection.Close()
delete(m.Connections, df.ID)
}
case TypeNormal:
connection, ok := m.Connections[df.ID]
if ok {
connection.RX = m.outgoing
m.outgoing <- df
}
}
}()
}
}
}
func (m *Manager) Connect()
func (m *Manager) Accept()
func (m *Manager) Close() error {
defer close(m.closed)
defer close(m.accept)
defer close(m.incoming)
defer close(m.outgoing)
for _, connection := range m.Connections {
connection.Close()
}
m.closed <- true
return nil
}

4
types.go Normal file
View File

@ -0,0 +1,4 @@
package tunnel
type ID string
type Type uint8