3 Commits

Author SHA1 Message Date
Sense T afc125cc1c log some message 2022-09-09 13:31:49 +00:00
Sense T c385a6b1ea can set logger compatiable with logrus 2022-09-09 13:16:36 +00:00
Sense T ef798c1ac7 error hint 2022-09-09 11:53:46 +00:00
5 changed files with 96 additions and 8 deletions
+8
View File
@@ -10,6 +10,11 @@ type Connection struct {
TX chan<- *DataFrame TX chan<- *DataFrame
ID ID ID ID
closed bool closed bool
logger Logger
}
func (c *Connection) SetLogger(logger Logger) {
c.logger = logger
} }
func (c *Connection) Read(p []byte) (int, error) { func (c *Connection) Read(p []byte) (int, error) {
@@ -17,6 +22,7 @@ func (c *Connection) Read(p []byte) (int, error) {
if !ok { if !ok {
return 0, c.Close() return 0, c.Close()
} }
c.logger.Trace("dataframe received: ", df)
return df.Read(p) return df.Read(p)
} }
@@ -37,11 +43,13 @@ func (c *Connection) Write(p []byte) (int, error) {
if err != nil { if err != nil {
return 0, err return 0, err
} }
c.logger.Trace("dataframe send: ", df)
c.TX <- df c.TX <- df
return n, nil return n, nil
} }
func (c *Connection) Close() error { func (c *Connection) Close() error {
defer c.logger.Tracef("connection closed")
var lock sync.Mutex var lock sync.Mutex
defer close(c.TX) defer close(c.TX)
if !c.closed { if !c.closed {
+11
View File
@@ -0,0 +1,11 @@
package tunnel
import "fmt"
type WrongDataFrameTypeError struct {
ShouldBe Type
}
func (w WrongDataFrameTypeError) Error() string {
return fmt.Sprintf("wrong dataframe type, should be %s(%d)", w.ShouldBe, w.ShouldBe)
}
+43
View File
@@ -0,0 +1,43 @@
package tunnel
type Logger interface {
Trace(args ...interface{})
Tracef(format string, args ...interface{})
Debug(args ...interface{})
Debugf(format string, args ...interface{})
Info(args ...interface{})
Infof(format string, args ...interface{})
Error(args ...interface{})
Errorf(format string, args ...interface{})
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Panic(args ...interface{})
Panicf(format string, args ...interface{})
}
type logger struct{}
func (l *logger) Trace(args ...interface{})
func (l *logger) Tracef(format string, args ...interface{})
func (l *logger) Debug(args ...interface{})
func (l *logger) Debugf(format string, args ...interface{})
func (l *logger) Info(args ...interface{})
func (l *logger) Infof(format string, args ...interface{})
func (l *logger) Error(args ...interface{})
func (l *logger) Errorf(format string, args ...interface{})
func (l *logger) Fatal(args ...interface{})
func (l *logger) Fatalf(format string, args ...interface{})
func (l *logger) Panic(args ...interface{})
func (l *logger) Panicf(format string, args ...interface{})
var DefaultLogger = &logger{}
+20 -8
View File
@@ -1,7 +1,6 @@
package tunnel package tunnel
import ( import (
"errors"
"io" "io"
) )
@@ -14,6 +13,7 @@ type Manager struct {
closed chan bool closed chan bool
newConnection chan *Connection newConnection chan *Connection
delConnection chan *Connection delConnection chan *Connection
logger Logger
} }
func NewManager(tun io.ReadWriter) *Manager { func NewManager(tun io.ReadWriter) *Manager {
@@ -25,22 +25,31 @@ func NewManager(tun io.ReadWriter) *Manager {
accept: make(chan *DataFrame, 1024), accept: make(chan *DataFrame, 1024),
newConnection: make(chan *Connection), newConnection: make(chan *Connection),
delConnection: make(chan *Connection), delConnection: make(chan *Connection),
logger: DefaultLogger,
} }
} }
func (m *Manager) SetLogger(logger Logger) {
m.logger = logger
}
func (m *Manager) Run() { func (m *Manager) Run() {
m.logger.Debug("manager run")
onReceiveQueue := make(chan bool) onReceiveQueue := make(chan bool)
for { for {
select { select {
case <-m.closed: case <-m.closed:
return return
case df := <-m.incoming: case df := <-m.incoming:
m.logger.Trace("dataframe->tunnel: ", df)
go df.Encode(m.Tunnel) go df.Encode(m.Tunnel)
case connection := <-m.newConnection: case connection := <-m.newConnection:
m.Connections[connection.ID] = connection m.Connections[connection.ID] = connection
m.logger.Tracef("connection '%s' registered", connection.ID)
case connection := <-m.delConnection: case connection := <-m.delConnection:
connection.Close() connection.Close()
delete(m.Connections, connection.ID) delete(m.Connections, connection.ID)
m.logger.Tracef("connection '%s' unregistered", connection.ID)
case onReceiveQueue <- true: case onReceiveQueue <- true:
go m.onReceive(onReceiveQueue) go m.onReceive(onReceiveQueue)
} }
@@ -53,6 +62,8 @@ func (m *Manager) onReceive(ch chan bool) {
if err := df.Decode(m.Tunnel); err != nil { if err := df.Decode(m.Tunnel); err != nil {
return return
} }
m.logger.Trace("dataframe<-tunnel: ", df)
switch df.Type { switch df.Type {
case TypeRequest: case TypeRequest:
m.accept <- df m.accept <- df
@@ -76,16 +87,16 @@ func (m *Manager) Connect() (*Connection, error) {
Type: TypeRequest, Type: TypeRequest,
} }
connection := &Connection{ connection := &Connection{
ID: df.ID, ID: df.ID,
TX: m.incoming, TX: m.incoming,
logger: DefaultLogger,
} }
m.newConnection <- connection m.newConnection <- connection
m.incoming <- df m.incoming <- df
df = <-connection.RX df = <-connection.RX
if df.Type != TypeConnected { if df.Type != TypeConnected {
return nil, WrongDataFrameTypeError{ShouldBe: TypeConnected}
return nil, errors.New("failed to connect")
} }
return connection, nil return connection, nil
} }
@@ -93,11 +104,12 @@ func (m *Manager) Connect() (*Connection, error) {
func (m *Manager) Accept() (*Connection, error) { func (m *Manager) Accept() (*Connection, error) {
df := <-m.accept df := <-m.accept
if df.Type != TypeRequest { if df.Type != TypeRequest {
return nil, errors.New("failed to accept") return nil, WrongDataFrameTypeError{ShouldBe: TypeRequest}
} }
connection := &Connection{ connection := &Connection{
ID: df.ID, ID: df.ID,
TX: m.incoming, TX: m.incoming,
logger: DefaultLogger,
} }
m.newConnection <- connection m.newConnection <- connection
+14
View File
@@ -9,3 +9,17 @@ func NewID() ID {
} }
type Type uint8 type Type uint8
func (t Type) String() string {
switch t {
case TypeNormal:
return "normal"
case TypeRequest:
return "request"
case TypeConnected:
return "connected"
case TypeClosed:
return "closed"
}
return "invalid"
}