77 lines
1.2 KiB
Go
77 lines
1.2 KiB
Go
package tun
|
|
|
|
import (
|
|
wgtun "golang.zx2c4.com/wireguard/tun"
|
|
"io"
|
|
"log"
|
|
"mpbl3p/proxy"
|
|
"os"
|
|
)
|
|
|
|
type SourceSink struct {
|
|
tun wgtun.Device
|
|
}
|
|
|
|
func NewTun(name string, mtu int) (t wgtun.Device, err error) {
|
|
return wgtun.CreateTUN(name, mtu)
|
|
}
|
|
|
|
func NewFromFile(fd uintptr, mtu int) (ss *SourceSink, err error) {
|
|
ss = new(SourceSink)
|
|
|
|
file := os.NewFile(fd, "")
|
|
ss.tun, err = wgtun.CreateTUNFromFile(file, mtu)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (t *SourceSink) Close() error {
|
|
return t.tun.Close()
|
|
}
|
|
|
|
func (t *SourceSink) Source() (proxy.Packet, error) {
|
|
mtu, err := t.tun.MTU()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
buf := make([]byte, mtu+4)
|
|
|
|
read, err := t.tun.Read(buf, 4)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if read == 0 {
|
|
return nil, io.EOF
|
|
}
|
|
|
|
return proxy.SimplePacket(buf[4 : read+4]), nil
|
|
}
|
|
|
|
var good, bad float64
|
|
|
|
func (t *SourceSink) Sink(packet proxy.Packet) error {
|
|
// make space for tun header
|
|
content := make([]byte, len(packet.Contents())+4)
|
|
copy(content[4:], packet.Contents())
|
|
|
|
_, err := t.tun.Write(content, 4)
|
|
if err != nil {
|
|
switch err.(type) {
|
|
case *os.PathError:
|
|
bad += 1
|
|
log.Printf("packet loss: %f%%\n", bad*100/(good+bad))
|
|
return nil
|
|
default:
|
|
return err
|
|
}
|
|
}
|
|
|
|
good += 1
|
|
return nil
|
|
}
|