mirror of
https://github.com/ScuroNeko/mtg.git
synced 2026-08-31 23:44:01 +03:00
FILE / ScuroNeko/mtg
proxy/middle.go
Исходный файл и его история в репозитории.
78 lines
1.9 KiB
Go
78 lines
1.9 KiB
Go
package proxy
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"sync"
|
|
|
|
"github.com/juju/errors"
|
|
|
|
"github.com/9seconds/mtg/client"
|
|
"github.com/9seconds/mtg/config"
|
|
"github.com/9seconds/mtg/mtproto"
|
|
"github.com/9seconds/mtg/telegram"
|
|
"github.com/9seconds/mtg/wrappers"
|
|
)
|
|
|
|
func NewProxyMiddle(conf *config.Config) *Proxy {
|
|
tg := telegram.NewMiddleTelegram(conf)
|
|
|
|
return &Proxy{
|
|
conf: conf,
|
|
acceptCallback: func(ctx context.Context, cancel context.CancelFunc, clientSocket net.Conn,
|
|
connID string, wait *sync.WaitGroup, conf *config.Config) error {
|
|
client, opts, err := client.MiddleInit(ctx, cancel, clientSocket, connID, conf)
|
|
if err != nil {
|
|
return errors.Annotate(err, "Cannot initialize client connection")
|
|
}
|
|
defer client.Close()
|
|
|
|
server, err := middleTelegramStream(ctx, cancel, opts, connID, tg)
|
|
if err != nil {
|
|
return errors.Annotate(err, "Cannot initialize telegram connection")
|
|
}
|
|
defer server.Close()
|
|
|
|
wait.Add(2)
|
|
|
|
go middlePipe(client, server, wait, &opts.ReadHacks)
|
|
go middlePipe(server, client, wait, &opts.WriteHacks)
|
|
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func middleTelegramStream(ctx context.Context, cancel context.CancelFunc, opts *mtproto.ConnectionOpts,
|
|
connID string, tg *telegram.MiddleTelegram) (wrappers.WrapPacketReadWriteCloser, error) {
|
|
streamConn, err := tg.Dial(connID, opts)
|
|
if err != nil {
|
|
return nil, errors.Annotate(err, "Cannot dial to Telegram")
|
|
}
|
|
streamConn = wrappers.NewCtx(ctx, cancel, streamConn)
|
|
|
|
packetConn, err := tg.Init(opts, streamConn)
|
|
if err != nil {
|
|
return nil, errors.Annotate(err, "Cannot handshake telegram")
|
|
}
|
|
|
|
return packetConn, nil
|
|
}
|
|
|
|
func middlePipe(src wrappers.WrapPacketReader, dst wrappers.WrapPacketWriter, wait *sync.WaitGroup, hacks *mtproto.Hacks) {
|
|
defer wait.Done()
|
|
|
|
for {
|
|
hacks.SimpleAck = false
|
|
hacks.QuickAck = false
|
|
|
|
packet, err := src.Read()
|
|
if err != nil {
|
|
return
|
|
}
|
|
if _, err = dst.Write(packet); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|