Skip to content

Commit

Permalink
feat: add graceful shutdown and add macos dns for tun mode
Browse files Browse the repository at this point in the history
  • Loading branch information
cxz66666 committed Nov 11, 2023
1 parent f302d6f commit 0dbae1b
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 2 deletions.
36 changes: 36 additions & 0 deletions internal/terminal_func/terminal_func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package terminal_func

import (
"context"
"github.com/mythologyli/zju-connect/log"
)

type TerminalFunc func(ctx context.Context) error
type TerminalItem struct {
f TerminalFunc
name string
}

var terminalFuncList []TerminalItem

func RegisterTerminalFunc(execName string, fun TerminalFunc) {
terminalFuncList = append(terminalFuncList, TerminalItem{
f: fun,
name: execName,
})
log.Println("Register func on terminal:", execName)
}

func ExecTerminalFunc(ctx context.Context) []error {
var errList []error
for _, item := range terminalFuncList {
log.Println("Exec func on terminal:", item.name)
if err := item.f(ctx); err != nil {
errList = append(errList, err)
log.Println("Exec func on terminal ", item.name, "failed:", err)
} else {
log.Println("Exec func on terminal ", item.name, "success")
}
}
return errList
}
19 changes: 17 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package main

import (
"context"
"fmt"
"github.com/mythologyli/zju-connect/client"
"github.com/mythologyli/zju-connect/dial"
"github.com/mythologyli/zju-connect/internal/terminal_func"
"github.com/mythologyli/zju-connect/log"
"github.com/mythologyli/zju-connect/resolve"
"github.com/mythologyli/zju-connect/service"
Expand All @@ -12,6 +14,9 @@ import (
"github.com/mythologyli/zju-connect/stack/tun"
"inet.af/netaddr"
"net"
"os"
"os/signal"
"syscall"
)

var conf Config
Expand Down Expand Up @@ -141,8 +146,18 @@ func main() {
}

if !conf.DisableKeepAlive {
service.KeepAlive(vpnResolver)
go service.KeepAlive(vpnResolver)
}

select {}
quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
<-quit
log.Println("Shutdown ZJU-Connect ......")
if errs := terminal_func.ExecTerminalFunc(context.Background()); errs != nil {
for _, err := range errs {
log.Printf("Shutdown ZJU-Connect failed:", err)
}
} else {
log.Println("Shutdown ZJU-Connect success, Bye~")
}
}
28 changes: 28 additions & 0 deletions stack/tun/stack_darwin.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package tun

import (
"context"
"fmt"
tun "github.com/cxz66666/sing-tun"
"github.com/mythologyli/zju-connect/client"
"github.com/mythologyli/zju-connect/internal/terminal_func"
"github.com/mythologyli/zju-connect/log"
"golang.org/x/sys/unix"
"net"
Expand Down Expand Up @@ -49,6 +52,23 @@ func (s *Stack) AddRoute(target string) error {
return nil
}

func (s *Stack) AddDnsServer(dnsServer string, targetHost string) error {
command := exec.Command("echo", "nameserver", dnsServer, ">", fmt.Sprintf("/etc/resolver/%s", targetHost))
err := command.Run()
if err != nil {
return err
}
terminal_func.RegisterTerminalFunc("DelDnsServer_"+targetHost, func(ctx context.Context) error {
delCommand := exec.Command("rm", fmt.Sprintf("/etc/resolver/%s", targetHost))
delErr := delCommand.Run()
if delErr != nil {
return delErr
}
return nil
})
return nil
}

func NewStack(easyConnectClient *client.EasyConnectClient, dnsServer string) (*Stack, error) {
var err error
s := &Stack{}
Expand Down Expand Up @@ -92,6 +112,7 @@ func NewStack(easyConnectClient *client.EasyConnectClient, dnsServer string) (*S
log.Printf("Interface Name: %s, index %d\n", tunName, netIfce.Index)

// We need this dialer to bind to device otherwise packets will not be sent via TUN
// Doesn't work on macos. See https://github.com/Mythologyli/zju-connect/pull/44#issuecomment-1784050022
s.endpoint.tcpDialer = &net.Dialer{
LocalAddr: &net.TCPAddr{
IP: s.endpoint.ip,
Expand All @@ -106,6 +127,7 @@ func NewStack(easyConnectClient *client.EasyConnectClient, dnsServer string) (*S
},
}

// Doesn't work on macos. See https://github.com/Mythologyli/zju-connect/pull/44#issuecomment-1784050022
s.endpoint.udpDialer = &net.Dialer{
LocalAddr: &net.UDPAddr{
IP: s.endpoint.ip,
Expand All @@ -120,5 +142,11 @@ func NewStack(easyConnectClient *client.EasyConnectClient, dnsServer string) (*S
},
}

if err = s.AddDnsServer(s.endpoint.ip.String(), "zju.edu.cn"); err != nil {
log.Printf("AddDnsServer failed: %v", err)
}
if err = s.AddDnsServer(s.endpoint.ip.String(), "cc98.org"); err != nil {
log.Printf("AddDnsServer failed: %v", err)
}
return s, nil
}

0 comments on commit 0dbae1b

Please sign in to comment.