package codec import ( "fmt" "github.com/go-faster/errors" "go.mau.fi/mautrix-telegram/pkg/gotd/bin" ) const ( // CodeAuthKeyNotFound means that specified auth key ID cannot be found by the DC. // Also, may be returned during key exchange. CodeAuthKeyNotFound = 404 // CodeWrongDC means that current DC is wrong. // Usually returned by server when key exchange sends wrong DC ID. CodeWrongDC = 444 // CodeTransportFlood means that too many transport connections are // established to the same IP in a too short lapse of time, or if any // of the container/service message limits are reached. CodeTransportFlood = 429 ) // ProtocolErr represents protocol level error. type ProtocolErr struct { Code int32 } func (p ProtocolErr) Error() string { switch p.Code { case CodeAuthKeyNotFound: return "auth key not found" case CodeTransportFlood: return "transport flood" case CodeWrongDC: return "wrong DC" default: return fmt.Sprintf("protocol error %d", p.Code) } } // Can be bigger that 1mb. // // See https://github.com/gotd/td/issues/412 // // See https://github.com/tdlib/td/blob/550ccc8d9bbbe9cff1dc618aef5764d2cbd2cd91/td/mtproto/TcpTransport.cpp#L53 const maxMessageSize = 1 << 24 // 16 MB func checkOutgoingMessage(b *bin.Buffer) error { length := b.Len() if length > maxMessageSize || length == 0 { return invalidMsgLenErr{n: length} } return nil } func checkAlign(b *bin.Buffer, n int) error { length := b.Len() if length%n != 0 { return alignedPayloadExpectedErr{expected: n} } return nil } func checkProtocolError(b *bin.Buffer) error { if b.Len() != bin.Word { return nil } code, err := b.Int32() if err != nil { return err } return &ProtocolErr{Code: -code} } type alignedPayloadExpectedErr struct { expected int } func (e alignedPayloadExpectedErr) Error() string { return fmt.Sprintf("payload is not aligned, expected align by %d", e.expected) } func (e alignedPayloadExpectedErr) Is(err error) bool { _, ok := err.(alignedPayloadExpectedErr) return ok } type invalidMsgLenErr struct { n int } func (e invalidMsgLenErr) Error() string { return fmt.Sprintf("invalid message length %d", e.n) } func (e invalidMsgLenErr) Is(err error) bool { _, ok := err.(invalidMsgLenErr) return ok } // ErrProtocolHeaderMismatch means that received protocol header // is mismatched with expected. var ErrProtocolHeaderMismatch = errors.New("protocol header mismatch")