73 lines
1.3 KiB
Go
73 lines
1.3 KiB
Go
|
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
|
||
|
}
|