mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-09-01 16:01:55 +03:00
linting the code
This commit is contained in:
@@ -4,7 +4,7 @@ APP_NAME := $(IMAGE_NAME)
|
|||||||
|
|
||||||
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
CC_BINARIES := $(shell bash -c "echo -n $(APP_NAME)-{linux,freebsd,openbsd}-{386,amd64} $(APP_NAME)-linux-{arm,arm64}")
|
||||||
|
|
||||||
GOLANGCI_LINT_VERSION := v1.15.0
|
GOLANGCI_LINT_VERSION := v1.20.0
|
||||||
|
|
||||||
VERSION_GO := $(shell go version)
|
VERSION_GO := $(shell go version)
|
||||||
VERSION_DATE := $(shell date -Ru)
|
VERSION_DATE := $(shell date -Ru)
|
||||||
@@ -51,10 +51,6 @@ crosscompile: $(CC_BINARIES)
|
|||||||
crosscompile-dir:
|
crosscompile-dir:
|
||||||
@rm -rf "$(CC_DIR)" && mkdir -p "$(CC_DIR)"
|
@rm -rf "$(CC_DIR)" && mkdir -p "$(CC_DIR)"
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
test: vendor
|
|
||||||
@$(MOD_ON) go test -v ./...
|
|
||||||
|
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: vendor
|
lint: vendor
|
||||||
@$(MOD_OFF) golangci-lint run
|
@$(MOD_OFF) golangci-lint run
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ func Generate(secretType string) {
|
|||||||
if _, err := rand.Read(data); err != nil {
|
if _, err := rand.Read(data); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secret := hex.EncodeToString(data)
|
secret := hex.EncodeToString(data)
|
||||||
|
|
||||||
switch secretType {
|
switch secretType {
|
||||||
|
|||||||
+10
-2
@@ -19,10 +19,11 @@ import (
|
|||||||
"github.com/9seconds/mtg/utils"
|
"github.com/9seconds/mtg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Proxy() error {
|
func Proxy() error { // nolint: funlen
|
||||||
ctx := utils.GetSignalContext()
|
ctx := utils.GetSignalContext()
|
||||||
|
|
||||||
atom := zap.NewAtomicLevel()
|
atom := zap.NewAtomicLevel()
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case config.C.Debug:
|
case config.C.Debug:
|
||||||
atom.SetLevel(zapcore.DebugLevel)
|
atom.SetLevel(zapcore.DebugLevel)
|
||||||
@@ -38,23 +39,28 @@ func Proxy() error {
|
|||||||
zapcore.Lock(os.Stderr),
|
zapcore.Lock(os.Stderr),
|
||||||
atom,
|
atom,
|
||||||
))
|
))
|
||||||
|
|
||||||
zap.ReplaceGlobals(logger)
|
zap.ReplaceGlobals(logger)
|
||||||
defer logger.Sync() // nolint: errcheck
|
defer logger.Sync() // nolint: errcheck
|
||||||
|
|
||||||
if err := config.InitPublicAddress(ctx); err != nil {
|
if err := config.InitPublicAddress(ctx); err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
zap.S().Debugw("Configuration", "config", config.Printable())
|
zap.S().Debugw("Configuration", "config", config.Printable())
|
||||||
|
|
||||||
if len(config.C.AdTag) > 0 {
|
if len(config.C.AdTag) > 0 {
|
||||||
zap.S().Infow("Use middle proxy connection to Telegram")
|
zap.S().Infow("Use middle proxy connection to Telegram")
|
||||||
|
|
||||||
diff, err := ntp.Fetch()
|
diff, err := ntp.Fetch()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal("Cannot fetch time data from NTP")
|
Fatal("Cannot fetch time data from NTP")
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff > time.Second {
|
if diff > time.Second {
|
||||||
Fatal("Your local time is skewed and drift is bigger than a second. Please sync your time.")
|
Fatal("Your local time is skewed and drift is bigger than a second. Please sync your time.")
|
||||||
}
|
}
|
||||||
|
|
||||||
go ntp.AutoUpdate()
|
go ntp.AutoUpdate()
|
||||||
} else {
|
} else {
|
||||||
zap.S().Infow("Use direct connection to Telegram")
|
zap.S().Infow("Use direct connection to Telegram")
|
||||||
@@ -62,10 +68,11 @@ func Proxy() error {
|
|||||||
|
|
||||||
PrintJSONStdout(config.GetURLs())
|
PrintJSONStdout(config.GetURLs())
|
||||||
|
|
||||||
antireplay.Init()
|
|
||||||
if err := stats.Init(ctx); err != nil {
|
if err := stats.Init(ctx); err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
antireplay.Init()
|
||||||
telegram.Init()
|
telegram.Init()
|
||||||
hub.Init(ctx)
|
hub.Init(ctx)
|
||||||
|
|
||||||
@@ -73,6 +80,7 @@ func Proxy() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fatal(err)
|
Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
proxyListener.Close()
|
proxyListener.Close()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ func Fatal(arg interface{}) {
|
|||||||
if value, ok := arg.(error); ok {
|
if value, ok := arg.(error); ok {
|
||||||
arg = fmt.Errorf("fatal error: %+v", value)
|
arg = fmt.Errorf("fatal error: %+v", value)
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintStderr(arg)
|
PrintStderr(arg)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-4
@@ -23,6 +23,7 @@ func (s SecretMode) String() string {
|
|||||||
case SecretModeSecured:
|
case SecretModeSecured:
|
||||||
return "secured"
|
return "secured"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "tls"
|
return "tls"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,7 +136,7 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
|||||||
case "influxdb":
|
case "influxdb":
|
||||||
C.StatsdTagsFormat = statsd.InfluxDB
|
C.StatsdTagsFormat = statsd.InfluxDB
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Incorrect statsd tag %s", value)
|
return fmt.Errorf("incorrect statsd tag %s", value)
|
||||||
}
|
}
|
||||||
case OptionTypeStatsdTags:
|
case OptionTypeStatsdTags:
|
||||||
C.StatsdTags = opt.Value.(map[string]string)
|
C.StatsdTags = opt.Value.(map[string]string)
|
||||||
@@ -152,7 +153,7 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
|||||||
case OptionTypeAdtag:
|
case OptionTypeAdtag:
|
||||||
C.AdTag = opt.Value.([]byte)
|
C.AdTag = opt.Value.([]byte)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unknown tag %v", opt.Option)
|
return fmt.Errorf("unknown tag %v", opt.Option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +164,7 @@ func Init(options ...Opt) error { // nolint: gocyclo, funlen
|
|||||||
case len(C.Secret) == SimpleSecretLength:
|
case len(C.Secret) == SimpleSecretLength:
|
||||||
C.SecretMode = SecretModeSimple
|
C.SecretMode = SecretModeSimple
|
||||||
default:
|
default:
|
||||||
return errors.New("Incorrect secret")
|
return errors.New("incorrect secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -173,11 +174,13 @@ func InitPublicAddress(ctx context.Context) error {
|
|||||||
if C.PublicIPv4.Port == 0 {
|
if C.PublicIPv4.Port == 0 {
|
||||||
C.PublicIPv4.Port = C.Bind.Port
|
C.PublicIPv4.Port = C.Bind.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
if C.PublicIPv6.Port == 0 {
|
if C.PublicIPv6.Port == 0 {
|
||||||
C.PublicIPv6.Port = C.Bind.Port
|
C.PublicIPv6.Port = C.Bind.Port
|
||||||
}
|
}
|
||||||
|
|
||||||
foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
|
foundAddress := C.PublicIPv4.IP != nil || C.PublicIPv6.IP != nil
|
||||||
|
|
||||||
if C.PublicIPv4.IP == nil {
|
if C.PublicIPv4.IP == nil {
|
||||||
ip, err := getGlobalIPv4(ctx)
|
ip, err := getGlobalIPv4(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -187,6 +190,7 @@ func InitPublicAddress(ctx context.Context) error {
|
|||||||
foundAddress = true
|
foundAddress = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if C.PublicIPv6.IP == nil {
|
if C.PublicIPv6.IP == nil {
|
||||||
ip, err := getGlobalIPv6(ctx)
|
ip, err := getGlobalIPv6(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -198,7 +202,7 @@ func InitPublicAddress(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !foundAddress {
|
if !foundAddress {
|
||||||
return errors.New("Cannot resolve any public address")
|
return errors.New("cannot resolve any public address")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ func getGlobalIPv4(ctx context.Context) (net.IP, error) {
|
|||||||
if err != nil || ip.To4() == nil {
|
if err != nil || ip.To4() == nil {
|
||||||
return nil, fmt.Errorf("cannot find public ipv4 address: %w", err)
|
return nil, fmt.Errorf("cannot find public ipv4 address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ func getGlobalIPv6(ctx context.Context) (net.IP, error) {
|
|||||||
if err != nil || ip.To4() != nil {
|
if err != nil || ip.To4() != nil {
|
||||||
return nil, fmt.Errorf("cannot find public ipv6 address: %w", err)
|
return nil, fmt.Errorf("cannot find public ipv6 address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ip, nil
|
return ip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,14 +56,17 @@ func fetchIP(ctx context.Context, network string) (net.IP, error) {
|
|||||||
if resp != nil {
|
if resp != nil {
|
||||||
io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
|
io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("cannot perform a request: %w", err)
|
return nil, fmt.Errorf("cannot perform a request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close() // nolint: errcheck
|
defer resp.Body.Close() // nolint: errcheck
|
||||||
|
|
||||||
respDataBytes, err := ioutil.ReadAll(resp.Body)
|
respDataBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read response body: %w", err)
|
return nil, fmt.Errorf("cannot read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
respData := strings.TrimSpace(string(respDataBytes))
|
respData := strings.TrimSpace(string(respDataBytes))
|
||||||
|
|
||||||
ip := net.ParseIP(respData)
|
ip := net.ParseIP(respData)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type IPURLs struct {
|
|||||||
|
|
||||||
func GetURLs() (urls IPURLs) {
|
func GetURLs() (urls IPURLs) {
|
||||||
secret := ""
|
secret := ""
|
||||||
|
|
||||||
switch C.SecretMode {
|
switch C.SecretMode {
|
||||||
case SecretModeSimple:
|
case SecretModeSimple:
|
||||||
secret = hex.EncodeToString(C.Secret)
|
secret = hex.EncodeToString(C.Secret)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ func (c ConnectionProtocol) String() string {
|
|||||||
case ConnectionProtocolIPv4:
|
case ConnectionProtocolIPv4:
|
||||||
return "ipv4"
|
return "ipv4"
|
||||||
}
|
}
|
||||||
|
|
||||||
return "ipv6"
|
return "ipv6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
package conntypes
|
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ func (c *connection) write(packet conntypes.Packet) error {
|
|||||||
c.pending = 0
|
c.pending = 0
|
||||||
c.mutex.Unlock()
|
c.mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +90,7 @@ func (c *connection) run() {
|
|||||||
logger.Debugw("Failed response", "error", err)
|
logger.Debugw("Failed response", "error", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if response.Type == rpc.ProxyResponseTypeCloseExt {
|
if response.Type == rpc.ProxyResponseTypeCloseExt {
|
||||||
logger.Debugw("Proxy has closed connection")
|
logger.Debugw("Proxy has closed connection")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -50,11 +50,11 @@ func (c *connectionHub) runGC() {
|
|||||||
case conn.closed():
|
case conn.closed():
|
||||||
logger.Debugw("Delete closed socket", "key", key)
|
logger.Debugw("Delete closed socket", "key", key)
|
||||||
delete(c.sockets, key)
|
delete(c.sockets, key)
|
||||||
|
|
||||||
case conn.idle():
|
case conn.idle():
|
||||||
logger.Debugw("Delete idle socket", "key", key)
|
logger.Debugw("Delete idle socket", "key", key)
|
||||||
conn.shutdown()
|
conn.shutdown()
|
||||||
delete(c.sockets, key)
|
delete(c.sockets, key)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,12 +65,14 @@ func (c *connectionHub) runConnectionRequest(req *connectionHubRequest) {
|
|||||||
|
|
||||||
for key, conn := range c.sockets {
|
for key, conn := range c.sockets {
|
||||||
delete(c.sockets, key)
|
delete(c.sockets, key)
|
||||||
|
|
||||||
if !conn.closed() {
|
if !conn.closed() {
|
||||||
logger.Debugw("Choose connection",
|
logger.Debugw("Choose connection",
|
||||||
"id", conn.id,
|
"id", conn.id,
|
||||||
"remote_addr", conn.conn.RemoteAddr())
|
"remote_addr", conn.conn.RemoteAddr())
|
||||||
req.response <- conn
|
req.response <- conn
|
||||||
close(req.response)
|
close(req.response)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +83,7 @@ func (c *connectionHub) runConnectionRequest(req *connectionHubRequest) {
|
|||||||
"remote_addr", conn.conn.RemoteAddr())
|
"remote_addr", conn.conn.RemoteAddr())
|
||||||
req.response <- conn
|
req.response <- conn
|
||||||
}
|
}
|
||||||
|
|
||||||
close(req.response)
|
close(req.response)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,6 +96,7 @@ func (c *connectionHub) runReturnConnection(conn *connection) {
|
|||||||
c.logger.Named("return-connection").Debugw("Return connection",
|
c.logger.Named("return-connection").Debugw("Return connection",
|
||||||
"id", conn.id,
|
"id", conn.id,
|
||||||
"remote_addr", conn.conn.RemoteAddr())
|
"remote_addr", conn.conn.RemoteAddr())
|
||||||
|
|
||||||
c.sockets[conn.id] = conn
|
c.sockets[conn.id] = conn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,13 @@ func (c *ctxChannel) sendBack(response *rpc.ProxyResponse) error {
|
|||||||
func (c *ctxChannel) Close() error {
|
func (c *ctxChannel) Close() error {
|
||||||
c.cancel()
|
c.cancel()
|
||||||
c.channel = nil
|
c.channel = nil
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCtxChannel(ctx context.Context) *ctxChannel {
|
func newCtxChannel(ctx context.Context) *ctxChannel {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
return &ctxChannel{
|
return &ctxChannel{
|
||||||
channel: make(chan *rpc.ProxyResponse),
|
channel: make(chan *rpc.ProxyResponse),
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
|
|||||||
+3
-2
@@ -42,9 +42,9 @@ func (h *hub) Write(packet conntypes.Packet, req *protocol.TelegramRequest) erro
|
|||||||
|
|
||||||
func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
|
func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
|
||||||
keyBuilder := strings.Builder{}
|
keyBuilder := strings.Builder{}
|
||||||
binary.Write(&keyBuilder, binary.LittleEndian, int16(req.ClientProtocol.DC()))
|
binary.Write(&keyBuilder, binary.LittleEndian, int16(req.ClientProtocol.DC())) // nolint: errcheck
|
||||||
keyBuilder.WriteRune('_')
|
keyBuilder.WriteRune('_')
|
||||||
binary.Write(&keyBuilder, binary.LittleEndian, uint8(req.ClientProtocol.ConnectionProtocol()))
|
binary.Write(&keyBuilder, binary.LittleEndian, uint8(req.ClientProtocol.ConnectionProtocol())) // nolint: errcheck
|
||||||
key := keyBuilder.String()
|
key := keyBuilder.String()
|
||||||
|
|
||||||
h.mutex.RLock()
|
h.mutex.RLock()
|
||||||
@@ -60,6 +60,7 @@ func (h *hub) getHub(req *protocol.TelegramRequest) *connectionHub {
|
|||||||
h.logger.Debugw("Create new connection hub",
|
h.logger.Debugw("Create new connection hub",
|
||||||
"dc", req.ClientProtocol.DC(),
|
"dc", req.ClientProtocol.DC(),
|
||||||
"protocol", req.ClientProtocol.ConnectionProtocol())
|
"protocol", req.ClientProtocol.ConnectionProtocol())
|
||||||
|
|
||||||
rv = newConnectionHub(h.logger.With(
|
rv = newConnectionHub(h.logger.With(
|
||||||
"dc", req.ClientProtocol.DC(),
|
"dc", req.ClientProtocol.DC(),
|
||||||
"protocol", req.ClientProtocol.ConnectionProtocol(),
|
"protocol", req.ClientProtocol.ConnectionProtocol(),
|
||||||
|
|||||||
@@ -40,5 +40,6 @@ func (r *registry) getChannel(id conntypes.ConnID) (*ctxChannel, bool) {
|
|||||||
if value, ok := r.conns[string(id[:])]; ok {
|
if value, ok := r.conns[string(id[:])]; ok {
|
||||||
return value, true
|
return value, true
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ func main() {
|
|||||||
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
|
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
|
||||||
case generateSecretCommand.FullCommand():
|
case generateSecretCommand.FullCommand():
|
||||||
cli.Generate(*generateSecretType)
|
cli.Generate(*generateSecretType)
|
||||||
|
|
||||||
case proxyCommand.FullCommand():
|
case proxyCommand.FullCommand():
|
||||||
err := config.Init(
|
err := config.Init(
|
||||||
config.Opt{Option: config.OptionTypeDebug, Value: *proxyDebug},
|
config.Opt{Option: config.OptionTypeDebug, Value: *proxyDebug},
|
||||||
|
|||||||
+11
-5
@@ -20,6 +20,7 @@ func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.PacketReadWriteC
|
|||||||
|
|
||||||
rpcNonceConn := packet.NewMtprotoFrame(conn, rpc.SeqNoNonce)
|
rpcNonceConn := packet.NewMtprotoFrame(conn, rpc.SeqNoNonce)
|
||||||
rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
|
rpcNonceReq, err := doRPCNonceRequest(rpcNonceConn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot do nonce request: %w", err)
|
return nil, fmt.Errorf("cannot do nonce request: %w", err)
|
||||||
}
|
}
|
||||||
@@ -35,6 +36,7 @@ func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.PacketReadWriteC
|
|||||||
if err := doRPCHandshakeRequest(frameConn); err != nil {
|
if err := doRPCHandshakeRequest(frameConn); err != nil {
|
||||||
return nil, fmt.Errorf("cannot do handshake request: %w", err)
|
return nil, fmt.Errorf("cannot do handshake request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := getRPCHandshakeResponse(frameConn); err != nil {
|
if err := getRPCHandshakeResponse(frameConn); err != nil {
|
||||||
return nil, fmt.Errorf("cannot get handshake response: %w", err)
|
return nil, fmt.Errorf("cannot get handshake response: %w", err)
|
||||||
}
|
}
|
||||||
@@ -42,11 +44,12 @@ func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.PacketReadWriteC
|
|||||||
return frameConn, nil
|
return frameConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRPCNonceRequest(conn conntypes.PacketWriter) (*rpc.NonceRequest, error) {
|
func doRPCNonceRequest(conn conntypes.BasePacketWriter) (*rpc.NonceRequest, error) {
|
||||||
rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
|
rpcNonceReq, err := rpc.NewNonceRequest(telegram.Middle.Secret())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
|
if err := conn.Write(rpcNonceReq.Bytes()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -54,7 +57,7 @@ func doRPCNonceRequest(conn conntypes.PacketWriter) (*rpc.NonceRequest, error) {
|
|||||||
return rpcNonceReq, nil
|
return rpcNonceReq, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRPCNonceResponse(conn conntypes.PacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
|
func getRPCNonceResponse(conn conntypes.BasePacketReader, req *rpc.NonceRequest) (*rpc.NonceResponse, error) {
|
||||||
packet, err := conn.Read()
|
packet, err := conn.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read from connection: %w", err)
|
return nil, fmt.Errorf("cannot read from connection: %w", err)
|
||||||
@@ -62,8 +65,9 @@ func getRPCNonceResponse(conn conntypes.PacketReader, req *rpc.NonceRequest) (*r
|
|||||||
|
|
||||||
resp, err := rpc.NewNonceResponse(packet)
|
resp, err := rpc.NewNonceResponse(packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot build rpc nonce responce: %w", err)
|
return nil, fmt.Errorf("cannot build rpc nonce response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = resp.Valid(req); err != nil {
|
if err = resp.Valid(req); err != nil {
|
||||||
return nil, fmt.Errorf("invalid nonce response: %w", err)
|
return nil, fmt.Errorf("invalid nonce response: %w", err)
|
||||||
}
|
}
|
||||||
@@ -71,14 +75,15 @@ func getRPCNonceResponse(conn conntypes.PacketReader, req *rpc.NonceRequest) (*r
|
|||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRPCHandshakeRequest(conn conntypes.PacketWriter) error {
|
func doRPCHandshakeRequest(conn conntypes.BasePacketWriter) error {
|
||||||
if err := conn.Write(rpc.HandshakeRequest); err != nil {
|
if err := conn.Write(rpc.HandshakeRequest); err != nil {
|
||||||
return fmt.Errorf("cannot make a request: %w", err)
|
return fmt.Errorf("cannot make a request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRPCHandshakeResponse(conn conntypes.PacketReader) error {
|
func getRPCHandshakeResponse(conn conntypes.BasePacketReader) error {
|
||||||
packet, err := conn.Read()
|
packet, err := conn.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot read a response: %w", err)
|
return fmt.Errorf("cannot read a response: %w", err)
|
||||||
@@ -88,6 +93,7 @@ func getRPCHandshakeResponse(conn conntypes.PacketReader) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot build a handshake response: %w", err)
|
return fmt.Errorf("cannot build a handshake response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := resp.Valid(); err != nil {
|
if err := resp.Valid(); err != nil {
|
||||||
return fmt.Errorf("invalid handshake response: %w", err)
|
return fmt.Errorf("invalid handshake response: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,11 @@ func (r *HandshakeResponse) Bytes() []byte {
|
|||||||
// Valid checks that handshake response compliments request.
|
// Valid checks that handshake response compliments request.
|
||||||
func (r *HandshakeResponse) Valid() error {
|
func (r *HandshakeResponse) Valid() error {
|
||||||
if !bytes.Equal(r.Type, TagHandshake) {
|
if !bytes.Equal(r.Type, TagHandshake) {
|
||||||
return errors.New("Unexpected handshake tag")
|
return errors.New("unexpected handshake tag")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(r.PeerPID, HandshakeSenderPID) {
|
if !bytes.Equal(r.PeerPID, HandshakeSenderPID) {
|
||||||
return errors.New("Incorrect sender PID")
|
return errors.New("incorrect sender PID")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -41,7 +42,7 @@ func (r *HandshakeResponse) Valid() error {
|
|||||||
// data.
|
// data.
|
||||||
func NewHandshakeResponse(data []byte) (*HandshakeResponse, error) {
|
func NewHandshakeResponse(data []byte) (*HandshakeResponse, error) {
|
||||||
if len(data) != 32 {
|
if len(data) != 32 {
|
||||||
return nil, fmt.Errorf("Incorrect handshake response length %d", len(data))
|
return nil, fmt.Errorf("incorrect handshake response length %d", len(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HandshakeResponse{
|
return &HandshakeResponse{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func NewNonceRequest(proxySecret []byte) (*NonceRequest, error) {
|
|||||||
if _, err := rand.Read(nonce); err != nil {
|
if _, err := rand.Read(nonce); err != nil {
|
||||||
return nil, fmt.Errorf("cannot generate nonce: %w", err)
|
return nil, fmt.Errorf("cannot generate nonce: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(keySelector, proxySecret)
|
copy(keySelector, proxySecret)
|
||||||
|
|
||||||
timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
|
timestamp := time.Now().Truncate(time.Second).Unix() % 4294967296 // 256 ^ 4 - do not know how to name
|
||||||
|
|||||||
@@ -28,13 +28,15 @@ func (r *NonceResponse) Bytes() []byte {
|
|||||||
|
|
||||||
func (r *NonceResponse) Valid(req *NonceRequest) error {
|
func (r *NonceResponse) Valid(req *NonceRequest) error {
|
||||||
if !bytes.Equal(r.Type, TagNonce) {
|
if !bytes.Equal(r.Type, TagNonce) {
|
||||||
return errors.New("Unexpected RPC type")
|
return errors.New("unexpected RPC type")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(r.Crypto, NonceCryptoAES) {
|
if !bytes.Equal(r.Crypto, NonceCryptoAES) {
|
||||||
return errors.New("Unexpected crypto type")
|
return errors.New("unexpected crypto type")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(r.KeySelector, req.KeySelector) {
|
if !bytes.Equal(r.KeySelector, req.KeySelector) {
|
||||||
return errors.New("Unexpected key selector")
|
return errors.New("unexpected key selector")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -43,7 +45,7 @@ func (r *NonceResponse) Valid(req *NonceRequest) error {
|
|||||||
// NewNonceResponse build new nonce response based on the given data.
|
// NewNonceResponse build new nonce response based on the given data.
|
||||||
func NewNonceResponse(data []byte) (*NonceResponse, error) {
|
func NewNonceResponse(data []byte) (*NonceResponse, error) {
|
||||||
if len(data) != 32 {
|
if len(data) != 32 {
|
||||||
return nil, fmt.Errorf("Unexpected message length %d", len(data))
|
return nil, fmt.Errorf("unexpected message length %d", len(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
return &NonceResponse{
|
return &NonceResponse{
|
||||||
|
|||||||
@@ -33,24 +33,31 @@ func (r ProxyRequestFlags) String() string {
|
|||||||
if r&ProxyRequestFlagsHasAdTag != 0 {
|
if r&ProxyRequestFlagsHasAdTag != 0 {
|
||||||
flags = append(flags, "HAS_AD_TAG")
|
flags = append(flags, "HAS_AD_TAG")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsEncrypted != 0 {
|
if r&ProxyRequestFlagsEncrypted != 0 {
|
||||||
flags = append(flags, "ENCRYPTED")
|
flags = append(flags, "ENCRYPTED")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsMagic != 0 {
|
if r&ProxyRequestFlagsMagic != 0 {
|
||||||
flags = append(flags, "MAGIC")
|
flags = append(flags, "MAGIC")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsExtMode2 != 0 {
|
if r&ProxyRequestFlagsExtMode2 != 0 {
|
||||||
flags = append(flags, "EXT_MODE_2")
|
flags = append(flags, "EXT_MODE_2")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsIntermediate != 0 {
|
if r&ProxyRequestFlagsIntermediate != 0 {
|
||||||
flags = append(flags, "INTERMEDIATE")
|
flags = append(flags, "INTERMEDIATE")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsAbdridged != 0 {
|
if r&ProxyRequestFlagsAbdridged != 0 {
|
||||||
flags = append(flags, "ABRIDGED")
|
flags = append(flags, "ABRIDGED")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsQuickAck != 0 {
|
if r&ProxyRequestFlagsQuickAck != 0 {
|
||||||
flags = append(flags, "QUICK_ACK")
|
flags = append(flags, "QUICK_ACK")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r&ProxyRequestFlagsPad != 0 {
|
if r&ProxyRequestFlagsPad != 0 {
|
||||||
flags = append(flags, "PAD")
|
flags = append(flags, "PAD")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,21 +29,23 @@ func ParseProxyResponse(packet conntypes.Packet) (*ProxyResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tag := packet[:4]
|
tag := packet[:4]
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case bytes.Equal(tag, TagProxyAns):
|
case bytes.Equal(tag, TagProxyAns):
|
||||||
response.Type = ProxyResponseTypeAns
|
response.Type = ProxyResponseTypeAns
|
||||||
copy(response.ConnID[:], packet[8:16])
|
copy(response.ConnID[:], packet[8:16])
|
||||||
response.Payload = packet[16:]
|
response.Payload = packet[16:]
|
||||||
return &response, nil
|
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
case bytes.Equal(tag, TagSimpleAck):
|
case bytes.Equal(tag, TagSimpleAck):
|
||||||
response.Type = ProxyResponseTypeSimpleAck
|
response.Type = ProxyResponseTypeSimpleAck
|
||||||
copy(response.ConnID[:], packet[4:12])
|
copy(response.ConnID[:], packet[4:12])
|
||||||
response.Payload = packet[12:]
|
response.Payload = packet[12:]
|
||||||
return &response, nil
|
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
case bytes.Equal(tag, TagCloseExt):
|
case bytes.Equal(tag, TagCloseExt):
|
||||||
response.Type = ProxyResponseTypeCloseExt
|
response.Type = ProxyResponseTypeCloseExt
|
||||||
|
|
||||||
return &response, nil
|
return &response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -21,15 +21,17 @@ var ntpEndpoints = [...]string{
|
|||||||
// Fetch fetches the data on time drift.
|
// Fetch fetches the data on time drift.
|
||||||
func Fetch() (time.Duration, error) {
|
func Fetch() (time.Duration, error) {
|
||||||
url := ntpEndpoints[rand.Intn(len(ntpEndpoints))]
|
url := ntpEndpoints[rand.Intn(len(ntpEndpoints))]
|
||||||
|
|
||||||
resp, err := ntp.Query(url)
|
resp, err := ntp.Query(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("Cannot fetch NTP server %s: %w", url, err)
|
return 0, fmt.Errorf("cannot fetch NTP server %s: %w", url, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetInt := int64(resp.ClockOffset)
|
offsetInt := int64(resp.ClockOffset)
|
||||||
if offsetInt < 0 {
|
if offsetInt < 0 {
|
||||||
offsetInt = -offsetInt
|
offsetInt = -offsetInt
|
||||||
}
|
}
|
||||||
|
|
||||||
offset := time.Duration(offsetInt)
|
offset := time.Duration(offsetInt)
|
||||||
|
|
||||||
return offset, nil
|
return offset, nil
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conn
|
|||||||
decryptor.XORKeyStream(decryptedFrame.Bytes(), fm.Bytes())
|
decryptor.XORKeyStream(decryptedFrame.Bytes(), fm.Bytes())
|
||||||
|
|
||||||
magic := decryptedFrame.Magic()
|
magic := decryptedFrame.Magic()
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case bytes.Equal(magic, conntypes.ConnectionTagAbridged):
|
case bytes.Equal(magic, conntypes.ConnectionTagAbridged):
|
||||||
c.connectionType = conntypes.ConnectionTypeAbridged
|
c.connectionType = conntypes.ConnectionTypeAbridged
|
||||||
@@ -66,7 +67,7 @@ func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conn
|
|||||||
case bytes.Equal(magic, conntypes.ConnectionTagSecure):
|
case bytes.Equal(magic, conntypes.ConnectionTagSecure):
|
||||||
c.connectionType = conntypes.ConnectionTypeSecure
|
c.connectionType = conntypes.ConnectionTypeSecure
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("Unknown connection type")
|
return nil, errors.New("unknown connection type")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.connectionProtocol = conntypes.ConnectionProtocolIPv4
|
c.connectionProtocol = conntypes.ConnectionProtocolIPv4
|
||||||
@@ -81,8 +82,9 @@ func (c *ClientProtocol) Handshake(socket conntypes.StreamReadWriteCloser) (conn
|
|||||||
|
|
||||||
antiReplayKey := decryptedFrame.Unique()
|
antiReplayKey := decryptedFrame.Unique()
|
||||||
if antireplay.Cache.Has(antiReplayKey) {
|
if antireplay.Cache.Has(antiReplayKey) {
|
||||||
return nil, errors.New("Replay attack is detected")
|
return nil, errors.New("replay attack is detected")
|
||||||
}
|
}
|
||||||
|
|
||||||
antireplay.Cache.Add(antiReplayKey)
|
antireplay.Cache.Add(antiReplayKey)
|
||||||
|
|
||||||
return stream.NewObfuscated2(socket, encryptor, decryptor), nil
|
return stream.NewObfuscated2(socket, encryptor, decryptor), nil
|
||||||
@@ -92,6 +94,7 @@ func (c *ClientProtocol) ReadFrame(socket conntypes.StreamReader) (fm Frame, err
|
|||||||
if _, err = io.ReadFull(handshakeReader{socket}, fm.Bytes()); err != nil {
|
if _, err = io.ReadFull(handshakeReader{socket}, fm.Bytes()); err != nil {
|
||||||
err = fmt.Errorf("cannot extract obfuscated2 frame: %w", err)
|
err = fmt.Errorf("cannot extract obfuscated2 frame: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ func TelegramProtocol(req *protocol.TelegramRequest) (conntypes.StreamReadWriteC
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot dial to telegram: %w", err)
|
return nil, fmt.Errorf("cannot dial to telegram: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = stream.NewTimeout(conn)
|
conn = stream.NewTimeout(conn)
|
||||||
conn = stream.NewCtx(req.Ctx, req.Cancel, conn)
|
conn = stream.NewCtx(req.Ctx, req.Cancel, conn)
|
||||||
fm := generateFrame(req.ClientProtocol)
|
fm := generateFrame(req.ClientProtocol)
|
||||||
@@ -45,6 +46,7 @@ func generateFrame(cp protocol.ClientProtocol) (fm Frame) {
|
|||||||
if _, err := rand.Read(data); err != nil {
|
if _, err := rand.Read(data); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if data[0] == 0xef {
|
if data[0] == 0xef {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,16 @@ func directConnection(request *protocol.TelegramRequest) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
telegramConn := telegramConnRaw.(conntypes.StreamReadWriteCloser)
|
telegramConn := telegramConnRaw.(conntypes.StreamReadWriteCloser)
|
||||||
|
|
||||||
defer telegramConn.Close()
|
defer telegramConn.Close()
|
||||||
|
|
||||||
wg := &sync.WaitGroup{}
|
wg := &sync.WaitGroup{}
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
go directPipe(telegramConn, request.ClientConn, wg, request.Logger)
|
go directPipe(telegramConn, request.ClientConn, wg, request.Logger)
|
||||||
|
|
||||||
go directPipe(request.ClientConn, telegramConn, wg, request.Logger)
|
go directPipe(request.ClientConn, telegramConn, wg, request.Logger)
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|||||||
+4
-3
@@ -10,11 +10,12 @@ import (
|
|||||||
"github.com/9seconds/mtg/wrappers/packetack"
|
"github.com/9seconds/mtg/wrappers/packetack"
|
||||||
)
|
)
|
||||||
|
|
||||||
func middleConnection(request *protocol.TelegramRequest) error {
|
func middleConnection(request *protocol.TelegramRequest) {
|
||||||
telegramConn := packetack.NewProxy(request)
|
telegramConn := packetack.NewProxy(request)
|
||||||
defer telegramConn.Close()
|
defer telegramConn.Close()
|
||||||
|
|
||||||
var clientConn conntypes.PacketAckFullReadWriteCloser
|
var clientConn conntypes.PacketAckFullReadWriteCloser
|
||||||
|
|
||||||
switch request.ClientProtocol.ConnectionType() {
|
switch request.ClientProtocol.ConnectionType() {
|
||||||
case conntypes.ConnectionTypeAbridged:
|
case conntypes.ConnectionTypeAbridged:
|
||||||
clientConn = packetack.NewClientAbridged(request.ClientConn)
|
clientConn = packetack.NewClientAbridged(request.ClientConn)
|
||||||
@@ -30,11 +31,10 @@ func middleConnection(request *protocol.TelegramRequest) error {
|
|||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
|
|
||||||
go middlePipe(telegramConn, clientConn, wg, request.Logger)
|
go middlePipe(telegramConn, clientConn, wg, request.Logger)
|
||||||
|
|
||||||
go middlePipe(clientConn, telegramConn, wg, request.Logger)
|
go middlePipe(clientConn, telegramConn, wg, request.Logger)
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func middlePipe(dst conntypes.PacketAckWriteCloser,
|
func middlePipe(dst conntypes.PacketAckWriteCloser,
|
||||||
@@ -50,6 +50,7 @@ func middlePipe(dst conntypes.PacketAckWriteCloser,
|
|||||||
for {
|
for {
|
||||||
acks := conntypes.ConnectionAcks{}
|
acks := conntypes.ConnectionAcks{}
|
||||||
packet, err := src.Read(&acks)
|
packet, err := src.Read(&acks)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Debugw("Cannot read packet", "error", err)
|
logger.Debugw("Cannot read packet", "error", err)
|
||||||
return
|
return
|
||||||
|
|||||||
+6
-1
@@ -34,6 +34,7 @@ func (p *Proxy) Serve(listener net.Listener) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go p.accept(conn)
|
go p.accept(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,10 +62,12 @@ func (p *Proxy) accept(conn net.Conn) {
|
|||||||
clientConn := stream.NewClientConn(conn, connID)
|
clientConn := stream.NewClientConn(conn, connID)
|
||||||
clientConn = stream.NewCtx(ctx, cancel, clientConn)
|
clientConn = stream.NewCtx(ctx, cancel, clientConn)
|
||||||
clientConn = stream.NewTimeout(clientConn)
|
clientConn = stream.NewTimeout(clientConn)
|
||||||
|
|
||||||
defer clientConn.Close()
|
defer clientConn.Close()
|
||||||
|
|
||||||
clientProtocol := p.ClientProtocolMaker()
|
clientProtocol := p.ClientProtocolMaker()
|
||||||
clientConn, err := clientProtocol.Handshake(clientConn)
|
clientConn, err := clientProtocol.Handshake(clientConn)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnw("Cannot perform client handshake", "error", err)
|
logger.Warnw("Cannot perform client handshake", "error", err)
|
||||||
return
|
return
|
||||||
@@ -83,8 +86,10 @@ func (p *Proxy) accept(conn net.Conn) {
|
|||||||
ClientProtocol: clientProtocol,
|
ClientProtocol: clientProtocol,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = nil
|
||||||
|
|
||||||
if len(config.C.AdTag) > 0 {
|
if len(config.C.AdTag) > 0 {
|
||||||
err = middleConnection(req)
|
middleConnection(req)
|
||||||
} else {
|
} else {
|
||||||
err = directConnection(req)
|
err = directConnection(req)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,13 @@ func Init(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
stats := []Interface{instancePrometheus}
|
stats := []Interface{instancePrometheus}
|
||||||
|
|
||||||
if config.C.StatsdAddr != nil {
|
if config.C.StatsdAddr != nil {
|
||||||
instanceStatsd, err := newStatsStatsd()
|
instanceStatsd, err := newStatsStatsd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot inialize statsd: %w", err)
|
return fmt.Errorf("cannot inialize statsd: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stats = append(stats, instanceStatsd)
|
stats = append(stats, instanceStatsd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +38,9 @@ func Init(ctx context.Context) error {
|
|||||||
srv := http.Server{
|
srv := http.Server{
|
||||||
Handler: mux,
|
Handler: mux,
|
||||||
}
|
}
|
||||||
|
|
||||||
go srv.Serve(listener) // nolint: errcheck
|
go srv.Serve(listener) // nolint: errcheck
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
srv.Shutdown(context.Background()) // nolint: errcheck
|
srv.Shutdown(context.Background()) // nolint: errcheck
|
||||||
|
|||||||
@@ -122,15 +122,19 @@ func newStatsPrometheus(mux *http.ServeMux) (Interface, error) {
|
|||||||
if err := registry.Register(instance.connections); err != nil {
|
if err := registry.Register(instance.connections); err != nil {
|
||||||
return nil, fmt.Errorf("cannot register metrics for connections: %w", err)
|
return nil, fmt.Errorf("cannot register metrics for connections: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := registry.Register(instance.telegramConnections); err != nil {
|
if err := registry.Register(instance.telegramConnections); err != nil {
|
||||||
return nil, fmt.Errorf("cannot register metrics for telegram connections: %w", err)
|
return nil, fmt.Errorf("cannot register metrics for telegram connections: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := registry.Register(instance.traffic); err != nil {
|
if err := registry.Register(instance.traffic); err != nil {
|
||||||
return nil, fmt.Errorf("cannot register metrics for traffic: %w", err)
|
return nil, fmt.Errorf("cannot register metrics for traffic: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := registry.Register(instance.crashes); err != nil {
|
if err := registry.Register(instance.crashes); err != nil {
|
||||||
return nil, fmt.Errorf("cannot register metrics for crashes: %w", err)
|
return nil, fmt.Errorf("cannot register metrics for crashes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := registry.Register(instance.antiReplays); err != nil {
|
if err := registry.Register(instance.antiReplays); err != nil {
|
||||||
return nil, fmt.Errorf("cannot register metrics for anti replays: %w", err)
|
return nil, fmt.Errorf("cannot register metrics for anti replays: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ func newStatsStatsd() (Interface, error) {
|
|||||||
for k, v := range config.C.StatsdTags {
|
for k, v := range config.C.StatsdTags {
|
||||||
tags = append(tags, k, v)
|
tags = append(tags, k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
options = append(options, statsd.Tags(tags...))
|
options = append(options, statsd.Tags(tags...))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,34 +31,36 @@ func getAddresses(url string) (map[conntypes.DC][]string, conntypes.DC, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("cannot get http response: %w", err)
|
return nil, 0, fmt.Errorf("cannot get http response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
|
||||||
scanner := bufio.NewScanner(resp)
|
scanner := bufio.NewScanner(resp)
|
||||||
data := map[conntypes.DC][]string{}
|
data := map[conntypes.DC][]string{}
|
||||||
|
defaultDC := conntypes.DCDefaultIdx
|
||||||
|
|
||||||
var defaultDC = conntypes.DCDefaultIdx
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
text := strings.TrimSpace(scanner.Text())
|
text := strings.TrimSpace(scanner.Text())
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case strings.HasPrefix(text, "#"):
|
case strings.HasPrefix(text, "#"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case strings.HasPrefix(text, "proxy_for"):
|
case strings.HasPrefix(text, "proxy_for"):
|
||||||
addr, idx, err := addressesParseProxyFor(text)
|
addr, idx, err := addressesParseProxyFor(text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("cannot parse 'proxy_for' section: %w", err)
|
return nil, 0, fmt.Errorf("cannot parse 'proxy_for' section: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if addresses, ok := data[idx]; ok {
|
if addresses, ok := data[idx]; ok {
|
||||||
data[idx] = append(addresses, addr)
|
data[idx] = append(addresses, addr)
|
||||||
} else {
|
} else {
|
||||||
data[idx] = []string{addr}
|
data[idx] = []string{addr}
|
||||||
}
|
}
|
||||||
|
|
||||||
case strings.HasPrefix(text, "default"):
|
case strings.HasPrefix(text, "default"):
|
||||||
idx, err := addressesParseDefault(text)
|
idx, err := addressesParseDefault(text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, fmt.Errorf("cannot parse 'default' section: %w", err)
|
return nil, 0, fmt.Errorf("cannot parse 'default' section: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultDC = idx
|
defaultDC = idx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,6 +99,7 @@ func addressesParseDefault(text string) (conntypes.DC, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dcString := strings.TrimRight(chunks[1], ";")
|
dcString := strings.TrimRight(chunks[1], ";")
|
||||||
|
|
||||||
dc, err := strconv.ParseInt(dcString, 10, 16)
|
dc, err := strconv.ParseInt(dcString, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("incorrect config '%s': %w", text, err)
|
return 0, fmt.Errorf("incorrect config '%s': %w", text, err)
|
||||||
|
|||||||
+3
-1
@@ -22,15 +22,17 @@ func request(url string) (io.ReadCloser, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("Accept", "text/plan")
|
req.Header.Set("Accept", "text/plan")
|
||||||
req.Header.Set("User-Agent", apiUserAgent)
|
req.Header.Set("User-Agent", apiUserAgent)
|
||||||
|
|
||||||
resp, err := httpClient.Do(req)
|
resp, err := httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
io.Copy(ioutil.Discard, resp.Body)
|
io.Copy(ioutil.Discard, resp.Body) // nolint: errcheck
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("cannot perform a request: %w", err)
|
return nil, fmt.Errorf("cannot perform a request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ func Secret() ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot access telegram server: %w", err)
|
return nil, fmt.Errorf("cannot access telegram server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Close()
|
defer resp.Close()
|
||||||
|
|
||||||
secret, err := ioutil.ReadAll(resp)
|
secret, err := ioutil.ReadAll(resp)
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ func (b *baseTelegram) chooseAddress(addresses map[conntypes.DC][]string,
|
|||||||
dc, defaultDC conntypes.DC) string {
|
dc, defaultDC conntypes.DC) string {
|
||||||
addrs, ok := addresses[dc]
|
addrs, ok := addresses[dc]
|
||||||
if !ok {
|
if !ok {
|
||||||
addrs, _ = addresses[defaultDC]
|
addrs = addresses[defaultDC]
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ func (m *middleTelegram) update() error {
|
|||||||
|
|
||||||
func (m *middleTelegram) backgroundUpdate() {
|
func (m *middleTelegram) backgroundUpdate() {
|
||||||
logger := zap.S().Named("telegram")
|
logger := zap.S().Named("telegram")
|
||||||
|
|
||||||
for range time.Tick(middleTelegramBackgroundUpdateEvery) {
|
for range time.Tick(middleTelegramBackgroundUpdateEvery) {
|
||||||
if err := m.update(); err != nil {
|
if err := m.update(); err != nil {
|
||||||
logger.Warnw("Cannot update Telegram proxies", "error", err)
|
logger.Warnw("Cannot update Telegram proxies", "error", err)
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ func InitTCP(conn net.Conn) error {
|
|||||||
if err := tcpConn.SetNoDelay(true); err != nil {
|
if err := tcpConn.SetNoDelay(true); err != nil {
|
||||||
return fmt.Errorf("cannot set TCP_NO_DELAY: %w", err)
|
return fmt.Errorf("cannot set TCP_NO_DELAY: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tcpConn.SetReadBuffer(config.C.ReadBuffer); err != nil {
|
if err := tcpConn.SetReadBuffer(config.C.ReadBuffer); err != nil {
|
||||||
return fmt.Errorf("cannot set read buffer size: %w", err)
|
return fmt.Errorf("cannot set read buffer size: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := tcpConn.SetWriteBuffer(config.C.WriteBuffer); err != nil {
|
if err := tcpConn.SetWriteBuffer(config.C.WriteBuffer); err != nil {
|
||||||
return fmt.Errorf("cannot set write buffer size: %w", err)
|
return fmt.Errorf("cannot set write buffer size: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ func ReadFull(src io.Reader) (rv []byte, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = append(rv, buf[:n]...)
|
rv = append(rv, buf[:n]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ package utils
|
|||||||
func ReverseBytes(data []byte) []byte {
|
func ReverseBytes(data []byte) []byte {
|
||||||
dataLen := len(data)
|
dataLen := len(data)
|
||||||
rv := make([]byte, dataLen)
|
rv := make([]byte, dataLen)
|
||||||
|
|
||||||
rv[dataLen/2] = data[dataLen/2]
|
rv[dataLen/2] = data[dataLen/2]
|
||||||
|
|
||||||
for i := dataLen/2 - 1; i >= 0; i-- {
|
for i := dataLen/2 - 1; i >= 0; i-- {
|
||||||
opp := dataLen - i - 1
|
opp := dataLen - i - 1
|
||||||
rv[i], rv[opp] = data[opp], data[i]
|
rv[i], rv[opp] = data[opp], data[i]
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ func SetLimits() error {
|
|||||||
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
|
if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
|
||||||
return fmt.Errorf("cannot get rlimit: %w", err)
|
return fmt.Errorf("cannot get rlimit: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rLimit.Cur = rLimit.Max
|
rLimit.Cur = rLimit.Max
|
||||||
|
|
||||||
if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
|
if err := unix.Setrlimit(unix.RLIMIT_NOFILE, &rLimit); err != nil {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ func GetSignalContext() context.Context {
|
|||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
|
|
||||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for range sigChan {
|
for range sigChan {
|
||||||
cancel()
|
cancel()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ type wrapperMtprotoFrame struct {
|
|||||||
writeSeqNo int32
|
writeSeqNo int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) {
|
func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) { // nolint: funlen
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
sum := crc32.NewIEEE()
|
sum := crc32.NewIEEE()
|
||||||
writer := io.MultiWriter(buf, sum)
|
writer := io.MultiWriter(buf, sum)
|
||||||
@@ -49,9 +49,11 @@ func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) {
|
|||||||
for {
|
for {
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
sum.Reset()
|
sum.Reset()
|
||||||
|
|
||||||
if _, err := io.CopyN(writer, w.parent, 4); err != nil {
|
if _, err := io.CopyN(writer, w.parent, 4); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read frame padding: %w", err)
|
return nil, fmt.Errorf("cannot read frame padding: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(buf.Bytes(), mtprotoFramePadding) {
|
if !bytes.Equal(buf.Bytes(), mtprotoFramePadding) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -62,19 +64,23 @@ func (w *wrapperMtprotoFrame) Read() (conntypes.Packet, error) {
|
|||||||
"messageLength", messageLength,
|
"messageLength", messageLength,
|
||||||
"sequence_number", w.readSeqNo,
|
"sequence_number", w.readSeqNo,
|
||||||
)
|
)
|
||||||
|
|
||||||
if messageLength%4 != 0 || messageLength < mtprotoFrameMinMessageLength ||
|
if messageLength%4 != 0 || messageLength < mtprotoFrameMinMessageLength ||
|
||||||
messageLength > mtprotoFrameMaxMessageLength {
|
messageLength > mtprotoFrameMaxMessageLength {
|
||||||
return nil, fmt.Errorf("Incorrect frame message length %d", messageLength)
|
return nil, fmt.Errorf("incorrect frame message length %d", messageLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
buf.Grow(int(messageLength) - 4 - 4)
|
buf.Grow(int(messageLength) - 4 - 4)
|
||||||
|
|
||||||
if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
|
if _, err := io.CopyN(writer, w.parent, int64(messageLength)-4-4); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read the message frame: %w", err)
|
return nil, fmt.Errorf("cannot read the message frame: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var seqNo int32
|
var seqNo int32
|
||||||
binary.Read(buf, binary.LittleEndian, &seqNo) // nolint: errcheck, gosec
|
|
||||||
|
binary.Read(buf, binary.LittleEndian, &seqNo) // nolint: errcheck
|
||||||
|
|
||||||
if seqNo != w.readSeqNo {
|
if seqNo != w.readSeqNo {
|
||||||
return nil, fmt.Errorf("unexpected sequence number %d (wait for %d)", seqNo, w.readSeqNo)
|
return nil, fmt.Errorf("unexpected sequence number %d (wait for %d)", seqNo, w.readSeqNo)
|
||||||
}
|
}
|
||||||
@@ -110,12 +116,12 @@ func (w *wrapperMtprotoFrame) Write(p conntypes.Packet) error {
|
|||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
buf.Grow(messageLength + paddingLength)
|
buf.Grow(messageLength + paddingLength)
|
||||||
|
|
||||||
binary.Write(buf, binary.LittleEndian, uint32(messageLength))
|
binary.Write(buf, binary.LittleEndian, uint32(messageLength)) // nolint: errcheck
|
||||||
binary.Write(buf, binary.LittleEndian, w.writeSeqNo)
|
binary.Write(buf, binary.LittleEndian, w.writeSeqNo) // nolint: errcheck
|
||||||
buf.Write(p)
|
buf.Write(p)
|
||||||
|
|
||||||
checksum := crc32.ChecksumIEEE(buf.Bytes())
|
checksum := crc32.ChecksumIEEE(buf.Bytes())
|
||||||
binary.Write(buf, binary.LittleEndian, checksum)
|
binary.Write(buf, binary.LittleEndian, checksum) // nolint: errcheck
|
||||||
buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4))
|
buf.Write(bytes.Repeat(mtprotoFramePadding, paddingLength/4))
|
||||||
|
|
||||||
w.logger.Debugw("Write MTProto frame",
|
w.logger.Debugw("Write MTProto frame",
|
||||||
|
|||||||
@@ -26,9 +26,11 @@ func (w *wrapperClientAbridged) Read(acks *conntypes.ConnectionAcks) (conntypes.
|
|||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
buf.Grow(1)
|
buf.Grow(1)
|
||||||
|
|
||||||
if _, err := io.CopyN(&buf, w.parent, 1); err != nil {
|
if _, err := io.CopyN(&buf, w.parent, 1); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read message length: %w", err)
|
return nil, fmt.Errorf("cannot read message length: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgLength := uint32(buf.Bytes()[0])
|
msgLength := uint32(buf.Bytes()[0])
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
|
|
||||||
@@ -39,17 +41,21 @@ func (w *wrapperClientAbridged) Read(acks *conntypes.ConnectionAcks) (conntypes.
|
|||||||
|
|
||||||
if msgLength == clientAbridgedSmallPacketLength {
|
if msgLength == clientAbridgedSmallPacketLength {
|
||||||
buf.Grow(3)
|
buf.Grow(3)
|
||||||
|
|
||||||
if _, err := io.CopyN(&buf, w.parent, 3); err != nil {
|
if _, err := io.CopyN(&buf, w.parent, 3); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read correct message length: %w", err)
|
return nil, fmt.Errorf("cannot read correct message length: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
number := utils.Uint24{}
|
number := utils.Uint24{}
|
||||||
copy(number[:], buf.Bytes())
|
copy(number[:], buf.Bytes())
|
||||||
msgLength = utils.FromUint24(number)
|
msgLength = utils.FromUint24(number)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgLength *= 4
|
msgLength *= 4
|
||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
buf.Grow(int(msgLength))
|
buf.Grow(int(msgLength))
|
||||||
|
|
||||||
if _, err := io.CopyN(&buf, w.parent, int64(msgLength)); err != nil {
|
if _, err := io.CopyN(&buf, w.parent, int64(msgLength)); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read message: %w", err)
|
return nil, fmt.Errorf("cannot read message: %w", err)
|
||||||
}
|
}
|
||||||
@@ -66,18 +72,20 @@ func (w *wrapperClientAbridged) Write(packet conntypes.Packet, acks *conntypes.C
|
|||||||
if _, err := w.parent.Write(utils.ReverseBytes(packet)); err != nil {
|
if _, err := w.parent.Write(utils.ReverseBytes(packet)); err != nil {
|
||||||
return fmt.Errorf("cannot send a simpleacked packet: %w", err)
|
return fmt.Errorf("cannot send a simpleacked packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
packetLength := len(packet) / 4
|
packetLength := len(packet) / 4
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case packetLength < clientAbridgedSmallPacketLength:
|
case packetLength < clientAbridgedSmallPacketLength:
|
||||||
data := append([]byte{byte(packetLength)}, packet...)
|
data := append([]byte{byte(packetLength)}, packet...)
|
||||||
if _, err := w.parent.Write(data); err != nil {
|
if _, err := w.parent.Write(data); err != nil {
|
||||||
return fmt.Errorf("cannot send small packet: %w", err)
|
return fmt.Errorf("cannot send small packet: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
|
||||||
|
return nil
|
||||||
case packetLength < clientAbridgedLargePacketLength:
|
case packetLength < clientAbridgedLargePacketLength:
|
||||||
length24 := utils.ToUint24(uint32(packetLength))
|
length24 := utils.ToUint24(uint32(packetLength))
|
||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
@@ -89,6 +97,7 @@ func (w *wrapperClientAbridged) Write(packet conntypes.Packet, acks *conntypes.C
|
|||||||
if _, err := w.parent.Write(buf.Bytes()); err != nil {
|
if _, err := w.parent.Write(buf.Bytes()); err != nil {
|
||||||
return fmt.Errorf("cannot send large packet: %w", err)
|
return fmt.Errorf("cannot send large packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,11 @@ func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (connty
|
|||||||
buf := bytes.Buffer{}
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
buf.Grow(4)
|
buf.Grow(4)
|
||||||
|
|
||||||
if _, err := io.CopyN(&buf, w.parent, 4); err != nil {
|
if _, err := io.CopyN(&buf, w.parent, 4); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read message length: %w", err)
|
return nil, fmt.Errorf("cannot read message length: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
length := binary.LittleEndian.Uint32(buf.Bytes())
|
length := binary.LittleEndian.Uint32(buf.Bytes())
|
||||||
|
|
||||||
if length > clientIntermediateQuickAckLength {
|
if length > clientIntermediateQuickAckLength {
|
||||||
@@ -34,6 +36,7 @@ func (w *wrapperClientIntermediate) Read(acks *conntypes.ConnectionAcks) (connty
|
|||||||
|
|
||||||
buf.Reset()
|
buf.Reset()
|
||||||
buf.Grow(int(length))
|
buf.Grow(int(length))
|
||||||
|
|
||||||
if _, err := io.CopyN(&buf, w.parent, int64(length)); err != nil {
|
if _, err := io.CopyN(&buf, w.parent, int64(length)); err != nil {
|
||||||
return nil, fmt.Errorf("cannot read the message: %w", err)
|
return nil, fmt.Errorf("cannot read the message: %w", err)
|
||||||
}
|
}
|
||||||
@@ -46,6 +49,7 @@ func (w *wrapperClientIntermediate) Write(packet conntypes.Packet, acks *conntyp
|
|||||||
if _, err := w.parent.Write(packet); err != nil {
|
if _, err := w.parent.Write(packet); err != nil {
|
||||||
return fmt.Errorf("cannot send simpleacked packet: %w", err)
|
return fmt.Errorf("cannot send simpleacked packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +59,7 @@ func (w *wrapperClientIntermediate) Write(packet conntypes.Packet, acks *conntyp
|
|||||||
if _, err := w.parent.Write(append(length[:], packet...)); err != nil {
|
if _, err := w.parent.Write(append(length[:], packet...)); err != nil {
|
||||||
return fmt.Errorf("cannot send packet: %w", err)
|
return fmt.Errorf("cannot send packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func (w *wrapperClientIntermediateSecure) Read(acks *conntypes.ConnectionAcks) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
length := len(data) - (len(data) % 4)
|
length := len(data) - (len(data) % 4)
|
||||||
|
|
||||||
return data[:length], nil
|
return data[:length], nil
|
||||||
@@ -30,6 +31,7 @@ func (w *wrapperClientIntermediateSecure) Write(packet conntypes.Packet, acks *c
|
|||||||
if _, err := w.parent.Write(packet); err != nil {
|
if _, err := w.parent.Write(packet); err != nil {
|
||||||
return fmt.Errorf("cannot send simpleacked packet: %w", err)
|
return fmt.Errorf("cannot send simpleacked packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,13 +39,14 @@ func (w *wrapperClientIntermediateSecure) Write(packet conntypes.Packet, acks *c
|
|||||||
paddingLength := rand.Intn(4)
|
paddingLength := rand.Intn(4)
|
||||||
buf.Grow(4 + len(packet) + paddingLength)
|
buf.Grow(4 + len(packet) + paddingLength)
|
||||||
|
|
||||||
binary.Write(&buf, binary.LittleEndian, uint32(len(packet)+paddingLength))
|
binary.Write(&buf, binary.LittleEndian, uint32(len(packet)+paddingLength)) // nolint: errcheck
|
||||||
buf.Write(packet)
|
buf.Write(packet)
|
||||||
buf.Write(make([]byte, paddingLength))
|
buf.Write(make([]byte, paddingLength))
|
||||||
|
|
||||||
if _, err := w.parent.Write(buf.Bytes()); err != nil {
|
if _, err := w.parent.Write(buf.Bytes()); err != nil {
|
||||||
return fmt.Errorf("cannot send packet: %w", err)
|
return fmt.Errorf("cannot send packet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type wrapperProxy struct {
|
type wrapperProxy struct {
|
||||||
flags rpc.ProxyRequestFlags
|
|
||||||
request *protocol.TelegramRequest
|
request *protocol.TelegramRequest
|
||||||
clientIPPort []byte
|
clientIPPort []byte
|
||||||
ourIPPort []byte
|
ourIPPort []byte
|
||||||
channelRead hub.ChannelReadCloser
|
channelRead hub.ChannelReadCloser
|
||||||
closeOnce sync.Once
|
closeOnce sync.Once
|
||||||
|
flags rpc.ProxyRequestFlags
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
|
func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.ConnectionAcks) error {
|
||||||
@@ -30,6 +30,7 @@ func (w *wrapperProxy) Write(packet conntypes.Packet, acks *conntypes.Connection
|
|||||||
if acks.Quick {
|
if acks.Quick {
|
||||||
flags |= rpc.ProxyRequestFlagsQuickAck
|
flags |= rpc.ProxyRequestFlagsQuickAck
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.HasPrefix(packet, rpc.ProxyRequestFlagsEncryptedPrefix[:]) {
|
if bytes.HasPrefix(packet, rpc.ProxyRequestFlagsEncryptedPrefix[:]) {
|
||||||
flags |= rpc.ProxyRequestFlagsEncrypted
|
flags |= rpc.ProxyRequestFlagsEncrypted
|
||||||
}
|
}
|
||||||
@@ -67,6 +68,7 @@ func (w *wrapperProxy) Close() error {
|
|||||||
w.channelRead.Close()
|
w.channelRead.Close()
|
||||||
hub.Registry.Unregister(w.request.ConnID)
|
hub.Registry.Unregister(w.request.ConnID)
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ func (w *wrapperBlockCipher) Write(p []byte) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return w.parent.Write(encrypted)
|
return w.parent.Write(encrypted)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,6 +36,7 @@ func (w *wrapperBlockCipher) WriteTimeout(p []byte, timeout time.Duration) (int,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return w.parent.WriteTimeout(encrypted, timeout)
|
return w.parent.WriteTimeout(encrypted, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +51,7 @@ func (w *wrapperBlockCipher) Read(p []byte) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("cannot read data: %w", err)
|
return 0, fmt.Errorf("cannot read data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBuffer = append(currentBuffer, rv...)
|
currentBuffer = append(currentBuffer, rv...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ func (w *wrapperConn) WriteTimeout(p []byte, timeout time.Duration) (int, error)
|
|||||||
func (w *wrapperConn) Write(p []byte) (int, error) {
|
func (w *wrapperConn) Write(p []byte) (int, error) {
|
||||||
n, err := w.parent.Write(p)
|
n, err := w.parent.Write(p)
|
||||||
w.logger.Debugw("write to stream", "bytes", n, "error", err)
|
w.logger.Debugw("write to stream", "bytes", n, "error", err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Close() // nolint: gosec
|
w.Close() // nolint: gosec
|
||||||
}
|
}
|
||||||
@@ -57,6 +58,7 @@ func (w *wrapperConn) ReadTimeout(p []byte, timeout time.Duration) (int, error)
|
|||||||
func (w *wrapperConn) Read(p []byte) (int, error) {
|
func (w *wrapperConn) Read(p []byte) (int, error) {
|
||||||
n, err := w.parent.Read(p)
|
n, err := w.parent.Read(p)
|
||||||
w.logger.Debugw("Read from stream", "bytes", n, "error", err)
|
w.logger.Debugw("Read from stream", "bytes", n, "error", err)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Close()
|
w.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/md5"
|
"crypto/md5" // nolint: gosec
|
||||||
"crypto/sha1"
|
"crypto/sha1" // nolint: gosec
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
@@ -61,13 +61,16 @@ func mtprotoDeriveKeys(purpose mtprotoCipherPurpose,
|
|||||||
|
|
||||||
clientIPv4 := mtprotoEmptyIP[:]
|
clientIPv4 := mtprotoEmptyIP[:]
|
||||||
serverIPv4 := mtprotoEmptyIP[:]
|
serverIPv4 := mtprotoEmptyIP[:]
|
||||||
|
|
||||||
if client.IP.To4() != nil {
|
if client.IP.To4() != nil {
|
||||||
clientIPv4 = utils.ReverseBytes(client.IP.To4())
|
clientIPv4 = utils.ReverseBytes(client.IP.To4())
|
||||||
serverIPv4 = utils.ReverseBytes(remote.IP.To4())
|
serverIPv4 = utils.ReverseBytes(remote.IP.To4())
|
||||||
}
|
}
|
||||||
|
|
||||||
message.Write(serverIPv4) // nolint: gosec
|
message.Write(serverIPv4) // nolint: gosec
|
||||||
|
|
||||||
var port [2]byte
|
var port [2]byte
|
||||||
|
|
||||||
binary.LittleEndian.PutUint16(port[:], uint16(client.Port))
|
binary.LittleEndian.PutUint16(port[:], uint16(client.Port))
|
||||||
message.Write(port[:]) // nolint: gosec
|
message.Write(port[:]) // nolint: gosec
|
||||||
|
|
||||||
@@ -90,6 +93,7 @@ func mtprotoDeriveKeys(purpose mtprotoCipherPurpose,
|
|||||||
message.Write(client.IP.To16()) // nolint: gosec
|
message.Write(client.IP.To16()) // nolint: gosec
|
||||||
message.Write(remote.IP.To16()) // nolint: gosec
|
message.Write(remote.IP.To16()) // nolint: gosec
|
||||||
}
|
}
|
||||||
|
|
||||||
message.Write(req.Nonce) // nolint: gosec
|
message.Write(req.Nonce) // nolint: gosec
|
||||||
|
|
||||||
data := message.Bytes()
|
data := message.Bytes()
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ func (w *wrapperObfuscated2) ReadTimeout(p []byte, timeout time.Duration) (int,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("cannot read stream ciphered data: %w", err)
|
return 0, fmt.Errorf("cannot read stream ciphered data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
w.decryptor.XORKeyStream(p, p[:n])
|
w.decryptor.XORKeyStream(p, p[:n])
|
||||||
|
|
||||||
return n, nil
|
return n, nil
|
||||||
@@ -32,6 +33,7 @@ func (w *wrapperObfuscated2) Read(p []byte) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.decryptor.XORKeyStream(p, p[:n])
|
w.decryptor.XORKeyStream(p, p[:n])
|
||||||
|
|
||||||
return n, nil
|
return n, nil
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ func NewTelegramStats(dc conntypes.DC, parent conntypes.StreamReadWriteCloser) c
|
|||||||
parent: parent,
|
parent: parent,
|
||||||
dc: dc,
|
dc: dc,
|
||||||
}
|
}
|
||||||
|
|
||||||
stats.Stats.TelegramConnected(dc, parent.RemoteAddr())
|
stats.Stats.TelegramConnected(dc, parent.RemoteAddr())
|
||||||
|
|
||||||
return conn
|
return conn
|
||||||
|
|||||||
Reference in New Issue
Block a user