eycorsican / go-tun2socks

A tun2socks implementation written in Go.
MIT License
1.3k stars 432 forks source link

通过function关闭tun2socks #109

Closed ghost closed 4 years ago

ghost commented 4 years ago

作者您好,我现在将go-tun2socks编译为库供软件进行调用,目前可以启动tun2scoks。有个小问题,怎么关闭tun2socks呢?因为是library,不能进行windows下的taskkill /f /im tun2socks.exe或者unix 下的kill -9。有没有一个类似的函数比如func stop()来关闭tun2socks?

wongsyrone commented 4 years ago

我做了些修改让go-tun2socks可以被关闭,作为igniter的组件存在,代码不能直接编译,但是可以参考。

ref: https://github.com/trojan-gfw/go-tun2socks

wongsyrone commented 4 years ago

由于我们这边的go-tun2socks是为android gomobile适配的,lwip部分修了Android日志及assert输出,其他的可以看commit log

ghost commented 4 years ago

我看一下,感谢大佬了

eycorsican commented 4 years ago

https://github.com/eycorsican/go-tun2socks/blob/ca0c721c0d65844e43f8b0f090d72d5e9f313515/core/lwip.go#L122

wongsyrone commented 4 years ago

这个提交其实不能正确释放资源,目前是先关掉sys_check_timeouts再关闭现有TCP和UDP,然后关闭监听,但是一旦timer停掉了,某些在超时状态的pcb会卡在那里,需要过了超时才会被lwip释放,目前我实现的是延迟停sys_check_timeouts,基本会在2分钟之内全部无关goroutine都退出,延迟到达之后sys_check_timeouts的goroutine也退出,避免无谓的轮询,节省电量。

这个现象是通过打印当前所有goroutine的数量以及详情看到

eycorsican commented 4 years ago

对Abort 做了修改

ghost commented 4 years ago

根据两位大佬的代码做了一点点修改,想着关闭tunDev应该就可以了,结果每次call stop_tun2socks 就会crash。

2020/04/05 20:29:19 Stopping tun2socks
2020/04/05 20:29:19 copying data failed: read utun3: file already closed
(6459,0x70000a74a000) malloc: *** error for object 0x7fba11d97a90: pointer being freed was not allocated
//reference https://github.com/trojan-gfw/igniter-go-libs/blob/master/tun2socks/tun2socks.go
package main

import (
    "C"

    "io"
    "net"
    "os"
    "os/signal"
    "strings"
    "syscall"

    "github.com/eycorsican/go-tun2socks/common/log"
    _ "github.com/eycorsican/go-tun2socks/common/log/simple"
    "github.com/eycorsican/go-tun2socks/core"
    "github.com/eycorsican/go-tun2socks/proxy/socks"
    "github.com/eycorsican/go-tun2socks/tun"
)

const (
    MTU = 1500
)

var (
    lwipWriter          io.Writer
    tunDev              io.ReadWriteCloser
)

//export stop_tun2socks
func stop_tun2socks() {
    log.Infof("Stopping tun2socks")

    err := tunDev.Close()
    if err != nil {
        log.Fatalf("failed to close tun device: %v", err)
    }
}

//export run_tun2socks
func run_tun2socks(tunName *C.char, tunAddr *C.char, tunGw *C.char, tunDns *C.char, proxyServer *C.char) {

    // Open the tun device.
    dnsServers := strings.Split(C.GoString(tunDns), ",")
    var err error
    tunDev, err = tun.OpenTunDevice(C.GoString(tunName), C.GoString(tunAddr), C.GoString(tunGw), "255.255.255.0", dnsServers, false)
    if err != nil {
        log.Fatalf("failed to open tun device: %v", err)
    }

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

    // Register tun2socks connection handlers.
    proxyAddr, err := net.ResolveTCPAddr("tcp", C.GoString(proxyServer))
    proxyHost := proxyAddr.IP.String()
    proxyPort := uint16(proxyAddr.Port)
    if err != nil {
        log.Infof("invalid proxy server address: %v", err)
    }
    core.RegisterTCPConnHandler(socks.NewTCPHandler(proxyHost, proxyPort))
    core.RegisterUDPConnHandler(socks.NewUDPHandler(proxyHost, proxyPort, 60))

    // Register an output callback to write packets output from lwip stack to tun
    // device, output function should be set before input any packets.
    core.RegisterOutputFn(func(data []byte) (int, error) {
        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)
        }
    }()

    log.Infof("Running tun2socks")

    osSignals := make(chan os.Signal, 1)
    signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGHUP)
    <-osSignals
}

func main() {
}
github-actions[bot] commented 4 years ago

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 7 days