FILE / ScuroNeko/mtg

main.go

Исходный файл и его история в репозитории.
FILE dd56f808ab447d0fbb6236c7ed76d7a7de14b0d7
Files
mtg/main.go
T
2018-05-31 09:54:20 +03:00

145 lines
3.1 KiB
Go

package main
//go:generate scripts/generate_version.sh
import (
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"github.com/9seconds/mtg/proxy"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
kingpin "gopkg.in/alecthomas/kingpin.v2"
)
var (
app = kingpin.New("mtg", "Simple MTPROTO proxy.")
debug = app.Flag("debug", "Run in debug mode.").
Short('d').
Envar("MTG_DEBUG").
Bool()
verbose = app.Flag("verbose", "Run in verbose mode.").
Short('v').
Envar("MTG_VERBOSE").
Bool()
bindIP = app.Flag("bind-ip", "Which IP to bind to.").
Short('i').
Envar("MTG_IP").
Default("127.0.0.1").
IP()
bindPort = app.Flag("bind-port", "Which port to bind to.").
Short('p').
Envar("MTG_PORT").
Default("3128").
Uint16()
statsIP = app.Flag("stats-ip", "Which IP bind stats server to").
Short('t').
Envar("MTG_STATS_IP").
Default("127.0.0.1").
IP()
statsPort = app.Flag("stats-port", "Which port bind stats to.").
Short('q').
Envar("MTG_STATS_PORT").
Default("3129").
Uint16()
readTimeout = app.Flag("read-timeout", "Socket read timeout.").
Short('r').
Envar("MTG_READ_TIMEOUT").
Default("30s").
Duration()
writeTimeout = app.Flag("write-timeout", "Socket write timeout.").
Short('w').
Envar("MTG_WRITE_TIMEOUT").
Default("30s").
Duration()
serverName = app.Flag("server-name",
"Which server name to use. Default is IP address resolved by ipify.").
Short('s').
Envar("MTG_SERVER").
String()
secret = app.Arg("secret", "Secret of this proxy.").String()
)
func main() {
app.Version(version)
kingpin.MustParse(app.Parse(os.Args[1:]))
secretBytes, err := hex.DecodeString(*secret)
if err != nil {
usage("Secret has to be hexadecimal string.")
}
if *serverName == "" {
resp, err := http.Get("https://api.ipify.org")
if err != nil || resp.StatusCode != http.StatusOK {
usage("Cannot get local IP address.")
}
myIPBytes, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
usage("Cannot get local IP address.")
}
*serverName = strings.TrimSpace(string(myIPBytes))
}
atom := zap.NewAtomicLevel()
if *debug {
atom.SetLevel(zapcore.DebugLevel)
} else if *verbose {
atom.SetLevel(zapcore.InfoLevel)
} else {
atom.SetLevel(zapcore.ErrorLevel)
}
encoderCfg := zap.NewProductionEncoderConfig()
logger := zap.New(zapcore.NewCore(
zapcore.NewJSONEncoder(encoderCfg),
zapcore.Lock(os.Stderr),
atom,
)).Sugar()
printURLs()
stat := proxy.NewStats()
go stat.Serve(*statsIP, *statsPort)
srv := proxy.NewServer(*bindIP, int(*bindPort), secretBytes, logger,
*readTimeout, *writeTimeout, stat)
if err := srv.Serve(); err != nil {
logger.Fatal(err.Error())
}
}
func usage(msg string) {
io.WriteString(os.Stderr, msg+"\n")
os.Exit(1)
}
func printURLs() {
values := url.Values{}
values.Set("server", *serverName)
values.Set("port", strconv.Itoa(int(*bindPort)))
values.Set("secret", *secret)
tgURL := url.URL{
Scheme: "tg",
Host: "proxy",
RawQuery: values.Encode(),
}
fmt.Println(tgURL.String())
tgURL.Scheme = "https"
tgURL.Host = "t.me"
tgURL.Path = "proxy"
fmt.Println(tgURL.String())
}