Fanakianana ny protocole sy ny fomba fandaminana ny Telegram. Fizarana 1, teknika: traikefa amin'ny fanoratana mpanjifa hatrany am-boalohany - TL, MT

Vao haingana, nanomboka nipoitra matetika tao amin'ny HabrΓ© ny lahatsoratra momba ny hatsaran'ny Telegram, ny famirapiratan'ireo rahalahy Durov sy za-draharaha amin'ny fananganana rafitra tambajotra, sns. Mandritra izany fotoana izany, vitsy dia vitsy ny olona tena miroboka amin'ny fitaovana ara-teknika - ny ankamaroany dia mampiasa Bot API miorina amin'ny JSON (ary tena tsy mitovy amin'ny MTProto), ary matetika manaiky fotsiny. amin’ny finoana ireo fiderana sy PR rehetra manodidina ny iraka. Efa ho herintaona sy tapany lasa izay, ny mpiara-miasa amiko ao amin'ny NPO Echelon Vasily (indrisy fa voafafa ny kaontiny ao amin'ny HabrΓ© miaraka amin'ny drafitra) dia nanomboka nanoratra ny mpanjifany Telegram manokana tany Perl, ary taty aoriana dia nanatevin-daharana ny mpanoratra ireo andalana ireo. Nahoana i Perl, hanontany avy hatrany ny sasany? Satria efa misy ny tetikasa toy izany amin'ny fiteny hafa, raha ny marina, tsy izany no tanjona, mety misy fiteny hafa any tranomboky vita, ary araka izany ny mpanoratra dia tsy maintsy mandeha amin'ny lalana rehetra avy amin'ny rangotra. Ankoatra izany, ny cryptography dia zavatra toy izany - matoky, fa manamarina. Miaraka amin'ny vokatra mifantoka amin'ny fiarovana, tsy afaka miantehitra fotsiny amin'ny tranomboky efa vita vita amin'ny mpivarotra ianao ary mino an-jambany izany (na izany aza, lohahevitra bebe kokoa amin'ny ampahany faharoa ity). Amin'izao fotoana izao, ny tranomboky dia miasa tsara amin'ny ambaratonga "afovoany" (mamela anao hanao fangatahana API).

Na izany aza, tsy hisy kriptografika sy matematika betsaka amin'ity andian-dahatsoratra ity. Saingy hisy tsipiriany ara-teknika maro hafa sy tehina ara-javakanto (ho an'ireo izay tsy hanoratra hatramin'ny voalohany, fa hampiasa ny tranomboky amin'ny fiteny rehetra). Noho izany, ny tanjona lehibe dia ny hanandrana hampihatra ny mpanjifa hatrany am-boalohany araka ny antontan-taratasy ofisialy. Izany hoe, eritrereto hoe mihidy ny kaody loharanon'ny mpanjifa ofisialy (indray, ao amin'ny tapany faharoa, dia hanambara amin'ny antsipiriany bebe kokoa ny lohahevitra momba ny tena izy. mitranga izany Noho izany), fa, toy ny tamin'ny andro taloha, ohatra, misy fenitra toy ny RFC - azo atao ve ny manoratra mpanjifa araka ny fepetra manokana, "tsy mitsikilo" ao amin'ny kaody loharano, na dia ofisialy aza (Telegram Desktop, finday ), na Telethon tsy ofisialy?

Fizahan-takelaka:

Documentation ... misy ve? Marina ve izany?..

Nanomboka nangonina tamin'ny fahavaratra lasa teo ny sombin-tsoratra ho an'ity lahatsoratra ity. Amin'izao fotoana rehetra izao ao amin'ny tranokala ofisialy https://core.telegram.org ny antontan-taratasy dia tamin'ny Layer 23, i.e. niraikitra tany ho any tamin'ny 2014 (tadidio fa mbola tsy nisy fantsona akory?). Mazava ho azy, amin'ny teoria, izany dia tokony ho nahafahana nametraka mpanjifa manana fiasa tamin'izany fotoana izany tamin'ny 2014. Saingy na dia tamin'ity fanjakana ity aza, ny antontan-taratasy dia, voalohany, tsy feno, ary faharoa, tany amin'ny toerana nifanohitra. Telo volana lasa izay, tamin'ny Septambra 2019 dia nitombo tsy nahy hita fa ny tranokala dia manana fanavaozana lehibe amin'ny antontan-taratasy, ho an'ny Layer 105 vaovao tanteraka, miaraka amin'ny fanamarihana fa mila vakiana indray izao ny zava-drehetra. Maro tokoa ny lahatsoratra nohavaozina, nefa maro no tsy niova. Noho izany, rehefa mamaky ny tsikera etsy ambany momba ny antontan-taratasy ianao dia tokony hotadidinao fa ny sasany amin'ireo zavatra ireo dia tsy manan-danja intsony, fa ny sasany dia mbola tena. Rehefa dinihina tokoa, ny 5 taona amin'ny tontolo maoderina dia tsy be dia be, fa tena be dia be. Nanomboka teo (indrindra raha tsy raisinao ny geochats nariana sy natsangana tamin'ny maty nanomboka teo), ny isan'ny fomba API ao amin'ny drafitra dia nitombo avy amin'ny zato ka hatramin'ny dimampolo sy roanjato mahery!

Aiza ianao no manomboka amin'ny maha-mpanoratra tanora anao?

Tsy maninona na manoratra avy amin'ny scratch ianao na mampiasa, ohatra, trano famakiam-boky efa vita toy ny Telethon ho an'ny Python na Madeline ho an'ny PHP, Na ahoana na ahoana, dia mila aloha ianao soraty ny fangatahanao - mahazo masontsivana api_id ΠΈ api_hash (ireo izay niasa tamin'ny VKontakte API dia mahazo avy hatrany) izay ahafahan'ny mpizara hamantatra ny fampiharana. izany tsy maintsy noho ny antony ara-dalΓ na, fa hiresaka bebe kokoa momba ny antony tsy ahafahan'ny mpanoratra trano famakiam-boky mamoaka azy amin'ny ampahany faharoa. Angamba ho afa-po amin'ny soatoavina fitsapana ianao, na dia voafetra be aza izy ireo - ny zava-misy dia izao ianao dia afaka misoratra anarana amin'ny nomerao iray monja fampiharana, ka aza maika loatra.

Ankehitriny, amin'ny lafiny ara-teknika, tokony ho nahaliana antsika ny hoe aorian'ny fisoratana anarana dia tokony hahazo fampandrenesana avy amin'ny Telegram momba ny fanavaozana ny antontan-taratasy, protocol, sns. Izany hoe, azo heverina fa ny tranokala misy docks dia "nahazo isa" fotsiny ary nanohy niasa manokana tamin'ireo izay nanomboka nanao mpanjifa, satria. mora kokoa izany. Saingy tsia, tsy nisy toy izany nojerena, tsy nisy vaovao tonga.

Ary raha manoratra avy amin'ny scratch ianao, dia mbola lavitra ny fampiasana ireo mari-pamantarana voaray. NA https://core.telegram.org/ ary miresaka momba azy ireo aloha ao amin'ny Getting Started, raha ny marina dia tsy maintsy mampihatra aloha ianao MTProto protocol - fa raha mino ianao layout araka ny modely OSI amin'ny faran'ny pejy ny famaritana ankapobeny ny protocole, dia very maina tanteraka.

Raha ny marina, na alohan'ny MTProto na aorian'izany, amin'ny ambaratonga maromaro indray mandeha (araka ny filazan'ireo mpiserasera vahiny miasa ao amin'ny kernel OS, fanitsakitsahana ny sosona), lohahevitra lehibe, maharary ary mahatahotra no hanakana ...

Serialization binary: TL (Type Language) sy ny drafitra, ary ny sosona, ary teny mampatahotra maro hafa

Ity lohahevitra ity, raha ny marina, no fanalahidin'ny olan'ny Telegram. Ary hisy teny mahatsiravina be dia be raha ezahinao handalina izany.

Noho izany, drafitra. Raha tadidinao io teny io dia lazao hoe: json schemaMarina ny nieritreritrao. Mitovy ihany ny tanjona: fiteny sasany hamaritana andiana angona azo alefa. Eto, raha ny marina, no nifarana ny fitoviana. Raha avy amin'ny pejy MTProto protocol, na avy amin'ny hazo loharanon'ny mpanjifa ofisialy, hiezaka hanokatra tetika isika, hahita zavatra toy izao:

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;

Ny olona iray izay mahita izany voalohany dia tsy hahafantatra afa-tsy ampahany amin'ny voasoratra - tsara, toa rafitra ireo (na dia aiza aza ny anarana, eo ankavia na ankavanana?), Misy saha ao aminy, ary avy eo ny karazana dia mandalo amin'ny colon ... angamba. Eto, amin'ny bracket zoro, mety misy modely toy ny ao amin'ny C ++ (raha ny marina, tsy dia tsara). Ary inona no dikan'ny marika hafa rehetra, marika fanontaniana, teboka, isan-jato, mason-tsivana (ary mazava ho azy fa samy hafa ny dikan'izy ireo amin'ny toerana samihafa), misy any amin'ny toerana iray, fa tsy any amin'ny toerana iray, isa hexadecimal - ary ny tena zava-dehibe, ny fomba hahazoana izany marina (izay tsy holavin'ny mpizara) byte stream? Tsy maintsy mamaky ny antontan-taratasy ianao (Eny, misy rohy mankany amin'ny schema ao amin'ny JSON version akaiky - saingy tsy manazava izany).

Manokatra ny pejy Serialization data binary ary miditra ao amin'ny tontolon'ny holatra majika sy ny matematika discrete, zavatra mitovy amin'ny matan amin'ny taona faha-4. Alfabeta, karazana, sanda, combinator, combinator fonctionnaire, endrika mahazatra, karazana composite, karazana polymorphique... ary io no pejy voalohany! Miandry anao ny manaraka TL Language, izay, na dia efa misy ohatra iray amin'ny fangatahana sy valiny tsy misy dikany aza, dia tsy manome valiny amin'ireo tranga mahazatra kokoa, izay midika fa tsy maintsy mandeha amin'ny famerenana ny matematika nadika avy amin'ny teny Rosiana ho amin'ny teny anglisy ianao amin'ny valo fanampiny. pejy!

Ny mpamaky mahazatra amin'ny fiteny miasa sy ny karazana inferences mandeha ho azy, mazava ho azy, dia nahita ny famaritana ny fiteny, na dia avy amin'ny ohatra iray aza, mahazatra kokoa, ary afaka milaza fa amin'ny ankapobeny dia tsy ratsy izany. Ny fanoherana izany dia:

  • eny, Ρ†Π΅Π»ΡŒ toa tsara, fa indrisy tsy tratra
  • fianarana any amin'ny oniversite Rosiana miovaova na dia eo amin'ny IT specialties - tsy ny rehetra mamaky ny mifanaraka Mazava ho azy
  • Farany, araka ny ho hitantsika, amin'ny fampiharana izany tsy ilaina, satria ampahany voafetra ihany na dia ny TL izay nofaritana aza no ampiasaina

Araka ny voalaza LeoNerd amin'ny fantsona #perl ao amin'ny tambajotra FreeNode IRC, manandrana mametraka vavahady avy amin'ny Telegram mankany Matrix (tsy marina amin'ny fitadidiana ny fandikana ilay teny nalaina):

Tahaka ny olona nampidirina voalohany tamin'ny teoria fanoratana, nientanentana ary nanomboka nanandrana nilalao izany, tsy dia niraharaha loatra raha ilaina izany amin'ny fampiharana.

Jereo ny tenanao raha toa ka tsy mametraka fanontaniana ny filana karazana miboridana (int, lava, sns.) ho toy ny zavatra fototra - amin'ny farany dia tsy maintsy ampiharina amin'ny tanana izany - ohatra, andeha isika hanandrana haka avy amin'izy ireo. vector. Izany hoe, raha ny marina, fihaingoana, raha miantso ny vokatra amin'ny anarany manokana ianao.

Fa aloha

Famaritana fohifohy momba ny ampahany amin'ny syntax TL ho an'ireo izay tsy… vakio ny antontan-taratasy ofisialy

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;

Manomboka famaritana foana endrika, aorian'izay, azo atao (amin'ny fampiharana, foana) amin'ny alΓ lan'ny marika # dia tsy maintsy ho CRC32 avy amin'ny tady famaritana ara-dalΓ na ny karazana nomena. Manaraka izany dia tonga ny famaritana ny saha, raha izy ireo - ny karazana dia mety ho foana. Izany rehetra izany dia mifarana amin'ny famantarana mitovy, ny anaran'ny karazana izay nomena constructor - izany hoe, ny subtype - an'ny. Ny karazana eo ankavanan'ny famantarana mitovy dia polymorphic - izany hoe afaka mifanandrify amin'ny karazana voafaritra maromaro.

Raha mitranga aorian'ny tsipika ny famaritana ---functions---, dia hitoetra ho mitovy ny syntax, fa ny dikany dia ho hafa: ny constructor dia ho lasa anaran'ny asa RPC, ny saha dia ho lasa paramètre (izany hoe, hitoetra ho toy izany koa ny rafitra nomena araka ny voalaza etsy ambany, io ihany no dikany omena), ary ny "karazana polymorphic" no karazana vokatra naverina. Marina fa mbola hitoetra polymorphic izy io - voafaritra ao amin'ny fizarana ---types---, ary ity mpanamboatra ity dia tsy hodinihina. Ampidiro ny enta-mavesatra amin'ny asa antsoina amin'ny alàlan'ny tohan-kevitr'izy ireo, i.e. noho ny antony sasany dia tsy omena ao amin'ny TL ny fiasa maromaro miaraka amin'ny anarana mitovy fa sonia hafa, toy ny ao amin'ny C++.

Nahoana no "mpanorina" sy "polymorphic" raha tsy OOP? Eny, raha ny marina, ho mora kokoa ho an'ny olona iray ny mieritreritra momba azy io amin'ny resaka OOP - karazana polymorphic ho kilasy abstract, ary ny constructors dia kilasy taranany mivantana, ankoatra izany. final amin'ny voambolana amin'ny fiteny maromaro. Raha ny marina, mazava ho azy, eto fitoviana miaraka amin'ny fomba fanamboarana tena be loatra amin'ny fiteny fandaharana OO. Satria misy firafitry ny angon-drakitra fotsiny eto dia tsy misy fomba (na dia ny famaritana ny fiasa sy ny fomba etsy ambany aza dia afaka miteraka fisavoritahana ao an-doha momba ny hoe inona izy ireo, fa momba ny zavatra hafa izany) - azonao atao ny mieritreritra ny mpanamboatra ho toy ny a sanda avy amin'izay amboarina soraty rehefa mamaky andian-bytes.

Ahoana no mitranga izany? Ny deserializer, izay mamaky 4 bytes foana, dia mahita ny sandany 0xcrc32 - ary mahafantatra izay hitranga manaraka field1 miaraka amin'ny karazana int, i.e. mivaky 4 bytes katroka, amin'ity saha ambony ity misy karazana PolymorType mamaky. mahita 0x2crc32 ary takany fa misy sehatra roa fanampiny, voalohany long, ka mamaky 8 bytes izahay. Ary avy eo indray karazana sarotra, izay deserialized amin'ny fomba mitovy. Ohatra, Type3 dia azo ambara ao amin'ny schema raha vantany vao misy mpanamboatra roa, tsirairay avy, dia tsy maintsy mihaona izy ireo 0x12abcd34, aorian'izay dia mila mamaky 4 bytes hafa ianao int, na 0x6789cdef, rehefa afaka izany, dia tsy hisy na inona na inona. Na inona na inona - mila manipy maningana ianao. Na ahoana na ahoana, aorian'izay dia miverina mamaky 4 bytes isika int saha field_c Π² constructorTwo ary amin'izany dia mamarana ny famakiana ny anay izahay PolymorType.

Farany, raha tratra 0xdeadcrc ho an'ny constructorThree, dia lasa sarotra kokoa ny raharaha. Sahantsika voalohany bit_flags_of_what_really_present miaraka amin'ny karazana # - raha ny marina dia solon'anarana ho an'ilay karazana fotsiny io natmidika hoe β€œisa voajanahary”. Izany hoe, raha ny marina, ny unsigned int no hany tranga, raha ny tarehimarika tsy misy sonia dia hita amin'ny tetika tena izy. Noho izany, manaraka ny fanorenana misy marika fanontaniana, izay midika fa izany no saha - dia ho eo amin'ny tariby ihany raha ny mifanaraka bit napetraka ao amin'ny saha references (tokony ho toy ny ternary operator). Noho izany, eritrereto hoe ity bit ity dia mandeha, dia mila mamaky saha toy izany ianao Type, izay amin'ny ohatra misy antsika dia manana mpanamboatra 2. Foana ny iray (famantarana ihany no misy), ny iray kosa manana saha ids miaraka amin'ny karazana ids:Vector<long>.

Mety hieritreritra ianao fa samy tsara na Java ny templates sy generics. Saingy tsia. Saika. izany irery ihany tranga misy fefy zoro amin'ny faritra tena izy, ary ampiasaina ho an'ny Vector IHANY. Ao amin'ny stream byte, dia ho 4 CRC32 bytes izany ho an'ny karazana Vector, mitovy foana, avy eo 4 byte - ny isan'ny singa array, ary avy eo ireo singa ireo.

Manampy izany ny zava-misy fa ny serialization dia mitranga amin'ny teny 4 bytes, ny karazany rehetra dia maromaro amin'izany - ny karazana namboarina dia voalaza ihany koa. bytes ΠΈ string miaraka amin'ny serialization amin'ny manual ny halavany sy ny fampifanarahana amin'ny 4 - tsara, toa toa mahazatra izany ary na dia mahomby aza? Na dia lazaina ho serialization binary mahomby aza ny TL, fa amin'ny helo miaraka amin'izy ireo, miaraka amin'ny fanitarana na inona na inona, eny fa na dia ny soatoavina boolean sy ny tady tokana hatramin'ny 4 bytes aza, mbola ho matevina kokoa ve i JSON? Jereo, na ny saha tsy ilaina aza dia azo tsidihana amin'ny sainam-pirenena kely, tsara daholo ny zava-drehetra, ary na dia azo avela ho an'ny ho avy aza, nampiana saha tsy voatery ho an'ny mpanamboatra ve ianao taty aoriana?..

Saingy tsia, raha tsy mamaky ny famaritana fohy aho, fa ny antontan-taratasy feno, ary mieritreritra ny fampiharana. Voalohany, ny CRC32 an'ny mpamorona dia kajy amin'ny alΓ lan'ny tady famaritana lahatsoratra schema mahazatra (esory ny habaka fotsy fanampiny, sns.) - ka raha ampiana saha vaovao dia hiova ny tady famaritana karazana, ary noho izany ny CRC32 ary, vokatr'izany, ny serialization. Ary inona no hataon'ilay mpanjifa taloha raha mahazo saha misy sainam-pirenena vaovao napetraka izy, nefa tsy fantany izay hataony manaraka? ..

Faharoa, aoka hotsaroantsika CRC32, izay ampiasaina eto amin'ny ankapobeny ho asa hash mba hamaritana manokana hoe inona no karazana atao (de)serialized. Eto isika dia miatrika ny olan'ny fifandonana - ary tsia, ny mety hitranga dia tsy iray amin'ny 232, fa mihoatra lavitra noho izany. Iza no nahatsiaro fa ny CRC32 dia natao hamantatra (sy hanitsiana) ny lesoka ao amin'ny fantsom-pifandraisana, ary hanatsara ireo fananana ireo mba hanimba ny hafa? Ohatra, tsy miraharaha ny permutation of bytes izy: raha manisa CRC32 avy amin'ny andalana roa ianao, amin'ny faharoa dia hanakalo ny 4 bytes voalohany amin'ny 4 bytes manaraka ianao - ho toy izany koa. Rehefa manana tady lahatsoratra avy amin'ny abidy latinina isika (sy mari-piatoana kely) ho fampidirana, ary tsy kisendrasendra manokana ireo anarana ireo, dia mitombo be ny mety hisian'ny fanovana toy izany.

Teny an-dalana, iza no nanamarina izay tao tena CRC32? Ao amin'ny iray amin'ireo loharano voalohany (na dia talohan'ny Waltman aza) dia nisy ny hash function izay nampitombo ny toetra tsirairay tamin'ny isa 239, tena tian'ireo olona ireo, ha ha!

Farany, okay, tsapanay fa ny mpanamboatra manana karazana saha Vector<int> ΠΈ Vector<PolymorType> dia hanana CRC32 hafa. Ary ahoana ny amin'ny famelabelarana eo amin'ny tsipika? Ary amin'ny teoria, lasa anisan'ny karazana ve izany? Andeha atao hoe mandalo laharan'ny isa iray alina isika, eny, miaraka amin'ny Vector<int> mazava ny zava-drehetra, ny halavany ary 40000 bytes hafa. Ary raha ity Vector<Type2>, izay tsy ahitana afa-tsy saha iray int ary io no hany amin'ny karazana - mila mamerina 10000xabcdef0 in-34 ve isika ary avy eo 4 bytes int, na ny fiteny dia afaka maneho izany ho antsika avy amin'ny mpamorona fixedVec ary fa tsy 80000bytes dia 40000 ihany indray no afindra?

Tsy fanontaniana ara-teorika tsy misy dikany mihitsy izany - alaivo sary an-tsaina hoe mahazo lisitry ny mpampiasa vondrona ianao, izay samy manana id, anarana voalohany, anarana farany - mety ho lehibe ny fahasamihafan'ny habetsaky ny angona nafindra tamin'ny fifandraisana finday. Ny fahombiazan'ny serialization Telegram no atolotra antsika.

Noho izany ...

Vector, izay tsy azo tsoahina

Raha manandrana mamakivaky ny pejy famaritana ny combinators sy ny manodidina ianao, dia ho hitanao fa ny vector (ary na ny matrix aza) dia manandrana manatsoaka takelaka maromaro amin'ny alΓ lan'ny tuples. Saingy amin'ny farany dia voafandrika izy ireo, ny dingana farany dia atsipy, ary ny famaritana ny vector dia omena tsotra izao, izay tsy mifamatotra amin'ny karazana iray ihany koa. Inona no olana eto? Amin'ny fiteny fandaharana, indrindra fa ireo miasa, dia mahazatra ny mamaritra ny rafitra miverimberina - ny compiler miaraka amin'ny fanombanana kamo dia hahatakatra ny zava-drehetra ary hanao izany. Amin'ny fiteny data serialization fa ny EFFICIENCY no ilaina: ampy hamaritana tsotra izao lisitra, i.e. firafitry ny singa roa - ny voalohany dia singa data, ny faharoa dia ny rafitra iray ihany na toerana banga ho an'ny rambony (pack (cons) amin'ny Lisp). Nefa mazava ho azy fa mitaky izany ny tsirairay Ny singa dia mandany 4 bytes (CRC32 amin'ny tranga TL) hamaritana ny karazana azy. Mora ny mamaritra ny array habe raikitra, fa raha misy laharan'ny halavany tsy fantatra teo aloha dia tapaka isika.

Koa satria tsy mamela anao hamoaka vector ny TL, dia tsy maintsy nampiana teo amin'ny sisiny izany. Amin'ny farany, ny antontan-taratasy dia milaza hoe:

Ny serialization dia mampiasa "vector" mpanorina mitovy foana (const 0x1cb5c415 = crc32("vector t: Type # [ t ] = Vector t") izay tsy miankina amin'ny sanda manokana amin'ny fari-piainana t.

Ny sandan'ny mari-pamantarana azo atao t dia tsy tafiditra amin'ny serialization satria avy amin'ny karazana vokatra (fantatra hatrany alohan'ny deserialization).

Jereo akaiky: vector {t:Type} # [ t ] = Vector t - fa na aiza na aiza ny dΓ©finition mihitsy tsy milaza hoe tsy maintsy mitovy amin'ny halavan'ny vector ny isa voalohany! Ary tsy manaraka na aiza na aiza. Ity dia nomena izay tokony hotadidinao sy ampiharinao amin'ny tananao. Any amin'ny toerana hafa, ny antontan-taratasy dia milaza am-pahatsorana fa sandoka ilay karazana:

Ny pseudotype polymorphic Vector t dia "karazana" izay ny sandany dia filaharan'ny sanda amin'ny karazana t rehetra, na boaty na tsy misy dikany.

… fa tsy mifantoka amin'izany. Rehefa reraky ny mamakivaky ny matematika ianao (mety ho fantatrao amin'ny fianarana eny amin'ny oniversite aza), dia manapa-kevitra ny hanao isa sy hijery ny fomba tena miasa miaraka aminy amin'ny fampiharana, dia mijanona ao an-dohanao ny fahatsapana: eto ny Serious Mathematics dia mifototra amin'ny , mazava ho azy fa Cool People (matematika roa - mpandresy ny ACM), fa tsy iza na iza. Tratra ny tanjona - ny mifoka rivotra.

Raha ny marina, momba ny isa. Tadidio # mitovy hevitra izy io nat, isa voajanahary:

Misy karazana fanehoan-kevitra (typeexpr) sy ny teny nomerika (nat-expr). Na izany aza, mitovy ny famaritana azy ireo.

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

fa amin'ny fitsipi-pitenenana dia mitovy ny famaritana azy ireo, i.e. io fahasamihafana io indray dia tsy maintsy tsaroana ary apetraka amin'ny fampiharana amin'ny tanana.

Eny, eny, karazana mΓ΄dely (vector<int>, vector<User>) manana identifier iombonana (#1cb5c415), i.e. raha fantatrao fa ny antso dia nambara ho

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

dia miandry tsy vector fotsiny ianao fa vector mpampiasa. Ny marimarina kokoa, tsy maintsy miandry - amin'ny code tena izy, ny singa tsirairay, raha tsy karazana tsy misy dikany, dia hanana mpanamboatra, ary amin'ny fomba tsara amin'ny fampiharana dia ilaina ny manamarina - ary nalefa tany amin'ny singa tsirairay amin'ity vector ity izahay. io karazana io? Ary raha toa ka karazana PHP izany, izay ahitana karazana karazana amin'ny singa samihafa ny array?

Amin'izao fotoana izao, manomboka manontany tena ianao - ilaina ve ny TL toy izany? Angamba ho an'ny sarety dia azo atao ny mampiasa ny serializer olombelona, ​​ilay protobuf efa nisy tamin'izany? Theorie ilay izy, andeha hojerentsika ny fampiharana.

Fampiharana TL efa misy amin'ny kaody

TL dia teraka tao an-kibon'ny VKontakte na dia talohan'ny hetsika fanta-daza tamin'ny fivarotana ny anjaran'i Durov sy (tokoa), na dia talohan'ny fivoaran'ny Telegram aza. Ary amin'ny loharano misokatra loharanon'ny fampiharana voalohany afaka mahita tehina mampihomehy be dia be ianao. Ary ny fiteny mihitsy no nampiharina tao amin'ny fomba feno kokoa noho ny amin'izao fotoana izao ao amin'ny Telegram. Ohatra, ny tenifototra dia tsy ampiasaina mihitsy amin'ny tetika (midika hoe pseudotype naorina (toy ny vector) miaraka amin'ny fitondran-tena mivilivily). Na

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

fa andeha hodinihintsika ho amin'ny fahafenoana ny sary, mba hijerena, raha lazaina, ny fivoaran'ny Giant of Thought.

#define ZHUKOV_BYTES_HACK

#ifdef ZHUKOV_BYTES_HACK

/* dirty hack for Zhukov request */

Na ity tsara tarehy ity:

    static const char *reserved_words_polymorhic[] = {

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

      };

Ity ampahany ity dia momba ny mΓ΄dely, toy ny:

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

Ity no famaritana ny karazana mΓ΄dely hashmap, ho vector ny int - Type pairs. Ao amin'ny C++ dia mety ho toy izao:

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

noho izany, alpha - teny fanalahidy! Fa amin'ny C++ ihany no afaka manoratra T, fa tsy maintsy manoratra alpha, beta ... Fa tsy mihoatra ny 8 parameters, ny fantasy dia nifarana tamin'ny theta. Toa nisy fifanakalozan-kevitra toy izany indray mandeha tany Saint-PΓ©tersbourg:

-- Надо ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π² TL ΡˆΠ°Π±Π»ΠΎΠ½Ρ‹
-- Π‘Π»... Ну ΠΏΡƒΡΡ‚ΡŒ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π·ΠΎΠ²ΡƒΡ‚ Π°Π»ΡŒΡ„Π°, Π±Π΅Ρ‚Π°,... КакиС Ρ‚Π°ΠΌ Π΅Ρ‰Ρ‘ Π±ΡƒΠΊΠ²Ρ‹ Π΅ΡΡ‚ΡŒ... О, тэта!
-- Π“Ρ€Π°ΠΌΠΌΠ°Ρ‚ΠΈΠΊΠ°? Ну ΠΏΠΎΡ‚ΠΎΠΌ напишСм

-- Π‘ΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅, ΠΊΠ°ΠΊΠΎΠΉ я синтаксис ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Π» для шаблонов ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€Π°!
-- Π’Ρ‹ долбанулся, ΠΊΠ°ΠΊ ΠΌΡ‹ это ΠΏΠ°Ρ€ΡΠΈΡ‚ΡŒ Π±ΡƒΠ΄Π΅ΠΌ?
-- Π”Π° Π½Π΅ ссытС, ΠΎΠ½ Ρ‚Π°ΠΌ ΠΎΠ΄ΠΈΠ½ Π² схСмС, Π·Π°Ρ…Π°Ρ€ΠΊΠΎΠ΄ΠΈΡ‚ΡŒ -- ΠΈ ΠΎΠΊ

Saingy momba ny fampiharana voalohany napetraka ny TL "amin'ny ankapobeny". Andao hiroso amin'ny fandinihana ny fampiharana amin'ny tena mpanjifa Telegram.

Ny tenin'i Basil:

Vasily, [09.10.18 17:07] Indrindra indrindra, mafana ny ampondra noho izy ireo nopotehin'izy ireo andiana abstractions, ary avy eo dia nasiany bolts teo amin'izy ireo, ary nopetahany tehina ny codegegerator.
Vokatr'izany, voalohany avy amin'ny docks ny pilot.jpg
Avy eo dia avy amin'ny code jekichan.webp

Mazava ho azy, avy amin'ny olona zatra algorithm sy matematika, dia afaka manantena isika fa namaky Aho, Ullman, ary zatra ny fitaovana manara-penitra indostrialy ho an'ny fanoratana ny DSL compiler-ny nandritra ny am-polony taona maro, sa tsy izany? ..

Mpanoratra telegram-cli dia Vitaliy Valtman, araka ny azo takarina avy amin'ny fisehoan'ny endrika TLO ivelan'ny fetra (cli), mpikambana ao amin'ny ekipa - ankehitriny ny tranomboky ho an'ny famakafakana TL dia omena. manokanainona ny eritreriny TL parser? ..

16.12 04:18 Vasily: raha ny hevitro dia misy tsy mahay lex + yacc
16.12 04:18 Vasily: raha tsy izany dia tsy hazavaiko izany
16.12 04:18 Vasily: eny, na naloa izy ireo noho ny isan'ny andalana ao amin'ny VK
16.12 04:19 Vasily: 3k+ andalana hafa<censored> fa tsy parser

Mety misy exception? Andeha hojerentsika hoe ahoana no ity no mpanjifa OFFICIAL - 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+ andalana amin'ny Python, fehezanteny mahazatra roa + tranga manokana amin'ny karazana vector, izay mazava ho azy fa ambara ao amin'ny drafitra araka ny tokony ho izy amin'ny TL syntax, fa apetrany amin'ity syntax ity izy ireo, manadihady bebe kokoa. ... Ny fanontaniana dia hoe, nahoana no manahirana amin’izao fahagagana rehetra izaoΠΈmifofofofo bebe kokoa, raha tsy misy olona hanadihady azy araka ny antontan-taratasy ihany?!

Raha ny marina... Tadidinao ve fa niresaka momba ny fanamarinana CRC32 isika? Noho izany, ao amin'ny Telegram Desktop mpamorona code dia misy lisitry ny maningana ho an'ireo karazana izay misy ny CRC32 kajy. tsy mifanaraka araka ny voalaza ao amin'ny diagram!

Vasily, [18.12 22:49] ary eto dia tokony hieritreritra ianao raha ilaina ny TL toy izany
raha te hikorontana amin'ny fampiharana hafa aho dia hanomboka hampiditra tsipika fiatoana, ny antsasaky ny parsers dia ho tapaka amin'ny famaritana maromaro
tdesktop koa anefa

Tsarovy ny teboka momba ny tsipika tokana, hiverina amin'izany isika aoriana kely.

Okay, telegram-cli dia tsy ofisialy, Telegram Desktop dia ofisialy, fa ahoana ny amin'ny hafa? Ary iza no mahalala?.. Ao amin'ny kaody mpanjifa Android dia tsy nisy parser schema mihitsy (izay mampametra-panontaniana momba ny loharano misokatra, fa ity no ampahany faharoa), saingy nisy fehezan-dalΓ na mampihomehy maro hafa, fa momba azy ireo ao ny fizarana etsy ambany.

Inona no fanontaniana hafa apetraky ny serialization amin'ny fampiharana? Ohatra, nopotehin'izy ireo, mazava ho azy, miaraka amin'ny saha bit sy saha misy fepetra:

vasily: flags.0? true
midika hoe misy ny saha ary marina raha napetraka ny saina

vasily: flags.1? int
midika izany fa misy ny saha ary mila deserialize

Vasily: Aza mirehitra, fa inona no ataonao!
Vasily: Any amin'ny toerana iray ao amin'ny doka dia misy filazana fa ny marina dia karazana tsy misy halavany, saingy tsy azo atao ny manangona zavatra avy amin'ny dosiny.
Vasily: Tsy misy toy izany koa amin'ny fampiharana an-kalamanjana, fa be dia be ny tehina sy props

Ahoana ny amin'ny Telethon? Mibanjina ny lohahevitry ny MTProto, ohatra - misy ampahany toy izany ao amin'ny antontan-taratasy, fa ny famantarana % voalaza fa "mifanaraka amin'ny karazana bare nomena" fotsiny izy io, izany hoe. amin'ireo ohatra etsy ambany, na fahadisoana, na zavatra tsy voarakitra:

Vasily, [22.06.18/18/38 XNUMX:XNUMX] Amin'ny toerana iray:

msg_container#73f1f8dc messages:vector message = MessageContainer;

Amin'ny endrika hafa:

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

Ary misy fahasamihafana lehibe roa ireo, amin'ny tena fiainana dia misy karazana vector miboridana tonga

Tsy mbola nahita famaritana vetaveta mibaribary aho ary tsy nahita izany

Famakafakana voasoratra amin'ny telethon amin'ny tanana

Naneho hevitra momba ny famaritana ny schemany msg_container

Mipetraka indray ny fanontaniana momba ny%. Tsy voalaza izany.

Vadim Goncharov, [22.06.18/19/22 XNUMX:XNUMX PM] ary ao amin'ny tdesktop?

Vasily, [22.06.18/19/23 XNUMX:XNUMX] Fa ny TL parser-ny ao amin'ny regulator dia mety tsy hihinana izany koa

// parsed manually

TL dia abstraction tsara tarehy, tsy misy mampihatra azy tanteraka

Ary tsy misy % amin'ny dikan-tenin'izy ireo

Fa eto ny antontan-taratasy dia mifanohitra amin'ny tenany, ka xs

Hita tamin'ny fitsipi-pitenenana izy io, afaka nanadino fotsiny ny famaritana ny semantika izy ireo

Eny, hitanao ny dock amin'ny TL, tsy azonao fantarina raha tsy misy antsasa-litatra

β€œEny, andao atao hoe”, hoy ny mpamaky iray hafa, β€œmanakiana ny zava-drehetra ianao, ka asehoy araka ny tokony ho izy izany.”

Namaly i Vasily hoe: β€œRaha ny momba ny parser dia mila zavatra toy izany aho

    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 ) ); }
            ;

toa mihoatra noho izany

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;
}

na

        # 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)

ity no lexer ENTIRE:

    ---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];

ireo. Ny tsotra kokoa dia ny fanaovana azy moramora."

Amin'ny ankapobeny, amin'ny farany, ny parser sy ny mpamorona kaody ho an'ny ampahany tena ampiasaina amin'ny TL dia mifanaraka amin'ny andalana gramatika 100 eo ho eo ary ~ 300 andalana amin'ny mpamokatra (anisan'izany ny rehetra). printny kaody novokarin'ny), anisan'izany ny karazana goodies, karazana fampahalalana ho an'ny introspection isaky ny kilasy. Ny karazana polymorphic tsirairay dia avadika ho kilasy fototra tsy misy dikany, ary ny mpanamboatra dia mandova azy ary manana fomba hanaovana serialization sy deserialization.

Tsy fahampian'ny karazana amin'ny fiteny karazana

Tsara ny fanoratana mafy, sa tsy izany? Tsia, tsy holivar ity (na dia aleoko aza ny fiteny mavitrika), fa postulate ao anatin'ny TL. Mifototra amin'izany, ny fiteny dia tokony hanome ny karazana fanamarinana rehetra ho antsika. Eny ary, aoka tsy izy, fa ny fampiharana, fa farafaharatsiny tokony hamariparitra azy ireo. Ary inona no fahafahana tiantsika?

Voalohany indrindra, teritery. Hitantsika eto amin'ny antontan-taratasy fampiakarana rakitra:

Ny atiny mimari-droa an'ny rakitra dia zaraina ho ampahany. Ny ampahany rehetra dia tsy maintsy mitovy habe ( ampahany_habe ) ary ireto fepetra manaraka ireto dia tsy maintsy fenoina:

  • part_size % 1024 = 0 (azo zaraina amin'ny 1KB)
  • 524288 % part_size = 0 (512KB dia tsy maintsy zaraina mitovy amin'ny ampahany_habe)

Ny ampahany farany dia tsy voatery mahafeno ireo fepetra ireo, raha toa ka latsaky ny ampahany_size ny habeny.

Ny ampahany tsirairay dia tokony hanana laharana filaharana, rakitra_part, miaraka amin'ny sanda manomboka amin'ny 0 ka hatramin'ny 2,999.

Aorian'ny fizarana ny rakitra dia mila misafidy fomba iray hamonjena azy amin'ny mpizara ianao. Ampiasao upload.saveBigFilePart raha toa ka mihoatra ny 10 MB ny haben'ny rakitra ary upload.saveFilePart ho an'ny rakitra kely kokoa.
[…] Mety haverina ny iray amin'ireto hadisoana fampidirana data manaraka ireto:

  • FILE_PARTS_INVALID - Isan'ny ampahany tsy mety. Ny sanda dia tsy eo anelanelan'ny 1..3000

Misy amin'ireo ve ao amin'ny schema? Azo ambara ve izany amin'ny alalan'ny TL? Tsia. Fa miala tsiny fa na ny Turbo Pascal efa lany andro aza dia afaka namaritra ireo karazana nomen'ny tandavan. Ary afaka nanao zavatra iray hafa izy, izay fantatra kokoa amin'ny anarana hoe enum - karazana misy fanisana isa raikitra (kely). Amin'ny fiteny toa an'i C - numeric, tsarovy fa karazany ihany no noresahinay hatreto. NOMERY. Misy koa anefa ny array, ny tady ... ohatra, tsara ny milaza fa io tady io dia tsy misy afa-tsy laharana finday, sa tsy izany?

Tsy misy ao amin'ny TL izany. Saingy misy, ohatra, ao amin'ny JSON Schema. Ary raha misy olon-kafa afaka manohitra ny fizarazarana ny 512 KB fa mbola mila hojerena ao amin'ny kaody, dia ataovy izay hahazoana antoka fa ny mpanjifa fotsiny tsy afaka mandefa laharana ivelan'ny faritra 1..3000 (ary tsy mety nipoitra ny fahadisoana mifandraika amin'izany) mety ho azo atao ve izany, sa tsy izany? ..

Teny an-dalana, momba ny fahadisoana sy ny fiverenana soatoavina. Manjavozavo ny maso na dia ho an'ireo izay niara-niasa tamin'ny TL aza - tsy tonga dia nazava taminay izany tsirairay avy Ny fiasa ao amin'ny TL dia afaka mamerina tsy ny karazana fiverenana voalaza ihany, fa fahadisoana ihany koa. Saingy tsy azo esorina amin'ny alΓ lan'ny TL mihitsy izany. Mazava ho azy fa azo takarina izany ary tsy ilaina ny nafig amin'ny fampiharana (na dia azo atao amin'ny fomba samihafa aza ny RPC, hiverina amin'izany isika) - fa ahoana kosa ny momba ny Fahadiovan'ny foto-kevitry ny Matematika amin'ny karazana Abstract avy amin'ny tontolon'ny lanitra? .. Nahazo ny fisintonana - mba mifanandrify.

Ary farany, ahoana ny amin'ny fahaiza-mamaky? Eny ary, amin'ny ankapobeny, tiako famaritana Ataovy ao amin'ny schema izany (indray, ao amin'ny schema JSON izy io), fa raha toa ka efa sahiran-tsaina miaraka aminy izany, dia ahoana ny amin'ny lafiny azo ampiharina - farafaharatsiny dia trite ny mijery ny diffs mandritra ny fanavaozana? Jereo ny tenanao ao amin'ny tena ohatra:

-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;

na

-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;

Misy olona tia azy, fa ny GitHub, ohatra, dia mandΓ  tsy hanasongadina fiovana ao anatin'ny andalana lava toy izany. Ny lalao "hitady fahasamihafana 10", ary izay hitan'ny atidoha avy hatrany dia mitovy ny fiandohana sy ny fiafarana amin'ireo ohatra roa ireo, mila mamaky amim-pitandremana ianao any amin'ny toerana afovoany ... Raha ny hevitro dia tsy amin'ny teoria fotsiny izany, fa hita maso fotsiny maloto sy tsy milamina.

Raha ny marina, momba ny fahadiovan'ny teoria. Nahoana no ilaina ny saha kely? Toa tsy izy ireo fofona ratsy raha ny fomba fijery ny karazana teoria? Misy fanazavana azo jerena ao amin'ny dikan-teny teo aloha momba ny skema. Tamin'ny voalohany, eny, izany tokoa, karazana vaovao no noforonina ho an'ny sneeze tsirairay. Ireto fototra ireto dia mbola misy amin'ity endrika ity, ohatra:

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;

Fa alaivo sary an-tsaina izao raha manana sehatra 5 ianao ao amin'ny rafitrao, dia mila karazana 32 ianao ho an'ny safidy rehetra azo atao. fipoahana combinatorial. Noho izany, ny fahadiovan'ny kristaly ny teoria TL indray dia nianjera tamin'ny ampondra vy tamin'ny zava-misy henjana momba ny serialization.

Fanampin'izany, any amin'ireo toerana ireo ry zalahy ireo mihitsy no mandika ny fanoratana azy manokana. Ohatra, ao amin'ny MTProto (tokony manaraka) ny valiny dia azo fehezin'ny Gzip, ny zava-drehetra dia saina - afa-tsy ny fanitsakitsahana ny sosona sy ny schema. Indray mandeha, ary tsy nijinja ny RpcResult mihitsy, fa ny ao anatiny. Eny ary, nahoana no manao an'izao?... Tsy maintsy nanapaka tehina aho mba hiasa na aiza na aiza.

Na ohatra iray hafa, nahita fahadisoana izahay indray mandeha - nalefa InputPeerUser raha tokony InputUser. Na ny mifamadika amin’izany. Nahomby anefa izany! Izany hoe tsy niraharaha ilay karazana ny mpizara. Ahoana izany? Ny valiny, angamba, dia hatosiky ny sombin-kaody avy amin'ny 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);

Raha lazaina amin'ny teny hafa, eto dia vita ny serialization AMIN'NY TANANA, tsy kaody novokarina! Angamba ny mpizara dia ampiharina amin'ny fomba mitovy?.. Amin'ny ankapobeny, ity dia hiasa raha vita indray mandeha, fa ahoana no ahafahanao manohana azy amin'ny fanavaozana? Tsy izany ve no nanaovana ilay tetika? Ary avy eo dia miroso amin'ny fanontaniana manaraka isika.

Versioning. sosona

Ny antony iantsoana ny dikan-teny skΓ©ma dia azo vinavinaina ihany mifototra amin'ny tantaran'ny skema navoaka. Toa tamin'ny voalohany dia toa tamin'ny mpanoratra fa ny zavatra fototra dia azo atao amin'ny drafitra tsy miova, ary raha ilaina, dia manondro amin'ny fangatahana manokana fa atao amin'ny dikan-teny hafa izy ireo. Amin'ny ankapobeny, na dia hevitra tsara aza - ary ny sitrapo vaovao, toy ny hoe, "mifangaro", sosona amin'ny taloha. Andeha hojerentsika anefa ny fomba nanaovana izany. Marina fa tsy azo atao ny mijery hatrany am-piandohana - mampihomehy, fa ny tetika sosona fototra dia tsy misy. Nanomboka tamin'ny 2 ny sosona. Ny antontan-taratasy dia milaza amintsika momba ny endri-javatra TL manokana:

Raha manohana ny Layer 2 ny mpanjifa, dia tsy maintsy ampiasaina ity mpanamboatra manaraka ity:

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

Amin'ny fampiharana, midika izany fa alohan'ny fiantsoana API rehetra, int miaraka amin'ny sandany 0x289dd1f6 tsy maintsy ampiana alohan'ny laharan'ny fomba.

Toa OK. Inona anefa no nitranga taorian’izay? Dia tonga

invokeWithLayer3#b7475268 query:!X = X;

Inona ary ny manaraka? Satria mora ny maminavina

invokeWithLayer4#dea0d430 query:!X = X;

mampihomehy? Tsia, aloha loatra ny mihomehy, eritrereto hoe inona tsirairay Ny fangatahana avy amin'ny sosona hafa dia mila fonosina amin'ny karazana manokana toy izany - raha samy manana azy ireo ianao, ahoana no hanavahana azy ireo? Ary ny fampidirana 4 bytes eo aloha dia fomba mahomby. Noho izany

invokeWithLayer5#417a57ae query:!X = X;

Saingy hita fa rehefa afaka kelikely dia ho lasa bacchanalia. Ary tonga ny vahaolana:

Fanavaozana: Manomboka amin'ny Layer 9, fomba mpanampy invokeWithLayerN azo ampiasaina miaraka amin'ny initConnection

Hooray! Taorian'ny dikan-teny 9 dia tonga tamin'ny zavatra natao tao amin'ny protocols Internet tamin'ny taona 80 izahay - fifampiraharahana dikan-teny indray mandeha teo am-piandohan'ny fifandraisana!

Dia inona no manaraka?..

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

Ary afaka mihomehy ianao izao. Taorian'ny sosona 9 hafa ihany dia nampiana constructor universal misy nomeraon'ny version, izay tsy maintsy antsoina indray mandeha monja amin'ny fiandohan'ny fifandraisana, ary toa nanjavona ny dikan'ny sosona, izao dia dikan-teny misy fepetra fotsiny, toy ny hatraiza hatraiza. Voavaha ny olana.

Sa tsy izany?..

Vasily, [16.07.18/14/01 XNUMX:XNUMX PM] Ny zoma dia nieritreritra aho hoe:
Mandefa hetsika tsy misy fangatahana ny teleserver. Ny fangatahana dia mila fonosina amin'ny InvokeWithLayer. Ny mpizara dia tsy mandrakotra ny fanavaozana, tsy misy rafitra hamenoana valiny sy fanavaozana.

Ireo. ny mpanjifa dia tsy afaka mamaritra ny sosona izay tiany fanavaozana

Vadim Goncharov, [16.07.18/14/02 XNUMX:XNUMX PM] Moa ve tsy ny InvokeWithLayer no tena fototra?

Vasily, [16.07.18/14/02 XNUMX:XNUMX PM] Io ihany no lalana

Vadim Goncharov, [16.07.18/14/02 XNUMX:XNUMX PM] izay amin'ny ankapobeny dia tokony hidika hoe sosona amin'ny fiandohan'ny fivoriana

Raha ny tokony ho izy, dia avy amin'izany fa tsy omena ny fampidinana mpanjifa

Fanavaozana, i.e. karazana Updates Ao amin'ny drafitra, ity no alefan'ny mpizara amin'ny mpanjifa tsy ho valin'ny fangatahana API, fa ho azy irery rehefa misy hetsika. Lohahevitra sarotra ity izay horesahina amin'ny lahatsoratra hafa, fa amin'izao fotoana izao dia zava-dehibe ny mahafantatra fa ny mpizara dia manangona Updates na dia ivelan'ny Internet aza ny mpanjifa.

Noho izany, rehefa mandΓ  ny fonony ny tsirairay fonosana hanondro ny dikan-ny, noho izany dia mipoitra araka ny lojika ny olana mety hitranga:

  • mandefa fanavaozam-baovao amin'ny mpanjifa ny mpizara alohan'ny nilazan'ny mpanjifa ny dikan-teny tohanany
  • inona no tokony hatao aorian'ny fanavaozana ny mpanjifa?
  • izay miantokafa ny hevitry ny mpizara momba ny laharan'ny sosona dia tsy hiova mandritra ny dingana?

Heverinao ve fa fisainana ara-teorika fotsiny izany, ary amin'ny fampiharana dia tsy mety hitranga izany, satria nosoratana araka ny tokony ho izy ny mpizara (na ahoana na ahoana, voasedra tsara)? Ha! Na ahoana na ahoana!

Izany indrindra no sendra anay tamin’ny volana aogositra. Tamin'ny 14 Aogositra, nisy hafatra nipoitra fa misy zavatra havaozina ao amin'ny mpizara Telegram ... ary avy eo ao amin'ny diary:

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.

ary avy eo megabytes vitsivitsy amin'ny dian'ny stack (tsara, miaraka amin'izay koa, raikitra ny logging). Raha ny marina, raha misy zavatra tsy fantatra ao amin'ny TL-nao - binary amin'ny sonia izany, any amin'ny renirano rEHETRA dia ho lasa tsy azo atao ny decoding. Inona no tokony hatao amin'ny toe-javatra toy izany?

Eny, ny zavatra voalohany tonga ao an-tsain'ny tsirairay dia ny manapaka ny fifandraisana ary manandrana indray. Tsy nanampy. Nijery ny CRC32 izahay tamin'ny google - ireo dia hita fa zavatra avy amin'ny skema 73, na dia niasa tamin'ny sketika 82 aza izahay. Nijery tsara ny logs izahay - misy famantarana avy amin'ny rafitra roa samihafa!

Angamba ny olana dia ao amin'ny mpanjifanay tsy ofisialy? Tsia, mampiasa Telegram Desktop 1.2.17 izahay (ny dikan-teny omena amin'ny fizarana Linux maromaro), manoratra amin'ny log Exception: MTP Unexpected type id #b5223b0f vakiana ao amin'ny MTPMessageMedia…

Fanakianana ny protocole sy ny fomba fandaminana ny Telegram. Fizarana 1, teknika: traikefa amin'ny fanoratana mpanjifa hatrany am-boalohany - TL, MT

Nasehon'i Google fa efa nisy olana mitovy amin'izany tamin'ny iray amin'ireo mpanjifa tsy ofisialy, fa avy eo ny laharan'ny dikan-teny ary, araka izany, dia samy hafa ny fiheverana ...

Inona Γ ry no hatao? Nisaraka izaho sy Vasily: nanandrana nanavao ny tetika ho 91 izy, nanapa-kevitra ny hiandry andro vitsivitsy aho ary nanandrana ny 73. Samy niasa ny fomba roa, saingy satria izy ireo dia empirical, tsy misy fahatakarana ny isan'ny dikan-teny ilainao hitsambikina. na midina, na mandra-pahoviana no tsy maintsy miandry .

Taty aoriana dia nahavita namerina indray ny toe-javatra aho: manomboka ny mpanjifa izahay, mamono azy, mamerina indray ny rafitra amin'ny sosona iray hafa, avereno indray, avereno indray ny olana, miverina amin'ny teo aloha - oops, tsy misy mamadika ny rafitra ary mamerina indray ny mpanjifa mandritra ny maromaro minitra dia hanampy. Hahazo fifangaroana rafitra angon-drakitra avy amin'ny sosona samihafa ianao.

Fanazavana? Araka ny azonao vinavinaina avy amin'ireo soritr'aretina ankolaka isan-karazany, ny mpizara dia ahitana karazana dingana maro samihafa amin'ny milina samihafa. Azo inoana fa ny iray amin'ireo mpizara izay tompon'andraikitra amin'ny "buffering" dia nametraka ny filaharana izay nomen'ny ambony, ary nomen'izy ireo izany tamin'ny drafitra tamin'ny fotoanan'ny taranaka. Ary mandra-pahavitan'ity filaharana ity dia "lo", tsy nisy azo natao tamin'izany.

Raha tsy hoe... fa tehina mahatsiravina ity?!.. Tsia, alohan'ny hieritreretana hevitra adala, andeha hojerentsika ny fehezan-dalΓ na momba ny mpanjifa ofisialy. Ao amin'ny dikan-teny Android dia tsy mahita parser TL izahay, fa mahita rakitra be dia be (github mandΓ  ny loko) miaraka amin'ny (de) serialization. Ireto ny snippet code:

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;

na

    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... toa adala. Saingy, angamba, kaody novokarina ity, avy eo okay? .. Fa azo antoka fa manohana ny dikan-teny rehetra! Marina fa tsy fantatra mazava hoe nahoana ny zava-drehetra no mifangaro amin'ny antontam-bato iray, sy ny resaka miafina, ary ny karazany rehetra _old7 tsy mitovy amin'ny famokarana milina ... Na izany aza, ny ankamaroan'ny rehetra dia lasa aho

TL_message_layer104
TL_message_layer104_2
TL_message_layer104_3

Ry zalahy, tsy afaka manapa-kevitra ao anatin'ny sosona iray akory ve ianao?! Eny ary, okay, "roa", ndao atao hoe, navotsotra tamin'ny fahadisoana, eny, mitranga izany, fa TELO? Karazana pΓ΄rnΓ΄grafia inona ity, azafady? ..

Amin'ny lafiny iray, misy zavatra mitovy amin'izany mitranga ao amin'ny loharano Telegram Desktop - raha izany, ary maro ny fanoloran-tena amin'ny andalana amin'ny drafitra dia tsy manova ny laharan'ny sosona, fa manamboatra zavatra. Amin'ny toe-javatra tsy misy loharano angon-drakitra ofisialy momba ny drafitra, aiza no ahafahako mahazo izany, afa-tsy amin'ny loharanon'ny mpanjifa ofisialy? Ary alainao avy eo izany, tsy azonao antoka fa marina tanteraka ilay tetika mandra-pitsapanao ny fomba rehetra.

Ahoana no hitsapana izany? Manantena aho fa hizara amin'ny fanehoan-kevitra ireo mpankafy unit, functional ary fitsapana hafa.

Eny ary, andeha isika hijery sombin-kaody hafa:

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;

Io fanehoan-kevitra "noforonina tanana" eto dia milaza fa ny ampahany amin'ity rakitra ity ihany no nosoratan'ny tanana (azonao sary an-tsaina ve ny nofy ratsy momba ny fikojakojana?), ary ny ambiny dia novokarin'ny milina. Na izany aza, misy fanontaniana iray hafa mipoitra - fa misy ny loharano tsy tanteraka (a la blobs eo ambanin'ny GPL ao amin'ny kernel Linux), fa ity dia efa lohahevitra ho an'ny ampahany faharoa.

Fa ampy. Andao hiroso amin'ny protocole izay enjehin'ireo serialization rehetra ireo.

MT Proto

Koa andao hisokatra famaritana ankapobeny ΠΈ famaritana amin'ny antsipiriany momba ny protocol ary ny zavatra voalohany manafintohina antsika dia ny terminology. Ary amin'ny habetsahan'ny zavatra rehetra. Amin'ny ankapobeny, toa marika famantarana an'ny Telegram izany - hiantso zavatra amin'ny toerana samihafa amin'ny fomba samihafa, na zavatra hafa amin'ny teny iray, na ny mifamadika amin'izany (ohatra, amin'ny API avo lenta raha mahita fonosana sticker ianao - ity tsy araka ny eritreritrao).

Ohatra, "hafatra" (hafatra) sy "session" (session) - eto izy ireo dia midika zavatra hafa noho ny mahazatra interface tsara ny mpanjifa Telegram. Eny, mazava tsara ny zava-drehetra amin'ny hafatra, azo adika amin'ny resaka OOP izy io, na antsoina hoe "fonosana" fotsiny - ambany io, ambaratonga fitaterana, tsy misy hafatra mitovy amin'ny ao amin'ny interface, be dia be. ny serivisy. Fa ny session ... fa ny zavatra voalohany aloha.

sosona fitaterana

Ny zavatra voalohany dia ny fitaterana. Holazaina momba ny safidy 5 isika:

  • TCP
  • websocket
  • Websocket amin'ny HTTPS
  • HTTP
  • HTTPS

Vasily, [15.06.18/15/04 XNUMX:XNUMX PM] Ary misy koa ny fitaterana UDP, saingy tsy voarakitra an-tsoratra.

Ary TCP amin'ny karazany telo

Ny voalohany dia mitovitovy amin'ny UDP amin'ny TCP, ny fonosana tsirairay dia misy laharana filaharana sy crc
Nahoana no maharary be ny mamaky docks amin'ny sarety?

Eny ary izao TCP efa misy karazany 4:

  • namintina
  • kafa
  • padded intermediate
  • Full

Ok, mpanelanelana Padded ho an'ny MTProxy, nampiana izany taty aoriana noho ny hetsika fantatra. Fa maninona no dikan-teny roa hafa (telo amin'ny fitambarany), nefa afaka manao izany? Ireo efatra ireo dia tsy mitovy amin'ny fomba fametrahana ny halavany sy ny enta-mavesatra amin'ny MTProto lehibe, izay horesahina bebe kokoa:

  • amin'ny Abridged dia 1 na 4 bytes fa tsy 0xef avy eo vatana
  • amin'ny Intermediate dia 4 bytes ny halavany sy saha iray, ary ny fotoana voalohany tsy maintsy alefan'ny mpanjifa 0xeeeeeeee mba hanondroana fa ny Intermediate
  • Amin'ny ankapobeny, ny tena mampiankin-doha indrindra, amin'ny fomba fijerin'ny tambajotra: ny halavany, ny laharan'ny filaharana, ary TSY ILAY izay amin'ny ankapobeny MTProto, vatana, CRC32. Eny, izany rehetra izany amin'ny TCP. Izay manome antsika ny fitaterana azo antoka amin'ny endrika serial stream of bytes, tsy misy filaharana ilaina, indrindra fa ny checksums. Eny, hanohitra ahy izy ireo fa manana checksum 16-bit ny TCP, ka mitranga ny kolikoly data. Tsara, afa-tsy ny tena manana protocole kriptografika miaraka amin'ny hashes mihoatra ny 16 bytes, ireo lesoka rehetra ireo - ary mihoatra noho izany aza - dia ho tratra amin'ny SHA mismatch amin'ny ambaratonga ambony. TSY misy hevitra ao amin'ny CRC32 momba izany.

Ampitahao ny Abridged, izay azo atao ny halavany iray, miaraka amin'ny Intermediate, izay manamarina ny "Raha ilaina ny fampifanarahana data 4-byte", izay tena tsy misy dikany. Inona no inoana fa kivy loatra ny mpandrindra Telegram ka tsy afaka mamaky angon-drakitra avy amin'ny socket mankany amin'ny buffer mifanaraka? Mbola mila manao izany ianao, satria ny famakiana dia afaka mamerina anao amin'ny isa maromaro (ary misy koa ny mpizara proxy, ohatra ...). Na, amin'ny lafiny iray, maninona no manahirana amin'ny Abridged raha mbola manana padding mavesatra avy amin'ny 16 bytes ambony isika - mitahiry 3 bytes indraindray ?

Ny iray dia mahazo ny fahatsapana fa Nikolai Durov dia tena tia mamorona bisikileta, anisan'izany ny tambajotra protocols, tsy misy tena ilaina.

Safidy fitaterana hafa, anisan'izany. Web sy MTProxy, tsy hodinihintsika izao, angamba amin'ny lahatsoratra hafa, raha misy fangatahana. Tsaroantsika fotsiny izao momba an'io MTProxy io fa tsy ela taorian'ny nivoahany tamin'ny taona 2018, dia nianatra nanakana azy io haingana ireo mpamatsy, natao ho an'ny bloc bypass, on haben'ny fonosana! Ary koa ny hoe ny mpizara MTProxy nosoratana (n'i Waltman indray) ao amin'ny C dia mifamatotra tsy amin'ny antony manokana amin'ny Linux, na dia tsy ilaina mihitsy aza izany (Hanamarina i Phil Kulin), ary ny mpizara mitovy amin'izany na ao amin'ny Go na amin'ny Node.js mifanentana latsaky ny zato andalana.

Fa hanatsoaka hevitra momba ny fahaiza-mamaky tekinika amin’ireo olona ireo isika any amin’ny faran’ny fizarana, rehefa avy nandinika olana hafa. Amin'izao fotoana izao, andao hiroso amin'ny sosona OSI faha-5, session - izay nametrahan'izy ireo ny session MTProto.

Fanalahidy, hafatra, fivoriana, Diffie-Hellman

Tsy araka ny tokony ho izy no napetrany tao ... Ny session dia tsy mitovy amin'ny session izay hita ao amin'ny interface eo ambanin'ny Active sessions. Fa araka ny filaharany.

Fanakianana ny protocole sy ny fomba fandaminana ny Telegram. Fizarana 1, teknika: traikefa amin'ny fanoratana mpanjifa hatrany am-boalohany - TL, MT

Eto izahay dia nahazo tady bytes fantatra ny halavany avy amin'ny sosona fitaterana. Hafatra voafono na soratra tsotra izany - raha mbola eo amin'ny sehatry ny fifampiraharahana isika ary tena manao izany. Iza amin'ireo andian-kevitra antsoina hoe "key" no resahina? Andeha hohazavaina ity olana ity ho an'ny ekipa Telegram mihitsy (miala tsiny aho tamin'ny nandikana ny antontan-taratasiko manokana avy amin'ny teny anglisy ho amin'ny atidoha reraka amin'ny 4 maraina, mora kokoa ny mamela fehezanteny sasany araka ny maha-izy azy):

Misy sampana roa antsoina hoe fivoriana - iray ao amin'ny UI an'ny mpanjifa ofisialy eo ambanin'ny "sessions ankehitriny", izay mifanandrify amin'ny fitaovana / OS iray manontolo ny fivoriana tsirairay.
Ny faharoa dia MTProto session, izay misy laharana filaharan'ny hafatra (amin'ny heviny ambany) ao anatiny, ary iza Mety haharitra eo anelanelan'ny fifandraisana TCP samihafa. Session MTProto maromaro no azo apetraka miaraka, ohatra, mba hanafainganana ny fampidinana rakitra.

Eo anelanelan'ireo roa ireo fivoriana dia ny hevitra alΓ lana. Amin'ny tranga miharatsy, dia afaka milaza izany Session UI dia mitovy amin'ny alΓ lanaIndrisy anefa fa sarotra. Mijery izahay:

  • Ny mpampiasa amin'ny fitaovana vaovao no mamorona voalohany auth_key ary mamehy azy amin'ny kaonty, ohatra, amin'ny SMS - izany no antony alΓ lana
  • Tao anatin'ny voalohany no nitrangan'izany MTProto session, izay manana session_id ao anatinao.
  • Amin'ity dingana ity, ny fitambarana alΓ lana ΠΈ session_id azo antsoina fahefana - Ity teny ity dia hita ao amin'ny antontan-taratasy sy ny code an'ny mpanjifa sasany
  • Avy eo, afaka misokatra ny mpanjifa maro Ireo singa mifandraika amin'ny MTProto ambanin'ny mitovy auth_key - amin'io DC io ihany.
  • Avy eo indray andro dia mila mangataka rakitra amin'ny mpanjifa ny mpanjifa DC hafa - ary ho an'ity DC ity dia hisy iray vaovao hatsangana auth_key !
  • Mba hilazana amin'ny rafitra fa tsy mpampiasa vaovao misoratra anarana izany, fa mitovy alΓ lana (Session UI), mampiasa antso API ny mpanjifa auth.exportAuthorization ao an-trano DC auth.importAuthorization amin'ny DC vaovao.
  • Na izany aza, mety misy maromaro misokatra Ireo singa mifandraika amin'ny MTProto (samy manana ny azy session_id) amin'ity DC vaovao ity, eo ambany ny auth_key.
  • Farany, ny mpanjifa dia mety maniry Perfect Forward Secrecy. rehetra auth_key izany no maharitra key - isaky ny DC - ary afaka miantso ny mpanjifa auth.bindTempAuthKey ho ampiasaina vonjimaika auth_key - ary indray, iray ihany temp_auth_key isaky ny DC, mahazatra amin'ny rehetra Ireo singa mifandraika amin'ny MTProto amin'ity DC ity.

Mariho izany sira (sy ny sira ho avy) ihany koa auth_key ireo. zaraina amin’ny rehetra Ireo singa mifandraika amin'ny MTProto amin'ny DC mitovy.

Inona no dikan'ny "eo anelanelan'ny fifandraisana TCP samihafa"? Midika izany fa ity zavatra toy ny Cookie fanomezan-dΓ lana amin'ny tranokala iray - mitohy (mivelona) ny fifandraisana TCP maro amin'ity mpizara ity, fa indray andro any dia ho ratsy izany. Tsy toy ny HTTP, ao amin'ny MTProto, ao anatin'ny fotoam-pivoriana, ny hafatra dia voaisa sy nohamafisina, niditra tao amin'ny tonelina izy ireo, tapaka ny fifandraisana - taorian'ny nananganana fifandraisana vaovao, ny mpizara dia handefa ny zava-drehetra amin'ity fivoriana ity izay tsy aterina ao amin'ny fifandraisana TCP teo aloha.

Na izany aza, ny vaovao etsy ambony dia tery taorian'ny volana maro nanaovana fitsarana. Mandra-pahatongan'izany, hampihatra ny mpanjifantsika hatrany am-boalohany ve isika? - andao hiverina amin'ny voalohany.

Ka mamorona izahay auth_key amin'ny dikan-tenin'i Diffie-Hellman avy amin'ny Telegram. Andao hiezaka hahatakatra ny antontan-taratasy...

Vasily, [19.06.18/20/05 1:255] data_with_hash := SHAXNUMX(data) + data + (any random bytes); ka ny halavany dia mitovy amin'ny XNUMX bytes;
encrypted_data := RSA(data_with_hash, server_public_key); isa lava 255-byte (endian lehibe) dia atsangana ho amin'ny hery takiana amin'ny modulus ilaina, ary ny vokatra dia voatahiry ho isa 256-byte.

Nahazo dope DH izy ireo

Tsy mitovy amin'ny DH an'ny olona salama
Tsy misy fanalahidin'ny daholobe roa ao amin'ny dx

Eny ary, tamin'ny farany, noheverinay izany, fa ny sediment dia nijanona - porofon'ny asa nataon'ny mpanjifa fa afaka nanamarina ny isa izy. Karazana fiarovana amin'ny fanafihana DoS. Ary ny lakile RSA dia ampiasaina indray mandeha amin'ny lalana iray, indrindra ho an'ny encryption new_nonce. Saingy raha mahomby io fandidiana toa tsotra io, inona no tsy maintsy atrehinao?

Vasily, [20.06.18/00/26 XNUMX:XNUMX] Mbola tsy tonga amin'ny fangatahana appid aho

Nandefa fangatahana tany amin'ny DH aho

Ary, ao amin'ny dock amin'ny fitaterana dia voasoratra fa afaka mamaly amin'ny 4 bytes ny code error. Dia izay ihany

Eny, hoy izy tamiko -404, dia ahoana?

Indro aho aminy: β€œsambory ny efignao misy encryption miaraka amin’ny lakilen’ny mpizara misy dian-tanana toy izao sy izao, mila DH aho”, dia mamaly adaladala 404.

Inona no hevitrao momba ny valintenin'ny mpizara toy izany? Ny hatao? Tsy misy manontany (fa bebe kokoa amin'ny ampahany faharoa).

Eto ny mahaliana rehetra amin'ny dock dia tokony hatao

Tsy misy zavatra hafa ataoko fa nanonofy fotsiny ny hamadika isa sy miverina

Isa roa 32 bit. Nofonosina toy ny olon-drehetra izy ireo

Saingy tsia, ireo roa ireo no ilainao voalohany amin'ny laharana toy ny BE

Vadim Goncharov, [20.06.18/15/49 404:XNUMX PM] ary noho io XNUMX io?

Vasily, [20.06.18/15/49 XNUMX:XNUMX PM] ENY!

Vadim Goncharov, [20.06.18/15/50 XNUMX:XNUMX PM] ka tsy azoko izay "tsy hitany"

Vasily, [20.06.18 15:50] about

Tsy hitako ny fanimbana toy izany ho fisarahana tsotra%)

Na ny tatitra diso aza tsy voafehy

Vasily, [20.06.18/20/18 5:XNUMX PM] Oh, misy MDXNUMX koa. Efa hash telo samy hafa

Toy izao manaraka izao ny fikajiana ny fingerprint key:

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

SHA1 sy sha2

Ka aleo apetraka auth_key 2048 bit ny habeny azonay araka ny Diffie-Hellman. Inona ny manaraka? Avy eo dia hitantsika fa ny bits ambany 1024 amin'ity fanalahidy ity dia tsy ampiasaina amin'ny fomba rehetra ... fa andeha hojerentsika izao. Amin'ity dingana ity dia manana tsiambaratelo iombonana amin'ny mpizara izahay. Natsangana ny analogue amin'ny fivoriana TLS, fomba fiasa tena lafo. Fa ny mpizara dia tsy mbola mahalala na inona na inona momba ny hoe iza isika! Tsy mbola, raha ny marina alΓ lana. Ireo. raha nieritreritra momba ny "login-password" ianao, toy ny taloha tao amin'ny ICQ, na farafaharatsiny "fanalahidy fidirana", toy ny ao amin'ny SSH (ohatra, amin'ny gitlab / github sasany). Nahazo anonyme izahay. Ary raha mamaly anay ny mpizara "ireo nomeraon-telefaona ireo dia atolotry ny DC hafa"? Na koa hoe β€œvoarara ny laharan-telefaoninao”? Ny tsara indrindra azontsika atao dia ny mitahiry ny lakile amin'ny fanantenana fa mbola hahasoa sy tsy ho lo amin'izay fotoana izay.

Raha ny marina, dia "nandray" azy tamin'ny famandrihana izahay. Ohatra, matoky ny mpizara ve isika? sandoka ve izy? Mila fanamarinana kriptografika izahay:

Vasily, [21.06.18/17/53 2:XNUMX PM] Manolotra mpanjifa finday izy ireo hanamarina isa XNUMXkbit ho an'ny fahatsorana%)

Fa tsy mazava mihitsy, nafeijoa

Vasily, [21.06.18/18/02 XNUMX:XNUMX] Ny dock dia tsy milaza izay tokony hatao raha toa ka tsy tsotra izany

Tsy lazaina. Andeha hojerentsika izay ataon'ny mpanjifa ofisialy ho an'ny Android amin'ity tranga ity? ny izay no (ary eny, mahaliana ny rakitra manontolo ao) - araka ny filazan'izy ireo, avelako eto fotsiny izany:

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

Tsia, mazava ho azy any SASANY misy ny fanamarinana ny fahatsoran'ny isa, fa izaho manokana dia tsy manana fahalalana ampy amin'ny matematika intsony.

Eny, azonay ny lakile master. Hiditra, i.e. mandefa fangatahana, ilaina ny manao encryption fanampiny, efa mampiasa AES.

Ny fanalahidin'ny hafatra dia voafaritra ho bits 128 afovoany amin'ny SHA256 amin'ny vatan'ny hafatra (ao anatin'izany ny session, message ID, sns.), anisan'izany ny padding bytes, prepended by 32 bytes nalaina avy amin'ny fanomezan-dΓ lana.

Vasily, [22.06.18/14/08 XNUMX:XNUMX PM] Salan'isa

nahazo auth_key. Rehetra. Manaraka azy ireo ... tsy mazava avy amin'ny seranana. Aza misalasala mandalina ny code open source.

Mariho fa ny MTProto 2.0 dia mitaky padding 12 ka hatramin'ny 1024 bytes, mbola iharan'ny fepetra hoe azo zaraina amin'ny 16 bytes ny halavan'ny hafatra.

Dia ohatrinona ny padding hapetraka?

Ary eny, eto koa, 404 raha misy hadisoana

Raha misy olona nandinika tsara ny kisary sy ny lahatsoratry ny antontan-taratasy dia voamariny fa tsy misy MAC ao. Ary io AES io dia ampiasaina amin'ny fomba IGE sasany izay tsy ampiasaina any an-kafa. Mazava ho azy fa manoratra momba izany ao amin'ny FAQ-ny izy ireo ... Eto, toy ny, ny lakilen'ny hafatra dia miaraka amin'ny SHA hash amin'ny angon-drakitra decrypted ampiasaina hanamarinana ny fahamendrehana - ary raha misy tsy fitoviana, ny antontan-taratasy momba ny Ny antony sasany dia manoro hevitra ny tsy hiraharaha azy ireo mangina (fa ahoana ny amin'ny fiarovana, manapotika antsika tampoka?).

Tsy cryptographer aho, angamba amin'ity fomba ity amin'ity tranga ity dia tsy misy diso amin'ny fomba fijery teorika. Saingy azoko atao ny manonona olana azo ampiharina, amin'ny fampiasana ny ohatra amin'ny Telegram Desktop. Izy io dia mamadika ny cache eo an-toerana (ireo D877F783D5D3EF8C rehetra ireo) mitovy amin'ny hafatra ao amin'ny MTProto (amin'ity tranga ity ihany, version 1.0), izany hoe. voalohany ny fanalahidin'ny hafatra, avy eo ny angon-drakitra (ary any an-toeran-kafa ny lehibe lehibe auth_key 256 bytes, raha tsy misy izany msg_key tsy misy ilana azy). Noho izany, ny olana dia lasa miharihary amin'ny rakitra lehibe. Izany hoe, mila mitazona dika roa amin'ny angon-drakitra ianao - encrypted sy decrypted. Ary raha misy megabytes, na horonan-tsary mivantana, ohatra? .. Ny rafitra klasika miaraka amin'ny MAC aorian'ny ciphertext dia ahafahanao mamaky azy mivantana, mamindra azy avy hatrany. Ary amin'ny MTProto dia tsy maintsy tamin'ny voalohany encrypt na decrypt ny hafatra manontolo, avy eo dia afindrao any amin'ny tambajotra na amin'ny kapila. Noho izany, amin'ny dikan-teny farany amin'ny Telegram Desktop ao amin'ny cache in user_data efa misy endrika hafa - miaraka amin'ny AES amin'ny fomba CTR.

Vasily, [21.06.18/01/27 20:XNUMX AM] Oh, hitako ny atao hoe IGE: IGE no andrana voalohany tamin'ny "mode encryption authentication", ho an'i Kerberos tany am-boalohany. Andrana tsy nahomby izany (tsy manome fiarovana amin'ny fahamendrehana), ary tsy maintsy nesorina. Izany no fiandohan'ny fikatsahana XNUMX taona ho an'ny fomba fanafenana fanamarinana izay miasa, izay vao haingana no niafara tamin'ny maodely toa ny OCB sy GCM.

Ary izao ny hevitra avy amin'ny sarety:

Ny ekipa ao ambadiky ny Telegram, tarihin'i Nikolai Durov, dia ahitana tompon-daka ACM enina, ka ny antsasany dia Ph.D amin'ny matematika. Roa taona teo ho eo izy ireo vao namoaka ny dikan-teny MTProto ankehitriny.

Inona no mampihomehy. Roa taona mankany amin'ny ambaratonga ambany

Na afaka maka tls fotsiny izahay

Okay, andao atao hoe nanao encryption sy ireo nuances hafa. Afaka mandefa fangatahana TL-serialized ve isika ary manafoana valiny? Inona Γ ry no tokony halefa ary ahoana? Ity ny fomba initConnectionmety io ve?

Vasily, [25.06.18/18/46 XNUMX:XNUMX PM] Manokatra fifandraisana ary mitahiry vaovao momba ny fitaovana sy fampiharana an'ny mpampiasa.

Manaiky app_id, device_model, system_version, app_version ary lang_code.

Ary fanontaniana sasany

Documentation toy ny mahazatra. Aza misalasala mandalina ny loharano misokatra

Raha mazava tsara ny zava-drehetra miaraka amin'ny invokeWithLayer, inona izany? Hita fa raha manana izahay - efa nanana zavatra hanontaniana ny mpizara ny mpanjifa - misy fangatahana tiana halefa:

Vasily, [25.06.18/19/13 XNUMX:XNUMX] Raha jerena amin'ny kaody, ny antso voalohany dia nofonosina ao anatin'ity fako ity, ary ny fako mihitsy no ao anaty invokewithlayer.

Nahoana no tsy afaka miantso manokana ny initConnection, fa tsy maintsy fonosina? Eny, araka ny hita, dia tsy maintsy atao isaky ny fiandohan'ny fotoam-pivoriana tsirairay, fa tsy indray mandeha, toy ny amin'ny fanalahidy fototra. Fa! Tsy azo antsoina amin'ny mpampiasa tsy nahazoana alalana izany! Eto isika dia tonga amin'ny sehatra azo ampiharina Ity iray ity pejin'ny antontan-taratasy - ary milaza amintsika fa...

Ampahany kely amin'ny fomba API ihany no azon'ny mpampiasa tsy nahazoana alalana:

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

Ny voalohany amin'izy ireo auth.sendCode, ary misy ilay fangatahana voalohany tena sarobidy izay handefasanay api_id sy api_hash, ary avy eo dia mahazo SMS misy kaody. Ary raha tonga any amin'ny DC diso isika (ohatra, ny nomeraon-telefaonina amin'ity firenena ity) dia hahazo fahadisoana miaraka amin'ny laharan'ny DC tiana. Raha te hahalala ny adiresy IP tokony hifandraisantsika amin'ny laharana DC, dia hanampy antsika help.getConfig. Raha vao 5 ihany no nisoratra anarana, saingy taorian’ny hetsika nalaza tamin’ny taona 2018 dia nitombo be izany.

Andeha hojerentsika izao fa tonga amin'ity dingana ity amin'ny mpizara tsy mitonona anarana isika. Tsy lafo loatra ve ny mahazo adiresy IP? Maninona raha manao an'ity, sy ny asa hafa, ao amin'ny faritra tsy voafehin'ny MTProto? Henoko ny fanoherana: β€œahoana no ahazoanao antoka fa tsy ny RKN no hamaly adiresy sandoka?”. Amin'izany dia tsaroanay fa, raha ny marina, amin'ny mpanjifa ofisialy lakile RSA tafiditra, i.e. azonao atao fotsiny FAMANTARANA ity vaovao ity. Raha ny marina, izany dia efa natao ho an'ny fampahalalana momba ny fanilihana hidin-trano izay azon'ny mpanjifa amin'ny alΓ lan'ny fantsona hafa (lojika fa tsy azo atao ao amin'ny MTProto mihitsy izany, satria mbola mila mahafantatra ianao hoe aiza no hifandraisana).

OK. Amin'izao dingan'ny fanomezan-dΓ lana ho an'ny mpanjifa izao dia mbola tsy nahazo alalana izahay ary tsy nisoratra anarana ny fangatahanay. Te-hijery fotsiny izahay amin'izao fotoana izao izay mamaly ny mpizara amin'ny fomba azon'ny mpampiasa tsy nahazoana alalana. Ary eto…

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;

Ao amin'ny drafitra, ny voalohany, ny faharoa dia tonga

Ao amin'ny schema tdesktop, ny sanda fahatelo dia

Eny, nanomboka teo, mazava ho azy, nohavaozina ny antontan-taratasy. Na dia tsy ho ela aza dia mety ho lasa tsy manan-danja indray izany. Ary ahoana no tokony ho fantatry ny mpamorona vaovao? Angamba raha manoratra ny fangatahanao ianao dia hampahafantatra anao izy ireo? Nanao izany i Vasily, saingy indrisy, tsy nisy nandefasana azy (indray, hiresaka momba izany isika amin'ny ampahany faharoa).

... Voamarikao fa efa nifindra tany amin'ny API izahay, i.e. mankany amin'ny ambaratonga manaraka ary tsy mahita zavatra amin'ny lohahevitra MTProto? Tsy misy mahagaga:

Vasily, [28.06.18/02/04 2:XNUMX AM] Mm, mikaroka ny sasany amin'ireo algorithm ao amin'ny eXNUMXe izy ireo.

Mtproto dia mamaritra ny algorithm encryption sy ny fanalahidy ho an'ny sehatra roa, ary koa ny firafitry ny fonosana

Saingy mampifangaro tsy tapaka ny haavon'ny stack izy ireo, ka tsy mazava foana hoe taiza no niafaran'ny mtproto ary nanomboka ny ambaratonga manaraka.

Ahoana no fampifangaroana azy ireo? Eny, ity ny fanalahidy vonjimaika ho an'ny PFS, ohatra (amin'ny fomba, Telegram Desktop tsy mahalala ny fomba hanaovana izany). Izy io dia tanterahina amin'ny fangatahana API auth.bindTempAuthKey, i.e. avy amin'ny ambaratonga ambony. Saingy amin'izany fotoana izany dia manelingelina ny fanafenana amin'ny ambaratonga ambany - aorian'izany, ohatra, mila manao izany indray ianao initConnection sns, tsy izany fotsiny fangatahana mahazatra. Misaraka, dia manome ihany koa fa afaka manana fanalahidy vonjimaika IRAY amin'ny DC ianao, na dia eo aza ny saha auth_key_id isaky ny hafatra dia ahafahanao manova ny lakile farafaharatsiny isaky ny hafatra, ary ny mpizara dia manan-jo "manadino" ny fanalahidy vonjimaika amin'ny fotoana rehetra - inona no tokony hatao amin'ity tranga ity, ny antontan-taratasy dia tsy milaza ... tsy ho azo atao ny manana fanalahidy maromaro, toy ny amin'ny andian-tsira ho avy, fa ?..

Misy zavatra vitsivitsy hafa tokony ho marihina ao amin'ny lohahevitra MTProto.

Hafatra hafatra, msg_id, msg_seqno, fankasitrahana, pings amin'ny lalana diso ary ireo idiosyncrasie hafa

Nahoana ianao no mila mahafantatra momba azy ireo? Satria izy ireo dia "mitete" ambaratonga iray avo kokoa, ary mila mahafantatra momba azy ireo ianao rehefa miara-miasa amin'ny API. Eritrereto hoe tsy liana amin'ny msg_key isika, ny ambaratonga ambany dia namadika ny zava-drehetra ho antsika. Fa ao anatin'ny angon-drakitra nohavaozina dia manana ireto saha manaraka ireto isika (ny halavan'ny angon-drakitra hahafantarana hoe aiza ny padding, saingy tsy zava-dehibe izany):

  • sira-int64
  • session_id - int64
  • message_id - int64
  • seq_no-int32

Tsarovy fa ny sira dia iray ho an'ny DC iray manontolo. Nahoana no mahalala ny momba azy? Tsy hoe satria misy fangatahana ihany get_future_salts, izay milaza hoe inona ny elanelana mety ho manan-kery, fa koa satria raha "lo" ny sira, dia ho very fotsiny ny hafatra (fangatahana). Ny mpizara dia mazava ho azy fa hitatitra ny sira vaovao amin'ny famoahana new_session_created - fa miaraka amin'ilay taloha dia tsy maintsy alefanao indray, ohatra. Ary io fanontaniana io dia misy fiantraikany amin'ny rafitry ny fampiharana.

Ny mpizara dia avela handao tanteraka ny fotoam-pivoriana ary hamaly amin'izany fomba izany noho ny antony maro. Raha ny marina, inona ny fivoriana MTProto avy amin'ny lafiny mpanjifa? Isa roa ireo session_id ΠΈ seq_no hafatra ao anatin'ity fivoriana ity. Eny ary, ary ny fifandraisana TCP fototra, mazava ho azy. Aoka hatao hoe mbola tsy mahay manao zavatra maro ny mpanjifanay, tapaka, mifandray indray. Raha nitranga haingana izany - ny fivoriana taloha dia nitohy tamin'ny fifandraisana TCP vaovao, mitombo seq_no fanampiny. Raha maharitra ela dia afaka mamafa azy ny mpizara, satria eo amin'ny ilany dia misy filaharana ihany koa, araka ny fantatray.

Inona no tokony ho seq_no? Oh, fanontaniana sarotra izany. Miezaha hahatakatra marina ny tiana holazaina:

Hafatra mifandraika amin'ny atiny

Hafatra mila fanekena mazava. Anisan'izany ny mpampiasa rehetra sy ny hafatra serivisy maro, saika ny rehetra afa-tsy ny fitoeran-javatra sy ny fankasitrahana.

Laharana filaharan'ny hafatra (msg_seqno)

Laharana 32-bit mitovy amin'ny indroa ny isan'ny hafatra "mifandray amin'ny votoaty" (ireo mitaky fanekena, ary indrindra ireo izay tsy fitoeran-javatra) noforonin'ny mpandefa alohan'ity hafatra ity ary ampitomboina iray avy eo raha toa ka hafatra mifandraika amin'ny atiny. Ny kaontenera dia amboarina foana aorian'ny votoatiny manontolo; noho izany, ny laharan'ny filaharany dia lehibe kokoa na mitovy amin'ny laharan'ny filaharan'ireo hafatra voarakitra ao.

Karazana cirque manao ahoana ity misy fisondrotana 1, ary 2 hafa? .. Miahiahy aho fa ny dikan'ny teny tany am-boalohany dia "ambany kely ho an'ny ACK, ny ambiny dia isa", fa ny vokatra dia tsy mety - indrindra indrindra, hita fa azo alefa maro fanamafisana izay manana mitovy seq_no! Ahoana? Eny, ohatra, ny mpizara dia mandefa zavatra ho antsika, mandefa, ary ny tenantsika dia mangina, dia mamaly amin'ny hafatra fanamafisana serivisy momba ny fandraisana ny hafany. Amin'ity tranga ity, ny fanamafisam-peo mivoaka dia hanana laharana mivoaka mitovy. Raha zatra amin'ny TCP ianao ary nihevitra fa toa adala izany, saingy toa tsy dia bibidia loatra izany, satria ao amin'ny TCP seq_no tsy miova, ary ny fanamafisana dia mandeha any seq_no ny ankilany - dia maika aho hanakorontana. Tonga ao amin'ny MTProto ny fanamafisana TSY amin'ny seq_no, toy ny ao amin'ny TCP, fa msg_id !

Inona ity msg_id, ny manan-danja indrindra amin'ireo sehatra ireo? Ny ID tokana an'ny hafatra, araka ny dikan'ny anarana. Nofaritana ho isa 64-bit izy io, ny bitika faran'izay manan-danja indrindra izay manana majika mpizara-tsy-server, ary ny ambiny dia famantarana famantarana Unix, anisan'izany ny ampahany kely, nafindra 32 bits miankavia. Ireo. timestamp per se (ary ny hafatra misy fotoana samy hafa dia holavin'ny mpizara). Avy amin'izany dia hita fa, amin'ny ankapobeny, ity dia famantarana iray manerantany ho an'ny mpanjifa. Raha - tsarovy session_id - azo antoka izahay: Na ahoana na ahoana dia tsy azo alefa any amin'ny fivoriana hafa ny hafatra natao ho an'ny fivoriana iray. Izany hoe, hita fa efa misy telo ambaratonga β€” session, session number, message id. Nahoana no sarotra be loatra, ity mistery ity dia tena lehibe.

Ary noho izany, msg_id ilaina ho…

RPC: fangatahana, valiny, fahadisoana. Confirmations.

Araka ny efa tsikaritrareo dia tsy misy karazana na fiasa manokana "manaova fangatahana RPC" na aiza na aiza ao amin'ny schema, na dia misy valiny aza. Rehefa dinihina tokoa, manana hafatra mifandraika amin'ny votoaty isika! Izany hoe, misy hafatra mety ho fangatahana! Na tsy ho. Sady koa anie, ny tsirairay dia msg_id. Ary ireto ny valiny:

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

Eo no ilazana ny hafatra izay valinteny. Noho izany, amin'ny ambaratonga ambony amin'ny API, dia tsy maintsy tadidinao hoe inona no isan'ny fangatahanao - heveriko fa tsy ilaina ny manazava fa ny asa dia asynchronous, ary mety hisy fangatahana maromaro miaraka, ny valiny izay azo averina amin'ny fomba rehetra? Amin'ny ankapobeny, avy amin'izany, ary ny hafatra diso toy ny tsy misy mpiasa, ny maritrano ao ambadik'izany dia azo trandrahana: ny mpizara izay mitazona fifandraisana TCP aminao dia mpifandanja eo anoloana, mitarika ny fangatahana ho any aoriana ary manangona azy ireo miaraka. message_id. Toa mazava sy mitombina ary tsara ny zava-drehetra eto.

Eny?.. Ary raha mieritreritra an'izany ianao? Raha ny marina, ny valin'ny RPC ihany koa dia manana sehatra msg_id! Mila miantsoantso amin'ny mpizara ve isika hoe "tsy mamaly ny valinteniko ianao!"? Ary eny, inona no nisy momba ny fanamafisana? Momba ny pejy hafatra momba ny hafatra milaza amintsika hoe inona izany

msgs_ack#62d6b459 msg_ids:Vector long = MsgsAck;

ary tsy maintsy manao izany ny andaniny sy ny ankilany. Fa tsy foana! Raha mahazo RpcResult ianao dia toy ny fanekena ho azy. Izany hoe, ny mpizara dia afaka mamaly ny fangatahanao amin'ny MsgsAck - toy ny hoe, "Nahazo izany aho." Afaka mamaly avy hatrany ny RpcResult. Mety ho izy roa.

Ary eny, mbola mila mamaly ny valiny ianao! fanamafisana. Raha tsy izany, heverin'ny mpizara ho tsy azo alefa ilay izy ary hatsipy any aminao indray. Na dia aorian'ny fifandraisana indray. Saingy eto, mazava ho azy, dia hipoitra ny fanontaniana momba ny fotoana fialan-tsasatra. Andeha hojerentsika izy ireo aoriana kely.

Mandra-pahatongan'izany, andeha hojerentsika ny mety ho lesoka amin'ny fanatanterahana fanontaniana.

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

Oh, hisy hihiaka, ity misy endrika olombelona kokoa - misy andalana! Ataovy miadana. Eto lisitry ny fahadisoananefa azo antoka fa tsy feno. Avy amin'izany no ianarantsika fa ny kaody dia βˆ’ zavatra toy ny Ny hadisoana HTTP (mazava ho azy fa tsy voahaja ny semantika amin'ny valinteny, any amin'ny toerana sasany dia zaraina amin'ny alΓ lan'ny kaody kisendrasendra), ary toa ny tady. CAPITAL_LETTERS_AND_NUMBERS. Ohatra, PHONE_NUMBER_OCCUPIED na FILE_PART_X_MISSING. Eny, izany hoe, mbola mila an'io andalana io ianao hadihadiana. Ohatra FLOOD_WAIT_3600 dia midika fa tsy maintsy miandry adiny iray ianao, ary PHONE_MIGRATE_5fa ny nomeraon-telefaonina misy an'io prefix io ​​dia tokony hisoratra anarana ao amin'ny DC faha-5. Manana fiteny karazana isika, sa tsy izany? Tsy mila ady hevitra avy amin'ny tady isika, ny fomba fiteny mahazatra dia hanao, cho.

Averina indray, ity dia tsy ao amin'ny pejin'ny hafatra momba ny serivisy, fa, toy ny efa mahazatra amin'ity tetikasa ity, dia azo jerena ny fampahalalana. amin'ny pejin'ny antontan-taratasy hafa. na mampiahiahy. Voalohany, jereo, fanitsakitsahana ny fanoratana/sosona - RpcError azo ampidirina ao RpcResult. Maninona raha any ivelany? Inona no tsy noraisintsika?... Araka izany, aiza ny antoka fa RpcError mety tsy ho investissement RpcResult, fa mivantana na mianaka amin'ny karazana hafa? tsy ampy izany req_msg_id ? ..

Fa andeha isika hanohy ny hafatra momba ny serivisy. Mety hihevitra ny mpanjifa fa mieritreritra ela ny mpizara, ary manao fangatahana mahafinaritra toy izao:

rpc_drop_answer#58e4a740 req_msg_id:long = RpcDropAnswer;

Misy valiny telo azo atao amin'izany, indray mifanelanelana amin'ny rafitra fanamafisana, mba hiezaka hahatakatra izay tokony ho izy ireo (ary inona ny lisitry ny karazana tsy mila fanamafisana amin'ny ankapobeny), ny mpamaky dia avela ho enti-mody (fanamarihana: ny tsy feno ny fampahalalana ao amin'ny loharano Telegram Desktop).

Fiankinan-doha: Statuses Post Message

Amin'ny ankapobeny, toerana maro ao amin'ny TL, MTProto ary Telegram amin'ny ankapobeny dia mamela fahatsapana mafy loha, fa noho ny fahalalam-pomba, ny fahaiza-mandanjalanja ary ny hafa. malefaka fahaiza-manao nangina tamim-pahalalam-pomba momba izany izahay, ary voasivana ny fahavetavetana tamin'ny fifanakalozan-kevitra. Na izany aza, ity toerana ityОny ankamaroan'ny pejy momba ny hafatra momba ny hafatra miteraka fahatafintohinana na dia ho ahy aza, izay efa niasa tamin'ny protocols tambajotra nandritra ny fotoana ela ary nahita bisikilety amin'ny ambaratonga samihafa amin'ny curvature.

Manomboka tsy mampidi-doza izany, miaraka amin'ny fanamafisana. Manaraka izany dia lazaina amintsika ny momba

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;

Eny, izay rehetra manomboka miasa amin'ny MTProto dia tsy maintsy miatrika azy ireo, ao amin'ny tsingerin'ny "nahitsy - naverina - natomboka", ny fahazoana lesoka amin'ny isa na sira izay simba nandritra ny fanovana dia zavatra mahazatra. Misy teboka roa anefa eto:

  1. Manaraka izany dia very ny hafatra tany am-boalohany. Mila fefy filaharana isika, hodinihintsika any aoriana.
  2. Inona ireo isa hafahafa ireo? 16, 17, 18, 19, 20, 32, 33, 34, 35, 48, 64... aiza ny isa ambiny ry Tommy?

Ny antontan-taratasy dia milaza hoe:

Ny tanjona dia ny hoe mivondrona ny soatoavina error_code (error_code >> 4): ohatra, ny code 0x40 - 0x4f dia mifanitsy amin'ny lesoka amin'ny fandotoana container.

fa, voalohany, fiovana amin'ny lalana hafa, ary faharoa, tsy maninona na aiza na aiza ny sisa amin'ny kaody? Ao amin'ny lohan'ny mpanoratra?.. Na izany aza dia zava-poana ireo.

Ny fiankinan-doha dia manomboka amin'ny hafatra momba ny sata ary mandefa kopia:

  • Fangatahana fampahalalana momba ny satan'ny hafatra
    Raha toa ka tsy nahazo vaovao momba ny satan'ny hafatra nivoaka nandritra ny fotoana kelikely ny roa tonta, dia mety hangataka izany amin'ny ankilany izy:
    msgs_state_req#da69fb52 msg_ids:Vector long = MsgsStateReq;
  • Hafatra fampahalalana momba ny satan'ny hafatra
    msgs_state_info#04deb57d req_msg_id:long info:string = MsgsStateInfo;
    Eto, info dia tady mirakitra iray byte ny satan'ny hafatra isaky ny hafatra avy amin'ny lisitry ny msg_ids miditra:

    • 1 = tsy misy fantatra momba ny hafatra (msg_id ambany loatra, mety hadinon'ny ankilany izany)
    • 2 = hafatra tsy voaray (msg_id dia tafiditra ao anatin'ny isan'ireo famantarana voatahiry; na izany aza, ny ankilany dia azo antoka fa tsy nahazo hafatra toy izany)
    • 3 = hafatra tsy voaray (msg_id avo loatra; na izany aza, ny ankilany mbola tsy nahazo izany)
    • 4 = hafatra voaray (mariho fa ity valinteny ity dia miaraka amin'ny fanekena tapakila ihany koa)
    • +8 = hafatra efa nekena
    • +16 = hafatra tsy mila fanekena
    • +32 = Fanontaniana RPC voarakitra ao amin'ny hafatra karakaraina na efa vita
    • +64 = valiny mifandraika amin'ny atiny amin'ny hafatra efa novokarina
    • +128 = fantatry ny hafa fa efa voaray ny hafatra
      Tsy mila fanekena izany valiny izany. Izany dia fanekena ny msgs_state_req mifandraika amin'izany, ao anatin'ny tenany.
      Mariho fa raha toa ka hita tampoka fa tsy manana hafatra toa ny nandefasana azy ny ankilany, dia azo alefa fotsiny ilay hafatra. Na dia mahazo kopia roa amin'ny hafatra miaraka aza ny ankilany, dia tsy hiraharaha ilay dika mitovy. (Raha be loatra ny fotoana lasa, ary tsy manankery intsony ny msg_id voalohany, dia tokony hofonosina msg_copy ny hafatra).
  • Fifandraisana an-tsitrapo momba ny satan'ny hafatra
    Na iza na iza dia afaka mampahafantatra an-tsitrapo ny ankilany ny sata mifehy ny hafatra ampitain'ny ankilany.
    msgs_all_info#8cc0d131 msg_ids:Vector long info:string = MsgsAllInfo
  • Fifandraisana an-tsitrapo amin'ny satan'ny hafatra iray
    ...
    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;
  • Fangatahana mazava handefasana hafatra
    msg_resend_req#7d861a08 msg_ids:Vector long = MsgResendReq;
    Ny antoko lavitra dia mamaly avy hatrany amin'ny fandefasana ireo hafatra nangatahana [...]
  • Fangatahana mazava mba handefasana valiny
    msg_resend_ans_req#8610baeb msg_ids:Vector long = MsgResendReq;
    Ny antoko lavitra dia mamaly avy hatrany amin'ny fandefasana indray valiny amin’ireo hafatra nangatahina […]
  • Hafatra kopia
    Amin'ny toe-javatra sasany dia mila alefa indray ny hafatra taloha misy msg_id izay tsy manankery intsony. Avy eo, fonosina ao anaty fitoeran-javatra kopia:
    msg_copy#e06046b2 orig_message:Message = MessageCopy;
    Rehefa voaray ny hafatra dia karakaraina toy ny hoe tsy eo ny fonony. Na izany aza, raha fantatra tsara fa voaray ilay hafatra orig_message.msg_id, dia tsy voakarakara ilay hafatra vaovao (raha toa ka ekena ihany koa izy sy ny orig_message.msg_id). Ny sandan'ny orig_message.msg_id dia tsy maintsy ambany noho ny msg_id an'ny container.

Aoka isika hangina mihitsy ny amin'ny hoe ao msgs_state_info indray, mipoitra ny sofin'ny TL tsy vita (mila vector of bytes izahay, ary ao amin'ny bits roa ambany amin'ny enum, ary amin'ny saina bits taloha). Ny teboka dia zavatra hafa. Misy mahatakatra ny antony mahatonga izany rehetra izany amin'ny fampiharana amin'ny tena mpanjifa ilaina?.. Amin'ny fahasarotana, fa azonao an-tsaina ny tombontsoa sasany raha misy olona mirotsaka amin'ny debugging, ary amin'ny fomba interactive - anontanio ny mpizara hoe inona ary ahoana. Fa ny fangatahana dia voalaza eto dia mandroso sy miverina.

Avy amin'izany ny lafiny tsirairay dia tsy maintsy manao encryption sy mandefa hafatra, fa mitahiry angona momba azy ireo ihany koa, momba ny valiny, ary mandritra ny fotoana tsy fantatra. Ny antontan-taratasy dia tsy mamaritra ny fotoana na ny fampiharana azo ampiharina amin'ireo endri-javatra ireo. tsy misy lalana. Ny tena mahagaga dia tena ampiasaina amin'ny code of clients ofisialy izy ireo! Raha ny fantatra dia zavatra tsy tafiditra ao anatin’ny antontan-taratasy misokatra no nolazaina tamin’izy ireo. Fantaro avy amin'ny code nahoana, dia tsy tsotra toy ny amin'ny raharaha TL intsony - tsy ampahany mitoka-monina (mitovy) amin'ny lojika izany, fa ampahany mifamatotra amin'ny rafitra fampiharana, i.e. dia mitaky fotoana bebe kokoa hahatakarana ny kaody fampiharana.

Pings sy fotoana. Filaharana.

Avy amin'ny zava-drehetra, raha tadidinao ny vinavina momba ny maritrano mpizara (fizarana ny fangatahana amin'ny backends), dia misy zavatra manjavozavo manaraka - na dia eo aza ny antoka rehetra amin'ny fandefasana izay ao amin'ny TCP (na ny angon-drakitra dia natolotra, na ianao dia hampahafantarina momba ny tapaka, fa ny angon-drakitra dia halefa mandra-pahatongan'ny fotoanan'ny olana), fa ny fanamafisana ao amin'ny MTProto mihitsy - tsy misy antoka. Ny mpizara dia afaka mamoy na manary mora foana ny hafatrao, ary tsy misy azo atao amin'izany, afa-tsy ny fefy tehina isan-karazany.

Ary voalohany indrindra - filaharana hafatra. Eny, ho an'ny zavatra iray, ny zava-drehetra dia hita hatrany am-boalohany - hafatra tsy voamarina dia tsy maintsy tehirizina sy tezitra. Ary aorian'ny fotoana inona? Ary fantatr'ilay vazivazy izy. Angamba ireo hafatra serivisy mpiankin-doha ireo dia mamaha ity olana ity amin'ny crutches, ohatra, ao amin'ny Telegram Desktop dia misy filaharana 4 eo ho eo mifanitsy amin'izy ireo (angamba bebe kokoa, araka ny efa voalaza, noho izany dia mila mandinika tsara kokoa ny kaody sy ny maritrano ianao; fotoana, fantatray fa tsy azo raisina ho santionany izany, karazana maromaro avy amin'ny tetika MTProto no tsy ampiasaina ao).

Nahoana no mitranga izany? Angamba, tsy afaka miantoka ny fahamendrehana ao anatin'ny cluster ny programmer server, na farafaharatsiny ny buffering amin'ny balancer eo anoloana, ary nafindra tany amin'ny mpanjifa io olana io. Noho ny famoizam-po, nanandrana nametraka safidy hafa i Vasily, miaraka amin'ny filaharana roa monja, mampiasa algorithm avy amin'ny TCP - mandrefy RTT mankany amin'ny mpizara ary manitsy ny haben'ny "varavarankely" (amin'ny hafatra) arakaraka ny isan'ny fangatahana tsy fantatra. Izany hoe, heuristika manjavozavo toy izany amin'ny fanombanana ny enta-mavesatry ny mpizara - firy amin'ny fangatahanay no azony tsikombakomba amin'ny fotoana iray ary tsy ho very.

Eny ary, azonareo izany, sa tsy izany? Raha tsy maintsy mampihatra TCP indray ianao eo an-tampon'ny protocole izay miasa amin'ny TCP, dia manondro protocole tena tsy dia tsara loatra izany.

Eny, nahoana no mila filaharana mihoatra ny iray, ary amin'ny ankapobeny, inona no dikan'izany ho an'ny olona iray miasa amin'ny API avo lenta? Jereo, manao fangatahana ianao, manao serial, fa matetika tsy azo alefa avy hatrany. Nahoana? Satria ny valiny dia ho msg_id, izay mihelinaΠ°Etikety aho, ny fanendrena izay tsara kokoa ahemotra araka izay azo atao - tampoka ny mpizara dia handΓ  izany noho ny tsy fitovian'ny fotoana eo amintsika sy izy (mazava ho azy fa afaka manao tehina isika izay manova ny fotoanantsika amin'izao fotoana izao. amin'ny fotoanan'ny mpizara amin'ny alΓ lan'ny fampidirana delta kajy avy amin'ny valintenin'ny mpizara - ny mpanjifa ofisialy dia manao izany, fa ity fomba ity dia manjavozavo sy tsy marina noho ny buffering). Ka rehefa manao fangatahana amin'ny antso an-toerana avy amin'ny tranomboky ianao dia mandalo amin'ireto dingana manaraka ireto ny hafatra:

  1. Mipetraka eo amin'ny filaharana mitovy ary miandry ny fanafenana.
  2. HOTENDRENA msg_id ary nandeha tany amin'ny filaharana hafa ny hafatra - azo alefa; alefaso amin'ny socket.
  3. a) Namaly ny MsgsAck ny mpizara - nalefa ilay hafatra, esorinay amin'ny "filaharana hafa".
    b) Na ny mifamadika amin'izany, tsy tiany ny zavatra iray, namaly ratsy izy - naverinay avy amin'ny "filaharana hafa"
    c) Tsy fantatra na inona na inona, ilaina ny mandefa hafatra avy amin'ny filaharana hafa - saingy tsy fantatra marina hoe rahoviana.
  4. Namaly ihany ny mpizara RpcResult - ny tena valiny (na ny fahadisoana) - tsy naterina fotsiny, fa nokarakaraina koa.

Angamba, mety hamaha ny olana amin'ny ampahany ny fampiasana kaontenera. Izany dia rehefa misy andiana hafatra voarakitra ho iray, ary ny mpizara dia namaly tamin'ny fankasitrahana ny rehetra indray mandeha, miaraka amin'ny iray msg_id. Ho laviny koa anefa io fonosana io, raha misy tsy nety, ary koa ny zava-drehetra.

Ary amin'izao fotoana izao, ny fiheverana tsy ara-teknika dia miditra an-tsehatra. Avy amin'ny traikefa, dia nahita tehina maro isika, ary ho fanampin'izany, izao dia hahita ohatra bebe kokoa momba ny torohevitra ratsy sy ny maritrano - amin'ny toe-javatra toy izany, mendrika ny hatoky sy handray fanapahan-kevitra toy izany ve? Retorika ny fanontaniana (mazava ho azy fa tsia).

Inona no resahina? Raha ao amin'ny lohahevitra "hafatra mpiankin-doha momba ny hafatra" ianao dia mbola afaka manombatombana amin'ny fanoherana toy ny hoe "adala ianao, tsy azonao ny hevitray mamirapiratra!" (ka soraty aloha ny antontan-taratasy, araka ny tokony ho izy ny olona tsotra, miaraka amin'ny rationale sy ny fifanakalozam-bola ohatra, dia hiresaka isika), avy eo ny fotoana / ny fotoana dia olana tena azo ampiharina sy manokana, ny zava-drehetra dia efa fantatra teto. Inona anefa no lazain'ny antontan-taratasy amintsika momba ny fe-potoana?

Matetika ny mpizara dia manaiky ny fandraisana hafatra avy amin'ny mpanjifa iray (matetika, fangatahana RPC) amin'ny fampiasana valiny RPC. Raha ela be ny valin-kafatra iray, ny mpizara iray dia mety handefa fanekena tapakila aloha, ary avy eo dia ny valin'ny RPC mihitsy.

MazΓ na ny mpanjifa dia manaiky ny fandraisana hafatra avy amin'ny mpizara (matetika, valiny RPC) amin'ny fampidirana fanekena amin'ny fangatahana RPC manaraka raha toa ka tsy tara loatra izany (raha voaforona, lazao, 60-120 segondra aorian'ny fandraisana. hafatra avy amin'ny mpizara). Na izany aza, raha mandritra ny fotoana maharitra dia tsy misy antony handefasana hafatra amin'ny mpizara na raha be dia be ny hafatra tsy fantatra avy amin'ny mpizara (milaza hoe, mihoatra ny 16), ny mpanjifa dia mandefa fanekena mitokana.

... Adikako hoe: ny tenantsika tsy mahalala hoe ohatrinona sy ny ilana azy, eny, ndeha tombanana fa aoka ho toy izao.

Ary momba ny ping:

Hafatra Ping (PING/PONG)

ping#7abe77ec ping_id:long = Pong;

Ny valiny dia matetika averina amin'ny fifandraisana mitovy:

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

Tsy mila fankasitrahana ireo hafatra ireo. Ny pong dia ampitaina ho setrin'ny ping ihany fa ny ping dia azo atomboka amin'ny andaniny roa.

Fikatonana fifandraisana nahemotra + PING

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

Miasa toy ny ping. Ho fanampin'izany, aorian'ny fandraisana izany, ny mpizara dia manomboka fameram-potoana izay hanidy ny fifandraisana ankehitriny disconnect_delay segondra taty aoriana raha tsy mahazo hafatra vaovao mitovy karazana izay mamerina ho azy ireo fameram-potoana teo aloha. Raha mandefa ireo ping ireo indray mandeha isaky ny 60 segondra ny mpanjifa, ohatra, dia mety hametraka disconnect_delay mitovy amin'ny 75 segondra.

Very saina ve ianao?! Ao anatin'ny 60 segondra dia hiditra ao amin'ny gara ny lamasinina, hidina ary haka mpandeha, ary very ny fifandraisana ao amin'ny tonelina. Ao anatin'ny 120 segondra, raha mitsambikina ianao, dia ho tonga amin'ny iray hafa izy, ary mety ho tapaka ny fifandraisana. Eny, mazava tsara hoe avy aiza ny tongotra - "Naheno feo aho, fa tsy fantatro hoe aiza izy io", misy ny algorithm Nagle sy ny safidy TCP_NODELAY, izay natao ho an'ny asa ifanakalozan-kevitra. Saingy, miala tsiny, ahemotra ny sandany mahazatra - 200 Millisegondra. Raha tena te haneho zavatra mitovitovy amin'izany ianao ary mitahiry fonosana azo atao - tsara, atsaharo izany, farafaharatsiny mandritra ny 5 segondra, na na inona na inona ny fe-potoana farany amin'ny hafatra "Manoratra ny mpampiasa ..." dia mitovy amin'izao. Tsy misy intsony anefa.

Ary farany, pings. Izany hoe, manamarina ny fahavitrihana ny fifandraisana TCP. Mampihomehy izany, saingy tokony ho 10 taona lasa izay dia nanoratra lahatsoratra mitsikera momba ny iraky ny trano fandraisam-bahiny ao amin'ny fakiolantsika aho - teo koa ny mpanoratra dia nandefa ny mpizara tamin'ny mpanjifa, fa tsy ny mifamadika amin'izany. Saingy zavatra iray ny mpianatra taona fahatelo, ary ny birao iraisam-pirenena dia hafa, sa tsy izany? ..

Voalohany, programa fanabeazana kely. Ny fifandraisana TCP, raha tsy misy ny fifanakalozana fonosana, dia afaka miaina mandritra ny herinandro. Sady tsara io no ratsy, arakaraka ny tanjona. Eny ary, raha manana fifandraisana SSH amin'ny mpizara misokatra ianao, dia nitsangana avy tao amin'ny solosainao ianao, namerina ny router herinaratra, niverina tany amin'ny toeranao - tsy tapaka ny fivoriana tamin'ny alΓ lan'ity mpizara ity (tsy nitendry na inona na inona, tsy nisy fonosana), mety. Ratsy raha misy mpanjifa an'arivony ao amin'ny lohamilina, samy maka loharanon-karena (miarahaba Postgres!), ary ny mpampiantrano mpanjifa dia mety efa naverina efa ela be - saingy tsy ho fantatsika izany.

Ny rafitra Chat/IM dia an'ny tranga faharoa noho ny antony hafa fanampiny - sata an-tserasera. Raha "lavo" ny mpampiasa, dia ilaina ny mampahafantatra ny mpiara-miresaka aminy momba izany. Raha tsy izany dia hisy ny hadisoana nataon'ireo mpamorona an'i Jabber (ary nanitsy nandritra ny 20 taona) - tapaka ny fifandraisan'ilay mpampiasa, saingy mbola manoratra hafatra ho azy izy ireo, mino fa ao anaty aterineto izy (izay very tanteraka ihany koa tao anatin'ny minitra vitsy talohan'izay. hita ny fiatoana). Tsia, ny safidy TCP_KEEPALIVE, izay olona maro tsy mahafantatra ny fomba fiasan'ny TCP timers, mipoitra na aiza na aiza (amin'ny fametrahana soatoavina toy ny segondra am-polony), dia tsy hanampy eto - mila mahazo antoka ianao fa tsy ny kernel OS ihany. velona ny masinin'ny mpampiasa, fa miasa ara-dalΓ na ihany koa, afaka mamaly, ary ny fampiharana mihitsy (heverinao ve fa tsy afaka mivaingana izany? Ny Telegram Desktop amin'ny Ubuntu 18.04 dia nianjera ho ahy imbetsaka).

Izany no antony tokony hanaovanao ping mpizara mpanjifa, fa tsy ny mifamadika amin'izany - raha manao izany ny mpanjifa, rehefa tapaka ny fifandraisana, dia tsy ho alefa ny ping, tsy tratra ny tanjona.

Ary inona no hitantsika ao amin'ny Telegram? Mifanohitra tanteraka amin’izany ny zava-drehetra! Eny, i.e. amin'ny fomba ofisialy, mazava ho azy, ny roa tonta dia afaka mifampiresaka. Amin'ny fampiharana, ny mpanjifa dia mampiasa tehina ping_delay_disconnect, izay mametaka fameram-potoana eo amin'ny mpizara. Miala tsiny fa tsy anjaran'ny mpanjifa ny manapa-kevitra hoe hafiriana no tiany hipetraka any tsy misy ping. Ny mpizara, mifototra amin'ny entany, dia mahafantatra tsara kokoa. Saingy, mazava ho azy, raha tsy malahelo ny loharanon-karena ianao, dia ny Pinocchio ratsy fanahy dia ny tenany ihany, ary hidina ny tehina ...

Ahoana no tokony ho nandrafetana azy?

Mino aho fa ireo zava-misy etsy ambony ireo dia manondro mazava tsara ny fahaiza-manaon'ny ekipa Telegram / VKontakte tsy dia avo loatra eo amin'ny sehatry ny fitaterana (sy ny ambany) amin'ny tambajotran'ny solosaina sy ny fahaiza-manaony ambany amin'ny raharaha mifandraika amin'izany.

Nahoana no sarotra be izany, ary ahoana no ahafahan'ny architects Telegram manandrana manohitra? Ny zava-misy fa nanandrana nanao fivoriana izay tafavoaka velona tamin'ny fifandraisana TCP izy ireo dia tapaka, izany hoe, izay tsy natolotray ankehitriny dia halefanay any aoriana. Mety nanandrana nanao fitaterana UDP ihany koa izy ireo, na dia tojo fahasahiranana aza izy ireo ary nandao izany (izay no mahatonga ny antontan-taratasy ho foana - tsy misy na inona na inona hireharehana). Saingy noho ny tsy fahampian'ny fahatakarana ny fomba fiasan'ny tambajotra amin'ny ankapobeny sy ny TCP manokana, izay ahafahanao miantehitra amin'izany, ary ny toerana tokony hanaovanao izany ny tenanao (sy ny fomba), ary manandrana manambatra izany amin'ny kriptografika "iray tifitra roa. vorona miaraka amin'ny vato iray" - nisy faty toy izany.

Ahoana no tokony ho izy? Mifototra amin'ny zava-misy izay msg_id dia mari-pamantarana izay ilaina ara-kriptografika mba hisorohana ny fanafihana miverimberina, hadisoana ny fametahana asa famantarana tokana aminy. Noho izany, raha tsy manova be ny maritrano ankehitriny (rehefa miforona ny kofehy Fanavaozana, lohahevitra API avo lenta ity ho an'ny ampahany hafa amin'ity andian-dahatsoratra ity), dia tsy maintsy:

  1. Ny mpizara mitazona ny fifandraisana TCP amin'ny mpanjifa dia mandray ny andraikiny - raha esorinao amin'ny socket ianao, raha sitrakao, manamafy, manamboatra na mamerina fahadisoana, tsy misy fatiantoka. Dia tsy ny vector ny id's no lasa confirmation, fa "ny farany nahazo seq_no" fotsiny - isa fotsiny, toy ny ao amin'ny TCP (isa roa - ny seq anao manokana ary voamarina). Mivory foana isika, sa tsy izany?
  2. Lasa sehatra mitokana ny tombokase mba hisorohana ny fanafihana miverimberina, a la nonce. Voamarina fa tsy misy zavatra hafa voa. Ampy ary uint32 - raha miova isaky ny antsasaky ny andro ny sira, dia afaka mizara 16 bitika amin'ny bitika ambany amin'ny ampahany amin'ny fotoana ankehitriny, ny ambiny - amin'ny ampahany kely amin'ny segondra (toy ny ankehitriny).
  3. Nihemotra msg_id amin'ny rehetra - avy amin'ny fomba fijery manavaka ny fangatahana eo amin'ny backends, misy, voalohany, ny mpanjifa id, ary faharoa, ny fivoriana id, ary concatenate azy ireo. Noho izany, amin'ny maha-identifier fangatahana dia iray ihany no ampy seq_no.

Tsy ny safidy tsara indrindra ihany koa, ny kisendrasendra tanteraka dia mety ho famantarana - efa vita amin'ny API avo lenta izany rehefa mandefa hafatra, raha ny marina. Tsara kokoa ny manova ny maritrano amin'ny ankapobeny ho tanteraka, fa lohahevitra iray hafa ity fa tsy ity lahatsoratra ity.

API?

Ta-daam! Noho izany, rehefa nandeha tamin'ny lalana feno fanaintainana sy tehina izahay, dia afaka nandefa fangatahana tany amin'ny mpizara ary nahazo valiny ho azy ireo, ary nahazo fanavaozana avy amin'ny mpizara (tsy ho valin'ny fangatahana, fa mandefa antsika ny tenany, toy ny PUSH, raha misy olona mazava kokoa).

Tandremo, izao no hany ohatra Perl ao amin'ny lahatsoratra! (ho an'ireo izay tsy mahafantatra ny syntax, ny tohan-kevitra voalohany hitahy dia ny firafitry ny angon-drakitra, ny faharoa dia ny kilasy):

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' )
};

Eny, indrindra fa tsy eo ambanin'ny mpandroba - raha mbola tsy namaky azy ianao dia mandehana ary ataovy izany!

Oh, wai~~… ahoana ny endriny? Zavatra mahazatra ... angamba ity no firafitry ny angon-drakitra amin'ny Web API mahazatra ao amin'ny JSON, afa-tsy ny kilasy misy zavatra miraikitra amin'ny zavatra?..

Dia hita fa ... Inona izany, ry namana? .. Miezaha mafy - ary nijanona sasatra teo amin'ny toerana misy ny Web programmer. vao manomboka?.. Tsy ho mora kokoa ve ny JSON amin'ny HTTPS?! Ary inona no azonay ho takalon'izany? Mendrika ve ireny ezaka ireny?

Andeha hojerentsika izay nomen'ny TL+MTProto antsika ary inona no safidy azo atao. Eny, ny valin'ny fangatahana HTTP dia tsy mety, fa farafaharatsiny misy zavatra eo an-tampon'ny TLS?

compact serialization. Raha mahita io firafitry ny angon-drakitra io, mitovy amin'ny JSON, dia tsaroana fa misy ny variana binary. Andao hanamarika ny MsgPack ho tsy ampy fanitarana, fa misy, ohatra, CBOR - raha ny marina, ny fenitra voalaza ao amin'ny RFC 7049. Misongadina amin'ny famaritana azy tag, ho mekanika fanitarana, ary anisan'izany efa manara-penitra misy:

  • 25 + 256 - fanoloana andalana dika mitovy amin'ny fanondro isa andalana, fomba famatrarana mora vidy
  • 26 - zavatra Perl serial miaraka amin'ny anaran'ny kilasy sy ny tohan-kevitry ny mpamorona
  • 27 - zavatra tsy miankina amin'ny fiteny serial miaraka amin'ny anarana karazana sy ny tohan-kevitry ny mpamorona

Eny ary, nanandrana nanamboatra ny angon-drakitra mitovy amin'ny TL sy CBOR aho miaraka amin'ny famenoana tady sy zavatra azo atao. Ny vokatra dia nanomboka tsy nitovy tamin'ny CBOR tany ho any amin'ny megabyte:

cborlen=1039673 tl_len=1095092

Ary noho izany, famaranana: Misy endrika tsotra kokoa izay tsy iharan'ny tsy fahombiazan'ny fandrindrana na olan'ny famantarana tsy fantatra, miaraka amin'ny fahombiazana azo oharina.

Fametrahana fifandraisana haingana. Midika izany fa aotra RTT aorian'ny fampifandraisana indray (rehefa efa novokarina indray mandeha ny fanalahidy) - azo ampiharina amin'ny hafatra MTProto voalohany, saingy tamin'ny famandrihana sasany - niditra tao anaty sira iray izy ireo, tsy lasa lo ny fivoriana, sns. Inona no atolotry ny TLS ho setrin'izany? Teny mifandraika amin'izany:

Rehefa mampiasa PFS amin'ny TLS, tapakila fivoriana TLS (RFC 5077) mba hanohy indray ny fotoam-pivoriana miafina tsy misy fifampiraharahana indray ny fanalahidy ary tsy mitahiry ny fampahalalana fototra ao amin'ny mpizara. Rehefa manokatra ny fifandraisana voalohany sy mamokatra fanalahidy, ny mpizara dia encryption ny toetry ny fifandraisana ary mandefa izany amin'ny mpanjifa (amin'ny endriky ny tapakila fivoriana). Noho izany, rehefa averina ny fifandraisana, ny mpanjifa dia mandefa tapakila fivoriana misy, ankoatra ny zavatra hafa, ny fanalahidin'ny session miverina amin'ny mpizara. Ny tapakila mihitsy dia voarakotra amin'ny fanalahidy vonjimaika (fanalahidin'ny tapakila fivoriana), izay voatahiry ao amin'ny mpizara ary tsy maintsy zaraina amin'ireo mpizara eo anoloana rehetra izay mitantana SSL amin'ny vahaolana mivondrona.[10]. Noho izany, ny fampidirana tapakila fivoriana dia mety hanitsakitsaka ny PFS raha toa ka voahitsakitsaka ny fanalahidin'ny mpizara vonjimaika, ohatra, rehefa voatahiry ela be izy ireo (OpenSSL, nginx, Apache amin'ny alΓ lan'ny default dia mitahiry azy ireo mandritra ny fotoana rehetra ampandehanana ny programa; tranokala malaza. ampiasao ny fanalahidy mandritra ny ora maromaro, hatramin'ny andro).

Eto dia tsy aotra ny RTT, mila mifanakalo farafaharatsiny ClientHello sy ServerHello ianao, aorian'izay, miaraka amin'ny Finished, ny mpanjifa dia afaka mandefa data. Saingy eto dia tokony ho tsaroana fa tsy manana ny Web isika, miaraka amin'ny andiana fifandraisana vao nosokafana, fa iraka iray, ny fifandraisana izay matetika dia iray na mihoatra na latsaka kely, fangatahana fohy ho an'ny pejin-tranonkala - ny zava-drehetra dia multiplexed anatiny. Izany hoe, tena azo ekena izany, raha tsy sendra faritra tena ratsy ny metro.

Nanadino zavatra hafa? Soraty ao amin'ny fanehoan-kevitra.

Mbola hitohy!

Ao amin'ny tapany faharoa amin'ity andian-dahatsoratra ity dia hodinihintsika ny olana momba ny fandaminana fa tsy ny ara-teknika - ny fomba fiasa, ny ideolojia, ny fifandraisana, ny fihetsika manoloana ny mpampiasa, sns. Mifototra amin’ny fanazavana ara-teknika natolotra teto anefa.

Ny ampahany fahatelo dia hanohy ny famakafakana ny traikefa ara-teknika / fampandrosoana. Hianatra manokana ianao:

  • fitohizan'ny pandemonium miaraka amin'ny karazana TL-karazana
  • zavatra tsy fantatra momba ny fantsona sy supergroups
  • noho ny fifanakalozan-kevitra dia ratsy noho ny lisitra
  • momba ny adiresy hafatra absolute vs relative
  • inona no maha samy hafa ny sary sy ny sary
  • ny fomba fitsabahan'ny emoji amin'ny lahatsoratra vita sora-mandry

sy tehina hafa! Maharaha vaovao!

Source: www.habr.com

Add a comment