FILE / ScuroNeko/mtg

_wrappers/mtproto_intermediate_secure.go

Исходный файл и его история в репозитории.
FILE 7827d1255a18a4196d54a7777a03c950117e210a
Files
mtg/_wrappers/mtproto_intermediate_secure.go
T
2019-09-04 10:19:01 +03:00

75 lines
1.9 KiB
Go

package wrappers
import (
"bytes"
"encoding/binary"
"math/rand"
"github.com/9seconds/mtg/mtproto"
)
// MTProtoIntermediateSecure is an extension of MTProtoIntermediate
// mode which supports random paddings (socalled 'secure mode' or
// 'dd-secrets').
type MTProtoIntermediateSecure struct {
MTProtoIntermediate
}
func (m *MTProtoIntermediateSecure) Read() ([]byte, error) {
data, err := m.MTProtoIntermediate.Read()
if err != nil {
return nil, err
}
length := len(data) - (len(data) % 4)
return data[:length], nil
}
func (m *MTProtoIntermediateSecure) Write(p []byte) (int, error) {
defer func() {
m.writeCounter++
}()
m.logger.Debugw("Write packet",
"simple_ack", m.opts.WriteHacks.SimpleAck,
"quick_ack", m.opts.WriteHacks.QuickAck,
"counter", m.writeCounter,
)
if m.opts.WriteHacks.SimpleAck {
return m.conn.Write(p)
}
buf := &bytes.Buffer{}
paddingLength := rand.Intn(4)
buf.Grow(4 + len(p) + paddingLength)
binary.Write(buf, binary.LittleEndian, uint32(len(p)+paddingLength)) // nolint: errcheck, gosec
buf.Write(p) // nolint: gosec
buf.Write(make([]byte, paddingLength)) // nolint: gosec
m.logger.Debugw("Write packet with padding",
"simple_ack", m.opts.WriteHacks.SimpleAck,
"quick_ack", m.opts.WriteHacks.QuickAck,
"counter", m.writeCounter,
"padding_length", paddingLength,
"length", len(p),
)
_, err := m.conn.Write(buf.Bytes())
return len(p), err
}
// NewMTProtoIntermediateSecure create new instance of
// MTProtoIntermediateSecure instance.
func NewMTProtoIntermediateSecure(conn StreamReadWriteCloser, opts *mtproto.ConnectionOpts) PacketReadWriteCloser {
return &MTProtoIntermediateSecure{
MTProtoIntermediate: MTProtoIntermediate{
conn: conn,
logger: conn.Logger().Named("mtproto-intermediate-secure"),
opts: opts,
},
}
}