Skip to content
This repository has been archived by the owner on Apr 3, 2021. It is now read-only.

add "sockPath" param to support directly use an exist tun device send… #118

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions cmd/tun2socks/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type CmdArgs struct {
UdpTimeout *time.Duration
LogLevel *string
DnsFallback *bool
SockPath *string
}

type cmdFlag uint
Expand Down Expand Up @@ -97,6 +98,7 @@ func main() {
args.BlockOutsideDns = flag.Bool("blockOutsideDns", false, "Prevent DNS leaks by blocking plaintext DNS queries going out through non-TUN interface (may require admin privileges) (Windows only) ")
args.ProxyType = flag.String("proxyType", "socks", "Proxy handler type")
args.LogLevel = flag.String("loglevel", "info", "Logging level. (debug, info, warn, error, none)")
args.SockPath = flag.String("sockPath", "", "unix local socks path to send fd")

flag.Parse()

Expand Down Expand Up @@ -130,7 +132,14 @@ func main() {

// Open the tun device.
dnsServers := strings.Split(*args.TunDns, ",")
tunDev, err := tun.OpenTunDevice(*args.TunName, *args.TunAddr, *args.TunGw, *args.TunMask, dnsServers, *args.TunPersist)

var tunDev io.ReadWriteCloser
var err error
if *args.SockPath != "" {
tunDev, err = tun.OpenTunDeviceByDomainSocket(*args.SockPath, *args.TunName, *args.TunAddr, *args.TunGw, *args.TunMask, dnsServers, *args.TunPersist)
} else {
tunDev, err = tun.OpenTunDevice(*args.TunName, *args.TunAddr, *args.TunGw, *args.TunMask, dnsServers, *args.TunPersist)
}
if err != nil {
log.Fatalf("failed to open tun device: %v", err)
}
Expand All @@ -141,9 +150,6 @@ func main() {
}
}

// Setup TCP/IP stack.
lwipWriter := core.NewLWIPStack().(io.Writer)

// Register TCP and UDP handlers to handle accepted connections.
if creater, found := handlerCreater[*args.ProxyType]; found {
creater()
Expand All @@ -166,14 +172,17 @@ func main() {
return tunDev.Write(data)
})

// Copy packets from tun device to lwip stack, it's the main loop.
go func() {
_, err := io.CopyBuffer(lwipWriter, tunDev, make([]byte, MTU))
if err != nil {
log.Fatalf("copying data failed: %v", err)
}
}()

if *args.SockPath == "" {
// Setup TCP/IP stack.
lwipWriter := core.NewLWIPStack().(io.Writer)
// Copy packets from tun device to lwip stack, it's the main loop.
go func() {
_, err := io.CopyBuffer(lwipWriter, tunDev, make([]byte, MTU))
if err != nil {
log.Fatalf("copying data failed: %v", err)
}
}()
}
log.Infof("Running tun2socks")

osSignals := make(chan os.Signal, 1)
Expand Down
4 changes: 4 additions & 0 deletions tun/tun_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,7 @@ func OpenTunDevice(name, addr, gw, mask string, dnsServers []string, persist boo
}
return tunDev, nil
}

func OpenTunDeviceByDomainSocket(sockpath, name, addr, gw, mask string, dnsServers []string, persist bool) (io.ReadWriteCloser, error) {
return nil,errors.New("no implement")
}
103 changes: 101 additions & 2 deletions tun/tun_linux.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package tun

import (
"io"

"fmt"
"github.com/eycorsican/go-tun2socks/core"
"github.com/songgao/water"
"io"
"net"
"os"
"syscall"
"time"
)

func OpenTunDevice(name, addr, gw, mask string, dnsServers []string, persist bool) (io.ReadWriteCloser, error) {
Expand All @@ -19,3 +24,97 @@ func OpenTunDevice(name, addr, gw, mask string, dnsServers []string, persist boo
name = tunDev.Name()
return tunDev, nil
}

func OpenTunDeviceByDomainSocket(sockpath, name, addr, gw, mask string, dnsServers []string, persist bool) (io.ReadWriteCloser, error) {
cfg := water.Config{
DeviceType: water.TUN,
}
cfg.Name = name
cfg.Persist = persist
tunDev, err := openDevByDomainSocket(cfg, sockpath)
if err != nil {
return nil, err
}
return tunDev, nil
}

//copied from https://golang.org/src/syscall/syscall_unix_test.go
func openDevByDomainSocket(config water.Config, sockpath string) (ifce *water.Interface, err error) {
//fmt.Println("sockpath=",sockpath)

os.RemoveAll(sockpath)
l, err := net.Listen("unix", sockpath)
if err != nil {
//t.Fatalf("unexpected FileConn type; expected UnixConn, got %T", c)
//return nil,errors.New(fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", c))
return nil,err
}

itf := &water.Interface{

}

go func() {
conn, err := l.Accept()
if err != nil {
fmt.Println(err)
return
}
uc, ok := conn.(*net.UnixConn)
if !ok {
fmt.Println(fmt.Sprintf("unexpected FileConn type; expected UnixConn, got %T", conn))
}
buf := make([]byte, 32) // expect 1 byte
oob := make([]byte, 32) // expect 24 bytes
closeUnix := time.AfterFunc(15*time.Second, func() {
//t.Logf("timeout reading from unix socket")
uc.Close()
//return nil,errors.New("timeout reading from unix socket")
fmt.Println("timeout reading from unix socket")
})
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
if err != nil {
//t.Fatalf("ReadMsgUnix: %v", err)
//return nil,errors.New(fmt.Sprintf("ReadMsgUnix: %v", err))
fmt.Println("ReadMsgUnix: ", err)
return
}
closeUnix.Stop()

scms, err := syscall.ParseSocketControlMessage(oob[:oobn])
if err != nil {
//t.Fatalf("ParseSocketControlMessage: %v", err)
//return nil,errors.New(fmt.Sprintf("ParseSocketControlMessage: %v", err))
fmt.Println("ParseSocketControlMessage: ", err)
return
}
if len(scms) != 1 {
//t.Fatalf("expected 1 SocketControlMessage; got scms = %#v", scms)
//return nil,errors.New(fmt.Sprintf("expected 1 SocketControlMessage; got scms = %#v", scms))
fmt.Println("expected 1 SocketControlMessage; got scms = ", scms)
return
}
scm := scms[0]
gotFds, err := syscall.ParseUnixRights(&scm)
if err != nil {
//t.Fatalf("syscall.ParseUnixRights: %v", err)
//return nil,errors.New(fmt.Sprintf("syscall.ParseUnixRights: %v", err))
fmt.Println("syscall.ParseUnixRights: ", err)
return
}
if len(gotFds) != 1 {
//t.Fatalf("wanted 1 fd; got %#v", gotFds)
//return nil,errors.New(fmt.Sprintf("wanted 1 fd; got %#v", gotFds))
fmt.Println("wanted 1 fd; got ", gotFds)
return
}
fdInt := gotFds[0]

itf.ReadWriteCloser = os.NewFile(uintptr(fdInt), "tun0")

lwipWriter := core.NewLWIPStack().(io.Writer)
io.CopyBuffer(lwipWriter, itf, make([]byte, 1500))
}()

return itf,nil
}
4 changes: 4 additions & 0 deletions tun/tun_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,7 @@ func (dev *winTapDev) Close() error {
sendStopMarker(dev.addr, dev.gw)
return windows.Close(dev.fd)
}

func OpenTunDeviceByDomainSocket(sockpath, name, addr, gw, mask string, dnsServers []string, persist bool) (io.ReadWriteCloser, error) {
return nil,errors.New("not supported")
}