dissertation-2-code/tun/tun.go

98 lines
1.4 KiB
Go
Raw Normal View History

2020-10-23 20:07:15 +01:00
package tun
import (
2020-11-01 16:50:02 +00:00
"fmt"
"github.com/pkg/taptun"
"io"
"log"
"mpbl3p/proxy"
"net"
2020-11-01 18:18:37 +00:00
"os"
"strings"
"sync"
"time"
)
2020-10-23 20:07:15 +01:00
type SourceSink struct {
tun *taptun.Tun
bufferSize int
up bool
upMu sync.Mutex
}
2020-10-24 17:44:14 +01:00
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
}
2020-10-23 20:07:15 +01:00
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 {
2020-10-23 20:07:15 +01:00
return proxy.Packet{}, err
}
if read == 0 {
2020-10-23 20:07:15 +01:00
return proxy.Packet{}, io.EOF
}
2020-10-26 11:11:15 +00:00
return proxy.NewPacket(buf[:read]), nil
}
2020-11-01 18:18:37 +00:00
var good, bad float64
2020-10-23 20:07:15 +01:00
func (t *SourceSink) Sink(packet proxy.Packet) error {
if !t.up {
t.upMu.Lock()
t.upMu.Unlock()
}
_, err := t.tun.Write(packet.Raw())
2020-11-01 18:18:37 +00:00
if err != nil {
switch err.(type) {
case *os.PathError:
bad += 1
fmt.Printf("packet loss: %f%%\n", bad*100/(good+bad))
return nil
default:
return err
}
}
good += 1
return nil
}