Kritik pwotokòl la ak apwòch òganizasyonèl nan Telegram. Pati 1, teknik: eksperyans nan ekri yon kliyan nan grafouyen - TL, MT

Dènyèman, posts sou ki jan Telegram bon se, ki jan briyan ak ki gen eksperyans frè Durov yo nan bati sistèm rezo, elatriye yo te kòmanse parèt pi souvan sou Habré. An menm tan an, trè kèk moun te reyèlman plonje tèt yo nan aparèy teknik la - nan pifò, yo sèvi ak yon jistis senp (ak byen diferan de MTProto) Bot API ki baze sou JSON, epi anjeneral jis aksepte. sou lafwa tout lwanj ak PR ki vire toutotou mesaje a. Prèske yon ane edmi de sa, kòlèg mwen nan ONG Eshelon Vasily (malerezman, kont li sou Habré te efase ansanm ak bouyon an) te kòmanse ekri pwòp kliyan Telegram li nan grate nan Perl, epi pita otè a nan liy sa yo ansanm. Poukisa Perl, kèk pral imedyatman mande? Paske pwojè sa yo deja egziste nan lòt lang.An reyalite, se pa sa a, ta ka gen nenpòt lòt lang kote pa genyen. bibliyotèk ki pare, epi kòmsadwa otè a dwe ale tout wout la nan grate. Anplis, kriptografik se yon kesyon de konfyans, men verifye. Avèk yon pwodwi ki vize a sekirite, ou pa ka tou senpleman konte sou yon bibliyotèk pare-fè soti nan manifakti a epi avèg fè konfyans li (sepandan, sa a se yon sijè pou dezyèm pati a). Nan moman sa a, bibliyotèk la travay byen byen nan nivo "mwayèn" (pèmèt ou fè nenpòt demann API).

Sepandan, pa pral gen anpil kriptografik oswa matematik nan seri post sa yo. Men, pral gen anpil lòt detay teknik ak beki achitekti (tou itil pou moun ki pa pral ekri nan grate, men ki pral sèvi ak bibliyotèk la nan nenpòt lang). Se konsa, objektif prensipal la se te eseye aplike kliyan an nan grate dapre dokiman ofisyèl yo. Sa vle di, an n sipoze ke kòd sous kliyan ofisyèl yo fèmen (ankò, nan dezyèm pati a nou pral kouvri an plis detay sijè a nan lefèt ke sa a se vre. k ap pase konsa), men, tankou nan ansyen tan, pou egzanp, gen yon estanda tankou RFC - èske li posib yo ekri yon kliyan dapre spesifikasyon la pou kont li, "san yo pa gade" nan kòd sous la, se pou li ofisyèl (Telegram Desktop, mobil), oswa Telethon ki pa ofisyèl?

Table of contents:

Dokimantasyon... li egziste, pa vre? Eske se vre?..

Fragman nòt pou atik sa a te kòmanse kolekte ete dènye a. Tout tan sa a sou sit entènèt ofisyèl la https://core.telegram.org Dokimantasyon an te apati Kouch 23, i.e. kole yon kote nan 2014 (sonje, pa t 'menm chanèl epòk sa a?). Natirèlman, nan teyori, sa a ta dwe pèmèt nou aplike yon kliyan ak fonksyonalite nan moman sa a nan 2014. Men, menm nan eta sa a, dokiman an te, premye, enkonplè, ak dezyèmman, nan kote li kontredi tèt li. Jis plis pase yon mwa de sa, nan mwa septanm 2019, li te pa chans Li te dekouvri ke te gen yon gwo aktyalizasyon nan dokiman an sou sit la, pou Kouch 105 la konplètman resan, ak yon nòt ke kounye a tout bagay bezwen li ankò. Vreman vre, anpil atik yo te revize, men anpil te rete san chanjman. Se poutèt sa, lè w ap li kritik ki anba a sou dokiman an, ou ta dwe kenbe nan tèt ou ke kèk nan bagay sa yo pa enpòtan ankò, men kèk yo toujou byen. Apre yo tout, 5 ane nan mond lan modèn se pa sèlman yon tan long, men trè anpil. Depi tan sa yo (sitou si ou pa pran an kont sit geochat yo abandone ak reviv depi lè sa a), kantite metòd API nan konplo a te grandi soti nan yon santèn a plis pase de san senkant!

Ki kote yo kòmanse kòm yon jèn otè?

Li pa enpòtan si ou ekri nan grafouyen oswa itilize, pou egzanp, bibliyotèk pare-fè tankou Telethon pou Python oswa Madeline pou PHP, nan nenpòt ka, w ap bezwen an premye enskri aplikasyon w lan - jwenn paramèt api_id и api_hash (moun ki te travay ak API VKontakte imedyatman konprann) pa ki sèvè a pral idantifye aplikasyon an. Sa a ap gen fè li pou rezon legal, men nou pral pale plis sou poukisa otè bibliyotèk yo pa ka pibliye li nan dezyèm pati a. Ou ka satisfè ak valè tès yo, byenke yo trè limite - reyalite a se ke kounye a ou ka enskri yon sèl app, kidonk pa kouri tèt devan nan li.

Koulye a, nan yon pwen de vi teknik, nou ta dwe enterese nan lefèt ke apre enskripsyon nou ta dwe resevwa notifikasyon nan men Telegram sou mizajou nan dokiman, pwotokòl, elatriye. Sa vle di, yon moun ta ka asime ke sit la ak waf yo te tou senpleman abandone ak kontinye travay espesyalman ak moun ki te kòmanse fè kliyan, paske li pi fasil. Men, non, pa gen anyen tankou sa yo te obsève, pa gen okenn enfòmasyon ki te vini.

Men, si ou ekri nan grafouyen, Lè sa a, lè l sèvi avèk paramèt yo jwenn se aktyèlman toujou yon fason lontan. Malgre ke https://core.telegram.org/ ak chita pale sou yo nan Kòmanse premye nan tout, an reyalite, ou pral premye gen aplike MTProto pwotokòl - men si ou te kwè layout selon modèl OSI nan fen paj la pou yon deskripsyon jeneral nan pwotokòl la, Lè sa a, li konplètman pou gremesi.

An reyalite, tou de anvan ak apre MTProto, sou plizyè nivo nan yon fwa (tankou rezo etranje k ap travay nan nwayo a OS yo di, vyolasyon kouch), yon sijè gwo, douloure ak terib pral jwenn nan wout la ...

Serializasyon binè: TL (Type Language) ak konplo li yo, ak kouch, ak anpil lòt mo pè

Sijè sa a, an reyalite, se kle nan pwoblèm Telegram yo. Epi pral gen yon anpil nan mo terib si ou eseye fouye nan li.

Se konsa, isit la nan dyagram nan. Si pawòl sa a vin nan tèt ou, di, Chema JSON, Ou te panse kòrèkteman. Objektif la se menm bagay la: kèk lang pou dekri yon seri posib done transmèt. Sa a se kote resanblans yo fini. Si soti nan paj la MTProto pwotokòl, oswa nan pye bwa sous kliyan ofisyèl la, nou pral eseye louvri kèk chema, nou pral wè yon bagay tankou:

int ? = Int;
long ? = Long;
double ? = Double;
string ? = String;

vector#1cb5c415 {t:Type} # [ t ] = Vector t;

rpc_error#2144ca19 error_code:int error_message:string = RpcError;

rpc_answer_unknown#5e2ad36e = RpcDropAnswer;
rpc_answer_dropped_running#cd78e586 = RpcDropAnswer;
rpc_answer_dropped#a43ad8b7 msg_id:long seq_no:int bytes:int = RpcDropAnswer;

msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;

---functions---

set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:bytes = Set_client_DH_params_answer;

ping#7abe77ec ping_id:long = Pong;
ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;

invokeAfterMsg#cb9f372d msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X;

account.updateProfile#78515775 flags:# first_name:flags.0?string last_name:flags.1?string about:flags.2?string = User;
account.sendChangePhoneCode#8e57deb flags:# allow_flashcall:flags.0?true phone_number:string current_number:flags.0?Bool = auth.SentCode;

Yon moun ki wè sa a pou premye fwa pral entwitivman kapab rekonèt sèlman yon pati nan sa ki ekri - byen, sa yo se aparamman estrikti (byenke kote non an ye, sou bò gòch la oswa sou bò dwat la?), gen jaden nan yo, apre ki yon kalite swiv apre yon kolon... pwobableman. Isit la nan parantèz ang gen pwobableman modèl tankou nan C++ (an reyalite, pa byen). Ak sa tout lòt senbòl yo vle di, mak kesyon, mak esklamasyon, pousantaj, mak hash (ak evidamman yo vle di bagay diferan nan diferan kote), pafwa prezan epi pafwa pa, nimewo egzadesimal - ak pi enpòtan, ki jan yo jwenn soti nan sa a bon youn (ki pap rejte pa sèvè a) byte stream? Ou pral oblije li dokiman an (wi, gen lyen ki mennen nan chema a nan vèsyon JSON ki tou pre - men sa pa fè li pi klè).

Louvri paj la Serializasyon done binè ak plonje nan mond lan majik nan dyondyon ak matematik disrè, yon bagay ki sanble ak matan nan 4yèm ane a. Alfabèt, kalite, valè, konbinatè, konbinatè fonksyonèl, fòm nòmal, kalite konpoze, kalite polimòfik... e sa se jis premye paj la! Next ap tann ou TL Lang, ki, byenke li deja genyen yon egzanp yon demann trivial ak repons, pa bay yon repons ditou nan ka ki pi tipik, ki vle di ke w ap oblije mache nan yon rakonte matematik tradui soti nan Ris nan lang angle sou yon lòt uit entegre. paj!

Lektè ki abitye ak lang fonksyonèl ak enferans kalite otomatik pral, nan kou, wè lang deskripsyon an nan lang sa a, menm nan egzanp lan, kòm pi plis abitye, epi yo ka di ke sa a se aktyèlman pa move nan prensip. Objeksyon sa yo se:

  • Wi, objektif la son bon, men Ay, li pa reyalize
  • Edikasyon nan inivèsite Ris varye menm pami espesyalite IT - se pa tout moun ki te pran kou ki koresponn lan
  • Finalman, jan nou pral wè, nan pratik li se pa obligatwa, piske se sèlman yon ti gwoup limite nan menm TL ki te dekri a yo itilize

Kòm te di LeonNerd sou kanal la #perl nan rezo FreeNode IRC, ki te eseye aplike yon pòtay soti nan Telegram nan Matrix (tradiksyon quote la pa kòrèk nan memwa):

Li santi tankou yon moun te prezante teyori tip la pou premye fwa, li te eksite, e li te kòmanse ap eseye jwe ak li, pa reyèlman pran swen si li te nesesè nan pratik.

Gade pou tèt ou, si bezwen an pou bare-types (int, long, elatriye) kòm yon bagay elemantè pa poze kesyon - finalman yo dwe aplike manyèlman - pou egzanp, an n fè yon tantativ pou sòti nan yo. vektè. Sa se, an reyalite, etalaj, si ou rele bagay ki lakòz yo pa pwòp non yo.

Men anvan

Yon deskripsyon kout sou yon pati nan sentaks TL pou moun ki pa li dokiman ofisyèl la

constructor = Type;
myVec ids:Vector<long> = Type;

fixed#abcdef34 id:int = Type2;

fixedVec set:Vector<Type2> = FixedVec;

constructorOne#crc32 field1:int = PolymorType;
constructorTwo#2crc32 field_a:long field_b:Type3 field_c:int = PolymorType;
constructorThree#deadcrc bit_flags_of_what_really_present:# optional_field4:bit_flags_of_what_really_present.1?Type = PolymorType;

an_id#12abcd34 id:int = Type3;
a_null#6789cdef = Type3;

Definisyon toujou kòmanse konstriksyon, apre sa opsyonèlman (nan pratik - toujou) atravè senbòl la # ta dwe CRC32 soti nan kòd deskripsyon nòmal nan kalite sa a. Apre sa vini yon deskripsyon jaden yo; si yo egziste, kalite a ka vid. Sa a tout fini ak yon siy egal, non an nan ki kalite konstrukteur sa a - ki se, an reyalite, subtip a - ki dwe. Nèg adwat siy egal a se polimòfik - se sa ki, plizyè kalite espesifik ka koresponn ak li.

Si definisyon an rive apre liy lan ---functions---, Lè sa a, sentaks la ap rete menm jan an, men siyifikasyon an pral diferan: konstrukteur a ap vin non an nan fonksyon RPC, jaden yo ap vin paramèt (byen, se sa ki, li pral rete egzakteman menm estrikti a bay, jan sa dekri anba a. , sa a pral tou senpleman bay siyifikasyon an), ak "kalite polimorfik la" - ki kalite rezilta a retounen. Se vre, li pral toujou rete polimòfik - jis defini nan seksyon an ---types---, men konstrukteur sa a "pa dwe konsidere". Surcharge kalite fonksyon yo rele pa agiman yo, i.e. Pou kèk rezon, plizyè fonksyon ki gen menm non men siyati diferan, tankou nan C++, yo pa bay nan TL la.

Poukisa "konstriktè" ak "polimòfik" si li pa OOP? Oke, an reyalite, li pral pi fasil pou yon moun panse sou sa a an tèm OOP - yon kalite polimòfik kòm yon klas abstrè, ak konstrukteur yo se klas desandan dirèk li yo, ak final nan tèminoloji yon kantite lang. An reyalite, nan kou, isit la sèlman resanblans ak vrè metòd konstrukteur twò chaje nan lang pwogramasyon OO. Depi isit la yo se jis estrikti done, pa gen okenn metòd (byenke deskripsyon an nan fonksyon ak metòd plis se byen kapab kreye konfizyon nan tèt la ke yo egziste, men sa a se yon pwoblèm diferan) - ou ka panse a yon konstrukteur kòm yon valè soti nan ki ap konstwi tape lè w ap li yon kouran byte.

Ki jan sa rive? Deserializer a, ki toujou li 4 bytes, wè valè a 0xcrc32 - epi konprann sa ki pral rive apre field1 ak kalite int, i.e. li egzakteman 4 bytes, sou sa a jaden an kouvri ak kalite a PolymorType li. Wè 0x2crc32 epi li konprann ke gen de jaden pi lwen, premye long, ki vle di nou li 8 octets. Lè sa a, ankò yon kalite konplèks, ki se deserialize nan menm fason an. Pa egzanp, Type3 ta ka deklare nan kous la le pli vit ke de konstrukteur, respektivman, Lè sa a, yo dwe rankontre swa 0x12abcd34, apre sa ou bezwen li 4 byte plis intOswa 0x6789cdef, apre sa pa pral gen anyen. Nenpòt lòt bagay - ou bezwen jete yon eksepsyon. De tout fason, apre sa nou tounen nan lekti 4 bytes int jaden yo field_c в constructorTwo ak sa nou fini li nou PolymorType.

Finalman, si ou jwenn kenbe 0xdeadcrc pou constructorThree, Lè sa a, tout bagay vin pi konplike. Premye jaden nou an se bit_flags_of_what_really_present ak kalite # - an reyalite, sa a se jis yon alyas pou kalite a nat, sa vle di "nimewo natirèl". Sa vle di, an reyalite, unsigned int se, nan chemen an, ka a sèlman lè nimewo ki pa siyen rive nan sikui reyèl. Se konsa, pwochen se yon konstriksyon ak yon mak kesyon, sa vle di ke jaden sa a - li pral prezan sou fil la sèlman si se ti jan ki koresponn lan mete nan jaden an refere yo (apeprè tankou yon operatè ternary). Se konsa, an n sipoze ke ti jan sa a te mete, ki vle di ke plis nou bezwen li yon jaden tankou Type, ki nan egzanp nou an gen 2 konstrukteur. Youn se vid (konsiste sèlman nan idantifyan an), lòt la gen yon jaden ids ak kalite ids:Vector<long>.

Ou ta ka panse ke tou de modèl ak jenerik yo nan avantaj yo oswa Java. Men non. Prèske. Sa a sèl la ka itilize parantèz ang nan sikui reyèl, epi li itilize SÈLMAN pou Vector. Nan yon kouran byte, sa yo pral 4 byte CRC32 pou kalite a vektè tèt li, toujou menm bagay la, Lè sa a, 4 bytes - kantite eleman etalaj, ak Lè sa a, eleman sa yo tèt yo.

Ajoute sa a lefèt ke serializasyon toujou fèt nan mo 4 bytes, tout kalite yo se miltip li - kalite yo bati-an yo dekri tou. bytes и string ak serializasyon manyèl nan longè a ak aliyman sa a pa 4 - byen, li sanble yo son nòmal e menm relativman efikas? Malgre ke TL yo reklame ke yo se yon seri serializasyon binè efikas, nan lanfè ak yo, ak ekspansyon nan jis sou anyen, menm valè Boolean ak fisèl yon sèl karaktè a 4 octets, èske JSON ap toujou pi epè? Gade, menm jaden ki pa nesesè yo ka sote ak drapo ti jan, tout bagay se byen bon, e menm ekstansibl pou lavni an, kidonk poukisa pa ajoute nouvo jaden si ou vle nan konstrukteur la pita? ..

Men, non, si ou li pa deskripsyon kout mwen an, men dokiman an plen, epi reflechi sou aplikasyon an. Premyèman, yo kalkile CRC32 konstrukteur a dapre liy nòmal deskripsyon tèks konplo a (retire espas blan siplemantè, elatriye) - kidonk si yo ajoute yon nouvo jaden, liy deskripsyon kalite a pral chanje, e pakonsekan CRC32 li yo ak , kidonk, serializasyon. Ak ki sa ansyen kliyan an ta fè si li te resevwa yon jaden ak nouvo drapo mete, epi li pa konnen ki sa yo dwe fè ak yo apre?..

Dezyèmman, ann sonje CRC32, ki itilize isit la esansyèlman kòm fonksyon hash pou detèmine inikman ki kalite y ap (de)serialize. Isit la nou ap fè fas ak pwoblèm nan nan kolizyon - e non, pwobabilite a se pa youn nan 232, men pi gwo. Ki moun ki sonje ke CRC32 fèt pou detekte (ak korije) erè nan kanal kominikasyon an, epi kòmsadwa amelyore pwopriyete sa yo nan detriman lòt moun? Pou egzanp, li pa pran swen sou rearanje bytes: si ou kalkile CRC32 soti nan de liy, nan dezyèm lan ou swap premye 4 bytes ak pwochen 4 bytes - li pral menm bagay la. Lè opinyon nou an se fisèl tèks ki soti nan alfabè Latin (ak yon ti ponktiyasyon), epi non sa yo pa patikilyèman o aza, chans pou yon rearanje konsa ogmante anpil.

By wout la, ki moun ki tcheke sa ki te la? vrèman CRC32? Youn nan sous yo byen bonè (menm anvan Waltman) te gen yon fonksyon hash ki miltipliye chak karaktè pa nimewo a 239, se konsa renmen anpil pa moun sa yo, ha ha!

Finalman, oke, nou reyalize ke konstrukteur ak yon kalite jaden Vector<int> и Vector<PolymorType> pral gen diferan CRC32. Ki sa ki sou pèfòmans sou entènèt? Ak nan yon pwen de vi teyorik, sa a vin yon pati nan kalite a? Ann di nou pase yon etalaj de dis mil nimewo, byen ak Vector<int> tout bagay klè, longè a ak yon lòt 40000 bytes. E si sa a Vector<Type2>, ki gen ladann yon sèl jaden int epi li se pou kont li nan kalite a - èske nou bezwen repete 10000xabcdef0 34 fwa ak Lè sa a, 4 octets int, oswa lang lan kapab ENDEPEND li pou nou soti nan konstrukteur la fixedVec ak olye pou yo 80000 bytes, transfere ankò sèlman 40000?

Sa a se pa yon kesyon teyorik san fè anyen konsa - imajine ou resevwa yon lis itilizatè gwoup, chak nan yo gen yon id, prenon, siyati - diferans ki genyen nan kantite done transfere sou yon koneksyon mobil ka enpòtan. Li se jisteman efikasite nan serializasyon Telegram ki fè piblisite pou nou.

Se konsa…

Vektè, ki pa janm te lage

Si w eseye pase nan paj deskripsyon konbinatè yo ak sou sa, ou pral wè ke yon vektè (e menm yon matris) se fòmèlman ap eseye pwodiksyon nan tuple nan plizyè fèy. Men, nan fen a yo bliye, etap final la sote, epi yo tou senpleman bay yon definisyon nan yon vektè, ki poko mare nan yon kalite. Ki pwoblèm nan? Nan lang pwogramasyon, espesyalman fonksyonèl yo, li se byen tipik dekri estrikti a recursively - du a ak evalyasyon parese li yo pral konprann epi fè tout bagay poukont li. Nan lang seri done sa ki nesesè se EFIKASYON: li se ase tou senpleman dekri список, i.e. estrikti de eleman - premye a se yon eleman done, dezyèm lan se menm estrikti nan tèt li oswa yon espas vid pou ke a (pake (cons) nan Lisp). Men, sa a pral evidamman mande pou chak eleman depanse yon lòt 4 bytes (CRC32 nan ka a nan TL) pou dekri kalite li yo. Yon etalaj kapab tou fasil dekri gwosè fiks, men nan ka a nan yon etalaj nan longè enkoni davans, nou kraze.

Se poutèt sa, depi TL pa pèmèt pwodiksyon yon vektè, li te dwe ajoute sou bò a. Finalman dokiman an di:

Serializasyon toujou sèvi ak menm konstrukteur "vektè" (const 0x1cb5c415 = crc32 ("vektè t:Type # [ t ] = Vektè t") ki pa depann de valè espesifik varyab tip t la.

Valè paramèt opsyonèl t la pa enplike nan seriyalizasyon an paske li sòti nan kalite rezilta a (toujou li te ye anvan deserializasyon).

Pran yon gade pi pre: vector {t:Type} # [ t ] = Vector t - men okenn kote Definisyon sa a li menm pa di ke premye nimewo a dwe egal a longè vektè a! Epi li pa soti nan nenpòt kote. Sa a se yon bay ki bezwen kenbe nan tèt ou ak aplike ak men ou. Yon lòt kote, dokiman an menm onètman mansyone ke kalite a pa reyèl:

Psedotip polimòfik vektè t la se yon "kalite" ki gen valè se yon sekans valè nenpòt kalite t, swa nan bwat oswa vid.

... men li pa konsantre sou li. Lè ou, fatige nan pated nan etann nan matematik (petèt menm li te ye nan yon kou inivèsite), deside abandone ak aktyèlman gade nan ki jan yo travay ak li nan pratik, enpresyon ki rete nan tèt ou se ke sa a se grav. Matematik nan nwayo a, li te klèman envante pa Cool People (de matematisyen - ACM gayan), epi li pa sèlman nenpòt moun. Objektif la - montre nan - te reyalize.

By wout la, sou nimewo a. Se pou nou fè w sonje sa # se yon sinonim nat, nimewo natirèl:

Gen ekspresyon kalite (kalite-ekspr) ak ekspresyon nimerik (nat-ekspr). Sepandan, yo defini menm jan an.

type-expr ::= expr
nat-expr ::= expr

men nan gramè a yo dekri menm jan an, i.e. Diferans sa a dwe sonje ankò epi mete an aplikasyon alamen.

Oke, wi, kalite modèl (vector<int>, vector<User>) gen yon idantifyan komen (#1cb5c415), sa vle di si ou konnen ke apèl la anonse kòm

users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;

Lè sa a, ou pa ap tann pou jis yon vektè, men yon vektè itilizatè yo. Pli presizeman, ta dwe tann - nan kòd reyèl, chak eleman, si se pa yon kalite fè, pral gen yon konstrukteur, ak nan yon bon fason nan aplikasyon li ta nesesè yo tcheke - men nou te voye egzakteman nan chak eleman nan vektè sa a. kalite sa? E si li te yon kalite PHP, nan ki yon etalaj ka genyen diferan kalite nan eleman diferan?

Nan pwen sa a ou kòmanse panse - èske tankou yon TL nesesè? Petèt pou kabwa a li ta posib pou sèvi ak yon serilizer imen, menm protobuf ki te deja egziste lè sa a? Se te teyori a, ann gade nan pratik.

Enplemantasyon TL ki deja egziste nan kòd

TL te fèt nan pwofondè VKontakte menm anvan evènman yo pi popilè ak vant pataje Durov la ak (siman), menm anvan devlopman Telegram te kòmanse. Ak nan sous louvri kòd sous premye aplikasyon an ou ka jwenn yon anpil nan beki komik. Ak lang nan tèt li te aplike la plis konplètman pase sa li ye kounye a nan Telegram. Pou egzanp, hashes yo pa itilize ditou nan konplo a (sa vle di yon pseudotype entegre (tankou yon vektè) ak konpòtman devye). Oswa

Templates are not used now. Instead, the same universal constructors (for example, vector {t:Type} [t] = Vector t) are used w

men se pou nou konsidere, pou dedomajman pou la konplè, trase, pou di konsa, evolisyon Giant Panse a.

#define ZHUKOV_BYTES_HACK

#ifdef ZHUKOV_BYTES_HACK

/* dirty hack for Zhukov request */

Oswa bèl sa a:

    static const char *reserved_words_polymorhic[] = {

      "alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", NULL

      };

Fragman sa a se sou modèl tankou:

intHash {alpha:Type} vector<coupleInt<alpha>> = IntHash<alpha>;

Sa a se definisyon yon kalite modèl hashmap kòm yon vektè int - Kalite pè. Nan C++ li ta sanble yon bagay tankou sa a:

    template <T> class IntHash {
      vector<pair<int,T>> _map;
    }

konsa, alpha - mo kle! Men, sèlman nan C ++ ou ka ekri T, men ou ta dwe ekri alfa, beta ... Men, pa plis pase 8 paramèt, se kote fantezi a fini. Li sanble ke yon fwa nan Saint Petersburg kèk dyalòg tankou sa a te fèt:

-- Надо сделать в TL шаблоны
-- Бл... Ну пусть параметры зовут альфа, бета,... Какие там ещё буквы есть... О, тэта!
-- Грамматика? Ну потом напишем

-- Смотрите, какой я синтаксис придумал для шаблонов и вектора!
-- Ты долбанулся, как мы это парсить будем?
-- Да не ссыте, он там один в схеме, захаркодить -- и ок

Men, sa a te sou premye aplikasyon an pibliye nan TL "an jeneral". Ann ale nan konsidere aplikasyon nan kliyan Telegram yo tèt yo.

Pawòl pou Vasily:

Vasily, [09.10.18 17:07] Pifò nan tout, bourik la cho paske yo te kreye yon pakèt moun nan abstraksyon, ak Lè sa a, mato yon boulon sou yo, epi yo kouvri dèlko kòd la ak beki.
Kòm yon rezilta, premye soti nan waf pilot.jpg
Lè sa a, soti nan kòd la dzhekichan.webp

Natirèlman, nan men moun ki abitye ak algoritm ak matematik, nou ka espere ke yo te li Aho, Ullmann, epi yo abitye ak zouti yo ki te vin estanda defakto nan endistri a pandan plizyè deseni pou ekri konpilatè DSL yo, pa vre?...

Pa telegram-cli se Vitaly Valtman, jan yo ka konprann nan ensidan an nan fòma TLO a deyò limit li yo (cli), yon manm nan ekip la - kounye a yo te resevwa yon bibliyotèk pou analiz TL. separeman, ki enpresyon li genyen TL analizeur? ..

16.12 04:18 Vasily: Mwen panse ke yon moun pa t metrize lex+yacc
16.12 04:18 Vasily: Mwen pa ka eksplike li otreman
16.12 04:18 Vasily: byen, oswa yo te peye pou kantite liy nan VK
16.12 04:19 Vasily: 3k+ liy elatriye.<censored> olye de yon analizeur

Petèt yon eksepsyon? Ann wè ki jan Sa a se kliyan OFISYE a - Telegram Desktop:

    nametype = re.match(r'([a-zA-Z.0-9_]+)(#[0-9a-f]+)?([^=]*)=s*([a-zA-Z.<>0-9_]+);', line);
    if (not nametype):
      if (not re.match(r'vector#1cb5c415 {t:Type} # [ t ] = Vector t;', line)):
         print('Bad line found: ' + line);

1100+ liy nan Python, yon koup nan ekspresyon regilye + ka espesyal tankou yon vektè, ki, nan kou, yo te deklare nan konplo a jan li ta dwe dapre sentaks la TL, men yo te konte sou sentaks sa a analize li ... Kesyon an rive, poukisa tout bagay te yon mirak?иLi plis kouch si pa gen moun ki pral analize li dapre dokiman an de tout fason?!

By the way... Sonje nou te pale sou CRC32 tcheke? Se konsa, nan dèlko kòd Telegram Desktop la gen yon lis eksepsyon pou kalite sa yo nan ki kalkile CRC32 la. pa matche ak youn ki endike nan dyagram nan!

Vasily, [18.12/22 49:XNUMX] ak isit la mwen ta panse sou si yon TL sa yo nesesè.
si mwen te vle dezòd ak aplikasyon altènatif, mwen ta kòmanse mete repo liy, mwatye nan analizeur yo pral kraze sou definisyon milti-liy.
tdesktop, sepandan, tou

Sonje pwen sou yon sèl-revètman, nou pral retounen nan li yon ti kras pita.

Oke, telegram-cli pa ofisyèl, Telegram Desktop se ofisyèl, men e lòt moun yo? Ki moun ki konnen? .. Nan kòd kliyan an android pa te gen okenn analizeur chema ditou (ki soulve kesyon sou sous louvri, men sa a se pou dezyèm pati a), men te gen plizyè lòt moso komik nan kòd, men plis sou yo nan la. seksyon anba a.

Ki lòt kesyon serializasyon poze an pratik? Pou egzanp, yo te fè anpil bagay, nan kou, ak jaden ti jan ak jaden kondisyonèl:

Vasily: flags.0? true
vle di ke jaden an prezan epi li egal vre si drapo a mete

Vasily: flags.1? int
vle di ke jaden an prezan epi li bezwen deserialize

Vasily: bourik, pa enkyetew pou sa wap fè!
Vasily: Gen yon mansyone yon kote nan dok la ki vre se yon kalite zewo-longè, men li enposib rasanble anyen nan doc yo.
Vasily: Nan aplikasyon sous louvri sa a se pa ka a tou, men gen yon pakèt beki ak sipò.

E Telethon? Gade pi devan nan sijè a nan MTProto, yon egzanp - nan dokiman an gen moso sa yo, men siy la % li dekri sèlman kòm "korespondan ak yon bay-tip fè", i.e. nan egzanp ki anba yo gen swa yon erè oswa yon bagay san papye:

Vasily, [22.06.18 18:38] Nan yon sèl kote:

msg_container#73f1f8dc messages:vector message = MessageContainer;

Nan yon diferan:

msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;

Ak sa yo se de gwo diferans, nan lavi reyèl kèk kalite vektè toutouni vini

Mwen pa te wè yon definisyon vektè fè epi yo pa te vini atravè youn

Analiz yo ekri alamen nan telethon

Nan dyagram li an kòmante definisyon an msg_container

Yon fwa ankò, kesyon an rete sou %. Li pa dekri.

Vadim Goncharov, [22.06.18 19:22] ak nan tdesktop?

Vasily, [22.06.18 19:23] Men, analizeur TL yo sou motè regilye yo pral gen plis chans pa manje sa a tou.

// parsed manually

TL se yon bèl abstraksyon, pèsonn pa aplike li nèt

Ak % se pa nan vèsyon yo nan konplo a

Men, isit la dokiman an kontredi tèt li, kidonk idk

Li te jwenn nan gramè a, yo te kapab tou senpleman bliye dekri semantik la

Ou te wè dokiman an sou TL, ou pa ka kalkile li san mwatye yon lit

"Oke, ann di," yon lòt lektè pral di, "ou kritike yon bagay, kidonk montre m 'ki jan li ta dwe fè."

Vasily reponn: “Kòm pou analiz la, mwen renmen bagay tankou

    args: /* empty */ { $$ = NULL; }
        | args arg { $$ = g_list_append( $1, $2 ); }
        ;

    arg: LC_ID ':' type-term { $$ = tl_arg_new( $1, $3 ); }
            | LC_ID ':' condition '?' type-term { $$ = tl_arg_new_cond( $1, $5, $3 ); free($3); }
            | UC_ID ':' type-term { $$ = tl_arg_new( $1, $3 ); }
            | type-term { $$ = tl_arg_new( "", $1 ); }
            | '[' LC_ID ']' { $$ = tl_arg_new_mult( "", tl_type_new( $2, TYPE_MOD_NONE ) ); }
            ;

yon jan kanmenm renmen li pi bon pase

struct tree *parse_args4 (void) {
  PARSE_INIT (type_args4);
  struct parse so = save_parse ();
  PARSE_TRY (parse_optional_arg_def);
  if (S) {
    tree_add_child (T, S);
  } else {
    load_parse (so);
  }
  if (LEX_CHAR ('!')) {
    PARSE_ADD (type_exclam);
    EXPECT ("!");
  }
  PARSE_TRY_PES (parse_type_term);
  PARSE_OK;
}

oswa

        # Regex to match the whole line
        match = re.match(r'''
            ^                  # We want to match from the beginning to the end
            ([w.]+)           # The .tl object can contain alpha_name or namespace.alpha_name
            (?:
                #             # After the name, comes the ID of the object
                ([0-9a-f]+)    # The constructor ID is in hexadecimal form
            )?                 # If no constructor ID was given, CRC32 the 'tl' to determine it

            (?:s              # After that, we want to match its arguments (name:type)
                {?             # For handling the start of the '{X:Type}' case
                w+            # The argument name will always be an alpha-only name
                :              # Then comes the separator between name:type
                [wd<>#.?!]+  # The type is slightly more complex, since it's alphanumeric and it can
                               # also have Vector<type>, flags:# and flags.0?default, plus :!X as type
                }?             # For handling the end of the '{X:Type}' case
            )*                 # Match 0 or more arguments
            s                 # Leave a space between the arguments and the equal
            =
            s                 # Leave another space between the equal and the result
            ([wd<>#.?]+)     # The result can again be as complex as any argument type
            ;$                 # Finally, the line should always end with ;
            ''', tl, re.IGNORECASE | re.VERBOSE)

sa a se WHOLE lexer la:

    ---functions---         return FUNCTIONS;
    ---types---             return TYPES;
    [a-z][a-zA-Z0-9_]*      yylval.string = strdup(yytext); return LC_ID;
    [A-Z][a-zA-Z0-9_]*      yylval.string = strdup(yytext); return UC_ID;
    [0-9]+                  yylval.number = atoi(yytext); return NUM;
    #[0-9a-fA-F]{1,8}       yylval.number = strtol(yytext+1, NULL, 16); return ID_HASH;

    n                      /* skip new line */
    [ t]+                  /* skip spaces */
    //.*$                 /* skip comments */
    /*.**/              /* skip comments */
    .                       return (int)yytext[0];

sa yo. pi senp se mete li dousman."

An jeneral, kòm yon rezilta, analizeur a ak dèlko kòd pou sous-ensemble TL yo itilize aktyèlman anfòm nan apeprè 100 liy gramè ak ~ 300 liy dèlko a (konte tout printkòd ki te pwodwi a), ki gen ladan tip enfòmasyon pen pou entwospeksyon nan chak klas. Chak kalite polimòfik vire nan yon klas baz abstrè vid, ak konstrukteur eritye de li epi yo gen metòd pou serializasyon ak deserializasyon.

Mank kalite nan lang tip

Sezisman fò se yon bon bagay, dwa? Non, sa a se pa yon holivar (byenke mwen prefere lang dinamik), men yon postila nan kad TL. Ki baze sou li, lang lan ta dwe bay tout kalite chèk pou nou. Oke, oke, petèt pa li menm, men aplikasyon an, men li ta dwe omwen dekri yo. Ak ki kalite opòtinite nou vle?

Premye a tout, kontrent. Isit la nou wè nan dokiman an pou telechaje dosye:

Lè sa a, kontni binè dosye a divize an pati. Tout pati yo dwe gen menm gwosè ( gwosè_pati ) epi yo dwe ranpli kondisyon sa yo:

  • part_size % 1024 = 0 (divizib pa 1KB)
  • 524288 % part_size = 0 (512KB dwe divizib egalman pa gwosè_pati)

Dènye pati a pa oblije satisfè kondisyon sa yo, depi gwosè li mwens pase part_size.

Chak pati ta dwe gen yon nimewo sekans, dosye_pati, ak yon valè ki sòti nan 0 a 2,999.

Apre dosye a te patisyone ou bezwen chwazi yon metòd pou sove li sou sèvè a. Sèvi ak upload.saveBigFilePart nan ka gwosè a plen nan dosye a se plis pase 10 MB ak upload.saveFilePart pou pi piti fichye yo.
[...] youn nan erè sa yo antre done yo ka retounen:

  • FILE_PARTS_INVALID — Kantite pati ki pa valab. Valè a se pa ant 1..3000

Èske nenpòt nan sa a nan dyagram nan? Èske sa a yon jan kanmenm eksprime lè l sèvi avèk TL? Non. Men, eskize m ', menm Turbo Pascal granpapa a te kapab dekri kalite yo espesifye chenn. Apre sa, li te konnen yon lòt bagay, kounye a pi byen konnen kòm enum - yon kalite ki fòme ak yon enimilasyon nan yon kantite fiks (ti) nan valè. Nan lang tankou C - nimerik, sonje ke jiskaprezan nou te sèlman pale sou kalite nimewo. Men, gen tou etalaj, fisèl ... pou egzanp, li ta bèl dekri ke fisèl sa a ka sèlman gen yon nimewo telefòn, dwa?

Okenn nan sa a se nan TL la. Men, gen, pou egzanp, nan JSON Schema. Men, si yon lòt moun ta ka diskite sou divizibilite nan 512 KB, ke sa a toujou bezwen tcheke nan kòd, Lè sa a, asire w ke kliyan an tou senpleman pa t 'kapab voye yon nimewo soti nan ranje 1..3000 (ak erè ki koresponn lan pa t 'kapab leve) li ta posib, pa vre?...

By wout la, sou erè ak valè retounen. Menm moun ki te travay ak TL flou je yo - li pa t 'imedyatman douvanjou sou nou sa chak grenn yon fonksyon nan TL ka aktyèlman retounen pa sèlman kalite retounen ki dekri, men tou, yon erè. Men, sa a pa ka dedwi nan okenn fason lè l sèvi avèk TL nan tèt li. Natirèlman, li deja klè epi pa gen okenn nesesite pou anyen nan pratik (byenke an reyalite, RPC ka fè nan diferan fason, nou pral tounen nan sa a pita) - men sa ki sou Pite a nan konsèp yo nan Matematik nan Kalite abstrè. soti nan mond lan nan syèl la? .. Mwen ranmase remòkè a - kidonk matche ak li.

E finalman, ki sa ki sou lizibilite? Oke, gen, an jeneral, mwen ta renmen deskripsyon gen li dwat nan chema a (nan chema a JSON, ankò, li se), men si w ap deja tension ak li, Lè sa a, sa ki sou bò a pratik - omwen trivially gade nan diferans pandan mizajou? Gade pou tèt ou nan egzanp reyèl:

-channelFull#76af5481 flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;
+channelFull#1c87a71a flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_view_stats:flags.12?true id:int about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?int migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int = ChatFull;

oswa

-message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;
+message#44f9b43d flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true id:int from_id:flags.8?int to_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long = Message;

Sa depann de tout moun, men GitHub, pou egzanp, refize mete aksan sou chanjman ki andedan liy long sa yo. Jwèt la "jwenn 10 diferans", ak sa sèvo a imedyatman wè se ke kòmansman ak fen nan tou de egzanp yo se menm bagay la, ou bezwen fatigan li yon kote nan mitan an ... Nan opinyon mwen, sa a se pa sèlman nan teyori, men piman vizyèlman sal ak neglijan.

By wout la, sou pite a nan teyori a. Poukisa nou bezwen ti jaden? Èske li pa sanble ke yo pran sant move nan pwen de vi nan teyori kalite? Ou ka wè eksplikasyon an nan vèsyon pi bonè nan dyagram nan. Okòmansman, wi, se konsa li te ye, pou chak etènye yo te kreye yon nouvo kalite. Rudiments sa yo toujou egziste nan fòm sa a, pou egzanp:

storage.fileUnknown#aa963b05 = storage.FileType;
storage.filePartial#40bc6f52 = storage.FileType;
storage.fileJpeg#7efe0e = storage.FileType;
storage.fileGif#cae1aadf = storage.FileType;
storage.filePng#a4f63c0 = storage.FileType;
storage.filePdf#ae1e508d = storage.FileType;
storage.fileMp3#528a0677 = storage.FileType;
storage.fileMov#4b09ebbc = storage.FileType;
storage.fileMp4#b3cea0e4 = storage.FileType;
storage.fileWebp#1081464c = storage.FileType;

Men koulye a, imajine, si ou gen 5 jaden opsyonèl nan estrikti ou, Lè sa a, w ap bezwen 32 kalite pou tout opsyon posib. Eksplozyon konbinezon. Kidonk, pite kristal la nan teyori TL la yon lòt fwa ankò kraze kont bourik la jete nan reyalite a piman bouk nan serializasyon.

Anplis de sa, nan kèk kote mesye sa yo tèt yo vyole tipoloji pwòp yo. Pou egzanp, nan MTProto (pwochen chapit) repons lan ka konprese pa Gzip, tout bagay anfòm - eksepte ke kouch yo ak kous yo vyole. Yon fwa ankò, se pa RpcResult tèt li ki te rekòlte, men sa ki ladan l yo. Oke, poukisa fè sa? .. Mwen te oblije koupe nan yon beki pou konpresyon an ta travay nenpòt kote.

Oswa yon lòt egzanp, nou yon fwa dekouvri yon erè - li te voye InputPeerUser olye pou yo InputUser. Oswa vis vèrsa. Men, li te travay! Sa vle di, sèvè a pa t 'pran swen sou kalite a. Ki jan sa ka ye? Repons lan ka ban nou pa fragman kòd ki soti nan telegram-cli:

  if (tgl_get_peer_type (E->id) != TGL_PEER_CHANNEL || (C && (C->flags & TGLCHF_MEGAGROUP))) {
    out_int (CODE_messages_get_history);
    out_peer_id (TLS, E->id);
  } else {    
    out_int (CODE_channels_get_important_history);

    out_int (CODE_input_channel);
    out_int (tgl_get_peer_id (E->id));
    out_long (E->id.access_hash);
  }
  out_int (E->max_id);
  out_int (E->offset);
  out_int (E->limit);
  out_int (0);
  out_int (0);

Nan lòt mo, sa a se kote serializasyon fè MANYÈLMAN, pa pwodwi kòd! Petèt sèvè a aplike nan yon fason menm jan an? .. Nan prensip, sa a pral travay si fè yon fwa, men ki jan li ka sipòte pita pandan mizajou? Èske se poutèt sa yo te envante konplo a? Ak isit la nou ale nan pwochen kesyon an.

Versioning. Kouch

Poukisa vèsyon yo chema yo rele kouch ka sèlman espekile ki baze sou istwa a nan chema pibliye. Aparamman, nan premye otè yo te panse ke bagay debaz yo ta ka fè lè l sèvi avèk konplo a ki pa chanje, epi sèlman kote sa nesesè, pou demann espesifik, endike ke yo te fè lè l sèvi avèk yon vèsyon diferan. Nan prensip, menm yon bon lide - ak nouvo a pral, kòm li te, "melanje", kouch sou tèt ansyen an. Men, ann wè ki jan li te fè. Se vre, mwen pa t 'kapab gade li depi nan konmansman an anpil - li se komik, men dyagram nan kouch debaz la tou senpleman pa egziste. Kouch te kòmanse ak 2. Dokimantasyon an di nou sou yon karakteristik espesyal TL:

Si yon kliyan sipòte Kouch 2, Lè sa a, yo dwe itilize konstrukteur sa a:

invokeWithLayer2#289dd1f6 {X:Type} query:!X = X;

Nan pratik, sa vle di ke anvan chak apèl API, yon int ak valè a 0x289dd1f6 dwe ajoute anvan nimewo metòd la.

Son nòmal. Men, sa ki te pase apre? Lè sa a, parèt

invokeWithLayer3#b7475268 query:!X = X;

Se konsa, sa ki pwochen? Kòm ou ta ka devine,

invokeWithLayer4#dea0d430 query:!X = X;

Komik? Non, li twò bonè pou ri, reflechi sou lefèt ke chak yon demann ki soti nan yon lòt kouch bezwen yo dwe vlope nan yon kalite espesyal - si yo tout diferan pou ou, ki jan lòt bagay ou ka distenge yo? Epi ajoute jis 4 octets devan se yon metòd trè efikas. Se konsa,

invokeWithLayer5#417a57ae query:!X = X;

Men, li evidan ke apre yon ti tan sa a pral vin yon kalite bakanal. Epi solisyon an te vini:

Mizajou: Kòmanse ak Kouch 9, metòd asistan invokeWithLayerN ka itilize sèlman ansanm ak initConnection

Houra! Apre 9 vèsyon, nou finalman rive nan sa ki te fè nan pwotokòl entènèt tounen nan ane 80 yo - dakò sou vèsyon an yon fwa nan kòmansman an nan koneksyon an!

Se konsa, sa ki pwochen? ..

invokeWithLayer10#39620c41 query:!X = X;
...
invokeWithLayer18#1c900537 query:!X = X;

Men koulye a, ou ka toujou ri. Se sèlman apre yon lòt 9 kouch, yo te finalman ajoute yon konstrukteur inivèsèl ak yon nimewo vèsyon, ki bezwen yo dwe rele sèlman yon fwa nan kòmansman koneksyon an, ak siyifikasyon an nan kouch yo te sanble yo te disparèt, kounye a li nan jis yon vèsyon kondisyonèl, tankou tout lòt kote. Pwoblèm rezoud.

Egzakteman?...

Vasily, [16.07.18 14:01] Menm vandredi mwen te panse:
Telesèvè a voye evènman san yon demann. Demann yo dwe vlope nan InvokeWithLayer. Sèvè a pa vlope mizajou; pa gen okenn estrikti pou vlope repons ak mizajou.

Moun sa yo. kliyan an pa ka presize kouch nan kote li vle mizajou

Vadim Goncharov, [16.07.18 14:02] se pa InvokeWithLayer yon beki an prensip?

Vasily, [16.07.18 14:02] Sa a se sèl fason

Vadim Goncharov, [16.07.18 14:02] ki esansyèlman ta dwe vle di dakò sou kouch la nan kòmansman sesyon an.

By wout la, li swiv ke kliyan downgrade pa bay

Mizajou, i.e. kalite Updates nan konplo a, sa a se sa sèvè a voye bay kliyan an pa an repons a yon demann API, men poukont li lè yon evènman rive. Sa a se yon sijè konplèks ki pral diskite nan yon lòt pòs, men pou kounye a li enpòtan konnen ke sèvè a sove Mizajou menm lè kliyan an se offline.

Kidonk, si ou refize vlope chak pake pou endike vèsyon li yo, sa lojikman mennen nan pwoblèm sa yo posib:

  • sèvè a voye mizajou bay kliyan an menm anvan kliyan an te enfòme ki vèsyon li sipòte
  • kisa mwen ta dwe fè apre amelyore kliyan an?
  • kiyès garantike opinyon sèvè a sou nimewo kouch la pa pral chanje pandan pwosesis la?

Èske ou panse ke sa a se espekilasyon piman teyorik, ak nan pratik sa a pa ka rive, paske sèvè a ekri kòrèkteman (omwen, li teste byen)? Ha! Kèlkeswa jan li ye!

Sa a se egzakteman sa nou te kouri nan mwa Out. Nan dat 14 out, te gen mesaj ke yon bagay te mete ajou sou sèvè Telegram yo ... ak Lè sa a, nan mòso bwa yo:

2019-08-15 09:28:35.880640 MSK warn  main: ANON:87: unknown object type: 0x80d182d1 at TL/Object.pm line 213.
2019-08-15 09:28:35.751899 MSK warn  main: ANON:87: unknown object type: 0xb5223b0f at TL/Object.pm line 213.

ak Lè sa a, plizyè megabyte nan tras chemine (byen, an menm tan an te fikse antre). Apre yo tout, si yon bagay pa rekonèt nan TL ou a, li nan binè pa siyati, pi lwen desann liy lan TOUT ale, dekodaj ap vin enposib. Kisa ou ta dwe fè nan yon sitiyasyon konsa?

Oke, premye bagay ki vin nan lespri nenpòt moun se dekonekte epi eseye ankò. pa t ede. Nou google CRC32 - sa yo te tounen bagay ki soti nan konplo 73, byenke nou te travay sou 82. Nou gade ak anpil atansyon nan mòso bwa yo - gen idantifyan ki soti nan de konplo diferan!

Petèt pwoblèm nan se piman nan kliyan ofisyèl nou an? Non, nou lanse Telegram Desktop 1.2.17 (vèsyon apwovizyone nan yon kantite distribisyon Linux), li ekri nan jounal Eksepsyon: MTP Inatandi kalite id #b5223b0f li nan MTPMessageMedia ...

Kritik pwotokòl la ak apwòch òganizasyonèl nan Telegram. Pati 1, teknik: eksperyans nan ekri yon kliyan nan grafouyen - TL, MT

Google te montre ke yon pwoblèm menm jan an te deja rive youn nan kliyan ofisyèl yo, men Lè sa a, nimewo vèsyon yo ak, kòmsadwa, sipozisyon yo te diferan ...

Se konsa, ki sa nou ta dwe fè? Vasily ak mwen divize: li te eseye mete ajou kous la nan 91, mwen deside rete tann kèk jou epi eseye sou 73. Tou de metòd yo te travay, men depi yo anpirik, pa gen okenn konpreyansyon sou konbyen vèsyon monte oswa desann ou bezwen. sote, oswa konbyen tan ou bezwen tann.

Apre sa, mwen te kapab repwodui sitiyasyon an: nou lanse kliyan an, fèmen li, rekonpile kous la nan yon lòt kouch, rekòmanse, trape pwoblèm nan ankò, retounen nan yon sèl anvan an - oops, pa gen okenn kantite chanjman sikwi ak rekòmanse kliyan pou yon kèk minit ap ede. Ou pral resevwa yon melanj de estrikti done ki soti nan diferan kouch.

Eksplikasyon? Kòm ou ka devine nan divès sentòm endirèk, sèvè a konsiste de anpil pwosesis diferan kalite sou machin diferan. Gen plis chans, sèvè a ki responsab pou "tanpon" mete nan keu sa siperyè li yo te ba li, epi yo te bay li nan konplo a ki te an plas nan moman jenerasyon an. Epi jiskaske keu sa a "pouri", pa gen anyen ki ka fè sou li.

Petèt... men sa a se yon beki terib?!.. Non, anvan ou panse sou lide fou, ann gade nan kòd la nan kliyan ofisyèl yo. Nan vèsyon an android nou pa jwenn okenn analizeur TL, men nou jwenn yon dosye for (GitHub refize manyen li) ak (de)serializasyon. Men fragman kòd yo:

public static class TL_message_layer68 extends TL_message {
    public static int constructor = 0xc09be45f;
//...
//еще пачка подобных
//...
    public static class TL_message_layer47 extends TL_message {
        public static int constructor = 0xc992e15c;
        public static Message TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
            Message result = null;
            switch (constructor) {
                case 0x1d86f70e:
                    result = new TL_messageService_old2();
                    break;
                case 0xa7ab1991:
                    result = new TL_message_old3();
                    break;
                case 0xc3060325:
                    result = new TL_message_old4();
                    break;
                case 0x555555fa:
                    result = new TL_message_secret();
                    break;
                case 0x555555f9:
                    result = new TL_message_secret_layer72();
                    break;
                case 0x90dddc11:
                    result = new TL_message_layer72();
                    break;
                case 0xc09be45f:
                    result = new TL_message_layer68();
                    break;
                case 0xc992e15c:
                    result = new TL_message_layer47();
                    break;
                case 0x5ba66c13:
                    result = new TL_message_old7();
                    break;
                case 0xc06b9607:
                    result = new TL_messageService_layer48();
                    break;
                case 0x83e5de54:
                    result = new TL_messageEmpty();
                    break;
                case 0x2bebfa86:
                    result = new TL_message_old6();
                    break;
                case 0x44f9b43d:
                    result = new TL_message_layer104();
                    break;
                case 0x1c9b1027:
                    result = new TL_message_layer104_2();
                    break;
                case 0xa367e716:
                    result = new TL_messageForwarded_old2(); //custom
                    break;
                case 0x5f46804:
                    result = new TL_messageForwarded_old(); //custom
                    break;
                case 0x567699b3:
                    result = new TL_message_old2(); //custom
                    break;
                case 0x9f8d60bb:
                    result = new TL_messageService_old(); //custom
                    break;
                case 0x22eb6aba:
                    result = new TL_message_old(); //custom
                    break;
                case 0x555555F8:
                    result = new TL_message_secret_old(); //custom
                    break;
                case 0x9789dac4:
                    result = new TL_message_layer104_3();
                    break;

oswa

    boolean fixCaption = !TextUtils.isEmpty(message) &&
    (media instanceof TLRPC.TL_messageMediaPhoto_old ||
     media instanceof TLRPC.TL_messageMediaPhoto_layer68 ||
     media instanceof TLRPC.TL_messageMediaPhoto_layer74 ||
     media instanceof TLRPC.TL_messageMediaDocument_old ||
     media instanceof TLRPC.TL_messageMediaDocument_layer68 ||
     media instanceof TLRPC.TL_messageMediaDocument_layer74)
    && message.startsWith("-1");

Hmm... sanble sovaj. Men, pwobableman, sa a se pwodwi kòd, Lè sa a, oke? .. Men, li sètènman sipòte tout vèsyon! Se vre, li pa klè poukisa tout bagay melanje ansanm, chat sekrè, ak tout kalite _old7 yon jan kanmenm pa gade tankou jenerasyon machin ... Sepandan, pi fò nan tout mwen te kònen lwen pa

TL_message_layer104
TL_message_layer104_2
TL_message_layer104_3

Mesye, ou pa ka menm deside sa ki andedan yon kouch?! Oke, oke, an n di "de" yo te lage ak yon erè, byen, li rive, men TWA? .. Touswit, menm rato a ankò? Ki kalite pònografi sa a, eskize?...

Nan kòd sous Telegram Desktop la, yon bagay menm jan an rive - si se konsa, plizyè komèt nan yon ranje nan konplo a pa chanje nimewo kouch li yo, men ranje yon bagay. Nan kondisyon kote pa gen okenn sous done ofisyèl pou konplo a, ki kote yo ka jwenn li, eksepte pou kòd sous kliyan ofisyèl la? Men, si ou pran li soti nan la, ou pa ka asire w ke konplo a konplètman kòrèk jiskaske ou teste tout metòd yo.

Ki jan sa ka menm fè tès? Mwen espere ke fanatik nan tès inite, fonksyonèl ak lòt pral pataje nan kòmantè yo.

Oke, ann gade yon lòt moso kòd:

public static class TL_folders_deleteFolder extends TLObject {
    public static int constructor = 0x1c295881;

    public int folder_id;

    public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
        return Updates.TLdeserialize(stream, constructor, exception);
    }

    public void serializeToStream(AbstractSerializedData stream) {
        stream.writeInt32(constructor);
        stream.writeInt32(folder_id);
    }
}

//manually created

//RichText start
public static abstract class RichText extends TLObject {
    public String url;
    public long webpage_id;
    public String email;
    public ArrayList<RichText> texts = new ArrayList<>();
    public RichText parentRichText;

    public static RichText TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
        RichText result = null;
        switch (constructor) {
            case 0x1ccb966a:
                result = new TL_textPhone();
                break;
            case 0xc7fb5e01:
                result = new TL_textSuperscript();
                break;

Kòmantè sa a "manyèlman kreye" sijere ke sèlman yon pati nan fichye sa a te ekri manyèlman (èske ou ka imajine kochma antretyen an antye?), ak rès la te pwodwi machin. Sepandan, Lè sa a, yon lòt kesyon rive - ke sous yo disponib pa konplètman (a la GPL blobs nan nwayo Linux), men sa a se deja yon sijè pou dezyèm pati a.

Men ase. Ann ale nan pwotokòl la sou tèt ki tout seri sa a kouri.

MT Proto

Se konsa, ann louvri Deskripsyon jeneral и deskripsyon detaye pwotokòl la ak premye bagay nou bite sou se tèminoloji a. Ak yon abondans nan tout bagay. An jeneral, sa a sanble se yon karakteristik propriétaires nan Telegram - rele bagay sa yo yon fason diferan nan diferan kote, oswa bagay diferan ak yon sèl mo, oswa vis vèrsa (pa egzanp, nan yon API wo nivo, si ou wè yon pake fichye, li pa. sa ou te panse).

Pou egzanp, "mesaj" ak "sesyon" vle di yon bagay diferan isit la pase nan koòdone abityèl kliyan Telegram. Oke, tout bagay klè ak mesaj la, li ka entèprete an tèm OOP, oswa tou senpleman rele mo "pake" - sa a se yon nivo transpò ki ba, pa gen mesaj yo menm jan ak nan koòdone a, gen anpil mesaj sèvis. . Men, sesyon an... men premye bagay an premye.

kouch transpò

Premye bagay se transpò. Yo pral di nou sou 5 opsyon:

  • Tchp
  • Websocket
  • Websocket sou HTTPS
  • HTTP
  • T

Vasily, [15.06.18 15:04] Genyen tou transpò UDP, men li pa dokimante

Ak TCP nan twa varyant

Premye a se menm jan ak UDP sou TCP, chak pake gen ladann yon nimewo sekans ak crc
Poukisa lekti dokiman sou yon charyo se konsa douloure?

Oke, gen li kounye a TCP deja nan 4 variantes:

  • Abridged
  • Entèmedyè
  • Matlasye entèmedyè
  • Plen

Oke, ok, Matlasye entèmedyè pou MTProxy, sa a te ajoute pita akòz evènman byen li te ye. Men, poukisa de plis vèsyon (twa nan total) lè ou ta ka jwenn ak yon sèl? Tout kat esansyèlman diferan sèlman nan fason yo mete longè ak chaj nan MTProto prensipal la, ki pral diskite pi lwen:

  • nan Abreje li se 1 oswa 4 bytes, men se pa 0xef, Lè sa a, kò a
  • nan Entèmedyè sa a se 4 bytes nan longè ak yon jaden, ak premye fwa kliyan an dwe voye 0xeeeeeeee pou endike ke li se Entèmedyè
  • nan Full ki pi depandans, nan pwen de vi nan yon rezo: longè, nimewo sekans, epi PA YON SÈL LA ki se sitou MTProto, kò, CRC32. Wi, tout bagay sa yo se sou tèt TCP. Ki bay nou transpò serye nan fòm yon kouran byte sekans; pa gen okenn sekans ki nesesè, espesyalman checksums. Oke, kounye a yon moun pral objeksyon pou mwen ke TCP gen yon sòm chèk 16-bit, kidonk koripsyon done rive. Gwo, men nou aktyèlman gen yon pwotokòl kriptografik ak hashes ki pi long pase 16 bytes, tout erè sa yo - e menm plis - yo pral kenbe pa yon dezakò nan SHA nan yon nivo ki pi wo. Pa gen okenn pwen nan CRC32 sou tèt sa a.

Ann konpare Abreje, kote yon sèl byte nan longè posib, ak Entèmedyè, ki jistifye "Nan ka aliyman done 4-byte nesesè," ki se byen istwa san sans. Ki sa, yo kwè ke pwogramasyon Telegram yo tèlman enkonpetan ke yo pa ka li done ki soti nan yon priz nan yon tanpon ki aliyen? Ou toujou dwe fè sa, paske lekti ka retounen ou nenpòt ki kantite bytes (e gen tou serveurs proxy, pou egzanp ...). Oswa nan lòt men an, poukisa bloke Abreje si nou pral toujou gen gwo padding sou tèt 16 bytes - sove 3 bytes pafwa ?

Youn gen enpresyon ke Nikolai Durov reyèlman renmen reenvante wou, ki gen ladan pwotokòl rezo, san okenn bezwen reyèl pratik.

Lòt opsyon transpò, enkli. Web ak MTProxy, nou pa pral konsidere kounye a, petèt nan yon lòt pòs, si gen yon demann. Konsènan MTProxy sa a, se pou nou sèlman sonje kounye a ke yon ti tan apre yo te pibliye l an 2018, founisè yo te aprann byen vit bloke li, ki gen entansyon pou kontoune blokepa gwosè pake! Epi tou lefèt ke sèvè MTProxy ekri (ankò pa Waltman) nan C te twò mare ak espesifik Linux, byenke sa a pa te obligatwa ditou (Phil Kulin pral konfime), e ke yon sèvè menm jan an swa nan Go oswa Node.js ta. anfòm nan mwens pase yon santèn liy.

Men, nou pral tire konklizyon sou alfabetizasyon teknik moun sa yo nan fen seksyon an, apre yo fin konsidere lòt pwoblèm. Pou kounye a, ann ale nan OSI kouch 5, sesyon - kote yo mete MTProto sesyon.

Kle, mesaj, sesyon, Diffie-Hellman

Yo mete l 'la pa totalman kòrèkteman... Yon sesyon se pa menm sesyon an ki vizib nan koòdone a anba sesyon aktif. Men, nan lòd.

Kritik pwotokòl la ak apwòch òganizasyonèl nan Telegram. Pati 1, teknik: eksperyans nan ekri yon kliyan nan grafouyen - TL, MT

Se konsa, nou te resevwa yon kòd byte nan longè li te ye nan kouch transpò a. Sa a se swa yon mesaj chiffres oswa tèks plen - si nou toujou nan etap nan akò kle epi yo aktyèlman ap fè li. De kiyès nan pakèt konsèp yo rele "kle" n ap pale? Ann klarifye pwoblèm sa a pou ekip Telegram la li menm (mwen mande padon paske m te tradui pwòp dokiman pa m nan lang angle ak yon sèvo fatige a 4 am, li te pi fasil pou m kite kèk fraz jan yo ye a):

Gen de antite ki rele Sesyon - youn nan UI a nan kliyan ofisyèl anba "sesyon aktyèl", kote chak sesyon koresponn ak yon aparèy / OS antye.
Dezyèm - MTProto sesyon, ki gen nimewo sekans mesaj la (nan yon sans ki ba-nivo) ladan l, epi ki ka dire ant diferan koneksyon TCP. Plizyè sesyon MTProto ka enstale an menm tan, pou egzanp, akselere telechaje dosye.

Ant de sa yo sesyon gen yon konsèp otorizasyon. Nan ka a dejenere, nou ka di sa Sesyon UI se menm jan ak otorizasyon, men Ay, tout bagay se konplike. Ann gade:

  • Itilizatè a sou nouvo aparèy la premye jenere auth_key ak limit li nan kont, pou egzanp via SMS - se poutèt sa otorizasyon
  • Sa te rive anndan premye a MTProto sesyon, ki gen session_id anndan tèt ou.
  • Nan etap sa a, konbinezon an otorizasyon и session_id ta ka rele egzanp - mo sa a parèt nan dokiman ak kòd kèk kliyan
  • Lè sa a, kliyan an ka louvri kèk MTProto sesyon yo anba menm auth_key - nan menm DC a.
  • Lè sa a, yon jou kliyan an ap bezwen mande dosye a nan yon lòt DC - ak pou DC sa a yon nouvo pral pwodwi auth_key !
  • Pou enfòme sistèm lan ke se pa yon nouvo itilizatè ki anrejistre, men se menm bagay la otorizasyon (Sesyon UI), kliyan an sèvi ak apèl API auth.exportAuthorization nan kay DC auth.importAuthorization nan nouvo DC a.
  • Tout bagay se menm bagay la, plizyè ka louvri MTProto sesyon yo (yo chak ak pwòp pa yo session_id) nan nouvo DC sa a, anba l ' auth_key.
  • Finalman, kliyan an ka vle pafè Forward Secrecy. Chak auth_key te pèmanan kle - pou chak DC - ak kliyan an ka rele auth.bindTempAuthKey pou itilize tanporè auth_key - e ankò, yon sèl sèlman temp_auth_key pou chak DC, komen pou tout moun MTProto sesyon yo pou DC sa a.

remake, sa sèl (ak sèl fiti) se tou yon sèl sou auth_key sa yo. pataje ant tout moun MTProto sesyon yo nan menm DC a.

Ki sa "ant diferan TCP koneksyon" vle di? Se konsa, sa vle di yon bagay tankou bonbon otorizasyon sou yon sit entènèt - li pèsiste (siviv) anpil koneksyon TCP ak yon sèvè bay, men yon jou li ale move. Se sèlman kontrèman ak HTTP, nan MTProto mesaj ki nan yon sesyon yo se sekans nimewote ak konfime; si yo te antre nan tinèl la, koneksyon an te kase - apre yo fin etabli yon nouvo koneksyon, sèvè a pral dous voye tout bagay nan sesyon sa a ke li pa te delivre nan anvan an. TCP koneksyon.

Sepandan, enfòmasyon ki anwo yo rezime apre plizyè mwa envestigasyon. Nan entre-temps la, èske nou aplike kliyan nou an nan grate? - Ann tounen nan kòmansman an.

Se konsa, kite a jenere auth_key sou Vèsyon Diffie-Hellman soti nan Telegram. Ann eseye konprann dokiman an...

Vasily, [19.06.18 20:05] data_with_hash := SHA1 (done) + done + (nenpòt octets o aza); konsa ke longè a egal 255 bytes;
done_chiffre:= RSA (done_with_hash, server_public_key); yon nimewo 255-byte long (big endian) ogmante nan pouvwa a mande sou modil la nesesè, epi rezilta a estoke kòm yon nimewo 256-byte.

Yo gen kèk dope DH

Pa sanble DH yon moun ki an sante
Pa gen de kle piblik nan dx

Oke, nan fen a sa a te klase soti, men yon rezidi rete - prèv nan travay fè pa kliyan an ke li te kapab faktè nimewo a. Kalite pwoteksyon kont atak DoS. Ak kle RSA a sèlman itilize yon fwa nan yon direksyon, esansyèlman pou chifreman new_nonce. Men, pandan ke operasyon sa a w pèdi senp pral reyisi, ki sa ou pral gen fè fas a?

Vasily, [20.06.18/00/26 XNUMX:XNUMX] Mwen poko rive nan demann aplikasyon an.

Mwen voye demann sa a bay DH

Epi, nan waf transpò a li di ke li ka reponn ak 4 octets nan yon kòd erè. Se tout

Oke, li te di m '-404, ebyen kisa?

Se konsa, mwen te di l ': "Trape bullshit ou ankripte ak yon kle sèvè ak yon anprent tankou sa a, mwen vle DH," epi li reponn ak yon estipid 404.

Kisa ou ta panse de repons sèvè sa a? Kisa pou fe? Pa gen moun pou mande (men plis sou sa nan dezyèm pati a).

Isit la se tout enterè a fè sou waf la

Mwen pa gen anyen ankò pou m fè, mwen jis reve konvèti nimewo ale ak tounen

De nimewo 32 bit. Mwen chaje yo tankou tout lòt moun

Men, non, de sa yo bezwen ajoute nan liy lan an premye kòm BE

Vadim Goncharov, [20.06.18 15:49] ak poutèt sa 404?

Vasily, [20.06.18 15:49] WI!

Vadim Goncharov, [20.06.18 15:50] Se konsa, mwen pa konprann sa li ka "pa t 'jwenn"

Vasily, [20.06.18 15:50] apeprè

Mwen pa t 'kapab jwenn yon dekonpozisyon konsa nan faktè premye%

Nou pa t menm jere rapò erè

Vasily, [20.06.18 20:18] Oh, gen MD5 tou. Deja twa hash diferan

Anprent kle a kalkile jan sa a:

digest = md5(key + iv)
fingerprint = substr(digest, 0, 4) XOR substr(digest, 4, 4)

SHA1 ak sha2

Se konsa, ann mete l ' auth_key nou te resevwa 2048 bit nan gwosè lè l sèvi avèk Diffie-Hellman. Ki sa kap vini? Apre sa, nou dekouvri ke 1024 Bits ki pi ba yo nan kle sa a pa itilize nan okenn fason ... men ann reflechi sou sa a pou kounye a. Nan etap sa a, nou gen yon sekrè pataje ak sèvè a. Yo te etabli yon analogue nan sesyon TLS la, ki se yon pwosedi trè chè. Men, sèvè a toujou pa konnen anyen sou ki moun nou ye! Poko, aktyèlman. otorizasyon. Moun sa yo. si ou te panse an tèm de "login-modpas", jan ou te fè yon fwa nan ICQ, oswa omwen "konekte-kle", tankou nan SSH (pa egzanp, sou kèk gitlab / github). Nou te resevwa yon nonm. E si sèvè a di nou "yon lòt DC sèvi ak nimewo telefòn sa yo"? Oswa menm "nimewo telefòn ou entèdi"? Pi bon an nou ka fè se kenbe kle a nan espwa ke li pral itil epi li pa pral pouri lè sa a.

By wout la, nou "resevwa" li ak rezèvasyon. Pou egzanp, èske nou fè sèvè a konfyans? E si li fo? Chèk kriptografik yo ta bezwen:

Vasily, [21.06.18 17:53] Yo ofri kliyan mobil yo tcheke yon nimewo 2kbit pou primalite%)

Men, li pa klè ditou, nafeijoa

Vasily, [21.06.18 18:02] Dokiman an pa di kisa pou w fè si li pa senp.

Pa di. Ann wè kisa kliyan ofisyèl Android fè nan ka sa a? A se sa (e repons lan se wi, tout fichye a enteresan) - jan yo di, mwen pral jis kite sa a isit la:

278     static const char *goodPrime = "c71caeb9c6b1c9048e6c522f70f13f73980d40238e3e21c14934d037563d930f48198a0aa7c14058229493d22530f4dbfa336f6e0ac925139543aed44cce7c3720fd51f69458705ac68cd4fe6b6b13abdc9746512969328454f18faf8c595f642477fe96bb2a941d5bcd1d4ac8cc49880708fa9b378e3c4f3a9060bee67cf9a4a4a695811051907e162753b56b0f6b410dba74d8a84b2a14b3144e0ef1284754fd17ed950d5965b4b9dd46582db1178d169c6bc465b0d6ff9ca3928fef5b9ae4e418fc15e83ebea0f87fa9ff5eed70050ded2849f47bf959d956850ce929851f0d8115f635b105ee2e4e15d04b2454bf6f4fadf034b10403119cd8e3b92fcc5b";
279   if (!strcasecmp(prime, goodPrime)) {

Non, nan kou li toujou la kèk Gen tès pou prensipal yon nimewo, men pèsonèlman mwen pa gen ase konesans nan matematik ankò.

Oke, nou jwenn kle mèt la. Pou konekte, i.e. voye demann, ou bezwen fè plis chifreman, lè l sèvi avèk AES.

Kle mesaj la defini kòm 128 bit mitan SHA256 nan kò mesaj la (ki gen ladan sesyon, ID mesaj, elatriye), ki gen ladan byte yo padding, ak 32 byte yo pran nan kle otorizasyon an.

Vasily, [22.06.18 14:08] Mwayèn, chen, bits

Resevwa auth_key. Tout. Pi lwen pase yo... li pa klè nan dokiman an. Ou lib pou etidye kòd sous louvri.

Remake byen ke MTProto 2.0 mande pou ant 12 ak 1024 byte nan padding, toujou sijè a kondisyon pou longè mesaj la ki kapab lakòz divizib pa 16 byte.

Se konsa, konbyen padding ou ta dwe ajoute?

Epi wi, gen tou yon 404 nan ka ta gen yon erè

Si yon moun ak anpil atansyon etidye dyagram ak tèks dokiman an, yo remake ke pa gen MAC la. E ke AES yo itilize nan yon sèten mòd IGE ki pa itilize okenn lòt kote. Yo, nan kou, ekri sou sa a nan FAQ yo ... Isit la, tankou, kle mesaj la tèt li se tou hash SHA nan done yo dechifre, yo itilize yo tcheke entegrite a - ak nan ka ta gen yon dezakò, dokiman an pou kèk rezon. rekòmande pou inyore yo an silans (men e sekirite, e si yo kraze nou?).

Mwen pa yon kriptograf, petèt pa gen anyen ki mal ak mòd sa a nan ka sa a soti nan yon pwen de vi teyorik. Men, mwen ka byen klè nonmen yon pwoblèm pratik, lè l sèvi avèk Telegram Desktop kòm yon egzanp. Li ankripte kachèt lokal la (tout D877F783D5D3EF8C sa yo) menm jan ak mesaj nan MTProto (sèlman nan ka sa a vèsyon 1.0), i.e. premye kle mesaj la, Lè sa a, done nan tèt li (ak yon kote sou kote gwo prensipal la auth_key 256 octets, san ki msg_key initil). Se konsa, pwoblèm nan vin aparan sou dosye gwo. Savwa, ou bezwen kenbe de kopi done yo - chiffres Et decrypted. Men, si gen megabyte, oswa videyo difizyon, pou egzanp? .. Konplo klasik ak MAC apre tèks chifre a pèmèt ou li li kouran, imedyatman transmèt li. Men, ak MTProto ou pral oblije an premye ankripte oswa dechifre mesaj la tout antye, sèlman Lè sa a, transfere li nan rezo a oswa nan disk. Se poutèt sa, nan dènye vèsyon yo nan Telegram Desktop nan kachèt la nan user_data Yo itilize yon lòt fòma tou - ak AES nan mòd CTR.

Vasily, [21.06.18 01:27] Oh, mwen te jwenn ki sa IGE ye: IGE te premye tantativ nan yon "otantifikasyon mòd chifreman," orijinal pou Kerberos. Se te yon tantativ echwe (li pa bay pwoteksyon entegrite), e li te dwe retire. Sa a te kòmansman yon demand 20 ane pou yon mòd chifreman otantifikasyon ki travay, ki dènyèman abouti nan mòd tankou OCB ak GCM.

Epi, koulye a agiman yo soti nan bò kabwa a:

Ekip la dèyè Telegram, ki te dirije pa Nikolai Durov, konsiste de sis chanpyon ACM, mwatye nan yo Ph.Ds nan matematik. Li te pran yo apeprè de ane yo woule vèsyon aktyèl la nan MTProto.

Sa komik. De ane nan nivo ki pi ba yo

Oswa ou ta ka jis pran tls

Oke, an n di nou te fè chifreman an ak lòt nuans. Èske li posib finalman voye demann seri nan TL ak deserialize repons yo? Se konsa, ki sa ak ki jan ou ta dwe voye? Isit la, an n di, metòd la initConnection, petèt sa a se li?

Vasily, [25.06.18 18:46] Inisyalize koneksyon epi sove enfòmasyon sou aparèy itilizatè a ak aplikasyon an.

Li aksepte app_id, device_model, system_version, app_version ak lang_code.

Ak kèk rechèch

Dokimantasyon kòm toujou. Ezite etidye sous la louvri

Si tout bagay te apeprè klè ak invokeWithLayer, Lè sa a, kisa ki mal isit la? Li sanble, ann di nou - kliyan an te deja gen yon bagay yo mande sèvè a sou - gen yon demann ke nou te vle voye:

Vasily, [25.06.18 19:13] Jije dapre kòd la, premye apèl la vlope nan krap sa a, epi crap la li menm vlope nan invokewithlayer.

Poukisa initConnection pa t 'kapab yon apèl separe, men li dwe yon anbalaj? Wi, jan li te tounen soti, li dwe fè chak fwa nan kòmansman an nan chak sesyon, epi yo pa yon fwa, menm jan ak kle prensipal la. Men! Li pa ka rele pa yon itilizatè san otorizasyon! Koulye a, nou te rive nan etap kote li aplikab Yon sèl sa a paj dokimantasyon - epi li di nou ke...

Sèlman yon ti pati nan metòd API yo disponib pou itilizatè ki pa otorize:

  • auth.sendCode
  • auth.resendCode
  • account.getPassword
  • auth.checkPassword
  • auth.checkPhone
  • auth.signUp
  • auth.signIn
  • auth.importAuthorization
  • help.getConfig
  • ede.getNearestDc
  • help.getAppUpdate
  • help.getCdnConfig
  • langpack.getLangPack
  • langpack.getStrings
  • langpack.getDifference
  • langpack.getLanguages
  • langpack.getLanguage

Premye nan yo, auth.sendCode, epi gen sa a cheri premye demann nan ki nou voye api_id ak api_hash, epi apre sa nou resevwa yon SMS ak yon kòd. Men, si nou nan move DC a (nimewo telefòn nan peyi sa a se sèvi pa yon lòt, pou egzanp), Lè sa a, nou pral resevwa yon erè ak nimewo a nan DC vle a. Pou chèche konnen ki adrès IP pa nimewo DC ou bezwen konekte, ede nou help.getConfig. Nan yon sèl fwa te gen sèlman 5 antre, men apre evènman yo pi popilè nan 2018, nimewo a te ogmante anpil.

Koulye a, kite a sonje ke nou te rive nan etap sa a sou sèvè a anonim. Èske li pa twò chè jis jwenn yon adrès IP? Poukisa nou pa fè sa a, ak lòt operasyon, nan pati ki pa chiffres nan MTProto? Mwen tande objeksyon an: "kijan nou ka asire w ke se pa RKN ki pral reponn ak fo adrès?" Pou sa a nou sonje ke, an jeneral, kliyan ofisyèl yo Kle RSA yo entegre, i.e. ou ka jis siyen enfòmasyon sa a. Aktyèlman, sa a deja fèt pou enfòmasyon sou kontoune bloke ke kliyan yo resevwa atravè lòt chanèl (lojikman, sa a pa ka fè nan MTProto tèt li; ou bezwen tou konnen ki kote konekte).

OK. Nan etap sa a nan otorizasyon kliyan an, nou poko otorize epi nou poko anrejistre aplikasyon nou an. Nou jis vle wè pou kounye a sa sèvè a reponn a metòd ki disponib pou yon itilizatè san otorizasyon. Ak isit la...

Vasily, [10.07.18 14:45] https://core.telegram.org/method/help.getConfig

config#7dae33e0 [...] = Config;
help.getConfig#c4f9186b = Config;

https://core.telegram.org/api/datacenter

config#232d5905 [...] = Config;
help.getConfig#c4f9186b = Config;

Nan konplo a, premye vini dezyèm fwa

Nan chema tdesktop twazyèm valè a se

Wi, depi lè sa a, nan kou, dokiman an te mete ajou. Malgre ke li ka byento vin petinan ankò. Ki jan yon pwomotè inisyasyon ta dwe konnen? Petèt si ou anrejistre aplikasyon w lan, yo pral enfòme w? Vasily te fè sa, men Ay, yo pa t 'voye l' anyen (ankò, nou pral pale sou sa a nan dezyèm pati a).

...Ou remake ke nou te deja yon jan kanmenm deplase nan API a, i.e. nan nivo siperyè-a, ak rate yon bagay nan sijè a MTProto? Pa gen sipriz:

Vasily, [28.06.18 02:04] Mm, yo ap fouye kèk nan algoritm yo sou e2e.

Mtproto defini algorithm chifreman ak kle pou tou de domèn, osi byen ke yon ti jan nan yon estrikti anbalaj.

Men, yo toujou ap melanje diferan nivo pil la, kidonk li pa toujou klè kote mtproto te fini ak pwochen nivo a te kòmanse.

Ki jan yo melanje? Oke, isit la se menm kle tanporè pou PFS, pou egzanp (pa chemen an, Telegram Desktop pa ka fè li). Li egzekite pa yon demann API auth.bindTempAuthKey, i.e. soti nan nivo siperyè-a. Men, an menm tan an entèfere ak chifreman nan nivo ki pi ba - apre li, pou egzanp, ou bezwen fè li ankò. initConnection elatriye, sa a se pa jis demann nòmal. Ki sa ki espesyal tou se ke ou ka gen sèlman YON kle tanporè pou chak DC, byenke jaden an auth_key_id nan chak mesaj pèmèt ou chanje kle a omwen chak mesaj, e ke sèvè a gen dwa "bliye" kle a tanporè a nenpòt ki lè - dokiman an pa di sa yo dwe fè nan ka sa a ... byen, poukisa pa t 'kapab. ou pa gen plizyè kle, menm jan ak yon seri sèl nan lavni, ak?...

Gen kèk lòt bagay ki vo anyen sou tèm nan MTProto.

Mesaj mesaj, msg_id, msg_seqno, konfimasyon, ping nan move direksyon ak lòt idiosinkrasi

Poukisa ou bezwen konnen sou yo? Paske yo "fuit" nan yon nivo ki pi wo, epi ou bezwen konnen yo lè w ap travay ak API a. Ann sipoze nou pa enterese nan msg_key; nivo ki pi ba a te dechifre tout bagay pou nou. Men, andedan done yo dechifre nou gen jaden sa yo (tou longè done yo, pou nou konnen ki kote padding a ye, men sa a pa enpòtan):

  • sèl - int64
  • session_id - int64
  • message_id — int64
  • seq_no - int32

Se pou nou raple w ke gen yon sèl sèl pou tout DC a. Poukisa konnen sou li? Se pa sèlman paske gen yon demann get_future_salts, ki di ou ki entèval yo pral valab, men tou paske si sèl ou a "pouri", Lè sa a, mesaj la (demann) ap tou senpleman pèdi. Sèvè a pral, nan kou, rapòte nouvo sèl la pa founi dokiman yo new_session_created - men ak ansyen an ou pral oblije renvoyer li yon jan kanmenm, pou egzanp. Ak pwoblèm sa a afekte achitekti aplikasyon an.

Sèvè a gen dwa lage sesyon yo tout ansanm epi reponn nan fason sa a pou plizyè rezon. Aktyèlman, ki sa ki se yon sesyon MTProto nan bò kliyan an? Sa yo se de nimewo session_id и seq_no mesaj nan sesyon sa a. Oke, ak koneksyon TCP kache a, nan kou. Ann di kliyan nou an toujou pa konnen ki jan fè anpil bagay, li dekonekte ak rekonekte. Si sa te rive byen vit - ansyen sesyon an kontinye nan nouvo koneksyon TCP a, ogmante seq_no pi lwen. Si li pran yon bon bout tan, sèvè a ta ka efase li, paske sou bò li se tou yon keu, jan nou te jwenn.

Ki sa li ta dwe ye seq_no? Oh, sa se yon kesyon difisil. Eseye konprann onètman sa yo te vle di:

Mesaj ki gen rapò ak kontni

Yon mesaj ki mande yon rekonesans eksplisit. Sa yo enkli tout itilizatè a ak anpil mesaj sèvis, nòmalman tout eksepte resipyan ak rekonesans.

Nimewo Sekans Mesaj (msg_seqno)

Yon nimewo 32-bit ki egal a de fwa kantite mesaj "ki gen rapò ak kontni" (sa yo ki mande rekonesans, epi an patikilye sa yo ki pa resipyan) ki te kreye pa moun k ap voye mesaj la anvan mesaj sa a epi apre sa ogmante pa youn si mesaj aktyèl la se yon mesaj ki gen rapò ak kontni. Yon veso toujou pwodwi apre tout sa ki ladan l; Se poutèt sa, nimewo sekans li yo pi gran pase oswa egal ak nimewo sekans mesaj yo genyen ladan yo.

Ki kalite sirk sa a ak yon enkreman pa 1, ak Lè sa a, yon lòt pa 2? .. Mwen sispèk ke okòmansman yo te vle di "ti pi piti a enpòtan pou ACK, rès la se yon nimewo", men rezilta a se pa byen menm - an patikilye, li soti, yo ka voye kèk konfimasyon ki gen menm bagay la tou seq_no! Ki jan? Oke, pou egzanp, sèvè a voye nou yon bagay, voye li, epi nou menm nou rete an silans, sèlman reponn ak mesaj sèvis ki konfime resi mesaj li yo. Nan ka sa a, konfimasyon sortan nou yo ap gen menm nimewo sòtan an. Si ou abitye ak TCP ak panse ke sa a son yon jan kanmenm sovaj, men li sanble pa trè sovaj, paske nan TCP seq_no pa chanje, men konfimasyon ale nan seq_no sou lòt bò a, mwen pral prese fache ou. Yo bay konfimasyon nan MTProto PA sou seq_no, tankou nan TCP, men pa msg_id !

Kisa sa ye msg_id, ki pi enpòtan nan jaden sa yo? Yon idantifyan mesaj inik, jan non an sijere. Li defini kòm yon nimewo 64-bit, ti moso ki pi ba yo ankò gen "sèvè-pa-sèvè" majik la, ak rès la se yon timestamp Unix, ki gen ladan pati nan fraksyon, deplase 32 bit sou bò gòch la. Moun sa yo. timestamp per se (ak mesaj ki gen tan ki diferan twòp ap rejte pa sèvè a). Soti nan sa a li sanble ke an jeneral sa a se yon idantifyan ki mondyal pou kliyan an. Etandone sa - ann sonje session_id - nou garanti: Nan okenn sikonstans, yo pa ka voye yon mesaj ki fèt pou yon sesyon nan yon lòt sesyon. Sa vle di, li sanble ke gen deja twa nivo - sesyon, nimewo sesyon, id mesaj. Poukisa sa yo twòp konplikasyon, mistè sa a se gwo anpil.

Se konsa, msg_id bezwen pou...

RPC: demann, repons, erè. Konfimasyon.

Kòm ou te remake, pa gen okenn kalite espesyal "fè yon demann RPC" oswa fonksyon nenpòt kote nan dyagram nan, byenke gen repons. Apre yo tout, nou gen mesaj ki gen rapò ak kontni! Sa vle di nenpòt mesaj la ta ka yon demann! Oswa pa dwe. Apre tou, chak gen msg_id. Men, gen repons:

rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult;

Sa a se kote li endike ki mesaj sa a se yon repons. Se poutèt sa, nan nivo siperyè API a, ou pral oblije sonje ki kantite demann ou an te - mwen panse ke pa gen okenn bezwen eksplike ke travay la se asynchrone, epi ka gen plizyè demann nan pwogrè an menm tan, repons yo ki ka retounen nan nenpòt lòd? Nan prensip, soti nan mesaj sa a ak erè tankou pa gen okenn travayè, achitekti ki dèyè sa a ka remonte: sèvè a ki kenbe yon koneksyon TCP avèk ou se yon balanse front-end, li voye demann bay backend yo epi kolekte yo tounen atravè. message_id. Li sanble ke tout bagay isit la se klè, lojik ak bon.

Wi?.. E si ou panse osijè de sa? Apre yo tout, repons lan RPC tèt li tou gen yon jaden msg_id! Èske nou bezwen rele nan sèvè a "ou pa reponn repons mwen an!"? Epi wi, ki sa ki te genyen sou konfimasyon? Sou paj mesaj sou mesaj yo di nou kisa

msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck;

epi li dwe fèt pa chak bò. Men, pa toujou! Si ou te resevwa yon RpcResult, li menm li sèvi kòm yon konfimasyon. Sa vle di, sèvè a ka reponn demann ou an ak MsgsAck - tankou, "Mwen te resevwa li." RpcResult ka reponn imedyatman. Li ta ka tou de.

E wi, ou toujou gen pou reponn repons lan! Konfimasyon. Sinon, sèvè a pral konsidere li pa ka delivre epi voye li tounen ba ou ankò. Menm apre rekoneksyon. Men, isit la, nan kou, pwoblèm nan nan timeout rive. Ann gade yo yon ti kras pita.

Antretan, an n gade nan posib erè ekzekisyon demann.

rpc_error#2144ca19 error_code:int error_message:string = RpcError;

Oh, yon moun pral di, isit la se yon fòma pi imen - gen yon liy! Pran tan ou. Isit la lis erè, men nan kou pa konplè. Soti nan li nou aprann ke kòd la se yon bagay tankou Erè HTTP (byen, nan kou, semantik repons yo pa respekte, nan kèk kote yo distribye owaza nan mitan kòd yo), ak liy lan sanble. CAPITAL_LETTERS_AND_NUMBERS. Pa egzanp, PHONE_NUMBER_OCCUPIED oswa FILE_PART_Х_MISSING. Oke, se sa ki, w ap toujou bezwen liy sa a analize. Pou egzanp FLOOD_WAIT_3600 pral vle di ke ou oblije rete tann yon èdtan, ak PHONE_MIGRATE_5, ke yon nimewo telefòn ki gen prefiks sa a dwe anrejistre nan 5yèm DC a. Nou gen yon lang tip, pa vre? Nou pa bezwen yon agiman ki soti nan yon fisèl, yo menm regilye yo pral fè, oke.

Ankò, sa a se pa sou paj mesaj sèvis la, men, jan sa deja abityèl ak pwojè sa a, enfòmasyon an ka jwenn. sou yon lòt paj dokiman. Oswa jete sispèk. Premyèman, gade, sezisman / vyolasyon kouch - RpcError ka fè nich nan RpcResult. Poukisa pa deyò? Ki sa nou pa t 'pran an kont?.. An konsekans, ki kote garanti a ke RpcError PA ka entegre nan RpcResult, men dwe dirèkteman oswa nich nan yon lòt kalite?.. Men, si li pa kapab, poukisa se pa li nan nivo siperyè-a, i.e. li manke req_msg_id ? ..

Men, ann kontinye sou mesaj sèvis yo. Kliyan an ka panse ke sèvè a ap panse pou yon tan long epi fè bèl demann sa a:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

Gen twa repons posib pou kesyon sa a, ankò kwaze ak mekanis konfimasyon an; eseye konprann ki sa yo ta dwe ye (ak ki lis jeneral la nan kalite ki pa mande pou konfimasyon) se kite pou lektè a kòm devwa (nòt: enfòmasyon ki nan kòd sous Telegram Desktop la pa konplè).

Dejwe dwòg: estati mesaj

An jeneral, anpil kote nan TL, MTProto ak Telegram an jeneral kite yon santiman tèt di, men soti nan politès, tak ak lòt moun. ladrès mou Nou politès te kenbe an silans sou li, ak sansi obscenite yo nan dyalòg yo. Sepandan, kote sa aОpi fò nan paj la se sou mesaj sou mesaj yo Li chokan menm pou mwen, ki te travay ak pwotokòl rezo pou yon tan long epi ki te wè bisiklèt nan diferan degre nan kwochi.

Li kòmanse inosan, ak konfimasyon. Apre sa yo di nou sou

bad_msg_notification#a7eff811 bad_msg_id:long bad_msg_seqno:int error_code:int = BadMsgNotification;
bad_server_salt#edab447b bad_msg_id:long bad_msg_seqno:int error_code:int new_server_salt:long = BadMsgNotification;

Oke, tout moun ki kòmanse travay ak MTProto pral gen fè fas ak yo; nan sik la "korije - rekonpile - lanse", jwenn erè nimewo oswa sèl ki jere yo ale mal pandan modifye se yon bagay komen. Sepandan, gen de pwen isit la:

  1. Sa vle di ke mesaj orijinal la pèdi. Nou bezwen kreye kèk keu, nou pral gade pita.
  2. Ki nimewo erè sa yo etranj? 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 64... kote lòt nimewo yo, Tommy?

Dokiman an di:

Entansyon an se ke valè error_code yo gwoupe (error_code >> 4): pou egzanp, kòd yo 0x40 — 0x4f koresponn ak erè nan dekonpozisyon veso.

men, premyèman, yon chanjman nan lòt direksyon an, epi dezyèmman, li pa enpòtan, ki kote lòt kòd yo? Nan tèt otè a?.. Sepandan, sa yo se vetiy.

Dejwe kòmanse nan mesaj sou estati mesaj ak kopi mesaj:

  • Demann enfòmasyon sou sitiyasyon mesaj la
    Si youn nan pati yo pa te resevwa enfòmasyon sou estati mesaj sortan li yo pou yon ti tan, li ka mande l klèman nan men lòt pati a:
    msgs_state_req#da69fb52 msg_ids:Vector long = MsgsStateReq;
  • Mesaj Enfòmasyon konsènan Sitiyasyon Mesaj yo
    msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
    Isit la, info se yon fisèl ki gen egzakteman yon byte nan estati mesaj pou chak mesaj ki soti nan lis msg_ids kap vini yo:

    • 1 = pa gen anyen konnen sou mesaj la (msg_id twò ba, lòt pati a ka bliye li)
    • 2 = mesaj pa resevwa (msg_id tonbe nan seri idantifyan ki estoke; sepandan, lòt pati a sètènman pa resevwa yon mesaj konsa)
    • 3 = mesaj pa resevwa (msg_id twò wo; sepandan, lòt pati a sètènman poko resevwa li)
    • 4 = mesaj ou resevwa (remake byen ke repons sa a se tou an menm tan an yon rekonesans resi)
    • +8 = mesaj deja rekonèt
    • +16 = mesaj ki pa mande rekonesans
    • +32 = Rekèt RPC ki nan mesaj k ap trete oswa pwosesis deja fini
    • +64 = repons ki gen rapò ak kontni a mesaj deja pwodwi
    • +128 = lòt pati konnen byen ke mesaj deja resevwa
      Repons sa a pa mande pou yon rekonesans. Li se yon rekonesans nan msgs_state_req ki enpòtan, nan ak nan tèt li.
      Remake byen ke si li vire soti toudenkou ke lòt pati a pa gen yon mesaj ki sanble li te voye ba li, mesaj la ka tou senpleman re-voye. Menm si lòt pati a ta dwe resevwa de kopi mesaj la an menm tan, kopi a pral inyore. (Si gen twòp tan pase, epi msg_id orijinal la pa valab ankò, mesaj la dwe vlope nan msg_copy).
  • Kominikasyon volontè sou sitiyasyon mesaj yo
    Nenpòt pati ka volontèman enfòme lòt pati a sou sitiyasyon mesaj lòt pati a transmèt.
    msgs_all_info#8cc0d131 msg_ids:Vector long info:string = MsgsAllInfo
  • Kominikasyon volontè pwolonje sou sitiyasyon yon mesaj
    ...
    msg_detailed_info#276d3ec6 msg_id:long answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
    msg_new_detailed_info#809db6df answer_msg_id:long bytes:int status:int = MsgDetailedInfo;
  • Demann eksplisit pou re-voye mesaj yo
    msg_resend_req#7d861a08 msg_ids:Vector long = MsgResendReq;
    Pati a aleka reponn imedyatman lè li voye mesaj yo mande yo [...]
  • Demann Eksplis pou Re-Voye Repons yo
    msg_resend_ans_req#8610baeb msg_ids:Vector long = MsgResendReq;
    Pati a aleka reponn imedyatman pa re-voye repons nan mesaj yo mande yo […]
  • Kopi mesaj
    Nan kèk sitiyasyon, yon ansyen mesaj ki gen yon msg_id ki pa valab ankò bezwen re-voye. Lè sa a, li vlope nan yon veso kopi:
    msg_copy#e06046b2 orig_message:Message = MessageCopy;
    Yon fwa resevwa mesaj la trete kòm si wrapper a pa t 'la. Sepandan, si yo konnen se sèten ke mesaj orig_message.msg_id la te resevwa, lè sa a nouvo mesaj la pa trete (pandan an menm tan an, li ak orig_message.msg_id yo rekonèt). Valè orig_message.msg_id dwe pi ba pase msg_id veso a.

An nou menm rete trankil sou sa msgs_state_info ankò zòrèy yo nan TL ki pa fini yo rete deyò (nou te bezwen yon vektè nan bytes, ak nan de bit ki pi ba yo te gen yon enum, ak nan de ti ki pi wo yo te gen drapo). Pwen an diferan. Èske gen moun ki konprann poukisa tout bagay sa yo an pratik? nan yon kliyan reyèl nesesè?.. Avèk difikilte, men yon moun ka imajine kèk benefis si yon moun angaje nan debogaj, ak nan yon mòd entèaktif - mande sèvè a ki sa ak ki jan. Men, isit la demann yo dekri ale retou.

Li swiv ke chak pati dwe pa sèlman ankripte ak voye mesaj, men tou, sere done sou tèt yo, sou repons yo bay yo, pou yon kantite tan enkoni. Dokimantasyon an pa dekri ni tan yo ni aplikasyon pratik karakteristik sa yo. nan okenn fason. Ki sa ki pi etonan se ke yo aktyèlman itilize nan kòd la nan kliyan ofisyèl! Aparamman yo te di yon bagay ki pa te enkli nan dokiman piblik la. Konprann nan kòd la poukisa, se pa senp tankou nan ka a nan TL - li se pa yon pati (relativman) lojikman izole, men yon moso mare nan achitekti aplikasyon an, i.e. pral mande siyifikativman plis tan pou konprann kòd aplikasyon an.

Ping ak tan. Ke moun kap kriye.

Soti nan tout bagay, si nou sonje devine yo sou achitekti sèvè a (distribisyon demann atravè backends), yon bagay olye tris swiv - malgre tout garanti yo livrezon nan TCP (swa done yo delivre, oswa ou pral enfòme sou espas sa a, men done yo pral delivre anvan pwoblèm nan rive), ke konfimasyon nan MTProto tèt li - pa gen okenn garanti. Sèvè a ka fasilman pèdi oswa voye mesaj ou a, epi pa gen anyen ki ka fè sou li, jis itilize diferan kalite beki.

Ak premye a tout - mesaj ke moun kap kriye. Oke, ak yon sèl bagay tout bagay te evidan depi nan konmansman an anpil - yon mesaj ki pa konfime yo dwe estoke ak ranvwaye. E apre ki lè? Epi boufon an konnen li. Petèt mesaj sèvis dejwe sa yo yon jan kanmenm rezoud pwoblèm sa a ak beki, di, nan Telegram Desktop gen apeprè 4 ke moun kap kriye ki koresponn ak yo (petèt plis, kòm deja mansyone, pou sa ou bezwen fouye nan kòd li yo ak achitekti pi seryezman; an menm tan an. tan, nou konnen ke li pa ka pran kòm yon echantiyon; yon sèten kantite kalite ki soti nan konplo MTProto yo pa itilize nan li).

Poukisa sa ap pase? Pwobableman, pwogramasyon sèvè yo pa t kapab asire fyab nan gwoup la, oswa menm tanpon sou balans devan an, epi yo te transfere pwoblèm sa a nan kliyan an. Nan dezespwa, Vasily te eseye aplike yon opsyon altènatif, ak sèlman de ke moun kap kriye, lè l sèvi avèk algoritm ki soti nan TCP - mezire RTT a sèvè a ak ajiste gwosè a nan "fenèt la" (nan mesaj) depann sou kantite demann ki pa konfime. Sa vle di, tankou yon eristik ki graj pou evalye chaj sèvè a se konbyen nan demann nou an li ka moulen an menm tan an epi yo pa pèdi.

Oke, sa vle di, ou konprann, dwa? Si ou gen pou aplike TCP ankò sou tèt yon pwotokòl kouri sou TCP, sa endike yon pwotokòl trè mal conçu.

Oh wi, poukisa ou bezwen plis pase yon keu, e ki sa sa vle di pou yon moun k ap travay ak yon API wo nivo de tout fason? Gade, ou fè yon demann, seri li, men souvan ou pa ka voye li imedyatman. Poukisa? Paske repons lan pral msg_id, ki se tanporèаMwen se yon etikèt, plasman nan ki pi bon ranvwaye jiska osi ta ke posib - nan ka sèvè a rejte li akòz yon dezakò nan tan ant nou menm ak li (nan kou, nou ka fè yon beki ki deplase tan nou soti nan prezan an. nan sèvè a lè yo ajoute yon delta kalkile nan repons sèvè a - kliyan ofisyèl yo fè sa, men li se brit ak kòrèk akòz tanpon). Se poutèt sa, lè ou fè yon demann ak yon apèl fonksyon lokal nan bibliyotèk la, mesaj la ale nan etap sa yo:

  1. Li kouche nan yon sèl keu epi li ap tann chifreman.
  2. Nonmen msg_id ak mesaj la te ale nan yon lòt keu - posib voye; voye nan priz la.
  3. a) Sèvè a reponn MsgsAck - mesaj la te delivre, nou efase li nan "lòt keu la".
    b) Oswa vis vèrsa, li pa t renmen yon bagay, li te reponn badmsg - revoye soti nan "yon lòt keu"
    c) Pa gen anyen li te ye, mesaj la bezwen yo dwe voye soti nan yon lòt keu - men li pa konnen egzakteman ki lè.
  4. Sèvè a finalman reponn RpcResult - repons aktyèl la (oswa erè) - pa sèlman delivre, men tou, trete.

Petèt, itilize nan resipyan ka pasyèlman rezoud pwoblèm nan. Sa a se lè yon pakèt mesaj yo chaje nan yon sèl, ak sèvè a reponn ak yon konfimasyon yo tout nan yon fwa, nan yon sèl. msg_id. Men, li pral tou rejte pake sa a, si yon bagay ale mal, nan antye li yo.

Ak nan pwen sa a, konsiderasyon ki pa teknik antre nan jwèt. Apati eksperyans, nou te wè anpil beki, epi anplis, kounye a nou pral wè plis egzanp move konsèy ak achitekti - nan kondisyon sa yo, èske li vo fè konfyans ak pran desizyon sa yo? Kesyon an se retorisyen (nan kou pa).

De kisa nap pale? Si sou sijè a nan "mesaj dwòg sou mesaj" ou ka toujou espekile ak objeksyon tankou "ou se estipid, ou pa t 'konprann plan briyan nou an!" (Se konsa, ekri dokiman an premye, jan moun nòmal yo ta dwe, ak rezon ak egzanp nan echanj pake, Lè sa a, nou pral pale), Lè sa a, timings / timeouts se yon kesyon piman pratik ak espesifik, tout bagay isit la te konnen pou yon tan long. Ki sa dokimantasyon an di nou sou timeout?

Yon sèvè anjeneral rekonèt li resevwa yon mesaj soti nan yon kliyan (nòmalman, yon demann RPC) lè l sèvi avèk yon repons RPC. Si yon repons se yon bon bout tan ap vini, yon sèvè ka premye voye yon rekonesans resi, ak yon ti jan pita, repons lan RPC tèt li.

Yon kliyan nòmalman rekonèt li resevwa yon mesaj ki soti nan yon sèvè (anjeneral, yon repons RPC) lè li ajoute yon rekonesans nan pwochen rechèch RPC a si li pa transmèt twò ta (si li pwodui, di, 60-120 segonn apre resi a). nan yon mesaj ki soti nan sèvè a). Sepandan, si pou yon peryòd tan ki long pa gen okenn rezon pou voye mesaj nan sèvè a oswa si gen yon gwo kantite mesaj ki pa rekonèt ki soti nan sèvè a (di, plis pase 16), kliyan an transmèt yon rekonesans endepandan.

... Mwen tradui: nou menm nou pa konnen konbyen ak ki jan nou bezwen li, kidonk ann sipoze ke kite l 'se konsa.

Ak sou ping:

Mesaj Ping (PING/PONG)

ping#7abe77ec ping_id:long = Pong;

Yon repons anjeneral retounen nan menm koneksyon an:

pong#347773c5 msg_id:long ping_id:long = Pong;

Mesaj sa yo pa mande pou rekonesans. Yon pong transmèt sèlman an repons a yon ping pandan y ap yon ping ka inisye pa chak bò.

Fèmti Koneksyon Difere + PING

ping_delay_disconnect#f3427b8c ping_id:long disconnect_delay:int = Pong;

Travay tankou ping. Anplis de sa, apre yo fin resevwa sa a, sèvè a kòmanse yon revèy ki pral fèmen koneksyon aktyèl la disconnect_delay segonn pita sof si li resevwa yon nouvo mesaj nan menm kalite a ki otomatikman reset tout revèy anvan yo. Si kliyan an voye ping sa yo yon fwa chak 60 segonn, pou egzanp, li ka mete disconnect_delay egal a 75 segonn.

Ou fou?! Nan 60 segonn, tren an pral antre nan estasyon an, depoze epi ranmase pasaje yo, epi ankò pèdi kontak nan tinèl la. Nan 120 segonn, pandan w ap tande l, li pral rive nan yon lòt, epi koneksyon an ap gen plis chans kraze. Oke, li klè kote pye yo soti - "Mwen tande yon sonnen, men mwen pa konnen ki kote li ye", gen algorithm Nagl a ak opsyon TCP_NODELAY, ki fèt pou travay entèaktif. Men, eskize m ', kenbe sou valè default li yo - 200 Millisegonn Si ou reyèlman vle dekri yon bagay ki sanble epi sove sou yon koup posib nan pake, Lè sa a, mete li koupe pou 5 segonn, oswa kèlkeswa "Itilizatè a ap tape ..." delè mesaj la se kounye a. Men, pa plis.

Epi finalman, pings. Sa vle di, tcheke lavi a nan koneksyon TCP la. Li komik, men sou 10 ane de sa mwen te ekri yon tèks kritik sou mesaje a nan dòtwa fakilte nou an - otè yo gen tou ping sèvè a soti nan kliyan an, epi yo pa vis vèrsa. Men, elèv 3yèm ane yo se yon bagay, epi yon biwo entènasyonal se yon lòt, pa vre?

Premyèman, yon ti pwogram edikasyon. Yon koneksyon TCP, nan absans echanj pake, ka viv pou semèn. Sa a se tou de bon ak move, tou depann de objektif la. Li bon si ou te gen yon koneksyon SSH ki louvri sou sèvè a, ou leve soti nan òdinatè a, rekòmanse routeur la, retounen nan plas ou - sesyon an atravè sèvè sa a pa te chire (ou pa t 'tape anyen, pa te gen okenn pake) , li pratik. Li pa bon si gen dè milye de kliyan sou sèvè a, chak pran resous (alo, Postgres!), ak lame kliyan an ka rekòmanse depi lontan - men nou pa pral konnen sou li.

Sistèm chat/IM tonbe nan dezyèm ka a pou yon lòt rezon - estati online. Si itilizatè a "tonbe", ou bezwen enfòme entèrlokuteur li yo sou sa. Sinon, ou pral fini ak yon erè ke kreyatè yo nan Jabber te fè (ak korije pou 20 ane) - itilizatè a te dekonekte, men yo kontinye ekri mesaj ba li, kwè ke li se sou entènèt (ki te tou konplètman pèdi nan sa yo). kèk minit anvan yo te dekouvri dekonekte a). Non, opsyon TCP_KEEPALIVE, ke anpil moun ki pa konprann ki jan TCP timers travay jete owaza (pa mete valè sovaj tankou dizèn segonn), pa pral ede isit la - ou bezwen asire w ke pa sèlman nwayo OS la. nan machin itilizatè a se vivan, men tou, fonksyone nòmalman, nan kapab reponn, ak aplikasyon an tèt li (ou panse li pa ka friz? Telegram Desktop sou Ubuntu 18.04 te jele pou mwen plis pase yon fwa).

Se poutèt sa ou oblije ping sèvè kliyan, epi yo pa vis vèrsa - si kliyan an fè sa, si koneksyon an kase, ping la pa pral delivre, objektif la pa pral reyalize.

Kisa nou wè sou Telegram? Se egzakteman opoze a! Oke, sa se. Fòmèlman, nan kou, tou de bò yo ka ping youn ak lòt. Nan pratik, kliyan yo sèvi ak yon beki ping_delay_disconnect, ki mete revèy la sou sèvè a. Bon, eskize m, se pa kliyan an deside konbyen tan li vle viv la san ping. Sèvè a, ki baze sou chaj li yo, konnen pi byen. Men, nan kou, si ou pa okipe resous yo, Lè sa a, ou pral pwòp ou a sa ki mal Pinokyo, ak yon beki pral fè ...

Ki jan li ta dwe fèt?

Mwen kwè ke reyalite ki anwo yo montre klèman ke ekip Telegram/VKontakte a pa trè konpetan nan domèn transpò (ak pi ba) nivo rezo òdinatè ak kalifikasyon ba yo nan zafè ki enpòtan.

Poukisa li te vin tèlman konplike, e ki jan achitèk Telegram yo ka eseye fè objeksyon? Lefèt ke yo te eseye fè yon sesyon ki siviv TCP koneksyon kraze, sa vle di, sa ki pa te delivre kounye a, nou pral delivre pita. Pwobableman yo te eseye tou fè yon transpò UDP, men yo te rankontre difikilte epi yo te abandone li (Se poutèt sa dokiman an vid - pa te gen anyen pou fè djòlè). Men, akòz yon mank de konpreyansyon sou ki jan rezo an jeneral ak TCP an patikilye travay, kote ou ka konte sou li, ak ki kote ou bezwen fè li tèt ou (ak ki jan), ak yon tantativ konbine sa a ak kriptografik "de zwazo ak yon sèl wòch ", sa a se rezilta a.

Ki jan li te nesesè? Baze sou lefèt ke msg_id se yon timestamp ki nesesè nan yon pwen de vi kriptografik pou anpeche atak reparèt, li se yon erè yo tache yon fonksyon idantifyan inik nan li. Se poutèt sa, san yo pa chanje fondamantalman achitekti aktyèl la (lè kouran Mizajou yo pwodwi, sa se yon sijè API wo nivo pou yon lòt pati nan seri pòs sa a), youn ta bezwen:

  1. Sèvè a ki kenbe koneksyon TCP a ak kliyan an pran responsablite - si li te li nan priz la, tanpri rekonèt, trete oswa retounen yon erè, pa gen okenn pèt. Lè sa a, konfimasyon an se pa yon vektè nan id, men tou senpleman "dènye a resevwa seq_no" - jis yon nimewo, tankou nan TCP (de nimewo - sek ou a ak youn nan konfime). Nou toujou nan sesyon an, pa vre?
  2. Timestamp la pou anpeche atak reparèt vin tounen yon jaden separe, yon nonce. Li tcheke, men li pa afekte nenpòt lòt bagay. Ase ak uint32 - Si sèl nou an chanje omwen chak mwatye yon jou, nou ka asiyen 16 Bits nan ti moso yo ba-lòd nan yon pati nonb antye relatif nan tan aktyèl la, rès la - nan yon pati fraksyon nan yon segonn (tankou kounye a).
  3. Retire msg_id nan tout - soti nan pwen de vi distenge demann sou backends yo, gen, premyèman, id kliyan an, ak dezyèmman, id nan sesyon, konkatene yo. An konsekans, yon sèl bagay se ase kòm yon idantifyan demann seq_no.

Sa a se tou pa opsyon ki gen plis siksè; yon o aza konplè ta ka sèvi kòm yon idantifyan - sa a deja fè nan API a wo nivo lè w ap voye yon mesaj, nan chemen an. Li ta pi bon konplètman refè achitekti a soti nan relatif nan absoli, men sa a se yon sijè pou yon lòt pati, pa pòs sa a.

API?

Ta-daam! Se konsa, nou te gen difikilte nan yon chemen plen doulè ak beki, nou te finalman kapab voye nenpòt demann nan sèvè a epi resevwa nenpòt repons yo, osi byen ke resevwa mizajou soti nan sèvè a (pa an repons a yon demann, men li menm. voye nou, tankou PUSH, si yon moun li pi klè konsa).

Atansyon, kounye a pral gen sèlman egzanp nan Perl nan atik la! (pou moun ki pa abitye ak sentaks la, premye agiman benediksyon an se estrikti done objè a, dezyèm lan se klas li yo):

2019.10.24 12:00:51 $1 = {
'cb' => 'TeleUpd::__ANON__',
'out' => bless( {
'filter' => bless( {}, 'Telegram::ChannelMessagesFilterEmpty' ),
'channel' => bless( {
'access_hash' => '-6698103710539760874',
'channel_id' => '1380524958'
}, 'Telegram::InputPeerChannel' ),
'pts' => '158503',
'flags' => 0,
'limit' => 0
}, 'Telegram::Updates::GetChannelDifference' ),
'req_id' => '6751291954012037292'
};
2019.10.24 12:00:51 $1 = {
'in' => bless( {
'req_msg_id' => '6751291954012037292',
'result' => bless( {
'pts' => 158508,
'flags' => 3,
'final' => 1,
'new_messages' => [],
'users' => [],
'chats' => [
bless( {
'title' => 'Хулиномика',
'username' => 'hoolinomics',
'flags' => 8288,
'id' => 1380524958,
'access_hash' => '-6698103710539760874',
'broadcast' => 1,
'version' => 0,
'photo' => bless( {
'photo_small' => bless( {
'volume_id' => 246933270,
'file_reference' => '
'secret' => '1854156056801727328',
'local_id' => 228648,
'dc_id' => 2
}, 'Telegram::FileLocation' ),
'photo_big' => bless( {
'dc_id' => 2,
'local_id' => 228650,
'file_reference' => '
'secret' => '1275570353387113110',
'volume_id' => 246933270
}, 'Telegram::FileLocation' )
}, 'Telegram::ChatPhoto' ),
'date' => 1531221081
}, 'Telegram::Channel' )
],
'timeout' => 300,
'other_updates' => [
bless( {
'pts_count' => 0,
'message' => bless( {
'post' => 1,
'id' => 852,
'flags' => 50368,
'views' => 8013,
'entities' => [
bless( {
'length' => 20,
'offset' => 0
}, 'Telegram::MessageEntityBold' ),
bless( {
'length' => 18,
'offset' => 480,
'url' => 'https://alexeymarkov.livejournal.com/[url_вырезан].html'
}, 'Telegram::MessageEntityTextUrl' )
],
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'text' => '???? 165',
'data' => 'send_reaction_0'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 9'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'message' => 'А вот и новая книга! 
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
напечатаю.',
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'date' => 1571724559,
'edit_date' => 1571907562
}, 'Telegram::Message' ),
'pts' => 158508
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'pts' => 158508,
'message' => bless( {
'edit_date' => 1571907589,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'date' => 1571807301,
'message' => 'Почему Вы считаете Facebook плохой компанией? Можете прокомментировать? По-моему, это шикарная компания. Без долгов, с хорошей прибылью, а если решат дивы платить, то и еще могут нехило подорожать.
Для меня ответ совершенно очевиден: потому что Facebook делает ужасный по качеству продукт. Да, у него монопольное положение и да, им пользуется огромное количество людей. Но мир не стоит на месте. Когда-то владельцам Нокии было смешно от первого Айфона. Они думали, что лучше Нокии ничего быть не может и она навсегда останется самым удобным, красивым и твёрдым телефоном - и доля рынка это красноречиво демонстрировала. Теперь им не смешно.
Конечно, рептилоиды сопротивляются напору молодых гениев: так Цукербергом был пожран Whatsapp, потом Instagram. Но всё им не пожрать, Паша Дуров не продаётся!
Так будет и с Фейсбуком. Нельзя всё время делать говно. Кто-то когда-то сделает хороший продукт, куда всё и уйдут.
#соцсети #facebook #акции #рептилоиды',
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 452'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'text' => '???? 21',
'data' => 'send_reaction_1'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'entities' => [
bless( {
'length' => 199,
'offset' => 0
}, 'Telegram::MessageEntityBold' ),
bless( {
'length' => 8,
'offset' => 919
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'offset' => 928,
'length' => 9
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 6,
'offset' => 938
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 11,
'offset' => 945
}, 'Telegram::MessageEntityHashtag' )
],
'views' => 6964,
'flags' => 50368,
'id' => 854,
'post' => 1
}, 'Telegram::Message' ),
'pts_count' => 0
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'message' => bless( {
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 213'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 8'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'views' => 2940,
'entities' => [
bless( {
'length' => 609,
'offset' => 348
}, 'Telegram::MessageEntityItalic' )
],
'flags' => 50368,
'post' => 1,
'id' => 857,
'edit_date' => 1571907636,
'date' => 1571902479,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'message' => 'Пост про 1С вызвал бурную полемику. Человек 10 (видимо, 1с-программистов) единодушно написали:
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
Я бы добавил, что блестящая у 1С дистрибуция, а маркетинг... ну, такое.'
}, 'Telegram::Message' ),
'pts_count' => 0,
'pts' => 158508
}, 'Telegram::UpdateEditChannelMessage' ),
bless( {
'pts' => 158508,
'pts_count' => 0,
'message' => bless( {
'message' => 'Здравствуйте, расскажите, пожалуйста, чем вредит экономике 1С?
// [текст сообщения вырезан чтоб не нарушать правил Хабра о рекламе]
#софт #it #экономика',
'edit_date' => 1571907650,
'date' => 1571893707,
'to_id' => bless( {
'channel_id' => 1380524958
}, 'Telegram::PeerChannel' ),
'flags' => 50368,
'post' => 1,
'id' => 856,
'reply_markup' => bless( {
'rows' => [
bless( {
'buttons' => [
bless( {
'data' => 'send_reaction_0',
'text' => '???? 360'
}, 'Telegram::KeyboardButtonCallback' ),
bless( {
'data' => 'send_reaction_1',
'text' => '???? 32'
}, 'Telegram::KeyboardButtonCallback' )
]
}, 'Telegram::KeyboardButtonRow' )
]
}, 'Telegram::ReplyInlineMarkup' ),
'views' => 4416,
'entities' => [
bless( {
'offset' => 0,
'length' => 64
}, 'Telegram::MessageEntityBold' ),
bless( {
'offset' => 1551,
'length' => 5
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'length' => 3,
'offset' => 1557
}, 'Telegram::MessageEntityHashtag' ),
bless( {
'offset' => 1561,
'length' => 10
}, 'Telegram::MessageEntityHashtag' )
]
}, 'Telegram::Message' )
}, 'Telegram::UpdateEditChannelMessage' )
]
}, 'Telegram::Updates::ChannelDifference' )
}, 'MTProto::RpcResult' )
};
2019.10.24 12:00:51 $1 = {
'in' => bless( {
'update' => bless( {
'user_id' => 2507460,
'status' => bless( {
'was_online' => 1571907651
}, 'Telegram::UserStatusOffline' )
}, 'Telegram::UpdateUserStatus' ),
'date' => 1571907650
}, 'Telegram::UpdateShort' )
};
2019.10.24 12:05:46 $1 = {
'in' => bless( {
'chats' => [],
'date' => 1571907946,
'seq' => 0,
'updates' => [
bless( {
'max_id' => 141719,
'channel_id' => 1295963795
}, 'Telegram::UpdateReadChannelInbox' )
],
'users' => []
}, 'Telegram::Updates' )
};
2019.10.24 13:01:23 $1 = {
'in' => bless( {
'server_salt' => '4914425622822907323',
'unique_id' => '5297282355827493819',
'first_msg_id' => '6751307555044380692'
}, 'MTProto::NewSessionCreated' )
};
2019.10.24 13:24:21 $1 = {
'in' => bless( {
'chats' => [
bless( {
'username' => 'freebsd_ru',
'version' => 0,
'flags' => 5440,
'title' => 'freebsd_ru',
'min' => 1,
'photo' => bless( {
'photo_small' => bless( {
'local_id' => 328733,
'volume_id' => 235140688,
'dc_id' => 2,
'file_reference' => '
'secret' => '4426006807282303416'
}, 'Telegram::FileLocation' ),
'photo_big' => bless( {
'dc_id' => 2,
'file_reference' => '
'volume_id' => 235140688,
'local_id' => 328735,
'secret' => '71251192991540083'
}, 'Telegram::FileLocation' )
}, 'Telegram::ChatPhoto' ),
'date' => 1461248502,
'id' => 1038300508,
'democracy' => 1,
'megagroup' => 1
}, 'Telegram::Channel' )
],
'users' => [
bless( {
'last_name' => 'Panov',
'flags' => 1048646,
'min' => 1,
'id' => 82234609,
'status' => bless( {}, 'Telegram::UserStatusRecently' ),
'first_name' => 'Dima'
}, 'Telegram::User' )
],
'seq' => 0,
'date' => 1571912647,
'updates' => [
bless( {
'pts' => 137596,
'message' => bless( {
'flags' => 256,
'message' => 'Создать джейл с именем покороче ??',
'to_id' => bless( {
'channel_id' => 1038300508
}, 'Telegram::PeerChannel' ),
'id' => 119634,
'date' => 1571912647,
'from_id' => 82234609
}, 'Telegram::Message' ),
'pts_count' => 1
}, 'Telegram::UpdateNewChannelMessage' )
]
}, 'Telegram::Updates' )
};

Wi, pa yon spoiler espre - si ou poko li li, ale pi devan epi fè li!

Oh, wai~~... kisa sa sanble? Yon bagay trè abitye... petèt sa a se estrikti done yon API Web tipik nan JSON, eksepte ke klas yo tou tache ak objè?..

Se konsa, sa a se ki jan li vire soti ... Ki sa ki tout bagay sou, kanmarad? jis kòmanse?..Èske jis JSON sou HTTPS pa ta pi senp?! Kisa nou te jwenn an echanj? Èske efò a te vo li?

Ann evalye sa TL+MTProto te ban nou ak ki altènativ ki posib. Oke, HTTP, ki konsantre sou modèl demann-repons la, se yon move anfòm, men omwen yon bagay sou tèt TLS?

Serializasyon kontra enfòmèl ant. Wè estrikti done sa a, menm jan ak JSON, mwen sonje ke gen vèsyon binè nan li. Ann make MsgPack kòm ensifizan ekstansib, men gen, pou egzanp, CBOR - nan chemen an, yon estanda ki dekri nan RFC 7049. Li se remakab pou lefèt ke li defini Tags, kòm yon mekanis ekspansyon, ak nan mitan deja estandadize disponib:

  • 25 + 256 - ranplase liy repete ak yon referans a nimewo liy lan, tankou yon metòd konpresyon bon mache
  • 26 - seri objè Perl ak non klas ak agiman konstrukteur
  • 27 - serialize objè endepandan lang ak non kalite ak agiman konstrukteur

Oke, mwen te eseye seri done yo menm nan TL ak nan CBOR ak fisèl ak anbalaj objè pèmèt. Rezilta a te kòmanse varye an favè CBOR yon kote nan yon megabyte:

cborlen=1039673 tl_len=1095092

Se konsa, konklizyon: Gen fòma sibstansyèlman pi senp ki pa sijè a pwoblèm nan echèk senkronizasyon oswa idantifyan enkoni, ak efikasite konparab.

Etablisman koneksyon rapid. Sa vle di zewo RTT apre rekoneksyon (lè kle a te deja pwodwi yon fwa) - aplikab depi premye mesaj MTProto a, men ak kèk rezèvasyon - frape sèl la menm, sesyon an pa pouri, elatriye. Kisa TLS ofri nou pito? Quote sou sijè:

Lè w ap itilize PFS nan TLS, tikè sesyon TLS (RFC 5077) pou rekòmanse yon sesyon chiffres san re-negosyasyon kle yo ak san sere enfòmasyon kle sou sèvè a. Lè w ap louvri premye koneksyon an ak kreye kle, sèvè a ankripte eta koneksyon an epi li transmèt li bay kliyan an (nan fòm lan nan yon tikè sesyon). An konsekans, lè koneksyon an rekòmanse, kliyan an voye yon tikè sesyon, ki gen ladan kle sesyon an, tounen nan sèvè a. Tikè a li menm ankode ak yon kle tanporè (kle sesyon tikè), ki estoke sou sèvè a epi yo dwe distribye pami tout sèvè entèfas ki trete SSL nan solisyon grap.[10]. Kidonk, entwodiksyon yon tikè sesyon ka vyole PFS si kle sèvè tanporè yo konpwomèt, pou egzanp, lè yo estoke pou yon tan long (OpenSSL, nginx, Apache estoke yo pa default pou tout dire pwogram nan; sit popilè yo itilize kle a pou plizyè èdtan, jiska jou).

Isit la RTT a se pa zewo, ou bezwen chanje omwen ClientHello ak ServerHello, apre sa kliyan an ka voye done ansanm ak fini. Men, isit la nou ta dwe sonje ke nou pa gen entènèt la, ak pakèt li yo nan koneksyon ki fèk louvri, men yon mesaje, koneksyon an ki souvan se youn ak plis oswa mwens ki dire lontan, demann relativman kout nan paj wèb - tout bagay se multiplexed. intern. Sa vle di, li se byen akseptab si nou pa t 'vin atravè yon seksyon tren vrèman move.

Bliye yon lòt bagay? Ekri nan kòmantè yo.

A kontinye!

Nan dezyèm pati seri post sa yo nou pral konsidere pa pwoblèm teknik, men pwoblèm òganizasyonèl - apwòch, ideoloji, koòdone, atitid anvè itilizatè yo, elatriye. Ki baze, sepandan, sou enfòmasyon teknik ki te prezante isit la.

Twazyèm pati a ap kontinye analize eleman teknik / eksperyans devlopman. Ou pral aprann, an patikilye:

  • kontinyasyon nan pandemonium la ak varyete nan kalite TL
  • bagay enkoni sou chanèl ak sipègwoup yo
  • poukisa dyalòg yo pi mal pase lis la
  • sou abòde mesaj absoli vs relatif
  • ki diferans ki genyen ant foto ak imaj
  • ki jan emoji entèfere ak tèks italik

ak lòt beki! Rete branche!

Sous: www.habr.com

Add nouvo kòmantè