dissertation-2-code/tun/tun.go
Jake Hillion ea0a9b45ce
All checks were successful
continuous-integration/drone/push Build is passing
slicing fix
2020-10-26 11:11:15 +00:00

82 lines
1.2 KiB
Go

package tun
import (
"github.com/pkg/taptun"
"io"
"log"
"mpbl3p/proxy"
"net"
"strings"
"sync"
"time"
)
type SourceSink struct {
tun *taptun.Tun
bufferSize int
up bool
upMu sync.Mutex
}
func NewTun(namingScheme string, bufferSize int) (ss *SourceSink, err error) {
ss = &SourceSink{}
ss.tun, err = taptun.NewTun(namingScheme)
if err != nil {
return
}
ss.bufferSize = bufferSize
ss.upMu.Lock()
go func() {
defer ss.upMu.Unlock()
for {
iface, err := net.InterfaceByName(ss.tun.String())
if err != nil {
panic(err)
}
if strings.Contains(iface.Flags.String(), "up") {
log.Println("tun is up")
ss.up = true
return
}
time.Sleep(100 * time.Millisecond)
}
}()
return
}
func (t *SourceSink) Source() (proxy.Packet, error) {
if !t.up {
t.upMu.Lock()
t.upMu.Unlock()
}
buf := make([]byte, t.bufferSize)
read, err := t.tun.Read(buf)
if err != nil {
return proxy.Packet{}, err
}
if read == 0 {
return proxy.Packet{}, io.EOF
}
return proxy.NewPacket(buf[:read]), nil
}
func (t *SourceSink) Sink(packet proxy.Packet) error {
if !t.up {
t.upMu.Lock()
t.upMu.Unlock()
}
_, err := t.tun.Write(packet.Raw())
return err
}