2019-01-19 00:42:53 +00:00
|
|
|
package yggdrasil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type awdl struct {
|
|
|
|
core *Core
|
|
|
|
mutex sync.RWMutex // protects interfaces below
|
|
|
|
interfaces map[string]*awdlInterface
|
|
|
|
}
|
|
|
|
|
|
|
|
type awdlInterface struct {
|
|
|
|
awdl *awdl
|
|
|
|
fromAWDL chan []byte
|
|
|
|
toAWDL chan []byte
|
|
|
|
shutdown chan bool
|
|
|
|
peer *peer
|
|
|
|
link *linkInterface
|
2019-01-19 12:19:24 +00:00
|
|
|
stream stream
|
2019-01-19 00:42:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *awdl) init(c *Core) error {
|
|
|
|
l.core = c
|
|
|
|
l.mutex.Lock()
|
|
|
|
l.interfaces = make(map[string]*awdlInterface)
|
|
|
|
l.mutex.Unlock()
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *awdl) create(fromAWDL chan []byte, toAWDL chan []byte, name string) (*awdlInterface, error) {
|
|
|
|
link, err := l.core.link.create(fromAWDL, toAWDL, name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
intf := awdlInterface{
|
|
|
|
awdl: l,
|
|
|
|
link: link,
|
|
|
|
fromAWDL: fromAWDL,
|
|
|
|
toAWDL: toAWDL,
|
|
|
|
shutdown: make(chan bool),
|
|
|
|
}
|
2019-01-19 12:19:24 +00:00
|
|
|
intf.stream.init()
|
|
|
|
go intf.handler()
|
2019-01-19 00:42:53 +00:00
|
|
|
l.mutex.Lock()
|
|
|
|
l.interfaces[name] = &intf
|
|
|
|
l.mutex.Unlock()
|
|
|
|
return &intf, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *awdl) getInterface(identity string) *awdlInterface {
|
|
|
|
l.mutex.RLock()
|
|
|
|
defer l.mutex.RUnlock()
|
|
|
|
if intf, ok := l.interfaces[identity]; ok {
|
|
|
|
return intf
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *awdl) shutdown(identity string) error {
|
|
|
|
if err := l.core.link.shutdown(identity); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if intf, ok := l.interfaces[identity]; ok {
|
|
|
|
intf.shutdown <- true
|
|
|
|
l.mutex.Lock()
|
|
|
|
delete(l.interfaces, identity)
|
|
|
|
l.mutex.Unlock()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return fmt.Errorf("interface '%s' doesn't exist or already shutdown", identity)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ai *awdlInterface) handler() {
|
2019-01-19 12:19:24 +00:00
|
|
|
inPacket := func(packet []byte) {
|
|
|
|
ai.link.fromlink <- packet
|
|
|
|
}
|
2019-01-19 00:42:53 +00:00
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ai.shutdown:
|
|
|
|
return
|
|
|
|
case <-ai.link.shutdown:
|
|
|
|
return
|
|
|
|
case in := <-ai.fromAWDL:
|
2019-01-19 12:19:24 +00:00
|
|
|
ai.stream.write(in, inPacket)
|
2019-01-19 00:42:53 +00:00
|
|
|
case out := <-ai.link.tolink:
|
|
|
|
ai.toAWDL <- out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|