Browse Source

style: optimize golang code

v1.x.x
dnomd343 2 years ago
parent
commit
06f91c1502
  1. 57
      src/config.go
  2. 44
      src/load.go
  3. 63
      src/network.go

57
src/config.go

@ -4,7 +4,6 @@ import (
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"net" "net"
"strconv"
"strings" "strings"
) )
@ -38,53 +37,39 @@ type Config struct {
} }
} }
func isIP(ipAddr string, isRange bool, ipLength int, ipFlag string) bool { func isIP(ipAddr string, isCidr bool) bool {
var address string if !isCidr {
if isRange { return net.ParseIP(ipAddr) != nil
temp := strings.Split(ipAddr, "/")
if len(temp) != 2 { // not {IP_ADDRESS}/{LENGTH} format
return false
} }
length, err := strconv.Atoi(temp[1]) _, _, err := net.ParseCIDR(ipAddr)
if err != nil { // range length not a integer return err == nil
return false
}
if length < 0 || length > ipLength { // length should between 0 ~ ipLength
return false
}
address = temp[0]
} else {
address = ipAddr
}
ip := net.ParseIP(address) // try to convert ip
return ip != nil && strings.Contains(address, ipFlag)
} }
func isIPv4(ipAddr string, isRange bool) bool { func isIPv4(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isRange, 32, ".") return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ".")
} }
func isIPv6(ipAddr string, isRange bool) bool { func isIPv6(ipAddr string, isCidr bool) bool {
return isIP(ipAddr, isRange, 128, ":") return isIP(ipAddr, isCidr) && strings.Contains(ipAddr, ":")
} }
func loadConfig(rawConfig []byte) { func loadConfig(rawConfig []byte) {
config := Config{} config := Config{}
log.Debug("Decode yaml content -> \n", string(rawConfig)) log.Debugf("Decode yaml content -> \n%s", string(rawConfig))
err := yaml.Unmarshal(rawConfig, &config) // yaml (or json) decode err := yaml.Unmarshal(rawConfig, &config) // yaml (or json) decode
if err != nil { if err != nil {
panic(err) log.Panicf("Decode config file error -> %v", err)
} }
log.Debug("Decoded config -> ", config) log.Debugf("Decoded config -> %v", config)
for _, address := range config.Network.DNS { // dns options for _, address := range config.Network.DNS { // dns options
if isIPv4(address, false) || isIPv6(address, false) { if isIPv4(address, false) || isIPv6(address, false) {
dnsServer = append(dnsServer, address) dnsServer = append(dnsServer, address)
} else { } else {
panic("Invalid DNS server -> " + address) log.Panicf("Invalid DNS server -> %s", address)
} }
} }
log.Info("DNS server -> ", dnsServer) log.Infof("DNS server -> %v", dnsServer)
for _, address := range config.Network.ByPass { // bypass options for _, address := range config.Network.ByPass { // bypass options
if isIPv4(address, true) { if isIPv4(address, true) {
@ -92,29 +77,29 @@ func loadConfig(rawConfig []byte) {
} else if isIPv6(address, true) { } else if isIPv6(address, true) {
v6Bypass = append(v6Bypass, address) v6Bypass = append(v6Bypass, address)
} else { } else {
panic("Invalid bypass CIDR -> " + address) log.Panicf("Invalid bypass CIDR -> %s", address)
} }
} }
log.Info("IPv4 bypass CIDR -> ", v4Bypass) log.Infof("IPv4 bypass CIDR -> %s", v4Bypass)
log.Info("IPv6 bypass CIDR -> ", v6Bypass) log.Infof("IPv6 bypass CIDR -> %s", v6Bypass)
v4Address = config.Network.IPv4.Address v4Address = config.Network.IPv4.Address
v4Gateway = config.Network.IPv4.Gateway v4Gateway = config.Network.IPv4.Gateway
if v4Address != "" && !isIPv4(v4Address, true) { if v4Address != "" && !isIPv4(v4Address, true) {
panic("Invalid IPv4 address -> " + v4Address) log.Panicf("Invalid IPv4 address -> %s", v4Address)
} }
if v4Gateway != "" && !isIPv4(v4Gateway, false) { if v4Gateway != "" && !isIPv4(v4Gateway, false) {
panic("Invalid IPv4 gateway -> " + v4Gateway) log.Panicf("Invalid IPv4 gateway -> %s", v4Gateway)
} }
log.Infof("IPv4 -> address = %s | gateway = %s", v4Address, v4Gateway) log.Infof("IPv4 -> address = %s | gateway = %s", v4Address, v4Gateway)
v6Address = config.Network.IPv6.Address v6Address = config.Network.IPv6.Address
v6Gateway = config.Network.IPv6.Gateway v6Gateway = config.Network.IPv6.Gateway
if v6Address != "" && !isIPv6(v6Address, true) { if v6Address != "" && !isIPv6(v6Address, true) {
panic("Invalid IPv6 address -> " + v6Address) log.Panicf("Invalid IPv6 address -> %s", v6Address)
} }
if v6Gateway != "" && !isIPv6(v6Gateway, false) { if v6Gateway != "" && !isIPv6(v6Gateway, false) {
panic("Invalid IPv6 gateway -> " + v6Gateway) log.Panicf("Invalid IPv6 gateway -> %s", v6Gateway)
} }
log.Infof("IPv6 -> address = %s | gateway = %s", v6Address, v6Gateway) log.Infof("IPv6 -> address = %s | gateway = %s", v6Address, v6Gateway)

44
src/load.go

@ -50,6 +50,10 @@ var outboundsConfig = `{
] ]
}` }`
type inboundsSettings struct {
Inbounds []interface{} `json:"inbounds"`
}
type sniffSettings struct { type sniffSettings struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
RouteOnly bool `json:"routeOnly"` RouteOnly bool `json:"routeOnly"`
@ -65,11 +69,7 @@ type inboundSettings struct {
Sniffing sniffSettings `json:"sniffing"` Sniffing sniffSettings `json:"sniffing"`
} }
type inboundsSettings struct { func runCommand(command ...string) (int, string) {
Inbounds []interface{} `json:"inbounds"`
}
func runCommand(command []string) (int, string) {
log.Debugf("Running system command -> %v", command) log.Debugf("Running system command -> %v", command)
process := exec.Command(command[0], command[1:]...) process := exec.Command(command[0], command[1:]...)
output, _ := process.CombinedOutput() output, _ := process.CombinedOutput()
@ -93,8 +93,7 @@ func createFolder(folderPath string) {
log.Debugf("Loading folder -> %s", folderPath) log.Debugf("Loading folder -> %s", folderPath)
err := os.MkdirAll(folderPath, 0755) err := os.MkdirAll(folderPath, 0755)
if err != nil { if err != nil {
log.Errorf("Failed to create folder -> %s", folderPath) log.Panicf("Failed to create folder -> %s", folderPath)
panic("Create folder failed")
} }
} }
@ -102,8 +101,7 @@ func listFolder(folderPath string, suffix string) []string {
var fileList []string var fileList []string
files, err := ioutil.ReadDir(folderPath) files, err := ioutil.ReadDir(folderPath)
if err != nil { if err != nil {
log.Errorf("Failed to list folder -> %s", folderPath) log.Panicf("Failed to list folder -> %s", folderPath)
panic("List folder failed")
} }
for _, file := range files { for _, file := range files {
if strings.HasSuffix(file.Name(), suffix) { if strings.HasSuffix(file.Name(), suffix) {
@ -117,18 +115,15 @@ func copyFile(source string, target string) {
log.Infof("Copy file `%s` => `%s`", source, target) log.Infof("Copy file `%s` => `%s`", source, target)
srcFile, err := os.Open(source) srcFile, err := os.Open(source)
if err != nil { if err != nil {
log.Errorf("Failed to open file -> %s", source) log.Panicf("Failed to open file -> %s", source)
panic("Open file failed")
} }
dstFile, err := os.OpenFile(target, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) dstFile, err := os.OpenFile(target, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil { if err != nil {
log.Errorf("Failed to open file -> %s", target) log.Panicf("Failed to open file -> %s", target)
panic("Open file failed")
} }
_, err = io.Copy(dstFile, srcFile) _, err = io.Copy(dstFile, srcFile)
if err != nil { if err != nil {
log.Errorf("Failed to copy from `%s` to `%s`", source, target) log.Panicf("Failed to copy from `%s` to `%s`", source, target)
panic("Copy file failed")
} }
} }
@ -141,8 +136,7 @@ func saveConfig(configDir string, caption string, content string, overwrite bool
log.Debugf("Loading %s -> \n%s", filePath, content) log.Debugf("Loading %s -> \n%s", filePath, content)
err := os.WriteFile(filePath, []byte(content), 0644) err := os.WriteFile(filePath, []byte(content), 0644)
if err != nil { if err != nil {
log.Errorf("File %s -> %v", caption, err) log.Panicf("File %s -> %v", caption, err)
panic("File save error")
} }
} }
@ -210,24 +204,24 @@ func loadProxy(configDir string, exposeDir string) {
logConfig = strings.ReplaceAll(logConfig, "${DIR}", exposeDir+"/log") logConfig = strings.ReplaceAll(logConfig, "${DIR}", exposeDir+"/log")
saveConfig(configDir, "log", logConfig+"\n", true) saveConfig(configDir, "log", logConfig+"\n", true)
inboundsObject := inboundsSettings{} inbounds := inboundsSettings{}
sniffObject := sniffSettings{ sniff := sniffSettings{
Enabled: enableSniff, Enabled: enableSniff,
RouteOnly: !enableRedirect, RouteOnly: !enableRedirect,
DestOverride: []string{"http", "tls"}, DestOverride: []string{"http", "tls"},
} }
inboundsObject.Inbounds = append(inboundsObject.Inbounds, loadTProxyConfig("tproxy", v4TProxyPort, sniffObject)) inbounds.Inbounds = append(inbounds.Inbounds, loadTProxyConfig("tproxy", v4TProxyPort, sniff))
inboundsObject.Inbounds = append(inboundsObject.Inbounds, loadTProxyConfig("tproxy6", v6TProxyPort, sniffObject)) inbounds.Inbounds = append(inbounds.Inbounds, loadTProxyConfig("tproxy6", v6TProxyPort, sniff))
for tag, port := range httpInbounds { for tag, port := range httpInbounds {
inboundsObject.Inbounds = append(inboundsObject.Inbounds, loadHttpConfig(tag, port, sniffObject)) inbounds.Inbounds = append(inbounds.Inbounds, loadHttpConfig(tag, port, sniff))
} }
for tag, port := range socksInbounds { for tag, port := range socksInbounds {
inboundsObject.Inbounds = append(inboundsObject.Inbounds, loadSocksConfig(tag, port, sniffObject)) inbounds.Inbounds = append(inbounds.Inbounds, loadSocksConfig(tag, port, sniff))
} }
for _, addon := range addOnInbounds { for _, addon := range addOnInbounds {
inboundsObject.Inbounds = append(inboundsObject.Inbounds, addon) inbounds.Inbounds = append(inbounds.Inbounds, addon)
} }
inboundsConfig, _ := json.MarshalIndent(inboundsObject, "", " ") // json encode inboundsConfig, _ := json.MarshalIndent(inbounds, "", " ") // json encode
saveConfig(configDir, "inbounds", string(inboundsConfig)+"\n", true) saveConfig(configDir, "inbounds", string(inboundsConfig)+"\n", true)
for _, configFile := range listFolder(exposeDir+"/config", ".json") { for _, configFile := range listFolder(exposeDir+"/config", ".json") {

63
src/network.go

@ -19,46 +19,45 @@ func loadDns() {
} }
err := os.WriteFile("/etc/resolv.conf", []byte(dnsContent), 0644) err := os.WriteFile("/etc/resolv.conf", []byte(dnsContent), 0644)
if err != nil { if err != nil {
log.Error("Setting up DNS failed") log.Panic("Setting up DNS failed")
panic("Setting up DNS failed")
} }
} }
func loadNetwork() { func loadNetwork() {
log.Info("Enabled IP forward") log.Info("Enabled IP forward")
runCommand([]string{"sysctl", "-w", "net.ipv4.ip_forward=1"}) runCommand("sysctl", "-w", "net.ipv4.ip_forward=1")
runCommand([]string{"sysctl", "-w", "net.ipv6.conf.all.forwarding=1"}) runCommand("sysctl", "-w", "net.ipv6.conf.all.forwarding=1")
log.Info("Flush system IP configure") log.Info("Flush system IP configure")
runCommand([]string{"ip", "link", "set", "eth0", "down"}) runCommand("ip", "link", "set", "eth0", "down")
runCommand([]string{"ip", "-4", "addr", "flush", "dev", "eth0"}) runCommand("ip", "-4", "addr", "flush", "dev", "eth0")
runCommand([]string{"ip", "-6", "addr", "flush", "dev", "eth0"}) runCommand("ip", "-6", "addr", "flush", "dev", "eth0")
runCommand([]string{"ip", "link", "set", "eth0", "down"}) runCommand("ip", "link", "set", "eth0", "down")
log.Info("Setting up system IP configure") log.Info("Setting up system IP configure")
if v4Address != "" { if v4Address != "" {
runCommand([]string{"ip", "-4", "addr", "add", v4Address, "dev", "eth0"}) runCommand("ip", "-4", "addr", "add", v4Address, "dev", "eth0")
} }
if v4Gateway != "" { if v4Gateway != "" {
runCommand([]string{"ip", "-4", "route", "add", "default", "via", v4Gateway}) runCommand("ip", "-4", "route", "add", "default", "via", v4Gateway)
} }
if v6Address != "" { if v6Address != "" {
runCommand([]string{"ip", "-6", "addr", "add", v6Address, "dev", "eth0"}) runCommand("ip", "-6", "addr", "add", v6Address, "dev", "eth0")
} }
if v6Gateway != "" { if v6Gateway != "" {
runCommand([]string{"ip", "-6", "route", "add", "default", "via", v6Gateway}) runCommand("ip", "-6", "route", "add", "default", "via", v6Gateway)
} }
} }
func v4SysBypass() { func v4SysBypass() {
_, output := runCommand([]string{"ip", "-4", "addr"}) _, output := runCommand("ip", "-4", "addr")
for _, temp := range regexp.MustCompile(`inet (\S+)`).FindAllStringSubmatch(output, -1) { for _, temp := range regexp.MustCompile(`inet (\S+)`).FindAllStringSubmatch(output, -1) {
v4Bypass = append(v4Bypass, temp[1]) v4Bypass = append(v4Bypass, temp[1])
} }
} }
func v6SysBypass() { func v6SysBypass() {
_, output := runCommand([]string{"ip", "-6", "addr"}) _, output := runCommand("ip", "-6", "addr")
for _, temp := range regexp.MustCompile(`inet6 (\S+)`).FindAllStringSubmatch(output, -1) { for _, temp := range regexp.MustCompile(`inet6 (\S+)`).FindAllStringSubmatch(output, -1) {
v6Bypass = append(v6Bypass, temp[1]) v6Bypass = append(v6Bypass, temp[1])
} }
@ -67,33 +66,33 @@ func v6SysBypass() {
func loadTProxy() { func loadTProxy() {
log.Info("Setting up TProxy of IPv4") log.Info("Setting up TProxy of IPv4")
v4TableNum := strconv.Itoa(v4RouteTable) v4TableNum := strconv.Itoa(v4RouteTable)
runCommand([]string{"ip", "-4", "rule", "add", "fwmark", "1", "table", v4TableNum}) runCommand("ip", "-4", "rule", "add", "fwmark", "1", "table", v4TableNum)
runCommand([]string{"ip", "-4", "route", "add", "local", "0.0.0.0/0", "dev", "lo", "table", v4TableNum}) runCommand("ip", "-4", "route", "add", "local", "0.0.0.0/0", "dev", "lo", "table", v4TableNum)
runCommand([]string{"iptables", "-t", "mangle", "-N", "XPROXY"}) runCommand("iptables", "-t", "mangle", "-N", "XPROXY")
v4SysBypass() v4SysBypass()
log.Infof("Setting up IPv4 bypass CIDR -> %v", v4Bypass) log.Infof("Setting up IPv4 bypass CIDR -> %v", v4Bypass)
for _, cidr := range v4Bypass { for _, cidr := range v4Bypass {
runCommand([]string{"iptables", "-t", "mangle", "-A", "XPROXY", "-d", cidr, "-j", "RETURN"}) runCommand("iptables", "-t", "mangle", "-A", "XPROXY", "-d", cidr, "-j", "RETURN")
} }
runCommand([]string{"iptables", "-t", "mangle", "-A", "XPROXY", "-p", "tcp", "-j", "TPROXY", runCommand("iptables", "-t", "mangle", "-A", "XPROXY", "-p", "tcp", "-j", "TPROXY",
"--on-port", strconv.Itoa(v4TProxyPort), "--tproxy-mark", "1"}) "--on-port", strconv.Itoa(v4TProxyPort), "--tproxy-mark", "1")
runCommand([]string{"iptables", "-t", "mangle", "-A", "XPROXY", "-p", "udp", "-j", "TPROXY", runCommand("iptables", "-t", "mangle", "-A", "XPROXY", "-p", "udp", "-j", "TPROXY",
"--on-port", strconv.Itoa(v4TProxyPort), "--tproxy-mark", "1"}) "--on-port", strconv.Itoa(v4TProxyPort), "--tproxy-mark", "1")
runCommand([]string{"iptables", "-t", "mangle", "-A", "PREROUTING", "-j", "XPROXY"}) runCommand("iptables", "-t", "mangle", "-A", "PREROUTING", "-j", "XPROXY")
log.Info("Setting up TProxy of IPv6") log.Info("Setting up TProxy of IPv6")
v6TableNum := strconv.Itoa(v6RouteTable) v6TableNum := strconv.Itoa(v6RouteTable)
runCommand([]string{"ip", "-6", "rule", "add", "fwmark", "1", "table", v6TableNum}) runCommand("ip", "-6", "rule", "add", "fwmark", "1", "table", v6TableNum)
runCommand([]string{"ip", "-6", "route", "add", "local", "::/0", "dev", "lo", "table", v6TableNum}) runCommand("ip", "-6", "route", "add", "local", "::/0", "dev", "lo", "table", v6TableNum)
runCommand([]string{"ip6tables", "-t", "mangle", "-N", "XPROXY6"}) runCommand("ip6tables", "-t", "mangle", "-N", "XPROXY6")
v6SysBypass() v6SysBypass()
log.Infof("Setting up IPv6 bypass CIDR -> %v", v6Bypass) log.Infof("Setting up IPv6 bypass CIDR -> %v", v6Bypass)
for _, cidr := range v6Bypass { for _, cidr := range v6Bypass {
runCommand([]string{"ip6tables", "-t", "mangle", "-A", "XPROXY6", "-d", cidr, "-j", "RETURN"}) runCommand("ip6tables", "-t", "mangle", "-A", "XPROXY6", "-d", cidr, "-j", "RETURN")
} }
runCommand([]string{"ip6tables", "-t", "mangle", "-A", "XPROXY6", "-p", "tcp", "-j", "TPROXY", runCommand("ip6tables", "-t", "mangle", "-A", "XPROXY6", "-p", "tcp", "-j", "TPROXY",
"--on-port", strconv.Itoa(v6TProxyPort), "--tproxy-mark", "1"}) "--on-port", strconv.Itoa(v6TProxyPort), "--tproxy-mark", "1")
runCommand([]string{"ip6tables", "-t", "mangle", "-A", "XPROXY6", "-p", "udp", "-j", "TPROXY", runCommand("ip6tables", "-t", "mangle", "-A", "XPROXY6", "-p", "udp", "-j", "TPROXY",
"--on-port", strconv.Itoa(v6TProxyPort), "--tproxy-mark", "1"}) "--on-port", strconv.Itoa(v6TProxyPort), "--tproxy-mark", "1")
runCommand([]string{"ip6tables", "-t", "mangle", "-A", "PREROUTING", "-j", "XPROXY6"}) runCommand("ip6tables", "-t", "mangle", "-A", "PREROUTING", "-j", "XPROXY6")
} }

Loading…
Cancel
Save