2019-04-28 16:14:09 +00:00
|
|
|
package tuntap
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
2019-05-02 22:37:49 +00:00
|
|
|
"github.com/yggdrasil-network/yggdrasil-go/src/util"
|
2019-04-28 16:14:09 +00:00
|
|
|
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
|
|
|
|
)
|
|
|
|
|
|
|
|
type tunConn struct {
|
|
|
|
tun *TunAdapter
|
|
|
|
conn *yggdrasil.Conn
|
|
|
|
send chan []byte
|
|
|
|
stop chan interface{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *tunConn) close() {
|
|
|
|
close(s.stop)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *tunConn) reader() error {
|
|
|
|
select {
|
|
|
|
case _, ok := <-s.stop:
|
|
|
|
if !ok {
|
|
|
|
return errors.New("session was already closed")
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
var n int
|
|
|
|
var err error
|
|
|
|
read := make(chan bool)
|
|
|
|
b := make([]byte, 65535)
|
|
|
|
for {
|
|
|
|
go func() {
|
|
|
|
if n, err = s.conn.Read(b); err != nil {
|
|
|
|
s.tun.log.Errorln(s.conn.String(), "TUN/TAP conn read error:", err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
read <- true
|
|
|
|
}()
|
|
|
|
select {
|
|
|
|
case <-read:
|
|
|
|
if n > 0 {
|
2019-05-02 22:37:49 +00:00
|
|
|
s.tun.send <- append(util.GetBytes(), b[:n]...)
|
2019-04-28 16:14:09 +00:00
|
|
|
}
|
|
|
|
case <-s.stop:
|
|
|
|
s.tun.log.Debugln("Stopping conn reader for", s)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *tunConn) writer() error {
|
|
|
|
select {
|
|
|
|
case _, ok := <-s.stop:
|
|
|
|
if !ok {
|
|
|
|
return errors.New("session was already closed")
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-s.stop:
|
|
|
|
s.tun.log.Debugln("Stopping conn writer for", s)
|
|
|
|
return nil
|
|
|
|
case b, ok := <-s.send:
|
|
|
|
if !ok {
|
|
|
|
return errors.New("send closed")
|
|
|
|
}
|
|
|
|
if _, err := s.conn.Write(b); err != nil {
|
|
|
|
s.tun.log.Errorln(s.conn.String(), "TUN/TAP conn write error:", err)
|
|
|
|
}
|
2019-05-02 22:37:49 +00:00
|
|
|
util.PutBytes(b)
|
2019-04-28 16:14:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|