Commit e12fc6e1 authored by nanahira's avatar nanahira

Merge branch 'master' of https://github.com/ginuerzh/gost

parents b3151cc7 81854a61
Pipeline #16009 passed with stages
in 1 minute and 17 seconds
FROM golang:1-alpine as builder
FROM golang:1.19-alpine as builder
# Convert TARGETPLATFORM to GOARCH format
# https://github.com/tonistiigi/xx
COPY --from=tonistiigi/xx:golang / /
ARG TARGETPLATFORM
RUN apk add --no-cache musl-dev git gcc
......@@ -8,9 +14,7 @@ WORKDIR /src
ENV GO111MODULE=on
RUN cd cmd/gost \
&& go env -w GOPROXY=https://goproxy.cn,https://gocenter.io,https://goproxy.io,direct \
&& go build -v
RUN cd cmd/gost && go env && go build -v
FROM alpine:latest
......@@ -19,5 +23,3 @@ WORKDIR /bin/
COPY --from=builder /src/cmd/gost/gost .
ENTRYPOINT ["/bin/gost"]
CMD ["-C", "/etc/gost/gost.json"]
......@@ -20,12 +20,14 @@ PLATFORM_LIST = \
linux-mips64 \
linux-mips64le \
linux-s390x \
linux-riscv64 \
freebsd-386 \
freebsd-amd64
WINDOWS_ARCH_LIST = \
windows-386 \
windows-amd64
windows-amd64 \
windows-arm64
all: linux-amd64 darwin-amd64 windows-amd64 # Most used
......@@ -74,6 +76,9 @@ linux-mips64le:
linux-s390x:
GOARCH=s390x GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
linux-riscv64:
GOARCH=riscv64 GOOS=linux $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
freebsd-386:
GOARCH=386 GOOS=freebsd $(GOBUILD) -o $(BINDIR)/$(NAME)-$@ $(GOFILES)
......@@ -86,6 +91,9 @@ windows-386:
windows-amd64:
GOARCH=amd64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES)
windows-arm64:
GOARCH=arm64 GOOS=windows $(GOBUILD) -o $(BINDIR)/$(NAME)-$@.exe $(GOFILES)
gz_releases=$(addsuffix .gz, $(PLATFORM_LIST))
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))
......
......@@ -58,7 +58,7 @@ go build
#### Docker
```bash
docker pull ginuerzh/gost
docker run --rm ginuerzh/gost -V
```
#### Homebrew
......
......@@ -53,7 +53,7 @@ go build
#### Docker
```bash
docker pull ginuerzh/gost
docker run --rm ginuerzh/gost -V
```
#### Homebrew
......
......@@ -212,6 +212,12 @@ func parseChainNode(ns string) (nodes []gost.Node, err error) {
Timeout: timeout,
IdleTimeout: node.GetDuration("idle"),
}
if config.KeepAlive {
config.KeepAlivePeriod = node.GetDuration("ttl")
if config.KeepAlivePeriod == 0 {
config.KeepAlivePeriod = 10 * time.Second
}
}
if cipher := node.Get("cipher"); cipher != "" {
sum := sha256.Sum256([]byte(cipher))
......@@ -458,6 +464,12 @@ func (r *route) GenRouters() ([]router, error) {
Timeout: timeout,
IdleTimeout: node.GetDuration("idle"),
}
if config.KeepAlive {
config.KeepAlivePeriod = node.GetDuration("ttl")
if config.KeepAlivePeriod == 0 {
config.KeepAlivePeriod = 10 * time.Second
}
}
if cipher := node.Get("cipher"); cipher != "" {
sum := sha256.Sum256([]byte(cipher))
config.Key = sum[:]
......@@ -652,6 +664,7 @@ func (r *route) GenRouters() ([]router, error) {
gost.IPsHandlerOption(ips),
gost.TCPModeHandlerOption(node.GetBool("tcp")),
gost.IPRoutesHandlerOption(tunRoutes...),
gost.ProxyAgentHandlerOption(node.Get("proxyAgent")),
)
rt := router{
......
module github.com/ginuerzh/gost
go 1.17
go 1.18
replace github.com/templexxx/cpu v0.0.7 => github.com/templexxx/cpu v0.0.10-0.20211111114238-98168dcec14a
require (
git.torproject.org/pluggable-transports/goptlib.git v1.2.0
github.com/LiamHaworth/go-tproxy v0.0.0-20190726054950-ef7efd7f24ed
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/docker/libcontainer v2.2.1+incompatible
github.com/go-gost/gosocks4 v0.0.1
github.com/go-gost/gosocks5 v0.3.0
github.com/go-gost/relay v0.1.1-0.20211123134818-8ef7fd81ffd7
......@@ -15,9 +16,8 @@ require (
github.com/gobwas/glob v0.2.3
github.com/gorilla/websocket v1.4.2
github.com/klauspost/compress v1.13.6
github.com/lucas-clemente/quic-go v0.26.0
github.com/lucas-clemente/quic-go v0.28.1
github.com/miekg/dns v1.1.47
github.com/milosgajdos/tenus v0.0.3
github.com/ryanuber/go-glob v1.0.0
github.com/shadowsocks/go-shadowsocks2 v0.1.5
github.com/shadowsocks/shadowsocks-go v0.0.0-20200409064450-3e585ff90601
......@@ -25,24 +25,26 @@ require (
github.com/xtaci/kcp-go/v5 v5.6.1
github.com/xtaci/smux v1.5.16
github.com/xtaci/tcpraw v1.2.25
gitlab.com/yawning/obfs4.git v0.0.0-20210511220700-e330d1b7024b
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064
golang.org/x/net v0.0.0-20220325170049-de3da57026de
gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8
golang.org/x/net v0.0.0-20220812174116-3211cb980234
)
require (
filippo.io/edwards25519 v1.0.0-rc.1.0.20210721174708-390f27c3be20 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/cheekybits/genny v1.0.0 // indirect
github.com/coreos/go-iptables v0.6.0 // indirect
github.com/dchest/siphash v1.2.2 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/klauspost/reedsolomon v1.9.15 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.1 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.1 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect
github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect
github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
......@@ -51,10 +53,10 @@ require (
github.com/templexxx/xorsimd v0.4.1 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/sys v0.0.0-20220325203850-36772127a21f // indirect
gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.10 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
golang.org/x/tools v0.1.12 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
)
This diff is collapsed.
......@@ -20,7 +20,7 @@ import (
)
// Version is the gost version.
const Version = "2.11.2"
const Version = "2.11.3"
// Debug is a flag that enables the debug log.
var Debug bool
......@@ -80,6 +80,8 @@ var (
// DefaultUserAgent is the default HTTP User-Agent header used by HTTP and websocket.
DefaultUserAgent = "Chrome/78.0.3904.106"
DefaultProxyAgent = "gost/" + Version
// DefaultMTU is the default mtu for tun/tap device
DefaultMTU = 1350
)
......
......@@ -42,6 +42,7 @@ type HandlerOptions struct {
IPs []string
TCPMode bool
IPRoutes []IPRoute
ProxyAgent string
}
// HandlerOption allows a common way to set handler options.
......@@ -211,6 +212,13 @@ func IPRoutesHandlerOption(routes ...IPRoute) HandlerOption {
}
}
// ProxyAgentHandlerOption sets the proxy agent for http handler.
func ProxyAgentHandlerOption(agent string) HandlerOption {
return func(opts *HandlerOptions) {
opts.ProxyAgent = agent
}
}
type autoHandler struct {
options *HandlerOptions
}
......
......@@ -173,7 +173,12 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
ProtoMinor: 1,
Header: http.Header{},
}
resp.Header.Add("Proxy-Agent", "gost/"+Version)
proxyAgent := DefaultProxyAgent
if h.options.ProxyAgent != "" {
proxyAgent = h.options.ProxyAgent
}
resp.Header.Add("Proxy-Agent", proxyAgent)
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[http] %s - %s : Unauthorized to tcp connect to %s",
......@@ -287,7 +292,7 @@ func (h *httpHandler) handleRequest(conn net.Conn, req *http.Request) {
if req.Method == http.MethodConnect {
b := []byte("HTTP/1.1 200 Connection established\r\n" +
"Proxy-Agent: gost/" + Version + "\r\n\r\n")
"Proxy-Agent: " + proxyAgent + "\r\n\r\n")
if Debug {
log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), conn.LocalAddr(), string(b))
}
......
......@@ -365,7 +365,11 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
log.Logf("[http2] %s - %s\n%s", r.RemoteAddr, laddr, string(dump))
}
w.Header().Set("Proxy-Agent", "gost/"+Version)
proxyAgent := DefaultProxyAgent
if h.options.ProxyAgent != "" {
proxyAgent = h.options.ProxyAgent
}
w.Header().Set("Proxy-Agent", proxyAgent)
if !Can("tcp", host, h.options.Whitelist, h.options.Blacklist) {
log.Logf("[http2] %s - %s : Unauthorized to tcp connect to %s",
......
......@@ -17,8 +17,7 @@ import (
)
type quicSession struct {
conn net.Conn
session quic.Session
session quic.EarlyConnection
}
func (session *quicSession) GetConn() (*quicConn, error) {
......@@ -60,100 +59,71 @@ func (tr *quicTransporter) Dial(addr string, options ...DialOption) (conn net.Co
option(opts)
}
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
}
tr.sessionMutex.Lock()
defer tr.sessionMutex.Unlock()
session, ok := tr.sessions[addr]
if !ok {
var cc *net.UDPConn
cc, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
var pc net.PacketConn
pc, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
return
}
conn = cc
if tr.config != nil && tr.config.Key != nil {
conn = &quicCipherConn{UDPConn: cc, key: tr.config.Key}
pc = &quicCipherConn{PacketConn: pc, key: tr.config.Key}
}
session = &quicSession{conn: conn}
tr.sessions[addr] = session
}
return session.conn, nil
}
func (tr *quicTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
opts := &HandshakeOptions{}
for _, option := range options {
option(opts)
}
config := tr.config
if opts.QUICConfig != nil {
config = opts.QUICConfig
}
if config.TLSConfig == nil {
config.TLSConfig = &tls.Config{InsecureSkipVerify: true}
}
tr.sessionMutex.Lock()
defer tr.sessionMutex.Unlock()
timeout := opts.Timeout
if timeout <= 0 {
timeout = HandshakeTimeout
}
conn.SetDeadline(time.Now().Add(timeout))
defer conn.SetDeadline(time.Time{})
session, ok := tr.sessions[opts.Addr]
if session != nil && session.conn != conn {
conn.Close()
return nil, errors.New("quic: unrecognized connection")
}
if !ok || session.session == nil {
s, err := tr.initSession(opts.Addr, conn, config)
session, err = tr.initSession(udpAddr, pc)
if err != nil {
conn.Close()
delete(tr.sessions, opts.Addr)
pc.Close()
return nil, err
}
session = s
tr.sessions[opts.Addr] = session
tr.sessions[addr] = session
}
cc, err := session.GetConn()
conn, err = session.GetConn()
if err != nil {
session.Close()
delete(tr.sessions, opts.Addr)
delete(tr.sessions, addr)
return nil, err
}
return conn, nil
}
return cc, nil
func (tr *quicTransporter) Handshake(conn net.Conn, options ...HandshakeOption) (net.Conn, error) {
return conn, nil
}
func (tr *quicTransporter) initSession(addr string, conn net.Conn, config *QUICConfig) (*quicSession, error) {
udpConn, ok := conn.(net.PacketConn)
if !ok {
return nil, errors.New("quic: wrong connection type")
func (tr *quicTransporter) initSession(addr net.Addr, conn net.PacketConn) (*quicSession, error) {
config := tr.config
if config == nil {
config = &QUICConfig{}
}
udpAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return nil, err
if config.TLSConfig == nil {
config.TLSConfig = &tls.Config{InsecureSkipVerify: true}
}
quicConfig := &quic.Config{
HandshakeIdleTimeout: config.Timeout,
KeepAlive: config.KeepAlive,
MaxIdleTimeout: config.IdleTimeout,
KeepAlivePeriod: config.KeepAlivePeriod,
Versions: []quic.VersionNumber{
quic.Version1,
quic.VersionDraft29,
},
MaxIdleTimeout: config.IdleTimeout,
}
session, err := quic.Dial(udpConn, udpAddr, addr, tlsConfigQUICALPN(config.TLSConfig), quicConfig)
session, err := quic.DialEarly(conn, addr, addr.String(), tlsConfigQUICALPN(config.TLSConfig), quicConfig)
if err != nil {
log.Logf("quic dial %s: %v", addr, err)
return nil, err
}
return &quicSession{conn: conn, session: session}, nil
return &quicSession{session: session}, nil
}
func (tr *quicTransporter) Multiplex() bool {
......@@ -162,15 +132,16 @@ func (tr *quicTransporter) Multiplex() bool {
// QUICConfig is the config for QUIC client and server
type QUICConfig struct {
TLSConfig *tls.Config
Timeout time.Duration
KeepAlive bool
IdleTimeout time.Duration
Key []byte
TLSConfig *tls.Config
Timeout time.Duration
KeepAlive bool
KeepAlivePeriod time.Duration
IdleTimeout time.Duration
Key []byte
}
type quicListener struct {
ln quic.Listener
ln quic.EarlyListener
connChan chan net.Conn
errChan chan error
}
......@@ -182,7 +153,7 @@ func QUICListener(addr string, config *QUICConfig) (Listener, error) {
}
quicConfig := &quic.Config{
HandshakeIdleTimeout: config.Timeout,
KeepAlive: config.KeepAlive,
KeepAlivePeriod: config.KeepAlivePeriod,
MaxIdleTimeout: config.IdleTimeout,
Versions: []quic.VersionNumber{
quic.Version1,
......@@ -200,17 +171,16 @@ func QUICListener(addr string, config *QUICConfig) (Listener, error) {
if err != nil {
return nil, err
}
lconn, err := net.ListenUDP("udp", udpAddr)
conn, err = net.ListenUDP("udp", udpAddr)
if err != nil {
return nil, err
}
conn = lconn
if config.Key != nil {
conn = &quicCipherConn{UDPConn: lconn, key: config.Key}
conn = &quicCipherConn{PacketConn: conn, key: config.Key}
}
ln, err := quic.Listen(conn, tlsConfigQUICALPN(tlsConfig), quicConfig)
ln, err := quic.ListenEarly(conn, tlsConfigQUICALPN(tlsConfig), quicConfig)
if err != nil {
return nil, err
}
......@@ -238,7 +208,7 @@ func (l *quicListener) listenLoop() {
}
}
func (l *quicListener) sessionLoop(session quic.Session) {
func (l *quicListener) sessionLoop(session quic.Connection) {
log.Logf("[quic] %s <-> %s", session.RemoteAddr(), session.LocalAddr())
defer log.Logf("[quic] %s >-< %s", session.RemoteAddr(), session.LocalAddr())
......@@ -295,12 +265,12 @@ func (c *quicConn) RemoteAddr() net.Addr {
}
type quicCipherConn struct {
*net.UDPConn
net.PacketConn
key []byte
}
func (conn *quicCipherConn) ReadFrom(data []byte) (n int, addr net.Addr, err error) {
n, addr, err = conn.UDPConn.ReadFrom(data)
n, addr, err = conn.PacketConn.ReadFrom(data)
if err != nil {
return
}
......@@ -320,7 +290,7 @@ func (conn *quicCipherConn) WriteTo(data []byte, addr net.Addr) (n int, err erro
return
}
_, err = conn.UDPConn.WriteTo(b, addr)
_, err = conn.PacketConn.WriteTo(b, addr)
if err != nil {
return
}
......
......@@ -12,7 +12,7 @@ import (
var (
// ErrNoneAvailable indicates there is no node available.
ErrNoneAvailable = errors.New("none available")
ErrNoneAvailable = errors.New("none node available")
)
// NodeSelector as a mechanism to pick nodes and mark their status.
......
......@@ -103,7 +103,7 @@ type Listener interface {
}
func transport(rw1, rw2 io.ReadWriter) error {
errc := make(chan error, 1)
errc := make(chan error, 2)
go func() {
errc <- copyBuffer(rw1, rw2)
}()
......@@ -113,10 +113,17 @@ func transport(rw1, rw2 io.ReadWriter) error {
}()
err := <-errc
err2 := <-errc
if err != nil && err == io.EOF {
err = nil
}
return err
if err != nil {
return err
}
if err2 != nil && err2 == io.EOF {
err2 = nil
}
return err2
}
func copyBuffer(dst io.Writer, src io.Reader) error {
......
name: gost
base: core20
version: '2.11.2'
version: '2.11.3'
summary: A simple security tunnel written in golang
description: |
Project: https://github.com/ginuerzh/gost
......@@ -20,7 +20,7 @@ parts:
source: https://github.com/ginuerzh/gost
source-subdir: cmd/gost
source-type: git
source-tag: v2.11.2
source-tag: v2.11.3
build-packages:
- gcc
......
//go:build !linux
// +build !linux
package gost
......@@ -8,4 +9,4 @@ func setSocketMark(fd int, value int) (e error) {
func setSocketInterface(fd int, value string) (e error) {
return nil
}
\ No newline at end of file
}
package gost
import (
"errors"
"fmt"
"net"
"syscall"
"os/exec"
"strings"
"github.com/docker/libcontainer/netlink"
"github.com/go-log/log"
"github.com/milosgajdos/tenus"
"github.com/songgao/water"
)
func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
ip, ipNet, err := net.ParseCIDR(cfg.Addr)
ip, _, err := net.ParseCIDR(cfg.Addr)
if err != nil {
return
}
......@@ -28,35 +26,21 @@ func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
return
}
link, err := tenus.NewLinkFrom(ifce.Name())
if err != nil {
return
}
mtu := cfg.MTU
if mtu <= 0 {
mtu = DefaultMTU
}
cmd := fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)
log.Log("[tun]", cmd)
if er := link.SetLinkMTU(mtu); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)); err != nil {
log.Log(err)
}
cmd = fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())
log.Log("[tun]", cmd)
if er := link.SetLinkIp(ip, ipNet); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())); err != nil {
log.Log(err)
}
cmd = fmt.Sprintf("ip link set dev %s up", ifce.Name())
log.Log("[tun]", cmd)
if er := link.SetLinkUp(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip link set dev %s up", ifce.Name())); err != nil {
log.Log(err)
}
if err = addTunRoutes(ifce.Name(), cfg.Routes...); err != nil {
......@@ -77,9 +61,8 @@ func createTun(cfg TunConfig) (conn net.Conn, itf *net.Interface, err error) {
func createTap(cfg TapConfig) (conn net.Conn, itf *net.Interface, err error) {
var ip net.IP
var ipNet *net.IPNet
if cfg.Addr != "" {
ip, ipNet, err = net.ParseCIDR(cfg.Addr)
ip, _, err = net.ParseCIDR(cfg.Addr)
if err != nil {
return
}
......@@ -95,37 +78,23 @@ func createTap(cfg TapConfig) (conn net.Conn, itf *net.Interface, err error) {
return
}
link, err := tenus.NewLinkFrom(ifce.Name())
if err != nil {
return
}
mtu := cfg.MTU
if mtu <= 0 {
mtu = DefaultMTU
}
cmd := fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)
log.Log("[tap]", cmd)
if er := link.SetLinkMTU(mtu); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip link set dev %s mtu %d", ifce.Name(), mtu)); err != nil {
log.Log(err)
}
if cfg.Addr != "" {
cmd = fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())
log.Log("[tap]", cmd)
if er := link.SetLinkIp(ip, ipNet); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip address add %s dev %s", cfg.Addr, ifce.Name())); err != nil {
log.Log(err)
}
}
cmd = fmt.Sprintf("ip link set dev %s up", ifce.Name())
log.Log("[tap]", cmd)
if er := link.SetLinkUp(); er != nil {
err = fmt.Errorf("%s: %v", cmd, er)
return
if err = exeCmd(fmt.Sprintf("ip link set dev %s up", ifce.Name())); err != nil {
log.Log(err)
}
if err = addTapRoutes(ifce.Name(), cfg.Gateway, cfg.Routes...); err != nil {
......@@ -151,8 +120,10 @@ func addTunRoutes(ifName string, routes ...IPRoute) error {
}
cmd := fmt.Sprintf("ip route add %s dev %s", route.Dest.String(), ifName)
log.Logf("[tun] %s", cmd)
if err := netlink.AddRoute(route.Dest.String(), "", "", ifName); err != nil && !errors.Is(err, syscall.EEXIST) {
return fmt.Errorf("%s: %v", cmd, err)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
log.Logf("[tun] %s: %v", cmd, er)
}
}
return nil
......@@ -165,9 +136,22 @@ func addTapRoutes(ifName string, gw string, routes ...string) error {
}
cmd := fmt.Sprintf("ip route add %s via %s dev %s", route, gw, ifName)
log.Logf("[tap] %s", cmd)
if err := netlink.AddRoute(route, "", gw, ifName); err != nil {
return fmt.Errorf("%s: %v", cmd, err)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
log.Logf("[tap] %s: %v", cmd, er)
}
}
return nil
}
func exeCmd(cmd string) error {
log.Log(cmd)
args := strings.Split(cmd, " ")
if err := exec.Command(args[0], args[1:]...).Run(); err != nil {
return fmt.Errorf("%s: %v", cmd, err)
}
return nil
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment