alibaba/kt-connect

View on GitHub
pkg/kt/service/tun/tun_linux.go

Summary

Maintainability
A
0 mins
Test Coverage
package tun

import (
    "fmt"
    "github.com/alibaba/kt-connect/pkg/kt/util"
    "github.com/rs/zerolog/log"
    "os/exec"
    "strings"
)

// CheckContext check everything needed for tun setup
func (s *Cli) CheckContext() error {
    if !util.CanRun(exec.Command("which", "ip")) {
        return fmt.Errorf("failed to found 'ip' command")
    }
    return nil
}

// SetRoute let specified ip range route to tun device
func (s *Cli) SetRoute(ipRange []string, excludeIpRange []string) error {
    // run command: ip link set dev kt0 up
    _, _, err := util.RunAndWait(exec.Command("ip",
        "link",
        "set",
        "dev",
        s.GetName(),
        "up",
    ))
    if err != nil {
        log.Error().Msgf("Failed to set tun device up")
        return AllRouteFailError{err}
    }
    var lastErr error
    anyRouteOk := false
    for _, r := range ipRange {
        log.Info().Msgf("Adding route to %s", r)
        // run command: ip route add 10.96.0.0/16 dev kt0
        _, _, err = util.RunAndWait(exec.Command("ip",
            "route",
            "add",
            r,
            "dev",
            s.GetName(),
        ))
        if err != nil {
            log.Warn().Msgf("Failed to set route %s to tun device", r)
            lastErr = err
        } else {
            anyRouteOk = true
        }
    }
    if !anyRouteOk {
        return AllRouteFailError{lastErr}
    }
    return lastErr
}

// CheckRoute check whether all route rule setup properly
func (s *Cli) CheckRoute(ipRange []string) []string {
    var failedIpRange []string
    // run command: ip route show
    out, _, err := util.RunAndWait(exec.Command("ip",
        "route",
        "show",
    ))
    if err != nil {
        log.Warn().Msgf("Failed to get route table")
        return []string{}
    }
    _, _ = util.BackgroundLogger.Write([]byte(">> Get route: " + out + util.Eol))

    nameWithPadding := fmt.Sprintf(" %s ", s.GetName())
    for _, ir := range ipRange {
        found := false
        for _, line := range strings.Split(out, util.Eol) {
            if strings.HasPrefix(line, ir) && strings.Contains(line, nameWithPadding) {
                found = true
                break
            }
        }
        if !found {
            failedIpRange = append(failedIpRange, ir)
        }
    }
    return failedIpRange
}

// RestoreRoute delete route rules made by kt
func (s *Cli) RestoreRoute() error {
    // Route will be auto removed when tun device destroyed
    return nil
}

func (s *Cli) GetName() string {
    return util.TunNameLinux
}