mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-13 04:24:09 +08:00
70 lines
1.2 KiB
Go
70 lines
1.2 KiB
Go
// +build darwin freebsd openbsd
|
|
|
|
package tun
|
|
|
|
import (
|
|
"golang.zx2c4.com/wireguard/tun"
|
|
|
|
"github.com/xjasonlyu/clash/common/pool"
|
|
"github.com/xjasonlyu/tun2socks/pkg/link/rwc"
|
|
)
|
|
|
|
const offset = 4
|
|
|
|
type unixTun struct {
|
|
*rwc.Endpoint
|
|
|
|
device tun.Device
|
|
}
|
|
|
|
func CreateTUN(name string, n uint32) (Device, error) {
|
|
device, err := tun.CreateTUN(name, int(n))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mtu, err := device.MTU()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ut := &unixTun{
|
|
device: device,
|
|
}
|
|
|
|
if ut.Endpoint, err = rwc.New(ut, uint32(mtu)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ut, nil
|
|
}
|
|
|
|
func (t *unixTun) Read(packet []byte) (n int, err error) {
|
|
buf := pool.Get(offset + len(packet))
|
|
defer pool.Put(buf)
|
|
|
|
if n, err = t.device.Read(buf, offset); err != nil {
|
|
return
|
|
}
|
|
|
|
copy(packet, buf[offset:offset+n])
|
|
return
|
|
}
|
|
|
|
func (t *unixTun) Write(packet []byte) (int, error) {
|
|
buf := pool.Get(offset + len(packet))
|
|
defer pool.Put(buf)
|
|
|
|
copy(buf[offset:], packet)
|
|
return t.device.Write(buf[:offset+len(packet)], offset)
|
|
}
|
|
|
|
func (t *unixTun) Name() string {
|
|
name, _ := t.device.Name()
|
|
return name
|
|
}
|
|
|
|
func (t *unixTun) Close() error {
|
|
return t.device.Close()
|
|
}
|