Как стать автором
Обновить

Критика протокола и оргподходов Telegram. Часть 1, техническая: опыт написания клиента с нуля — TL, MT

Perl *Ненормальное программирование *Анализ и проектирование систем *Сетевые технологии *API *
Всего голосов 187: ↑182 и ↓5 +177
Просмотры 53K
Комментарии 240

Комментарии 240

В коде Android-клиента вообще не нашлось парсера схемы (что вызывает вопросы к опенсорсности
В репозитории F-Droid проприетарные части кода удаляют перед сборкой и собирают клиент из исходников, следовательно, парсер таки должен быть.

Никто не утверждал, что оно не собирается. И наличие парсера отсюда никак не следует. Тезис в другом. Представьте, некто написал приложение на Си и выложил в качестве исходников некоего подмодуля вывод промежуточной стадии компилятора в ассемблер. Соберется ли оно? Да. Исходники открыты? Вроде бы тоже да, но те ли это исходники?..

Логично, но в F-Droid такое не должны принимать именно из-за проблем с тем, чтобы убедиться, что это те исходники. Поэтому, им и доверяют такие параноики, как я. Таким образом, либо их сборка официального клиента обходится без парсера, либо пишут свой, либо я совершенно напрасно о них так хорошо думаю, либо парсер таки есть в исходниках в виде исходников.
либо их сборка официального клиента обходится без парсера

А зачем бы ей в нём нуждаться? Выкладывают уже сгенерированный отдельно лежащим парсером код, например, компилятор его соберёт; разве F-Droid делает доскональный аудит кода, а уж тем более пишет за авторов не выложенные ими инструменты? Лично для меня звоночек — сообщения типа "исходники клиента на GitHub обновлены до версии ..." — почему разработка не ведется в самом гитхабе?..


Если парсер есть, следует ткнуть пальцем, где же он.

Насколько я слышал, Android выкладывают с задержкой для того чтоб форки не набирали излишней популярности

И что в форках плохого, спрашивается?

Потребителям, наверное, ничего. Для telegram — отсутствие контроля над ними.

А зачем им контроль над ними? Они этот выбор — опенсорс и возможность каждому написать свой клиент — выбрали еще в 2013. И подтвердили этой осенью свежей документацией. То бишь, им должно быть достаточно контроля над протоколом и сервером.

Надеюсь, не надо объяснять, почему это плохо?

Кому плохо?

(со)Обществу.

github.com:Telegram-FOSS-Team/Telegram-FOSS → TMessagesProj/jni/tgnet/MTProtoScheme.cpp

Парсера нет. В исходниках (это те, из которых собирается f-droid версия) лежит уже сгенерированный (или написанный вручную) .cpp файл + его .h.

+ дополнительный бонус, мы видим, как внутри TL может лежать JSON. %)
Самое поразительное это то, что у них при всём безумии подхода получается самый быстрый и удобный мессенджер с очень маленьким количеством багов силами крошечной по современным меркам команды.
И именно ето больше всего бесит хейтеров
Но переехать на TLS на уровне транспорта им бы не помешало.
НЛО прилетело и опубликовало эту надпись здесь

Прокси протокол не описан. Описан обфусцированный транспорт для нижнего уровня. Если вы про faketls, то это не TLS.

Выходит вообще дичь. Обернутый в псевдо-TLS MTProto, который является неумелым переизобертением TLS.

это не переизобретение. У него только одна цель — выглядеть как TLS на проводе (для маскировки). Т.к. одно дело если DPI видит поток байт ни на что не похожий (что подозрительно) и другое — валидный http/2 TLS.

Я про то что сам MTProto в чистом в виде без всяких прокси, это по сути попытка Николая сделать TLS. В посте ведь как раз об этом.

Ну как бы… Сейчас уже "всё интернет-сообщество" признало, что TCP+TLS1.2 не очень-то подходит для современных реалий (мобильные устройства, частые подключения-отключения, смена IP). Из за этого сделали TLS1.3 и HTTP/3 + QUIC на подходе.
Мессенджеры в этом плане первыми начали с такими проблемами сталкиваться. Делали бы telegram в 2019м — наверное сделали бы на TLS1.3 или QUIC (в статье же писали, что они UDP тоже пытались написать, но не осилили).

Необходимость UDP vs недостатки TCP и нужность QUIC и прочих поделок Гугла сильно преувеличена хайпом. Гугл здесь тоже изобретает велосипеды вместо SCTP, просто более качественные. Да и проистекает всё это в основном как подпорки других архитектурных проблем современного Веба.

Из того что я читал — основная проблема SCTP в том, что его не понимает сетевое оборудование (в отличие от TCP и UDP).


В разработке HTTP/3 + QUIC не только гугл участвует (Mozilla, Cloudflare, Netflix), видимо не у одного него есть к TCP + TLS претензии.

Он прекрасно оборачивается в UDP, так что эта проблема давно решена.


А эти участвуют по чуть другой причине — Google делает это всё сугубо для целей своего бизнеса, а не блага всея Интернета, т.е. если не вмешаться в процесс, можно проворонить что-нибудь плохое уже для своего бизнеса. Вот потому и участвуют.

Крошечная, это сколько? Очень маленькое количество багов, это сколько? Удобный, это как считали? Быстрый, это с чем сравнивали? Ну и наконец — а сколько времени эта «крошечная» команда ваяла этот примитивный засланец сообщений?

Если посчитать метрики, то окажется, что задачу для пятого класса детишки из института решали года два.
Крошечная, это сколько?

Два десятка челобит

Удобный, это как считали?

— Product-as-a-Platform, ЕВПОЧЯ.
— удобная однопальцевость
— отправка фоточек альбомами
— уникальные на момент запуска фичи типа секретных чатов, live location, каналов, и live preview
— поддержка прокси-серверов
Два десятка челобит

Откуда сведения?


— удобная однопальцевость

Нет. Несколько версий как на андроиде переделали контекстное меню, теперь приходится перемещать пальцы (у меня планшет).


— отправка фоточек альбомами
— уникальные на момент запуска фичи типа секретных чатов, live location, каналов, и live preview
— поддержка прокси-серверов

А вот и нет. На момент запуска из этого не было ничего. Каналы появились в 2015, альбомы вообще почти через 5 лет после запуска

Откуда сведения?

В прессе проскакивала инфа.

теперь приходится перемещать пальцы (у меня планшет).

На планшетах в принципе однопальцевость недостижима, а на телефонах она и не менялась.

На момент запуска из этого не было ничего

Не на момент запуска мессенджера, а на момент запуска фич. Они были первыми на рынке.
На планшетах в принципе однопальцевость недостижима, а на телефонах она и не менялась.

Достижима на некоторое определенное время (листание одного канала, например).


а на момент запуска фич. Они были первыми на рынке.

Чушь какая. Многое из этого было задолго до. Например информация о ссылке — боты в IRC делали это еще в досмартфонную эру.

Например информация о ссылке — боты в IRC делали это еще в досмартфонную эру.

Тут ключевое — в досмартфонную. В досмартфонную эру, эти ваши IRC, например, прошли мимо меня — ICQ и вебчатики были наше всё.
и вебчатики

Ну, тут можно только посочувствовать.

Чему посочувствовать? (: тепло, лампово, уютно. И как это сейчас говорится — трендовенько. зеро-клиент, и вот это всё.

Они же ведь убогие даже сейчас, когда Web 2.0 во все щели, а уж тогда-то...

Сейчас они давно мертвы — все ушли на мобилы.
А тогда это было очень удобно — порой на рабочую машину нельзя было ставить сторонний софт, флэшек еще не было, а на дискетах таскать неудобно. А «ослик ИЕ» — вот он, под рукой. В 4.0 появился XHR и стало еще более бодро: AJAX-чатики выигрывали у перегружаемых тупо UX-ом, и народ туда валил толпами.

Ну не знаю, я в те годы Миранду именно на дискетке по кафедрам таскал.

Не на момент запуска мессенджера, а на момент запуска фич. Они были первыми на рынке.

The OTR protocol was designed by cryptographers Ian Goldberg and Nikita Borisov and released on 26 October 2004.

Я OTR впиливал в свой мессенджер году в 2010-м. Чего-чего первыми они сделали?

Куда вы его впиливали? Первым массовым мессенджером в мобильном сегменте был WhatsApp.
А OTR — это шифровальный оверлей для семейства протоколов Jabber.
Куда вы его впиливали?

Вы не хотите знать, правда. Я вырос из коротких штанишек пиара своей недоподелки, теперь только свои скиллы пиарю.


А OTR — это шифровальный оверлей для семейства протоколов Jabber.

Orly? Я OTR-стримы гонял через вконтактик в том числе (очень смешно выглядела личка в вебне после этого). OTR вообще плевать на конкретный протокол.

Эта штука называлась Leechcraft, и я даже одно время её использовал. Комбайн аля старая опера.

Ну не комбайн же, модули же!

>> Два десятка челобит

Если, как пишет автор, только кривую копию TLS они 2 года ваяли, то…

Даже за 2 года — это уже 40 человеко-лет. Сорок!!! И на выходе что? Отправка и приём сообщений. Ну да, с рядом удобств, плюс на нескольких платформах. Но за минимум 40 человеко-лет!!!

Пусть 4 платформы (браузер, ведроид, ифон, сервер), пусть по 10 рыл на платформу. Три команды пишут строго одно и то-же, но с перламутровыми пуговицами. Итого — 10 человеко-лет на условную единую ведроид-софтину с весьма скромным функционалом. Или 10 человеко-лет на сервер, который реализует весьма простую очередь с асинхронным доступом. И это минимум. А скорее всего они лет 20-30 пилили свой сервер очередей.

За 10 человеко-лет можно винду переписать, плюс ещё браузер с блокнотами всякими до кучи. Правда без миллиона драйверов, понятно. И хотя такая эффективность не для больших контор, но 20-30 лет на просто сервер очередей — это ужас даже по меркам толстой конторы.

В общем — эффективность Дурова в плане разработки софта на весьма посредственном уровне. Когда бюджет лошадиный — тогда можно. Но был бы это стартап — однозначно раз в 10 могли бы время сократить, ведь стартапу никто бесконечных миллионов зеленью не отваливает.
Это эффективность всяких WhatsApp на весьма посредственном уровне. Что они там делают командами в 300 человек я без понятия.
Удобный, это как считали?


Я сравнивал Telegram с его ближайшими конкурентами — WhatsApp, Viber, Facebook Messsenger. В чем Telegram удобнее:

  1. Десктопный клиент. Он не самый лучший, если сравнивать с мультпротокольными Jabber-клиентами, но он хотя бы есть и не требует принудительно включенного телефона в той же сети
  2. Удобные группы и супергруппы с более-менее приемлемыми возможностями администрирования, не светящие при этом телефоны всех участников
  3. Боты с человеческим API и отсутствием странных лимитов


быстрый и удобный мессенджер

Это больше похоже на социальную сеть из которой убрали все кроме личных сообщений: каналы, стикеры, эможи, «постоянный онлайн», отсутствие нормального ростера/вкладок, привязка к телефону и пр. Ну и на уровне кода туда из vk утащили несколько кусков.
С пробуждением. Все эти мессенджеры «нового поколения» и есть социальные сети, упрощённые под управление со смартфонов. Они спят и видят, как повторяют успехи азиатских сетей, привязавших к себе пользователей по рукам и ногам их же собственными действиями.

Задаваться тут вопросом, зачем нужны привязка к телефону и доступ к контактам, — всё равно, что удивляться, что в тюрьме шнурки и ремни отбирают.
С пробуждением. Все эти мессенджеры «нового поколения» и есть социальные сети, упрощённые под управление со смартфонов

Да я и не спал. И не пользуюсь подобным софтом. просто до многих это не дошло еще…
каналы, стикеры, эможи, «постоянный онлайн»

С разморозочкой. Всё это есть сто лет как.

отсутствие нормального ростера/вкладок

Plus Messenger. Ростер не нужен — есть просто список активных чатов, сортированный по last updated
список активных чатов, сортированный по last updated

который пересортировывается пока ты пытаешься попасть в нужный чат пальцем
Может у вас просто слишком много чатов? Никогда такой проблемы не испытывал.

И в хроме у меня слишком много вкладок, я знаю.

Более сотни, а что? Это не от количества чатов зависит, а исключительно от активности в них — достаточно флуда всего в 3-4...

Как человек с пятью флудилками — несогласен )

Значит, у Вас не было потребности форвардить между ними, например, или долгое время не читать одну, но потом всё-таки желать всё это вычитать. "Потребности в колбасе нет"

Долгое время не читать — действительно не было, просто отписываюсь и все.

Ну вот есть у меня каналы, которые пишут не то чтоб часто, и у меня возникает настроение почитать данную тематику раз в несколько недель, допустим. Зачем мне от них отписываться и терять позицию прочтения, если потенциально все эти статьи будут мне интересны?..

Ростер не нужен — есть просто список активных чатов, сортированный по last updated

Это одна из самых отвратительных вещей, за которые их хочется убивать. Неоднократные промахивания "не в тот чат" из-за того, что они успели пересортироваться в этот момент. Что в сочетании с пометкой всего диалога прочитанным сразу (до сих пор на десктопе так!) вынуждает после этого брать его и читать. Ведь потом убежит же, не вспомнишь. Ну и постоянно искать в прокрутке в этом плоском списке.


Впрочем, это тема для второй части.

Сейчас они в оф клиенте это немного улучшили — добавили т.н. «архив», где можно прикрепить больше 5 чатов. Поэтому у меня все флудилки сразу уехали в архив, и им были закреплены постоянные места. Но все равно выглядит как костыль. Очень сильно не хватает ростера и групп…

На самом деле, там был задел на "папки" — но появилось всего 2 метода в folders.* т.е. клиент может пользоваться только готовыми предсозданными на сервере папками (на данный момент архив). Почему так недоделано, если вот уже почти было сделано правильно, непонятно.

В результате чего наверху флуд, а важное сообщение, отправленное ночью в личку — внизу? :)
Нет.

Ну как нет, регулярно с этим сталкиваюсь.

Хз, УМВР )

Сколько у Вас диалогов-то?

Регулярно — порядка 50, а так за всю историю — несколько сотен.

Видимо, Вам везет, у меня примерно такие же цифры.

Ну, в них не пишут одновременно как правило.

Кстати, я не могу утверждать наверняка, пишут или не пишут в мои. Это может быть и кривая работа апдейтов — на десктопе и андроиде задержка в обновлении одного и того же чата могла достигать минут.

Подтверждаю, лаги с доставкой сообщений с сервера легко доходили до минуты, когда то мои боты анализировали пампчаты, где команду 'на старт' давали сообщением (или картинкой) в чат (я то анализировал активность на рынке и сравнивал с чатом).

И этот лаг было фичей, чтобы разные люди заходили с разным временем старта. То что люди об этом не знали, никого не волновало.
С разморозочкой. Всё это есть сто лет как.

ну так я этим и не польззуюсь 100 лет, жду когда дурная мода пройдет и начнется новая, может она не такая дурная будет.

Ростер не нужен — есть просто список активных чатов, сортированный по last updated

Вот знаешь, хочется взять у*бать за такое. Мало того, что интерфейс не компактен и нет группировок, так еще и чаты скачут как бешеные козлы туда-сюда.
ну так я этим и не польззуюсь 100 лет, жду когда дурная мода пройдет и начнется новая, может она не такая дурная будет.

Ждите. Не пройдет, потому что выразительно и эмоционально.

Мало того, что интерфейс не компактен и нет группировок

Берете Plus Messenger — там есть группировки по типам: лички, группы, супергруппы, каналы, боты.
Спасибо, не надо. Сами в своих соц. сетях сидите

Ну да, из 200 диалогов поделим на 5, получим 40 — всё равно много.


Ждите. Не пройдет, потому что выразительно и эмоционально.

Мы надеемся, что пройдёт. Ибо выразительности там кот наплакал.

Вот да, такой терминальный, загробный Not Invented Here, но ведь мне самому продуктом пользоваться приятнее, чем любым аналогом. Когнитивный диссонанс.
силами крошечной по современным меркам команды

Силами оперативки моего мака десктопный клиент у них быстрый. Telegram — Memory: 4.59GB — вот что я вижу прямо сейчас. Да у меня Photoshop и Illustrator вместе взятые меньше памяти жрут. Что конкретно такого быстрого в этом вашем телеграмме по сравнению с iMessage, WhatsApp и Viber? Клиент WhatApp для мака, кстати говоря, занимает всего лишь 300mb оперативки на том же маке, с тем же количеством контактов и с б`ольшим количеством чатов.
Пользуюсь телегой только из-за того, что он выбран основным мессенджером на работе, а так давно бы от него избавился.
Есть необходимость пользоваться еще и Viber, WhatsApp, iMessage, так что не понятно что такое «самый быстрый и удобный»? Сравнивая мобильные приложения вообще не понятно о чем речь. На iOS у всех мессенджеров ± все одинаково. Если сравнивать десктопные клиенты — Telegram, в моем личном рейтинге, самый не удобный, самый забагованный, самый ресурсозатратный, самый тормознутый (из-за блокировок долго загружается, бывает что не присылает push-уведомления на телефон) и самый переоцененный.
Прям таки интересно стало, сколько у меня TG Desktop жрет. Под Windows диспетчер задач выдал вполне ожидаемые 118 мегабайт памяти. Под Linux немного веселее все оказалось. Попытка замерить память телеграма командой pmap выдало что-то в районе 3.5 гигабайт. Ирония в том, что другой скрипт, показывающий общую загрузку памяти мне отчитался о загрузке… 0.4 гигабайт занятой памяти. Я так и не понял, что он там считал, но возможно, что всю замапленную память, а не реально используемую. ps уже показал более реалистичную цифру — в районе 250 мегабайт.
Мака у меня, к сожалению, нет, но в правдивости цифры 4.6 гигабайт отожраной оперативки есть повод сомневаться.
Вот у меня на маке прямо сейчас
Да, клиент явно течёт. При длительном аптайме клиента в несколько дней сутки или недель реальная память растёт до гигабайта и больше, сжатая – несколько гигов, отчего система начинает свопаться.
В Linux измерить потребление памяти очень не просто. Я бы сказал не возможно.

Т.е. измерить потребление виртуальной памяти да, можно. Измерить RSS сейчас этого процесса можно.

Но это все погода и вектор )
> Telegram — Memory: 4.59GB — вот что я вижу прямо сейчас.
Если это та память, что в Unix системах зовётся VSZ, то это показатель тупо ни о чём: процесс может замапить себе всё, что найдёт в файловой системе, и показатель вырастет до петабайт (если процессор позволит), но ничего из этого не будет подгружено. VSZ это вроде самодекларированных «намерений» процесса использовать данный объём в наиболее крайнем случае.
Посчитайте RSS и сумму размеров dirty pages. Вот их уже можно сравнивать. (Я не знаю, почему dirty pages не включается в показ по всяким ps — на практике это даже более полезный показатель, чем RSS.)
Вот после нескольких дней аптайма клиента: жрёт 2,64 Гб физической + 6,25 Гб сжатой памяти. Это больше ядра и больше тяжёлой IDE с открытым проектом. Как я понимаю, сжатая память – это то что при возможности скидывается в своп. Ладно бы просто маппинг фалов, но больше похоже что кроме дискового кэша используется и кэш в памяти. Перезапуск клиента освобождает ресурсы, картинки при этом повторно не перекачиваются. Видимо, отсутствие оптимизации, а может баг.
скрин

Я тут по результатам другого треда таки поставил телегу на десктоп.


  1. Версия из исходников тянет штук двадцать лишних зависимостей. Неудобно. Ну да ладно, позволим себе поставить -bin, на один раз сойдёт.
  2. Требует телефон. Пришлось вспоминать пароль от sms-reg.com. Неудобно.
  3. Как-то подлагивает. По-видимому, когда пытается воспроизводить звук. По-видимому, потому, что у меня нет пульсаудио. Без багов, ага. И быстро.
  4. После джойна в чатик с сотней человек жрёт 200 мегабайт памяти. Быстро!
  5. Как сделать текст во всю ширину экрана, а не 300 пикселей, не нашёл. Удобно. У меня 3840 пикселей по горизонтали, из которых используется десятая часть, класс.
  6. Как настроить уведомления, ключевые слова для хайлайта, вот это всё. что ожидаешь от адекватного мессенджера, не нашёл. Удобно.

Потом ещё придирки были, но то уже мелочи.

Нужно понять, что телеграм это, в первую очередь, мобильный мессенджер. И его ближайшие конкуренты — это вайбер и вацап. Пункт два сразу же отпадает.
Пункты 3-4… А вы точно пользовались electron-based мессенджерами? Они и жрут больше и лагают тоже больше. Телега тут не первая, не последняя.
5-6 это вообще вкусовщина.
Почему это отпадает? Использую дискорд и матрикс с телефона без номера.

Телега не электрон, соответственно сравнивать надо с не-электроном.
Нужно понять, что телеграм это, в первую очередь, мобильный мессенджер. И его ближайшие конкуренты — это вайбер и вацап. Пункт два сразу же отпадает.

То есть, с десктопа им пользоваться никак? Какой же это тогда мессенджер для профессионального и тематического™ общения?


А вы точно пользовались electron-based мессенджерами?

Только дискордом на игровой машине с виндой, но я там никогда не смотрел на потребление памяти. Но он, э, игровой. Push-to-talk там, многопользовательские голосовые каналы, игровой оверлей. В телеге это всё есть?


5-6 это вообще вкусовщина.

Танковые смотровые щели вместо сообщений и всякое, нулевое отсутствие кастомизируемости и всего того, что ожидаешь от мессенджера с групповыми чатами — вкусовщина? Если это вкусовщина, то я не знаю, что не вкусовщина.

5-6 это вообще вкусовщина.

Ни раз нет. Это — эргономика. Попробуйте использовать на работе разработчиком, вот тогда поймёте и поплюетесь.

А какой мессенджер позволяет настроить ключевые слова для хайлайта?
IRC?
А из тех, которым реально пользуются?

IRC сейчас реально пользуются несколько сотен тысяч человек в мире, причем не простых негров или домохозяек, как в типичных мессенджерах, а технически продвинутых (например, официальные каналы кучи опенсорс-проектов на Freenode). Поэтому они гораздо весомее цифр других мессенджеров. Смотреть надо на другое — почему эти "современные, которыми пользуются", не могут сделать то, что было в старичке IRC.

Я рад за этих технически продвинутых, но тут я на стороне «простых негров и домохозяек». Если мессенджером никто из моих контактов не будет пользоваться, то для меня это бесполезное приложение.

А вопрос нужно ставить по-другому: не «не могут», а «не делают». Телеграм и WhatsApp — это мессенджеры для повседневного общения, а не для работы. Выделять ресурсы на внедрение функций, которыми будут пользоваться одна сотая аудитории, — очень сомнительное решение.

Тогда вам стоило бы сформулировать вопрос как «а из тех, которым реально пользуются мои контакты».


Потому что мои контакты не пользуются телеграмом или воцапом, например (потому что у меня нет тг или воцапа, и нет соответствующих контактов).


А настройка хайлайта — это одна из первых добавленных мной фич в самописный IM, потому что это на самом деле очень удобно и полезно, если вы тусуетесь в многопользовательских конференциях.

Почти любой IRC-клиент. Slack (что не удивительно, он вырастал из IRC и имел в него гейты). Discord, если склероз не изменяет...

А какой клиент? Их, гхм, несколько.
Если тот, который telegram-desktop, то он, ну, такой.

Он самый, да. Он разве не официальный?

Ну, он из тех, на которые стоит ссылка на официальном сайте, да.
Официальность у телеги понятие относительное, это скорее "рекомендуемый" клиент из разработок коммьюнити — десктоп у них явно на последнем месте в приоритетах.


Под линукс, если честно, даже не знаю, что нормальное посоветовать. Даже вебморда лучше этого.
Под мак есть TelegramSwift, который очень неплох.

Да как Вам сказать… Хуже вебморды у них клиента наверное нет. На маке я через пару месяцев не выдержал и поставил telegram-desktop в дополнение к родному. Да, так и пользовался двумя сразу — потому что множества фич и багов у них малопересекающиеся :/

Вебморда хотя бы не течет. :)


На маке есть overtake/TelegramSwift, который лучше telegram-desktop на порядок, зачем эти мучения?


Вот на линуксе, да, все сложно, но линукс у меня не основная десктоп-система, а для пары раз в месяц вебморда сойдет.

На линуксе тот же официальный десктопный клиент месяцами работает.

Судя по скриншотам, именно им я вроде бы и пользовался. Всех проблем сейчас не упомню, хреновая прокрутка стикеров была, вроде копипаста сообщений неудобная. Так вот и жил, Instant View в нём, стикеры из десктопа.

С копипастой проблем не вижу, может, версия старая была.
На стикеры мне как-то все равно :)

На счет количества человек в команде толком непонятно, но здесь можно взглянуть на презентацию telegram TON. в скринах презентации есть инфа, что помимо Павла работают еще 12 человек, 4 из которых призеры ACM ICPC(Николай был даже абсолютным чемпионом), а это самые престижные студентческие соревнования по спортивному программированию. Команда у них действительно очень сильная.
Как-то пробовал использовать штуки три готовых библиотеки (под разные языки), и ни одна сходу не заработала. Теперь понятно, почему.

А проверка на простоту — это вообще шедевр.
if (!strcasecmp(prime, goodPrime))

Я так понимаю это какое-то легаси число захардкодили, там дальше вроде идет нормальная проверка.

Легаси?.. Тогда бы уже выпилили, наверное? Да и статистику пособирать надо. Но вопросы возникают другие — то есть оно что, критериям этой проверки — не удовлетворяет?

то есть оно что, критериям этой проверки — не удовлетворяет?

удовлетворяет, просто захардкожено, чтобы бедная мобила не тратила много усилий на проверку is prime для него.

Ох-ох-ох! Может ну её, эту вторую часть? Я уже от первой устал материться!
Я даже и не представлял, что там настолько всё из говна и палок собрано! Аж расхотелось им пользоваться :(

О да.


Меня периодически просят впилить поддержку протокола телеги в один IM, который я попиливаю, и я всё откладывал, а теперь, ну, короче, это совсем какое-то бессмысленное занятие. Лучше на ring и matrix посмотрю.

Что-то еще забыл? Пишите в комментах.

Возможно не совсем в тему, но как пример из разряда «и так сойдет».

Http апи для ботов и tdlib (оно тоже умеет авторизоваться как бот из коробки, если кто не в курсе) используют разные диалекты markdown при парсинге сообщений.

Как хочет tdlib
**жирный**
__курсив__
~~зачеркнутый~~

Как хочет бот апи
*жирный*
_курсив_
зачеркнутый не умеет 

Одинаковый парсер для tdlib и для сервера не осилили. И как подсказывает подсветка хабра, что первый, что второй вариант не соответствуют общепринятым стандартам.
Еще 5 копеек про TDLib и опенсорц:

На днях обновилась приватная версия TDLib.
На GitHub странице клиента Unigram появились коммиты, благодаря которым известно, что библиотека уже поддерживает…

Ну, приватные версии у опенсорса ещё как бывают. Возьмите модель разработки nethack какого-нибудь. Да, мне тоже это кажется странным, но общественное мнение говорит, что это такой же полноправный опенсорс.

Сломал мозг на середине статьи. Авторам — респект, у вас железные нервы.

А вообще все пляски с кодом (плюс api ключи) похоже на обфускацию и вендер-лок для усложнения исследования кода и написания альтернативных клиентов (а может и серверов).

Проект альтернативного сервера на GitHub как-то видел. Вот только нужен ли он кому, если с основным оно федерацию не сможет?..

«В принципе, такое сгодится, если сделать один раз, но как это потом поддерживать при обновлениях?

Типичное „олимпийское“ программирование, IMHO. Видна рука мастера.
Спасибо за разбор!
Нет ли планов изучить блокчейн TON?
На первый взгляд там тоже есть «интересные» решения.

А там, на первый взгляд, всё примерно на тех же подходах. Особенно позабавил, видимо, тот же "восторг отрочества", когда ребята открыли для себя Forth и воодушевлённые этим фактом "написали" его специализированный эрзац Fift.

Это еще год потратить на попытки разобраться и писать свой клиент? :) Они ведь еще даже не запустились. Может оказаться, что их сама жизнь на практике, так сказать, сурово научит о применимости тех или иных подходов.

Вы смерти nuclight хотите? Я пока пролистал whitepaper TON, чуть монитор не разбил. Спецификация TL по сравнению с ним — стихи.

Лучшая статья за этот год, что я прочитал на швабре. Ребятки, пишите еще. Можно потом про matrix продолжить, например. В сравнении с…
к сожалению, его учетку на Хабре стёрли вместе с черновиком

Учетка нашлась, а вот черновики куда-то сгинули.

Я теперь понимаю, почему Дуров отказался отдавать ключи шифрования, аргументируя тем, что это технически невозможно)

А в этой истории вообще слишком много подозрительного.

Технически невозможно, ибо не смогли найти в дереве исходников? :-)

Ну ура, наконец-то кто-то раскопал эту глинищу. Уважение!


А результат трудов вы выложите в общий доступ? И чтобы не в виде предскомпилированного кода?)

Уже выложили. Просто правила Хабра вроде запрещают рекламу своих проектов...

В хабе «я пиарюсь» вроде можно же?

Часто можно видеть в подобных ситуациях, как автор в комментариях даёт такую ссылку. Вроде как не запрещено, просьбу дать ссылку поддерживаю.

Правила не запрещают ссылки на гитхаб.
Разработка ведётся открыто на гитхабе.
Спасибо за статью. Тут уже пишут, что мол. ведь работает же быстро и все такое. Ну а чему там не работать? Задача то простая, а все скользкие моменты, большинство которых появились из-за странных решений, переложены на клиентов. Лишняя нагрузка на сервер их не смущает, они просто поднимают тысячи и тысячи нод в облаках. И даже гордятся этим. Главный принцип, если тебе нужно 30млн на запуск, возьми миллиард и не парься.

Как-то я тоже в исходники сунулся, хотелось проникнуться, что пишут очень умные люди. Потом два дня плакал. Интрига в том, что они правда умные и в чем-то конкретном им разобраться легко. Но вот сделать просто и понятно им не круто, нужно чтобы «перло», до конца доводить им тоже не круто.

Эта элитарность растет от П. Дурова, который жуткий сноб. Он гордится своей ограничительной (вегетарианской) диетой, а также отказом от любых медицинских препаратов, что, по его мнению, возвышает над другими. Его кумир Джобс, который тоже весь элита и на диете, а еще менеджер, который умел презентовать статусность продукта вместо самого продукта. Т.е. эти вот «я не понял, что он сделал, но раз многократный чемпион ACM старательно трудился, значит это круто, об этом и поговорим». Еще он ссылается на Че, но идея свободы выражается в «отвалите от меня, я свободный человек».

Что такое айфон? Новая индустрия, выросшая из продукта, который по сути обычные смартфон и ноутбук, с отличным дизайном, странными костылями, головной болью разработчиков приложений и замкнутой экосистемой.
Так что, они будут пилить это год за годом, пока однажды у них не получится свой json over https. И работать с этим придется как с тем же hls, который, при внешней простоте, очень сложно балансируется на клиенте, а на сервере реализуется непонятно как и во всех случаях по разному.
Так что, они будут пилить это год за годом, пока однажды у них не получится свой json over https

Вы сейчас будете смеяться...


jsonObjectValue#c0de1bd9 key:string value:JSONValue = JSONObjectValue;

jsonNull#3f6d7b68 = JSONValue;
jsonBool#c7345e6a value:Bool = JSONValue;
jsonNumber#2be0dfa4 value:double = JSONValue;
jsonString#b71e767a value:string = JSONValue;
jsonArray#f7444763 value:Vector<JSONValue> = JSONValue;
jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;

Это уже в 91-й схеме.

Это вы в статье упоминаете про 'json over https', я на него и ссылаюсь. Получается, что вы предвидели даже их дальнейшие шаги. Когда им понадобилось что-то пересылать всерьез (payments), они прикручивают еще один слой, просто чтобы работало.

Меня беспокоит даже не качество продукта, который скоро будет везде, а его влияние на культуру разработки. Если apple повлияли главным образом на культуру среди пользователей, а ios осталась вещью в себе, с замкнутым циклом, то эти ребята нагло лезут со своим бардаком в общую тусовку, заявляя как надо делать и подкупая пафосом элитаризма. Через несколько лет мы будем с грустными лицами слушать молодых и активных про то, что это круто и как все классно изобретено. И ощущения будут как у прочитавших «Пикник на обочине», которым рассказывают про классную идею автора книги про сталкеров, сделанной по игре.
> заявляя как надо делать

Я вот не помню прямых подобных заявлений, как минимум. По-моему, вы обвиняете воображаемого оппонента, в том же комменте выше — не припомню, чтобы Павел писал, как вегетарианство «возвышает его над другими».
А может это возрастное. Посмотрим к чему со временем всё это причалит.
Но вот сделать просто и понятно им не круто, нужно чтобы «перло», до конца доводить им тоже не круто.

Сложилось ровно такое впечатление. Особенно про тот же TL — уау, мы крутые, мы пересказали в доках учебник статью из вики про завтипы и начали писать маленький кусок тайпчекера, но потом стало чо-т влом, давайте так хреначить, норм будет.

НЛО прилетело и опубликовало эту надпись здесь

А вот сырой JSON в схеме:


inputMediaInvoice#f4e096c3 flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:string provider_data:DataJSON start_param:string = InputMedia;

updateBotWebhookJSON#8317c0c3 data:DataJSON = Update;
updateBotWebhookJSONQuery#9b9240a6 query_id:long data:DataJSON timeout:int = Update;
help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;

dataJSON#7d748d04 data:string = DataJSON;

Используется например в payments.

nuclight ждем еще такой же разбор исходников TON, что-то мне кажется, что там будет еще хуже.

Олимпиадникам не нужен обфускатор — они сразу пишут обфусцированный код :)

(На правах параноика.) Давайте спросим себя, зачем нужен такой цирк из велосипедов и костылей уже на уровне протокола? Не для того ли, чтобы даже другие люди в команде, имеющие доступ к коду, не понимали до конца, как он работает, и тем более не могли отрефакторить? А не способ ли это скрыть масштабную закладку?
НЛО прилетело и опубликовало эту надпись здесь

По пунктам:


TL (Type Language) и его схема

Для разработки простого клиента не нужно досконально разбираться в TL. До появления флагов можно было вообще за один вечер написать генератор типов и RPC запросов. Когда появились флаги и стали добавляться сложные типы, то да, пришлось немного пореверсить и почитать код других парсеров TL.


если Ваша соль "протухла", то сообщение (запрос) — просто потеряется. Сервер, конечно, сообщит новую соль, выдав new_session_created — но со старым придется как-то делать перепосылку, например.

Ротация в криптографии — обычное дело. Сервер отправит BadMsgNotification типа bad_server_salt. Запоминать отправляемые сообщения — это обычная практика. «Как-то делать перепосылку» придётся и в случае обрыва TCP соединения.


Серверу разрешено вообще дропать сессии и отвечать таким образом по многим поводам.

Чаще всего, сервер возвращает RPC Error — включая случаи, когда он не может десериализовать сообщение. Если продолжение невозможно (из-за некорректных данных на транспортном уровне), тогда сервер возвращает 4х байтный код ошибки и, действительно, рвёт соединение.


С трудом, но можно представить себе какую-то пользу, если человек занимается отладкой, причем в интерактивном режиме — спросить у сервера, что да как. Но здесь описываются запросы в обе стороны.

Для секретных чатов используется вложенное соединение MTProto, защищённое end-to-end шифрованием. В таких случаях оба клиента могут отправлять друг-другу запросы (можно сказать, что протокол используется в режиме peer-to-peer).


И о пингах: <...> Да вы с ума сошли?! За 60 секунд поезд въедет на станцию… <...> есть алгоритм Нагла <...> дефолтное значение задержи — 200 миллисекунд. Если вам так уж хочется изобразить нечто похожее и сэкономить на возможной паре пакетов — ну отложите, накрайняк, на 5 секунд, или чему там сейчас равен таймаут сообщения "User is typing...". Но не больше.

Ну и зачем пользователям или серверу знать с точностью до 200 мс или 5 с, что пользователь ушёл в offline? Ну и в чём проблема того, что приложение на телефоне скажет ОС, что его нужно будить каждые 30/60 секунд (пробуждение в ряде случаев приводит к увеличению частоты CPU) и будет именно с таким интервалом сообщать серверу о своей работоспособности? Telegram запарился насчёт энергосбережения — ну и молодец.


Транспортный уровень. Нам расскажут аж про 5 вариантов

Никто не заствляет разработчиков поддерживать всё, что сервер. Можно реализовать только Abridged TCP и никаких проблем не будет.


У меня тоже есть опыт написания клиента с нуля. А потом — опыт переписывания клиента и написания (простого, на данный момент обеспечивающего только одиночные чаты) сервера (можно найти на github по словам telegram и qt; поддерживается только Linux).
На мой взгляд, при всех его проблемах, Telegram по прежнему является технически наиболее совершенным и продуманным протоколом. Это подтверждается, например, хорошей масштабируемостью — ни один другой IM не поддерживает групповые чаты на 200 000 пользователей. И даже на порядок меньшая планка в 20к участников чата является практически недостижимой.


Telegram вообще большие молодцы и почти всё делают максимально эффективно. Протокол становится лучше от схемы к схеме. Увы, каким-нибудь XMPP и Matrix (хотя сердцем я именно за них) до подобной эффективности ещё очень и очень далеко. Очень жаль, что к Telegram почти невозможно прикрутить федерализацию не растеряв всю эффективность.

В случае TCP, когда пингует сервер, в случае разрыва из-за сети очень часто приходит RST и сервер сразу узнает о проблеме. Так что пробы можно слать хоть раз в 5сек, а вот таймаут главное настроить больше максимального энергосберегающего цикла мобильных ос, чтобы клиент успел ответить. Тогда хоть и не во всех случаях, но об оффлайне узнаем максимально быстро, при пингах с клиента так не получится.

У Matrix все-же больше другая проблема — крайне тормознутая реализация. Когда сервер на go начили писать совсем другое дело стало, но фичи не все реализовали.
У Matrix все-же больше другая проблема — крайне тормознутая реализация. Когда сервер на go начили писать совсем другое дело стало, но фичи не все реализовали.

А как там с нужностью альтернативных реализаций? У меня руки чешутся на хаскеле что-нибудь этакое пописать.

Не вкурсе. Думаю это просто довольно сложно. Пока из альтернативных есть только Ruma (Rust) и Dendrite (go).
Для разработки простого клиента не нужно досконально разбираться в TL. До появления флагов можно было вообще за один вечер написать генератор типов и RPC запросов. Когда появились флаги и стали добавляться сложные типы, то да, пришлось немного пореверсить и почитать код других парсеров TL.

Пореверсить — это плохо. Обязана быть спецификация, по которой можно просто взять и сделать. В статье мысль о документации проносится не один раз. А TL простой тогда, когда всё понято и пишется конечный код; как уже упоминалось, в Teleperl парсер очень короткий вышел. Но сначала нужно продраться через всю эту ненужную (как в итоге оказывается) заумь. Тогда как в действительности хватило бы вон того подраздела в статье.


И да, если для флагов Вам "пришлось пореверсить" — это говорит, что Вы плохо знакомы с сетевымии протоколами. Как раз это место — очень простое, прием используется в 80-х, можно сказать, он интуитивно понятен. Правда, изобретен не Дуровым :)


Ротация в криптографии — обычное дело. Сервер отправит BadMsgNotification типа bad_server_salt.

Ротация — да. Терять при этом данные — нет.


Запоминать отправляемые сообщения — это обычная практика. «Как-то делать перепосылку» придётся и в случае обрыва TCP соединения.

Нет, это не является обычной практикой, уровень TCP плюс некоторые специальные вещи — единственные, где такая буферизация нормально. В прикладном коде такие слои городить нечего.


Чаще всего, сервер возвращает RPC Error — включая случаи, когда он не может десериализовать сообщение. Если продолжение невозможно (из-за некорректных данных на транспортном уровне), тогда сервер возвращает 4х байтный код ошибки и, действительно, рвёт соединение.

Да, спасибо, Кэп. Но речь была не об этом уровне, а выше — у нас нет гарантий, и если серверу ВНЕЗАПНО приспичило забыть сессию, то придется повторять наши сообщения.


Для секретных чатов используется вложенное соединение MTProto, защищённое end-to-end шифрованием. В таких случаях оба клиента могут отправлять друг-другу запросы (можно сказать, что протокол используется в режиме peer-to-peer).

Нет, это не соединение. Нет, нельзя так сказать. Я конечно понимаю, на что отсылка, но это кривое понимание и изложение — будь я преподом на экзамене, поставил бы 2.


Ну и зачем пользователям или серверу знать с точностью до 200 мс или 5 с, что пользователь ушёл в offline?

Неверное понимание работы TCP. Уйдёт он далеко не сразу, а когда сработают таймеры ретрансмитов. И речь в этом месте была о подтверждении получения, т.е. освобождении буферов противоположной стороны. Статус пользователя к ресурсам сервера имеет мало отношения.


Ну и в чём проблема того, что приложение на телефоне скажет ОС, что его нужно будить каждые 30/60 секунд (пробуждение в ряде случаев приводит к увеличению частоты CPU) и будет именно с таким интервалом сообщать серверу о своей работоспособности? Telegram запарился насчёт энергосбережения — ну и молодец.

Вы тут снова мешаете в кучу две разные вещи. Пинги — это вопрос онлайна, когда приложение живо, соединение активно и поддерживается. Если же нас сворачивают, значит пользователю это неактуально — наоборот, для энергосбережения надо сообщить серверу как можно раньше, что мы оффлайн, и он начнет оптимизировать очередь (UpatesCombined) сообщений, чтобы меньше на нас вывалить в следующий раз, да и ресурсы сервера расхода пооптимальнее.

Вот! Отличный ответ! Его-то я и ждал :)


Обязана быть спецификация

Знакомы с поговоркой «дарённому коню в зубы не смотрят»? В случае, если вы заказываете/оплачиваете разработку, вы можете выдвигать свои требования. Хоть спецификацию просить, хоть эталонную реализацию («хозяин — барин»).


Telegram LLC вправе сам решать, какие данные о своих разработках он будет (или не будет) публиковать.
Вся статья сквозит идеей о том, что Telegram кому-то чем-то обязаны. Вы ещё к WhatsApp и Facebook Messenger с такими требованиями обратитесь :).


Поймите меня правильно (хотя пока это не удаётся), за время разработки клиента я и сам столкнулся со множеством интересных моментов и могу очень долго рассказывать о проблемах в Telegram. Но перед этим нужно признать, что у Telegram получилось (на практике) лучше, чем у всех остальных. И за документацию, какой бы она ни была, и за открытый код клиентов — нужно в первую очередь сказать спасибо. И только после этого конструктивно (без характеристик, типа «наркомания») рассуждать о технических недостатках протокола. Если бы не Telegram, то в XMPP и Matrix было бы совсем скучно, потому что остальные (Facebook, WhatsApp, Viber и другие) далеко не настолько дружелюбны.


Продолжу по пунктам:


Ротация — да. Терять при этом данные — нет.

Клиент отправил заведомо недостоверные (с точки зрения аутентификации) данные (всё-равно, что накосячил с подписью). С чего бы серверу их сохранять? Сервер предоставляет возможность делать всё эффективно и правильно — можно даже запрашивать соль на несколько часов вперёд.


Нет, это не является обычной практикой, уровень TCP плюс некоторые специальные вещи — единственные, где такая буферизация нормально. В прикладном коде такие слои городить нечего.

В статье правильно написано, что необходимо сохранять, например, исходящие сообщения до получения подтверждения от сервера. Так что в реальном мире в прикладном коде приходится это всё городить, чтобы обеспечить лучший UX для пользователя.


Нет, это не соединение.

Нет, соединение. :-) Если хотите, можете посмотреть общепринятое значение слова «соединение» (только не нужно додумывать что-то, чтобы это опровергать). Я же не написал, например, «TCP соединение».


Нет, нельзя так сказать.

Вы не можете указывать, кому и как можно или нельзя говорить. Я считаю, что выразился достаточно понятно.


Неверное понимание работы TCP

Наверно это потому, что речь не о TCP.


речь в этом месте была о подтверждении получения, т.е. освобождении буферов противоположной стороны

Я процитировал абзац про ping_delay_disconnect с большим интервалом и написал комментарий именно к нему.


Если же нас сворачивают, значит пользователю это неактуально — наоборот, для энергосбережения надо сообщить серверу как можно раньше, что мы оффлайн

Да не хотим мы быть offline! Мы хотим быть online (получать сообщения сразу), но не тратить аккумулятор впустую.


P.S.: С вами трудно поддерживать конструктивный разговор. Пожалуйста, оставьте свои оценки (например — двойки) себе. Я считаю, что статья была бы значительно лучше, если бы техническая часть не была так перемешана с выплеском эмоций.


P.P.S.: При написании сервера я собрал ещё вторую порцию граблей и я тоже в восторге от документации. Вот пример:


https://core.telegram.org/api/optimisation#server-salt


At present, a single salt’s lifespan is 1 hour

https://core.telegram.org/mtproto/description#server-salt


{server salt is} periodically (say, every 24 hours) changed (separately for each session)

https://core.telegram.org/mtproto/service_messages#request-for-several-future-salts


a server salt is attached to the authorization key rather than being session-specific
Вся статья сквозит идеей о том, что Telegram кому-то чем-то обязаны.

Ну, если б не пошли в опенсорс — не были бы. А так, простите, какая-то голимая эзотерика. Претендуешь — соответствуй.

Я лично в недоумении — архитектура насквозь велосипедная. TLS+JSON — и погнали. И не нужно писать отдельный IDL (а TL фактически именно его функции выполняет).

Да не хотим мы быть offline! Мы хотим быть online (получать сообщения сразу), но не тратить аккумулятор впустую.

Это так не работает. Ты либо тратишь батарейку на поддержание wakelock-ов и keepalive-трафик, либо отваливаешься.

«Запрос соли у сервера» — вообще за гранью разумного.
архитектура насквозь велосипедная

Что есть — то есть. :) У Telegram куча своих велосипедов, зато ездят быстро.


Как выглядит подключение приложение после пробуждения в Telegram?
Клиент: сессия-123456-дай-диалоги
Сервер: ОК-первый-контакт-556-второй-738-третий-129-кстати-первый-это-вася, второй-дима, третий-саша,-от-васи-пять-непрочитанных-последнее-сообщение-ты-тут?-от-димы-...


То есть через сетевой пинг до сервера и обратно, буквально с первого пакета, Telegram готов отобразить начало списока диалогов со всеми данными и последними сообщениями. Разве что без аватарок (они обычно есть в кеше). Быстрее просто некуда и больше никто из IM так не умеет.


TLS

Достаточно быстрое и безопасное кеширование сессий появилось только в TLS 1.3. См, например, https://blog.cloudflare.com/introducing-0-rtt/


+JSON — и погнали.

Telegram экономят каждый байт трафика, так что на json они бы явно не согласились. Может CBOR бы подошёл.

Достаточно быстрое и безопасное кеширование сессий появилось только в TLS 1.3. См, например, blog.cloudflare.com/introducing-0-rtt

По опыту — это все равно занимает несколько секунд (Waiting for network… Connecting to proxy… Updating ...), если не пуш, а открываешь морду приложеньки. Так что — экономия на спичках.

Telegram экономят каждый байт трафика, так что на json они бы явно не согласились. Может CBOR бы подошёл.

Или BSON, но суть в другом — уже обкатанный стандарт.
Как выглядит подключение приложение после пробуждения в Telegram? Клиент: сессия-123456-дай-диалоги

А вот и нет. Первым после соединения чаще будет updates.getState или updates.getDifference, и это еще тоже как смотреть, совсем первым может быть например ping, который не жалко потерять, если вдруг случится bad_server_salt.


То есть через сетевой пинг до сервера и обратно, буквально с первого пакета, Telegram готов отобразить начало списока диалогов со всеми данными и последними сообщениями. Разве что без аватарок (они обычно есть в кеше). Быстрее просто некуда и больше никто из IM так не умеет.

А точно всех проверяли, чтоб вот так безапелляционно утверждать, будто никто больше до такой "гениальной идеи" не додумался? Давайте я NNTP из 80-х вспомню, где тоже можно этот список первым же запросом получить.


Telegram экономят каждый байт трафика, так что на json они бы явно не согласились. Может CBOR бы подошёл.

… а потом нивелируют это килобайтом padding? Впрочем, и без него TL совсем не оптимален по байтам, вот пост https://m.roem.ru/17-07-2013/115554/durov-ishchet-razrabotchikov-dlya-novogo-protokola-kommentariy-pavla/#comment-115125 еще аж от 2013 года, где человек сравниваниет и аналоги по сериализации, и дополнительная критика по криптографии, которой не было у меня.

Это так не работает. Ты либо тратишь батарейку на поддержание wakelock-ов и keepalive-трафик, либо отваливаешься.

Ну, у меня — работает на Sailfish OS. Настраиваю ping_with_disconnect на 45 секунд и пробуждение приложения на каждые 30 секунд.


https://git.merproject.org/mer-core/nemo-keepalive/blob/master/lib/backgroundactivity.h#L54

Ну, у меня — работает на Sailfish OS.

Мы щас про андроид так то )
Я, когда портировал Orchid — замечательно наелся, что девайс уходит в слип, и никакие write/flush на сокетах не работают. Так у меня развалился tor circuit. Пришлось костылить.
Мы щас про андроид так то )

Статья — про протокол Telegram. Я комментировал и продолжаю комментировать протокол. В частности — функцию ping_with_disconnect. Когда и как разговор стал про Android?

Когда начались разговоры про батарейку.
> Ну, если б не пошли в опенсорс — не были бы.

Ну вот в моем опенсорсном проекте нет ридми, нет доков и описания работы. Они есть, но лежат в моих личных/рабочих местах. А перенести в паблик с кодом — лень. Не обязан.
А перенести в паблик с кодом — лень. Не обязан.

Я обычно на такие репозитории трачу пару секунд времени и никогда не использую.
Поэтому в моих — обычно есть. Чтобы человек, который пришел — мог понять: что это, зачем, и как работает.
Я говорю, что вы обязаны тратить на них время? Тогда почему вы говорите, что их авторы обязаны что-то делать?
Есть такая штука — best practice.
Формально — никто не обязан.
Но после этого не удивляйтесь, если вам скажут, что ваш репозиторий — помойка.

Существуют разные причины опенсорсить код.


Например, я так делаю с собственными библиотеками, которые реюзаю для различных заказчиков — просто потому что "по умолчанию" заказчику передаются исключительные права на код. А так — вот, использовал open source библиотеку под BSDL, какая разница, кто ее автор?


В том, чтобы кто-то пришел и мог что-то легко понять, я и не заинтересован.

В том, чтобы кто-то пришел и мог что-то легко понять, я и не заинтересован.

А зачем тогда опенсорсить?
Опенсорс — это про поделиться знаниями.

На вопрос «зачем» я ответил абзацем выше процитированного вами.


И, нет, опенсорс не обязательно про поделиться знаниями. Это юридический инструмент, имеющий самые различные применения.

Юридический инструмент — это лицензия )
А опенсорс — именно что про поделиться.

Опенсорс — это и есть лицензирование ПО по определенным принципам. По определению.

Опенсорс — это прежде всего философия и этика. Которой должны соответствовать лицензии, позиционирующие себя как таковые.
Сам по себе опенсорс наличия лицензии не требует — я могу спокойно дать вам пачку своих исходников — и это будет опенсорс.

Нет, это не будет опенсорс: без лицензии у меня не будет тех самых четырех свобод, поскольку я буду ограничен действующим законодательством подавляющего большинства юрисдикций: по умолчанию все права принадлежат автору, пока он их не передал. Если я захочу распространять ваш код, я таким образом нарушу закон.


С этикой я не вижу никаких проблем: если кого-то тот код заинтересует, он может всегда сделать свой форк, задокументировать и так далее. Если меня попросит помочь разобраться — помогу по мере наличия времени. А просто так делать что-либо я не обязан, тем более что я очень сомневаюсь, что этот код вообще кому-то интересен :-)

Нет, это именно что инструмент: когда наступит идеальный мир и лицензии станут не нужны, сам опенсорс при этом останется


если кого-то тот код заинтересует, он может всегда сделать свой форк, задокументировать и так далее

Вы правда не понимаете, откуда здесь растет этика? Чтобы этот "кто-то" мог "сделать форк, задокументировать" и так далее, он должен потратить время не только на эти вещи, но и на то, чтобы разобраться — т.е. сначала понять, что было в голове автора. Это всё — затраты. При том, что у автора эта информация уже имеется, и для него это заняло бы меньше ресурсов. Перекладывание своей работы на других. короче, что и есть неэтично; причем по сути на неопределенный круг лиц:


  • "Как тебе спится, Джон, серийный программист?" (с) известная картинка с расчетами

Правда не понимаю.


У меня есть библиотека, которой люди действительно пользуются, там есть вводный readme, все покрыто тестами так, что они прекрасно выполняют роль документации, даже запилил по реквестам в github issues пару фич, которые мне самому не особо и нужны были, но из соображений полноты архитектуры они там очень даже уместны.


А рядом лежат куски сомнительного кода, которые вряд ли нужны кому-то кроме меня, никто ни разу не интересовался, зачем мне на это тратить свое время? Я вроде никому ничего не должен.


Первое и второе — это разный опенсорс, для разных целей: первое — чтобы поделиться, второе — просто для упрощения моей жизни (намного проще брать собственный BSDL-код, чем объяснять заказчикам, почему на "вот это вот" исключительные права не передаются, и прописывать исключения в договор).

Ах, ну хотя бы тесты. Они вполне себе частичная замена документации.

Из меня фиговый писатель, мне проще кодом показать. :)

У меня на гитхабе больше всего звездочек у проекта с околонулевой документацией, тестами и всем таким. А начинал я его, чтобы учиться.

Ну, значит напрашиваетесь на общественное порицание и реакцию "не буду даже разбираться, что это вообще такое, если автор ведет себя так неэтично, вряд ли там будет что-то хорошее".

> Ну, значит напрашиваетесь на общественное порицание

Если у вас много лишнего времени для доказательств как весь опенсорс обязан «обществу», то не для всех в обществе это так.

В обществе хватает отсталых элементов, что есть, то есть, да.

«Адекватный» ответ, ничего не скажешь. Дальнейшая дискуссия с вами действительно бессмысленна.

И в самом деле, бессмысленно: вот этот https://habr.com/ru/post/472970/#comment_20814008 человек ведет дискуссию более адекватно.

(ответ выходит по тематике 2 части, зачем-то лезете вперёд)


В случае, если вы заказываете/оплачиваете разработку, вы можете выдвигать свои требования. Хоть спецификацию просить, хоть эталонную реализацию («хозяин — барин»).

Есть принятые в среде профессионалов и других участвующих в развитии Интернета нормы. Например, публикации RFC. И требование определенного уровня к оформлению оных.


Telegram LLC вправе сам решать, какие данные о своих разработках он будет (или не будет) публиковать.

А мы вправе сами решать, называть ли коричневую субстанцию фекалями.


Вся статья сквозит идеей о том, что Telegram кому-то чем-то обязаны. Знакомы с поговоркой «дарённому коню в зубы не смотрят»?

А с чего это Вы собственно решили, что не обязаны? Знакомы с поговоркой "Со свиным рылом да в калашный ряд"? Или, знакомы с понятием "общественный договор"? Человек (и контора) очень много чего обязан, начиная от безусловных вещей, типа уголовного кодекса, и заканчивая обусловленными областью деятельности. Например, я никому не обязан уметь рисовать, как Пикассо, или петь, как Шаляпин — но если я попытаюсь выдать себя за певца или художника, со мной вполне могут поступить очень неприятным образом, как с Остапом Бендером и Кисой Воробьяниновым в так и не успевшей стать столицей мира деревне. Улавливаете?


Вы ещё к WhatsApp и Facebook Messenger с такими требованиями обратитесь :)

Что-нибудь слышали о громадных антимонопольных штрафах, которые накладывали сначала на Microsoft, потом на Google? То, что большая бюрократическая машина тормозит, еще не означает, что эти ребята всё делают правильно и с них нельзя потребовать


Поймите меня правильно (хотя пока это не удаётся), за время разработки клиента я и сам столкнулся со множеством интересных моментов и могу очень долго рассказывать о проблемах в Telegram. Но перед этим нужно признать, что у Telegram получилось (на практике) лучше, чем у всех остальных.

Лучше остальных? Это напоминает анекдот "мне не надо бежать быстрее медведя, мне надо бежать быстрее тебя", примерно как сказать, что лето в Москве лучше Мурманска (даже позагорать можно).


А с чем сравнивали-то, что вот ну "прям точно лучше всех остальных"? Кругозор-то невелик, похоже? Кто эти остальные? Не считать же таковыми всё это мобильное хипстерское говно последнего десятилетия, типа WhatsApp, Viber, Facebook ?


Я к Telegram отношусь так — этот "йогурт с пониженным содержанием говна", настолько, что им уже хоть как-то стало можно пользоваться. То, что индустрия скатилась куда-то в жопу, и у конкурентов на двойку, не делает телегу на пятерку — так, три с плюсом. По второй части опишу и интерфейсные претензии, например, не только протокольные (в отличие от протокола, их хоть попытаюсь исправить в своем клиенте).


И за документацию, какой бы она ни была, и за открытый код клиентов — нужно в первую очередь сказать спасибо.

И только после этого конструктивно (без характеристик, типа «наркомания») рассуждать о технических недостатках протокола. Если бы не Telegram, то в XMPP и Matrix было бы совсем скучно, потому что остальные (Facebook, WhatsApp, Viber и другие) далеко не настолько дружелюбны.
P.S.: С вами трудно поддерживать конструктивный разговор. Пожалуйста, оставьте свои оценки (например — двойки) себе. Я считаю, что статья была бы значительно лучше, если бы техническая часть не была так перемешана с выплеском эмоций.

Вот еще один из принципиальных моментов, на материал для 2 части. Ваше понимание понятия "конструктивно", похоже, отличается от общепринятого. Что это такое, "конструктивно", молчать в тряпочку и гладить по головке? Дайте свое определение.


Для меня конструктивно — это помогающе людям делать полезное дело, противоположность — наоборот, им мешающее. Так вот, я имею опыт и время, потраченное на реализацию этого кадавра, больше года, если вместе с товарищем — и имею как достаточный опыт за плечами в сетевых протоколах вообще, так и могу сравнить с чем-то другим — например, разобраться с JSON API ВКонтакте (совершенно новой для меня тогда теме), потребовало где-то недели полторы чистых. Соответственно, явственно видно, что Телеграм-команда мешает людям реализовывать свои API эффективно, то есть, они делают людям плохо, а следовательно, их надо наказывать за это, безжалостно и беспощадно. Чтоб неповадно было. "Как тебе спится, Джон, серийный программист?" (с) видели такую картинку?


И да, поскольку я убил на них дохрена времени, то имею полное право и выплеснуть эмоции за этот год — тем более, когда объективно действительно дело именно так и обстоит, и оценка "наркомания" правомерна. Король-то голый.


Кроме того, в статье содержится и, между прочим, энное количество полезной информации для тех, кто попытается работать с этим протоколом — в том числе, описаний и объяснений, сделанных мною за них. Хотя строго говоря, раз "критика", то не обязан был, хехе.


P.S. Я, как любитель психологии и диагнозов по юзерпикам, по такой форме изложения тем "я не обязан" и неприятия темы оценок, детектирую истероидную акцентуацию. И в следующем комменте, с садистской ухмылкой, пожалуй стану давить еще сильнее — чем более выпукло обнажать неадекват, тем тоже лучше для лечения.

> И да, поскольку я убил на них дохрена времени, то имею полное право и выплеснуть эмоции за этот год

Вот. Эмоции. Это то, что преобладает в вашем тексте.
Возможно, вам стоит поостыть, перестать давиться кактусом на некоторое время (вас же никто не заставлял реимплементить опенсорснутую разработку частной коммерческой компании?), и взглянуть на это более взвешенно.

Да, внутри все плохо. Да, реимплементация тяжелая.
Но сам продукт работает отлично, а большего вам никто не обещал. Вы же продолжаете писать, как будто в этом коде вам обещали божью истину, а дали коричневую жижу.

И снова темы для второй части поднимаются...


Вот. Эмоции. Это то, что преобладает в вашем тексте.

Нет. Преобладает технический разбор.


вас же никто не заставлял реимплементить опенсорснутую разработку частной коммерческой компании

Эм, знаете, вообще-то заставляют. Юридически — не особо, а по факту — очень даже. А именно, у меня отнимают контроль над моими же данными. Последней каплей стало введение в марте удаления чужих сообщений за любой срок.


Но сам продукт работает отлично,

Неправда. Постоянно проблемы с непрочитанными сообщениями, например — и тикеты про это висят годами.


Вы же продолжаете писать, как будто в этом коде вам обещали божью истину

Ну дык посмотрите хоть на пиар TON в этом же месяце. Примерно так и есть, и я расцениваю это как обман. Которому нужно противостоять.

явственно видно, что Телеграм-команда мешает людям реализовывать свои API эффективно, то есть, они делают людям плохо, а следовательно, их надо наказывать за это, безжалостно и беспощадно

в следующем комменте, с садистской ухмылкой, пожалуй стану давить еще сильнее

чем более выпукло обнажать неадекват, тем тоже лучше для лечения.

Не могу не признать, что вам удалось достаточно выпукло обнажить неадекват.


Вы не сообщили мне ничего нового, интересного или полезного. Похоже, что и я не смог вам ничего объяснить. Я бы продолжил разговор, если бы вы соблюдали «принятые в среде профессионалов» нормы поведения (например — не переходили на личности), но в данном случае считаю продолжение беседы бессмысленным и нецелесообразным.

Понимаете ли, психология такая штука, в которой переход на личности неизбежен. Если Вы исходите из инфантильной позиции "никто никому ничего не должен и не обязан, делаю что хочу, выкладываю как хочу, говорите мне спасибо уже за это (вон Telegram так делает, берите пример)" — она идеологически застилает Вам глаза и мешает объективно, честно и непредвзято обсуждать технические решения и сравнивать их. Поэтому этично Вам на неё указать, чтоб Вы могли осознать свою ошибку и исправиться.


Ведь, что характерно, своего определения "конструктивно", либо возражения на моё определение, мы так и не услышали — не считать же таковым эгоистичное детское "сообщить мне нового, интересного или полезного" вместо пользы для всего сообщества.

А можно с вами обоими не согласиться?


Они имеют право выкладывать произвольный трэш в паблик (покуда это лицензии не нарушает, но там тоже вопрос интересный). А вы имеете право произвольным образом про это отзываться. Всё.

Это полное равенство — кажущееся. Задумайтесь, например, о причинах существования такой штуки, как, скажем, "Закон о защите прав потребителей" или сертификации продукции — ведь в "чистой" версии этой логики, производители имели бы право производить любой трэш, а покупатели имели бы право голосовать рублём (не покупать) и оставлять любые отзывы.


Просто IT-отрасль еще молодая и дикая, даже до этической стороны еще не все понимают, а уж до юридической части тем более еще не дошло.

Я во многом согласен с технической частью статьи. Вы (утверждаете, что) написали клиент, я же настолько намучился с реверсом и с официальным сервером Telegram, что написал как клиент, так и свой (простой) сервер.
Я не привожу ссылку, потому что считаю неуместным рекламировать (а многие сочтут ссылку именно так) свой клиент и сервер в комментариях к чужой статье. Кому нужно — без проблем могут найти на github. Кому не нужно — спокойно пройдут мимо.


Вместо того, чтобы обмениться опытом, вы пытаетесь ставить мне двойки и предполагать, что у меня «кругозор не велик». Я мог бы вам помочь. Мой сервер мог бы упростить вам разработку. Вместо этого вы хотите «с садистской ухмылкой давить еще сильнее».
Ну и флаг вам в руки. :)

А где обмен опытом? Мы не видим пока что не только статьи, но даже и комментария с таковым. И кстати, непонятно, как бы мог помочь "упростить разработку" написанный вами сервер, ведь он наверняка будет отличаться от их сервера, во всяких недореверсенных (а это неизбежно в сложный проектах) вещах?..


Вы (утверждаете, что) написали клиент

Библиотеку, которая умеет делать любые запросы, получать апдейты и делать пару несложных действий. Полноценный клиент же еще, можно сказать, в самом начале.

Я не привожу ссылку, потому что считаю неуместным рекламировать

А вот жаль.
Я как-то искал реализации Telegram-сервера, нашел только какую-то заброшку на Java.
начиная с этого места дальше читать совсем не интересно стало… со свиным рылом, гавно, мне должны… пф…

Продолжаем техническую часть.


Ротация — да. Терять при этом данные — нет.


Клиент отправил заведомо недостоверные (с точки зрения аутентификации) данные (всё-равно, что накосячил с подписью). С чего бы серверу их сохранять? Сервер предоставляет возможность делать всё эффективно и правильно — можно даже запрашивать соль на несколько часов вперёд.

С чего это вдруг недостоверные? Расшифровались по ключу правильно, хэш сошелся. Криптографическое обоснование предоставить не затруднит? Тем более, что если у нас сессии не было несколько дней (ну в поход ушли, мало ли), то ситуация плохой соли неизбежна — ведь её нельзя запросить "на следующий раз", а не далее некоторого интервала.


Более того, соль по определению — то, что кладется рядом в открытом виде. То, что Коленька Дуров положил её внутрь и использует вот эдак, еще не делает её таковой — более корректное назначение у таких полей называется nonce. Откуда немедленно возникают вопросы:


  1. Почему бы не менять это поле в каждом пакете? Еще безопаснее будет же.
  2. Почему вообще клиенту соль назначает сервер? Какой в этом криптографический смысл?

А разгадка одна — не осилили нормально ни Perfect Forward Secrecy, ни сеансовые ключи — костыль, то бишь.


Нет, это не является обычной практикой, уровень TCP плюс некоторые специальные вещи — единственные, где такая буферизация нормально. В прикладном коде такие слои городить нечего.
В статье правильно написано, что необходимо сохранять, например, исходящие сообщения до получения подтверждения от сервера.

Э, нет. Неправильная расстановка акцентов. В статье написано не что необходимо, а что приходится. Из-за костылей. И даже описано, как можно было бы упростить.


Так что в реальном мире в прикладном коде приходится это всё городить, чтобы обеспечить лучший UX для пользователя.

Ничего подобного. В лучшем случае (нормальном мире) эти две вещи никак не связаны, в плохом случае (реальности) такая реализация наоборот, ухудшает UX (той же задержкой на новую соль).


Нет, это не соединение.


Нет, соединение. :-) Если хотите, можете посмотреть общепринятое значение слова «соединение» (только не нужно додумывать что-то, чтобы это опровергать). Я же не написал, например, «TCP соединение».

Мы вообще-то на техническом ресурсе, и такие вольности "я имел в виду неопределенно-размытое чо попало с любыми ассоциациями на это слово" здесь недопустимы.


Нет, нельзя так сказать.


Вы не можете указывать, кому и как можно или нельзя говорить.

Диалог получается вида:


  • Так, скажем, что "паровоз" — это животное, которое мяукает и ловит мышей
  • Нельзя так говорить вообще-то
  • Вы не можете никому указывать, как можно или нельзя говорить!!!!111

Ну, об этом неадеквате я уже сказал в соседнем комменте.


Я считаю, что выразился достаточно понятно.
Неверное понимание работы TCP
Наверно это потому, что речь не о TCP.
речь в этом месте была о подтверждении получения, т.е. освобождении буферов противоположной стороны
Я процитировал абзац про ping_delay_disconnect с большим интервалом и написал комментарий именно к нему.

Мы на техническом ресурсе, и должны. во-первых, использовать термины четко и строго, во-вторых, смотреть на вещи системно, т.е. в их связи с остальными. Выдергивая лишь отдельные места и вольно трактуя понятия, у Вас в голове сложилась искаженная картина, которая приводит к неверным результатам. Попробуйте перечитать внимательно соответствующее место в статье, и пояснения от других людей в соседних комментариях.


Если же нас сворачивают, значит пользователю это неактуально — наоборот, для энергосбережения надо сообщить серверу как можно раньше, что мы оффлайн


Да не хотим мы быть offline! Мы хотим быть online (получать сообщения сразу), но не тратить аккумулятор впустую.

ДА НЕ БЫВАЕТ ТАК. Компьютерные сети так не работают. Кроме того, смешение понятий — пользовательский статус (видимый собеседнику) online и живость TCP-соединения. Их удобно соединить для оптимизации ровно в одном случае — сообщении со смыслом disconnect, которое выставит в оффлайн и то и другое.


a server salt is attached to the authorization key rather than being session-specific

Это было в статье, невнимательно читали. И процитированные циферки времени жизни соли в документации — тоже отличаются от реальных.

«Знакомы с поговоркой «дарённому коню в зубы не смотрят»?»

Гхм, а каким боком здесь эта поговорка? Разговор о том, что «конь» мягко говоря кривоват. Приведен технический анализ конкретных проблем. А уж даром он, или не даром — это вопрос не технический, а вопрос бизнеса.

Если оставить эти аллегории, и перейти к сути, то на рынке соревнуется куча бесплатных менеджеров. Каждый рекламирует свои преимущества. Телеграм рекламируется владельцами как супер открытый. Кроме того, в рекламе делается упор на то, что он написан супер-мега-профи.
Как видно из статьи, оба тезиса несколько спорны.
Спасибо автору за прекрасный разбор.
А вы эти свои рассуждения насчет «дареного коня» направляйте непосредственно Павлу. Когда он в очередной раз начнет критиковать конкурентов, а вы ему так, и шпилечку, про коня. Мол чего кивать, все ж бесплатно, да?
Если человек выкладывает 20к строк лапши ( официальный mtproxy, например, github.com/TelegramMessenger/MTProxy/blob/master/mtproto/mtproto-proxy.c ) с кучей хардкода и магии, без единой строчки хоть какой-нибудь документации, то за что спасибо? За то, что не пришлось дизассемблировать, чтобы посмотреть, что внутри?

Я когда дописывал Erlang реализацию mtproto proxy часто туда заглядывал. Без него было бы на порядок сложнее, так что спасибо, да

В JS прокси только один протокол реализован (нет randomized протокола, нет fake-TLS), нет мультиплексирования, он подключается к серверам предназначенным для подключения telegram клиентов, а не прокси-серверов (т.е. не работают promoted channels). Несрванимые вещи...

Также нет статистики и остальных плюшек использования официального прокси-протокола с смс и регистрацией, но свою задачу решает. Padded intermediate очень легко допиливается.

Вот насколько пока Василий с этим поковырялся, к этим вторичным прокси-серверам возникает ряд вопрос. Я им не доверяю.

Telegram LLC вправе сам решать, какие данные о своих разработках он будет (или не будет) публиковать.

Это скорее вопрос этики. Facebook и WhatsApp не позиционируют себя как открытых, а на сайте телеги это преимущество прям в первой строчке.


Если бы не Telegram, то в XMPP и Matrix было бы совсем скучно, потому что остальные (Facebook, WhatsApp, Viber и другие) далеко не настолько дружелюбны.

Какая-то непонятная мне логика. Причём остальные к XMPP и Matrix?

У меня тоже есть опыт написания клиента с нуля. А потом — опыт переписывания клиента и написания (простого, на данный момент обеспечивающего только одиночные чаты) сервера (можно найти на github по словам telegram и qt; поддерживается только Linux).

Давали бы ссылку сразу; хотя почему только Linux, если уж Qt...


На мой взгляд, при всех его проблемах, Telegram по прежнему является технически наиболее совершенным и продуманным протоколом. Это подтверждается, например, хорошей масштабируемостью — ни один другой IM не поддерживает групповые чаты на 200 000 пользователей. И даже на порядок меньшая планка в 20к участников чата является практически недостижимой.

Не является. Ребята из psyced и на миллион делали; в NNTP такого ограничения вообще нет.


Telegram вообще большие молодцы и почти всё делают максимально эффективно.

Не всё, и в статье как раз и рассказывается, где и как.


Протокол становится лучше от схемы к схеме.

Протокол у них менялся раза полтора — на 2.0 да мелочи типа обфускации MTProxy.


Увы, каким-нибудь XMPP и Matrix (хотя сердцем я именно за них) до подобной эффективности ещё очень и очень далеко. Очень жаль, что к Telegram почти невозможно прикрутить федерализацию не растеряв всю эффективность.

Федерация к эффективности никаким боком.

Давали бы ссылку сразу; хотя почему только Linux, если уж Qt...

Под другие ОС может быть сложно собрать ввиду кривых или отсутствующих системных пакетных менеджеров и необходимости зависимостей.

Это подтверждается, например, хорошей масштабируемостью — ни один другой IM не поддерживает групповые чаты на 200 000 пользователей. И даже на порядок меньшая планка в 20к участников чата является практически недостижимой.


В 2011 году я для tigase (XMPP/Jabber на Java кстати) с commet (HTTP, тогда не было еще web socket) делал proof of concept на больше миллиона активных соединений, с пиковой нагрузкой до 10 миллионов на ноду: catap.ru/blog/2011/12/19/over-1m-open-sockets-linux-node

Latency на нескольких миллионах (простите, не помню сколько, 4-5 или что-то такое) было в районе 200-300 ms.

Сейчас железо стало куда более масштабным, и такое уже не удивляет как бы.

В общем я не вижу какой-то rocket science в том что они делают ;)

Я говорю о большом количестве пользователей в одном групповом чате (в одной комнате, если говорить в терминах XMPP), а не просто на сервере.


Например, вот тут пишут, что 10k на комнату не заработало:
https://stackoverflow.com/questions/41748148/what-is-the-max-number-of-users-per-room-on-ejabberd


Даже в редакции от 2019-05-15, XEP-0045: Multi-User Chat говорит о том, что:


the service MUST then return the full member list to the admin

https://xmpp.org/extensions/xep-0045.html#modifymember


Многие места в протоколе XMPP не рассчитаны на огромное количество пользователей и приводят к большой нагрузке на сервер. Например, в Telegram сообщение из mega-группы (на усмотрение сервера; практически всегда) приходит сразу с информацией как о чате (на случай, если он не был загружен вместе со списком недавних диалогов), так и о контакте-отправителе сообщения. Это позволяет клиенту сразу отображать новое сообщение без дополнительных задержек и лишней нагрузки на сервер. Разве XMPP позволяет серверу «просто так» или вместе с сообщением передать клиенту информацию об отправителе?


В общем я не вижу какой-то rocket science в том что они делают ;)

Решение использовать ленивую загрузку списка участников чата и упреждающее включение информации (об отправителе и чате; first/last name, avatar, online status и т.д.) в сообщение сервера о новом сообщение — является простым и эффективным.
Rocket science я бы это не назвал, но, например, Matrix так не делает (клиент вынужден отдельным запросом получать информацию об отправителе). Используя пример Telegram, разработчики могут оптимизировать протокол Matrix и это здорово!

Разве XMPP позволяет серверу «просто так» или вместе с сообщением передать клиенту информацию об отправителе?

Она там в станзе прям в поле from написана. Или вы хотите полный vcard вместе с сообщением каждый раз отправлять?

Даже в редакции от 2019-05-15, XEP-0045: Multi-User Chat говорит о том, что:

XMPP — плохой пример для сравнения с технической стороны, они почти всё, что можно, сделали не так. Проще говоря, сложно сделать MUC хуже, чем в Jabber, здесь любой другой выиграет скорее всего.


Решение использовать ленивую загрузку списка участников чата и упреждающее включение информации (об отправителе и чате; first/last name, avatar, online status и т.д.) в сообщение сервера о новом сообщение — является простым и эффективным.

Это решение в публичном Интернете впервые было использовано еще в DNS в середине 80-х. Но там несколько другие соотношения, а вот в случае Telegram вопрос является таки спорным: первый раз в сессии ладно, сообщить о чате — клиенту будет удобно. Но зачем повторять после этого — только зря трафик и ресурсы сервера расходовать?


На самом деле, оно просто скопировано из ВКонтакте, где в API, работающем поверх HTTP, действительно — следующего запроса может и не быть, или будет хрен знает когда, все запросы лучше трактовать как независимые.

Увы, каким-нибудь XMPP и Matrix (хотя сердцем я именно за них) до подобной эффективности ещё очень и очень далеко.

Что неэффективно? XMPP отлично жмётся, нет всей этой ерунды с TL и вложенными сообщениями, простой клиент/бот пишется левой пяткой за вечер, секретные чаты и шифрование прикручено на правильном уровне, XMPP об этом просто не думает, и точно так же можно будить раз в 30/60 секунд, есть XEP'ы на быстрое восстановление сессии, етц.


Это подтверждается, например, хорошей масштабируемостью — ни один другой IM не поддерживает групповые чаты на 200 000 пользователей.

Чаты на 200к пользователей онлайн одновременно?


И даже на порядок меньшая планка в 20к участников чата является практически недостижимой.

Ирка 10к тянет и не давится.

Чат на 200к в группе, ну онлайн пусть около 20-30к. Телеграм использует ленивую загрузку списка участников и да, вместо загрузки 200 000 vcard при подключении, он отправляет аналог vcard отправителя (100-250 байт) в событие добавления сообщения в группу. При ленивой загрузке (участников) это всё-равно следующее, что запросили бы клиенты.


Именно включение данных о контексте, на мой взгляд, является той фичей, которой было бы здорово научиться остальным (XMPP/Matrix).
Например, когда мы запрашиваем историю сообщений мега-группы, мы, опять-таки, вместе с сообщениями получаем информацию обо всех упомянутых пользователях. И смысл тут не в экономии трафика, а в экономии round-trip'ов и максимально быстрой работе клиентов (из этого предложения не следует, что все клиенты Телеграм работают быстро. Я говорю о возможностях протокола.)


Я сравниваю с XMPP и Matrix, потому что знаком с их протоколами, хотя и не так детально, как с Telegram.
IRC, при всём уважении и при том, что я им пользуюсь, не отвечает современным представлениям об удобстве. Ни картинку (inline) не отправить, ни даже сообщение отредактировать. О поиске сообщений в канале за определённую дату и от определённого пользователя даже мечтать не приходится.


Я занимаюсь разработкой коммерческого IM и у меня была задача разобраться, как приблизить наш протокол (закрытый, бинарный) по скорости к протоколу Телеграм. Так что я сужу не только по своему клиенту/серверу Телеграм, но и по недельному целенаправленному анализу моих коллег (работа при потере пакетов и больших задержках и т.д.). При больших сетевых задержках (не редкость при работе по 2G/3G в местах с плохим покрытием) всё становится просто очевидно.

Недельному анализу… это прекрасно просчитывалось бы "на кончике карандаша" еще на стадии проектирования, при условии, что архитектор хорошо понимает, как работают сети, разумеется.

Телеграм использует ленивую загрузку списка участников и да, вместо загрузки 200 000 vcard при подключении, он отправляет аналог vcard отправителя (100-250 байт) в событие добавления сообщения в группу.

Каждого сообщения?


А если мне этот вкард не нужен? Если аватар я давно закешировал или вообще их не показываю, и ника достаточно? XMPP это отлично обрабатывает.

В Telegram в информацию о пользователе включаются ссылки на файлы большой и маленькой аватарки, если она вообще есть. Ссылка на файл — 24 байта.
Весь профиль – это флаги (контакт, бот, заблокирован и т.д.) + {first,last,user}name + phone (если доступен) + online status — от 40 до 320 байт при максимально длинных именах (по 64 символа по 4 байта utf8) и заданной аватарке.
В большинстве случаев, профиль (тип User) занимает меньше 100 байт. Сервер Telegram сам решает (в зависимости от типа чата и другихпараметров), какую дополнительную информацию включать в событие и может не отправлять одни и те же данные без необходимости.

Ссылка на файл — 24 байта.

На самом деле нет (с)


Было — 28 байт, до середины 80-х схем. Сейчас в FileLocation еще включается file_reference переменной длины, в среднем 25 байт.


Сервер Telegram сам решает (в зависимости от типа чата и другихпараметров), какую дополнительную информацию включать в событие

В теории может. На практике же я наблюдаю, что он включает это в каждое сообщение.

Ну и зачем пользователям или серверу знать с точностью до 200 мс или 5 с, что пользователь ушёл в offline? Ну и в чём проблема того, что приложение на телефоне скажет ОС, что его нужно будить каждые 30/60 секунд (пробуждение в ряде случаев приводит к увеличению частоты CPU) и будет именно с таким интервалом сообщать серверу о своей работоспособности? Telegram запарился насчёт энергосбережения — ну и молодец.

Я не работа с Телегой (даже не устанавливал ее никогда) но я так понимаю эпизод на который Вы ссылаетесь (аналогичнео поступают серверы mqtt почему я это проблему прочувствовал)


При переходе сворачивании приоложения или при переходе в спящий режим все сетевые соединения почти сразу закрываются. Говорят что можно поставить какой-то таск который будет один раз примерно в 15 минут делать какую-то работу но я этим не пользовался.


Однако после пробуждения устройства и после реконнекта я не получаю сразу пропущенные сообщения так как сервер проверяет и доставляет отложенные сообщения для mqtt по умочанию через 60 секунд. Как это выглядит. Я выводу мобилу из спящего режима проверяю сообщения и ничего не получаю новых сообщений, т.к. я не жду 60 секунд. Сворачиваю прилоежние — опять рвется коннект и сообщения не приходят. Я это время с умолчательного уменьшил до 5 секунд и этого уже достаточно чтобы пока пользователь соображает есть и у него новое сообщение — сообщение сервер ему присылает. Так что в данном моменте имеем не экономию батарейки на клиенте а экономию на сервере. Который реже доставляет пропущенные сообщения. Но это чревато.


Возможно после реконнекта клиент принудительно "вытягивает" новые сообщения с сервера, но это как бы уже не в рамках протокола получается.

Возможно после реконнекта клиент принудительно "вытягивает" новые сообщения с сервера, но это как бы уже не в рамках протокола получается.

Ну, это зависит от определения термина "протокол", который в наши времена хипстерских API, коими неправомочно назвали Web-запросы, стал как-то размыт. Тема updates — отдельная и больная, в некоторых случаях можно сказать, что Telegram-клиент поступает именно так.

Спасибо за интересную статью.

Я хочу ее добавить одним очень интересный вопрос который мне не дает покоя.

В любой из клиентов что я видел имеет вшитый в него набор ключей которым надо верить что они-то надежные. Это несколько ключей. Откуда они взялись это вопрос ибо из документации это не следует никак, и если поискать эти ключи как константу то можно найти что самое первое упоминание их тут: github.com/d0ctrey/telegram-client/commit/b1297677df381e90c1e54515b648b15cf250d0cc

Это Dec 19, 2017 и коммит сделал некий d0ctrey который создал репозиторий с этим коммитом за пару часов до этого коммита.

Почему именно эти ключи? Почему тайминг так хорошо пересекается с временем блокировок с РКН я тоже не знаю.

Это – публичные RSA ключи сервера. Худшее, что может произойти (если в Telegram LLC произойдёт утечка) — подмена сервера.

Но почему именно эти ключи? Почему их нет нигде на сайте telegram? И откуда они вообще берутся? Что бы их получить надо присоединиться к сети telegram и выполнить команду — сервер а дай все ключи которым верить? А почему не может быть main in the middle в этом дизайне например?

А, это за привычностью за год работы глаз уже замылился, и не было упомянуто. Эти ключи Вам выдадут на https://my.telegram.org/apps при регистрации своего приложения — но не торопитесь это делать, см. тему про api_id/api_hash — вместе с самими id/hash. Да, чтоб это сделать, нужно уже иметь аккаунт в Telegram через какое-то другое приложение, иначе на этот сайт не залогиниться. Проблема бутстрапа, видимо, считается решенной, если ставите официальное приложение из официального магазина Apple/Google.

О, т.е. для каждого приложения ключи могут быть вообще свои?

Как-то это совсем не прозрачно.

Пока что везде были одинаковые. Теоретически да, могли бы, но тут они прострелили ногу сами себе — на этапе согласования ключей еще никак нельзя выяснить, какое приложение подключается, это сильно позже. Разве что закладывать информацию в самые первые 16 байт nonce.

Cert pinning?
Но почему именно они?

Т.е. я не нашел ссылки на сайте telegram.org что наша CDN использует вот эти вот ключи.

Кстати, внутри обычного контейнера c сертификатом кроме ключей существует еще масса мета-информации которая делает валидацию значительно проще.

Но и тут авторы решили сделать все иначе.
Кстати, внутри обычного контейнера c сертификатом кроме ключей существует еще масса мета-информации которая делает валидацию значительно проще.

Какая, например? Тут только 2 пути: использовать обычную инфраструктуру PKI, доверяя всем корневым CA, или зашить ключ в клиенте. Второй способ довольно популярен у закрытых приложений (ибо безопаснее), но отсутствие ссылок на этот ключ в официальных источниках — это несколько странно, да.

Никто не мешает использовать x509 и прочие сертификаты и доверять не всем CA а только например трем:
— Telegram root CA
— Telegram root CA #2
— Telegram root CA #3

Второй на случай если сертификат первого того, ну и третий на случай полного ужаса.

Ибо вся эта инфраструктура она же не только про контейнер для ключей. Она еще про способы распространения отозванных сертификатов.

Там очень много работы, и очень многое сделано что бы было прозрачно и верефицируемо.

И вот прозрачно и верефицируемо это то чего не хватает от telegram
Она еще про способы распространения отозванных сертификатов.

Да, но это всё равно не совсем работает (см. https://habr.com/ru/post/332730/).


В условиях, когда Telegram не использует TLS, тащить x509 смысла немного. SSH например тоже работает напрямую с ключами.

Я готов согласиться что это не стоит делать, если бы сейчас была возможность узнать список ключей которым надо доверять.

В текущем дизайне меня не покидает ощущение что man-in-the-middle там есть, и он просто часть его.

А точно не раньше? Может плохо искали? Правда, я не смотрел в историю, только в относительно свежие версии — везде вшиты вот эти ключи, которые выдают и автору нового приложения.


Почему тайминг так хорошо пересекается с временем блокировок с РКН я тоже не знаю.

Но ведь блокировки — апрель 2018, а не декабрь 2017.


Посмотрел сейчас в логах TDesktop:


commit 273ac5eaf1209df35371033d435640c1f811084f
Author: John Preston johnprestonmail@gmail.com
Date: Fri Dec 8 19:24:09 2017 +0400


Add some more public keys
Спасибо, возможно когда я искал я не нашел этих ключей через поиск github.

Но это не отменяет исходный вопрос почему именно они.

Чуть прояснилось ковыряние MTProxy:


Vasily, [29.10.19 23:54]
Клиент — < obfuscated+ transport > — mtproxy server — < true proxy protocol > — proxy server — Telegram DC

Есть возможность, что новые ключи — это ключи вот этих новых proxy второго уровня, которые таким образом могут быть сами MitM, для вставки promoted-каналов. Требуются дальнейшие исследования.

Вот ощущение что они встроили MitM в дизайн протокола меня активно не покидало и не покидает.

Спасибо за этот update.
Кстати про 2 года вы оптимисты.

Код сервера (то что нам показали как прокси сервер) есть развитие того что выложила эта команда в open source когда была еще в vk.

Сравните например две функции:

github.com/vk-com/kphp-kdb/blob/master/common/crc32.c#L576
github.com/TelegramMessenger/MTProxy/blob/master/common/crc32.c#L945
его придумали в vk еще, как и сервер telegram был «форком» сервера сообщений в vk вроде никто особо не отрицает, хотя и не акцентирует внимание.

Собственно лимит на 1 миллион сообщений у аккаунта там например еще с тех времен ;) Хотя, возможно, они его убрали. Но не уверен.

Так это упомянуто в статье.

НПО "Эшелон" связан с
Минобороны
Роскомнадзор
"Защита" персональных данных

Что там сбербанку за слив данных будет? Интернет в ноябре выключат или только в тестовом режиме и только вне крупных городов?

Раз уж тут знатоки, может вы мне объясните смысл в ограничении на пять закреплённых чатов? Даже в сторонних клиентах оно есть, а значит, это особенность протокола?

У клиента минимум свобод, большая часть заашита в протоколе.

Количество прикрепляемых диалогов приходит параметром конфигурации сервера, то есть его легко могут увеличить в любой момент для всех клиентов сразу.
Единственное ограничение на уровне протокола заключается в том, что запрос прикреплённых диалогов (getPinnedDialogs) не поддерживает "пагинацию", но можно без проблем воспользоваться и обычным getDialogs (ну да, результат может включать и обычные диалоги, не велика проблема).

А они ещё СВОЮ крипту пилят… Закупайтесь! ;)
24 октября 2019 в 20:24

Во второй части этой серии постов мы рассмотрим…

В третьей части будет продолжение разбора...

Когда продолжение ждать? В этом году я уже и не надеюсь…

Когда будет продолжение?

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.