mirror of
https://github.com/xjasonlyu/tun2socks.git
synced 2025-10-05 08:47:00 +08:00
Refactor: rewrite engine
This commit is contained in:
104
engine/engine.go
104
engine/engine.go
@@ -2,6 +2,7 @@ package engine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/xjasonlyu/tun2socks/component/dialer"
|
"github.com/xjasonlyu/tun2socks/component/dialer"
|
||||||
"github.com/xjasonlyu/tun2socks/core/device"
|
"github.com/xjasonlyu/tun2socks/core/device"
|
||||||
@@ -11,31 +12,53 @@ import (
|
|||||||
"github.com/xjasonlyu/tun2socks/stats"
|
"github.com/xjasonlyu/tun2socks/stats"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Engine struct {
|
var _engine = &engine{}
|
||||||
mtu uint32
|
|
||||||
iface string
|
// Start starts the default engine up.
|
||||||
stats string
|
func Start() error {
|
||||||
token string
|
return _engine.start()
|
||||||
logLevel string
|
}
|
||||||
rawProxy string
|
|
||||||
rawDevice string
|
// Stop shuts the default engine down.
|
||||||
|
func Stop() error {
|
||||||
|
return _engine.stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert loads *Key to the default engine.
|
||||||
|
func Insert(k *Key) {
|
||||||
|
_engine.insert(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Key struct {
|
||||||
|
MTU uint32
|
||||||
|
Proxy string
|
||||||
|
Stats string
|
||||||
|
Token string
|
||||||
|
Device string
|
||||||
|
LogLevel string
|
||||||
|
Interface string
|
||||||
|
Version bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type engine struct {
|
||||||
|
*Key
|
||||||
|
|
||||||
stack *stack.Stack
|
stack *stack.Stack
|
||||||
proxy proxy.Proxy
|
proxy proxy.Proxy
|
||||||
device device.Device
|
device device.Device
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(opts ...Option) *Engine {
|
func (e *engine) start() error {
|
||||||
e := &Engine{}
|
if e.Key == nil {
|
||||||
|
return errors.New("empty key")
|
||||||
for _, opt := range opts {
|
|
||||||
opt(e)
|
|
||||||
}
|
}
|
||||||
return e
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Engine) Start() error {
|
if e.Version {
|
||||||
for _, set := range []func() error{
|
showVersion()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, f := range []func() error{
|
||||||
e.setLogLevel,
|
e.setLogLevel,
|
||||||
e.setInterface,
|
e.setInterface,
|
||||||
e.setStats,
|
e.setStats,
|
||||||
@@ -43,23 +66,26 @@ func (e *Engine) Start() error {
|
|||||||
e.setDevice,
|
e.setDevice,
|
||||||
e.setStack,
|
e.setStack,
|
||||||
} {
|
} {
|
||||||
if err := set(); err != nil {
|
if err := f(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) Stop() {
|
func (e *engine) stop() error {
|
||||||
if e.device != nil {
|
if e.device != nil {
|
||||||
if err := e.device.Close(); err != nil {
|
return e.device.Close()
|
||||||
log.Fatalf("%v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setLogLevel() error {
|
func (e *engine) insert(k *Key) {
|
||||||
level, err := log.ParseLevel(e.logLevel)
|
e.Key = k
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *engine) setLogLevel() error {
|
||||||
|
level, err := log.ParseLevel(e.LogLevel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -67,46 +93,46 @@ func (e *Engine) setLogLevel() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setInterface() error {
|
func (e *engine) setInterface() error {
|
||||||
if e.iface != "" {
|
if e.Interface != "" {
|
||||||
if err := dialer.BindToInterface(e.iface); err != nil {
|
if err := dialer.BindToInterface(e.Interface); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Infof("[BOUND] bind to interface: %s", e.iface)
|
log.Infof("[BOUND] bind to interface: %s", e.Interface)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setStats() error {
|
func (e *engine) setStats() error {
|
||||||
if e.stats != "" {
|
if e.Stats != "" {
|
||||||
go func() {
|
go func() {
|
||||||
_ = stats.Start(e.stats, e.token)
|
_ = stats.Start(e.Stats, e.Token)
|
||||||
}()
|
}()
|
||||||
log.Infof("[STATS] listen and serve at: http://%s", e.stats)
|
log.Infof("[STATS] stats server listen at: http://%s", e.Stats)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setProxy() (err error) {
|
func (e *engine) setProxy() (err error) {
|
||||||
if e.rawProxy == "" {
|
if e.Proxy == "" {
|
||||||
return errors.New("empty proxy")
|
return errors.New("empty proxy")
|
||||||
}
|
}
|
||||||
|
|
||||||
e.proxy, err = parseProxy(e.rawProxy)
|
e.proxy, err = parseProxy(e.Proxy)
|
||||||
proxy.SetDialer(e.proxy)
|
proxy.SetDialer(e.proxy)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setDevice() (err error) {
|
func (e *engine) setDevice() (err error) {
|
||||||
if e.rawDevice == "" {
|
if e.Device == "" {
|
||||||
return errors.New("empty device")
|
return errors.New("empty device")
|
||||||
}
|
}
|
||||||
|
|
||||||
e.device, err = parseDevice(e.rawDevice, e.mtu)
|
e.device, err = parseDevice(e.Device, e.MTU)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) setStack() (err error) {
|
func (e *engine) setStack() (err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Infof(
|
log.Infof(
|
||||||
|
@@ -1,40 +0,0 @@
|
|||||||
package engine
|
|
||||||
|
|
||||||
type Option func(*Engine)
|
|
||||||
|
|
||||||
func WithDevice(device string) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.rawDevice = device
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithInterface(iface string) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.iface = iface
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithLogLevel(level string) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.logLevel = level
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithMTU(mtu int) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.mtu = uint32(mtu)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithProxy(proxy string) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.rawProxy = proxy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func WithStats(stats, token string) Option {
|
|
||||||
return func(e *Engine) {
|
|
||||||
e.stats = stats
|
|
||||||
e.token = token
|
|
||||||
}
|
|
||||||
}
|
|
22
engine/version.go
Normal file
22
engine/version.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package engine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/xjasonlyu/tun2socks/constant"
|
||||||
|
)
|
||||||
|
|
||||||
|
func showVersion() {
|
||||||
|
fmt.Print(versionString())
|
||||||
|
fmt.Print(releaseString())
|
||||||
|
}
|
||||||
|
|
||||||
|
func versionString() string {
|
||||||
|
return fmt.Sprintf("%s %s\n", constant.Name, strings.TrimPrefix(constant.Version, "v"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func releaseString() string {
|
||||||
|
return fmt.Sprintf("%s/%s, %s, %s\n", runtime.GOOS, runtime.GOARCH, runtime.Version(), constant.BuildTime)
|
||||||
|
}
|
62
main.go
62
main.go
@@ -1,69 +1,41 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/xjasonlyu/tun2socks/constant"
|
|
||||||
"github.com/xjasonlyu/tun2socks/engine"
|
"github.com/xjasonlyu/tun2socks/engine"
|
||||||
"github.com/xjasonlyu/tun2socks/log"
|
"github.com/xjasonlyu/tun2socks/log"
|
||||||
|
|
||||||
flag "github.com/spf13/pflag"
|
flag "github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var key = new(engine.Key)
|
||||||
device string
|
|
||||||
iface string
|
|
||||||
level string
|
|
||||||
proxy string
|
|
||||||
stats string
|
|
||||||
token string
|
|
||||||
mtu int
|
|
||||||
version bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
flag.StringVarP(&device, "device", "d", "", "Use this device [driver://]name")
|
flag.StringVarP(&key.Device, "device", "d", "", "use this device [driver://]name")
|
||||||
flag.StringVarP(&iface, "interface", "i", "", "Use network INTERFACE (Linux and MacOS only)")
|
flag.StringVarP(&key.Interface, "interface", "i", "", "use network INTERFACE (Linux/MacOS only)")
|
||||||
flag.StringVarP(&proxy, "proxy", "p", "", "Use this proxy [protocol://]host[:port]")
|
flag.StringVarP(&key.Proxy, "proxy", "p", "", "use this proxy [protocol://]host[:port]")
|
||||||
flag.StringVarP(&level, "loglevel", "l", "info", "Log level [debug|info|warn|error|silent]")
|
flag.StringVarP(&key.LogLevel, "loglevel", "l", "info", "log level [debug|info|warn|error|silent]")
|
||||||
flag.StringVar(&stats, "stats", "", "HTTP statistic server listen address")
|
flag.StringVar(&key.Stats, "stats", "", "HTTP statistic server listen address")
|
||||||
flag.StringVar(&token, "token", "", "HTTP statistic server auth token")
|
flag.StringVar(&key.Token, "token", "", "HTTP statistic server auth token")
|
||||||
flag.IntVarP(&mtu, "mtu", "m", 0, "Set device maximum transmission unit (MTU)")
|
flag.Uint32VarP(&key.MTU, "mtu", "m", 0, "set device maximum transmission unit (MTU)")
|
||||||
flag.BoolVarP(&version, "version", "v", false, "Show version information and quit")
|
flag.BoolVarP(&key.Version, "version", "v", false, "show version information and quit")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if version {
|
engine.Insert(key)
|
||||||
fmt.Printf("%s %s\n%s/%s, %s, %s\n",
|
|
||||||
constant.Name,
|
checkErr := func(msg string, f func() error) {
|
||||||
constant.Version,
|
if err := f(); err != nil {
|
||||||
runtime.GOOS,
|
log.Fatalf("Failed to %s: %v", msg, err)
|
||||||
runtime.GOARCH,
|
}
|
||||||
runtime.Version(),
|
|
||||||
constant.BuildTime,
|
|
||||||
)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options := []engine.Option{
|
checkErr("start engine", engine.Start)
|
||||||
engine.WithDevice(device),
|
defer checkErr("stop engine", engine.Stop)
|
||||||
engine.WithInterface(iface),
|
|
||||||
engine.WithLogLevel(level),
|
|
||||||
engine.WithMTU(mtu),
|
|
||||||
engine.WithProxy(proxy),
|
|
||||||
engine.WithStats(stats, token),
|
|
||||||
}
|
|
||||||
|
|
||||||
eng := engine.New(options...)
|
|
||||||
if err := eng.Start(); err != nil {
|
|
||||||
log.Fatalf("Start engine error: %v", err)
|
|
||||||
}
|
|
||||||
defer eng.Stop()
|
|
||||||
|
|
||||||
sigCh := make(chan os.Signal, 1)
|
sigCh := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
Reference in New Issue
Block a user