61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"regexp"
|
|
|
|
"sing-cli/proxy"
|
|
)
|
|
|
|
type Config struct {
|
|
UpstreamHost string `json:"upstream_host"`
|
|
UpstreamPort int `json:"upstream_port"`
|
|
UpstreamUsername string `json:"upstream_username"`
|
|
UpstreamPassword string `json:"upstream_password"`
|
|
LocalPort int `json:"local_port"`
|
|
}
|
|
|
|
func stripJSONCComments(data []byte) []byte {
|
|
// Remove single-line comments (// ...)
|
|
re := regexp.MustCompile(`(?m)//.*$`)
|
|
return re.ReplaceAll(data, nil)
|
|
}
|
|
|
|
func main() {
|
|
configPath := flag.String("c", "config.jsonc", "path to config file")
|
|
flag.Parse()
|
|
|
|
data, err := os.ReadFile(*configPath)
|
|
if err != nil {
|
|
log.Fatalf("failed to read config: %v", err)
|
|
}
|
|
|
|
clean := stripJSONCComments(data)
|
|
var cfg Config
|
|
if err := json.Unmarshal(clean, &cfg); err != nil {
|
|
log.Fatalf("failed to parse config: %v", err)
|
|
}
|
|
|
|
upstream := fmt.Sprintf("%s:%d", cfg.UpstreamHost, cfg.UpstreamPort)
|
|
listen := fmt.Sprintf("127.0.0.1:%d", cfg.LocalPort)
|
|
|
|
log.Printf("SING VPN CLI v0.1")
|
|
log.Printf("upstream: %s (user: %s)", upstream, cfg.UpstreamUsername)
|
|
log.Printf("listening on %s", listen)
|
|
|
|
server := &proxy.Socks5Server{
|
|
ListenAddr: listen,
|
|
UpstreamAddr: upstream,
|
|
UpstreamUsername: cfg.UpstreamUsername,
|
|
UpstreamPassword: cfg.UpstreamPassword,
|
|
}
|
|
|
|
if err := server.Run(); err != nil {
|
|
log.Fatalf("server error: %v", err)
|
|
}
|
|
}
|