FILE / ScuroNeko/mtg

wrappers/mtproto_intermediate_secure.go

Исходный файл и его история в репозитории.
FILE 71da117d941ccdabe8e37e3a9607d878df92d999
Files
mtg/wrappers/mtproto_intermediate_secure.go
T
2018-07-13 08:04:04 +03:00

75 lines
1.7 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
buf.Write(p)
buf.Write(make([]byte, paddingLength))
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,
},
}
}