== Zasady opisywania protokoĹĂłw == Autor: Aleksy Schubert === Streszczenie === Niniejszy dokument opisuje strukturÄ i podstawowe wymagania dotyczÄ ce sposobu opisywania protokoĹĂłw. Spodziewamy siÄ, Ĺźe kaĹźdy opis protokoĹu bÄdzie miaĹ nastÄpujÄ cÄ strukturÄ: # Streszczenie # Opis celĂłw protokoĹu # Opis zaĹoĹźeĹ protokoĹu # Opis formatu komunikatĂłw # Opis wymienianych komunikatĂłw # Opis stanĂłw # Podsumowanie uĹźywanych numerĂłw Przedstawione dokumenty nie muszÄ siÄ ograniczaÄ do tego ksztaĹtu. MogÄ zawieraÄ dodatkowe sekcje, ktĂłre objaĹniajÄ i precyzujÄ inne istotne aspekty dziaĹania protokoĹu, np. bezpieczeĹstwo, odpornoĹÄ na awarie itp. TakĹźe konstrukcja protokoĹu moĹźe wykraczaÄ poza zakreĹlone tutaj ramy (moĹźna sobie wyobraziÄ, Ĺźe twĂłrcy opracujÄ jakiĹ system trybĂłw lub poziomĂłw dziaĹania protokoĹu, ktĂłry nie da siÄ prosto ujÄ Ä w ramach prostego wyliczenia stanĂłw i komunikatĂłw). === Cele === Opis protokoĹu powinien opisywaÄ w sposĂłb zrozumiaĹy jego dziaĹanie. W obecnym dokumencie wyznaczamy pewien standard opisu protokoĹu, ktĂłry powinien zmniejszyÄ iloĹÄ niedomĂłwieĹ zwiÄ zanych z interpretacjÄ . W sekcji tej powinno byÄ opisane, jakim celom ma sĹuĹźyÄ protokĂłĹ, np. zapewnianiu przesyĹania danych strumieniowych do komunikacji multimedialnej. === ZaĹoĹźenia === ZakĹadamy, Ĺźe opisy protokoĹĂłw bÄdÄ wykonywane w jÄzyku polskim i bÄdÄ stanowiĹy podstawÄ do tworzenia przez niezaleĹźne zespoĹy programistĂłw implementacji. Róşne implementacje w zaĹoĹźeniu majÄ ze sobÄ wspĂłĹdziaĹaÄ. ZakĹadamy, Ĺźe komunikacja miÄdzy twĂłrcÄ opisu protokoĹu a implementatorami jest ograniczona (np. ze wzglÄdu na brak czasu twĂłrcy opisu). ZakĹadamy, Ĺźe opisy mogÄ byÄ wykonane zarĂłwno w formatach pozwalajÄ cych na wstawianie rysunkĂłw, jak i w czystym ASCII (byÄ moĹźe wzbogaconym o moĹźliwoĹÄ wpisywania polskich znakĂłw diakrytycznych). ZakĹadamy, Ĺźe opisy bÄdÄ pozwalaĹy na napisanie w jÄzyku C (w wersji pod sysemy uniksowe) kodu ĹşrĂłdĹowego, ktĂłry skompilowany na dwĂłch maszynach o róşnej architekturze bÄdzie dawaĹ mogÄ ce ze sobÄ wspĂłĹpracowaÄ programy. W czÄĹci tej m.in. powinny znaleĹşÄ siÄ informacje o tym, z czego opisywany protokóŠkorzysta. W szczegĂłlnoĹci powinny znaleĹşÄ siÄ tutaj informacje o tym: * w jakiej warstwie dziaĹa protokĂłĹ, * z jakich protokoĹĂłw korzysta do transportu (UDP, TCP, RTP, itp.), * z jakich protokoĹĂłw usĹugowych bezpoĹrednio korzysta (np. DHCP, DNS itp.), * z jakich funkcjonalnoĹci wspomnianych wyĹźej protokoĹĂłw korzysta (np. numer portu), * z jakiego modelu komunikacji korzystamy (klient-serwer, P2P itp.). === Format komunikatĂłw === Przy opisie protokoĹu przeznaczonym do interpretacji bez udziaĹu twĂłrcy protokoĹu konieczne jest jednoznaczne opisanie binarnego formatu wymienianych komunikatĂłw. Ten format powinien uwzglÄdniaÄ takie elementy jak: * porzÄ dek oktetĂłw w liczbach (sieciowy, little endian, big endian itp.), * sposĂłb interpretacji znakĂłw (w arytmetyce uzupeĹnieĹ do 2, do 1, itp.), * format liczb zmiennoprzecinkowych (np. IEEE 754), * dopuszczalne uzupeĹnienia formatu (np. czy liczby dwuoktetowe sÄ uzupeĹniane do czterech oktetĂłw i jakimi danymi (zerami, przez 0xFF, losowymi danymi itp.), * jakie pola wystÄpujÄ w komunikacie i w jakiej kolejnoĹci. Opisanie tego ostatniego elementu wymaga uĹźycia jakiegoĹ formatu opisu komunikatĂłw. Przyjmujemy, Ĺźe nasze opisy bÄdÄ uĹźywaÄ formatu przedstawionego poniĹźej. ZakĹadamy, Ĺźe oktety okreĹlonej wedĹug poniĹźszych zasad reprezentacji sÄ przesyĹane przez sieÄ w ten sposĂłb, Ĺźe najpierw transmitowany jest pierwszy oktet, potem drugi, itd. aĹź do ostatniego. Uwaga: na zajÄciach przyjmujemy, Ĺźe przez sieÄ przesyĹane sÄ liczby w sieciowym porzÄ dku oktetĂłw. ==== Typy podstawowe ==== BÄdziemy uĹźywali nastÄpujÄ cych typĂłw podstawowych: * octet, * int, * float. Typ octet oznacza zawsze wielkoĹÄ oĹmiobitowÄ bez okreĹlenia sposobu interpretacji jako liczby caĹkowitej. Typ ten przydaje siÄ, gdy chcemy okreĹliÄ, Ĺźe w danym miejscu znajdujÄ siÄ dane, ktĂłre sÄ opisane w innej czÄĹci dokumentu. Potrzeba taka zachodzi na przykĹad, gdy najpierw opisujemy ogĂłlny format komunikatu, a nastÄpnie uszczegĂłĹawiamy go, opisujÄ c konkretne komunikaty. W wypadku typĂłw caĹkowitoliczbowych bÄdziemy uĹźywali prefiksĂłw okreĹlajÄ cych znak oraz sufiksĂłw okreĹlajÄ cych wielkoĹÄ reprezentacji. BÄdziemy stosowali dwa rodzaje prefiksĂłw: "u" oraz "s". Dozwolone sÄ wszystkie sufiksy bÄdÄ ce wielokrotnoĹciami liczby 8, czyli: 8, 16, 24, 32, 40, itd. PrzykĹadowe typy caĹkowitoliczbowe to: uint32, sint16 itp. W wypadku typĂłw zmiennoprzecinkowych bÄdziemy uĹźywali tylko sufiksĂłw 32 i 64 na oznaczenie wielkoĹci liczby (32 bity, 64 bity). PrzykĹady: float32, float64. ==== Typy zĹoĹźone ==== OprĂłcz typĂłw podstawowych moĹźemy teĹź korzystaÄ z typĂłw zĹoĹźonych. Pierwszy rodzaj typu zĹoĹźonego to tablica. Tablice opisujemy wedĹug wzoru: TYP [WIELKOĹÄ] NAZWA; gdzie TYP to jeden z typĂłw podstawowych lub wczeĹniej zdefiniowanych, NAZWA to nazwa pola, zaĹ WIELKOĹÄ to liczba elementĂłw tablicy. Tablice sÄ zawsze indeksowane od 0 do WIELKOĹÄ-1. WartoĹÄ oznaczona tutaj jako WIELKOĹÄ musi byÄ znana na etapie specyfikacji protokoĹu lub obliczalna na podstawie czÄĹci komunikatu odebranej przed przetwarzaniem tablicy. WartoĹÄ WIELKOĹÄ moĹźe byÄ opisana symbolicznie. Format binarny tablicy opisanej jako TYP [WIELKOĹÄ] NAZWA; jest nastÄpujÄ cy: po kolei umieszczane sÄ oktety reprezentacji binarnej pola o indeksie 0, 1, itd. aĹź do pola o indeksie WIELKOĹÄ-1. Na przykĹad reprezentacja binarna tablicy: uint16 [3] ala; zawierajÄ cej elementy ala[0]=34324, ala[1]=4534, ala[2]=233 wyglÄ daĹaby binarnie tak (zakĹadamy sieciowÄ reprezentacjÄ uint16): 0x86 0x14 0x11 0xB6 0x00 0xE9 Opis uint16 [3] ala; moĹźna teĹź rĂłwnowaĹźnie przedstawiÄ jako uint16 [ARRAY_LEN] ala; przy czym naleĹźy wczeĹniej opisaÄ (nie wprowadzamy tu specjalnej skĹadni), Ĺźe symbol ARRAY_LEN ma wartoĹÄ 3. OprĂłcz tablic moĹźemy uĹźywaÄ struktur. Struktury opisujemy, korzystajÄ c z nastÄpujÄ cego formatu: NAZWA_STRUKTURY { TYP1 NAZWA1; ... TYPN NAZWAN; } Reprezentacja binarna takiej struktury wyglÄ da w ten sposĂłb, Ĺźe najpierw umieszczane sÄ oktety pola NAZWA1, potem NAZWA2 itd. wedĹug kolejnoĹci tekstowego wystÄpowania aĹź do pola NAZWAN. NAZWA_STRUKTURY moĹźe byÄ wykorzystywana do opisywania innych typĂłw. OkreĹlenie TYPi obejmuje takĹźe opisanÄ powyĹźej specyfikacjÄ rodzaju i wielkoĹci tablicy. PrzykĹad struktury: PROTOCOL_MSG { uint8 message_type; uint32 total_length; uint32 payload_length; octet [payload_length] payload; octet [padding_length] padding; uint32 mac; } gdzie padding_length= total_length - payload_length - 13. Warto zwrĂłciÄ uwagÄ, Ĺźe liczba 13 odpowiada ĹÄ cznej dĹugoĹci pĂłl message_type, total_length, payload_length i mac. ==== Opisy dĹugoĹci ==== JeĹli w komunikacie wystÄpuje pole opisujÄ ce dĹugoĹÄ jakiejĹ czÄĹci komunikatu, to przy opisie tego pola powinny byÄ jawnie wymienione nazwy pĂłl, jakie ta dĹugoĹÄ obejmuje. W wypadku komunikatu PROTOCOL_MSG opisanego w poprzedniej sekcji opis pola total_length powinien brzmieÄ w przybliĹźeniu tak: total_length - pole zawierajÄ ce dĹugoĹÄ caĹego pakietu, dĹugoĹÄ ta obejmuje pola: message_type, total_length, payload_length, payload, padding, mac. Nie uĹźywamy natomiast skrĂłtĂłw myĹlowych takich jak w tym opisie: total_length - pole zawierajÄ ce dĹugoĹÄ caĹego pakietu. gdyĹź mogÄ pojawiÄ siÄ wÄ tpliwoĹci interpretacyjne, czy chodzi o caĹy pakiet rzeczywiĹcie, czy o jego czÄĹÄ za polem total_length, czy oktety pola total_length teĹź wchodzÄ w skĹad tej wartoĹci itp. === Opis komunikatĂłw === NiezaleĹźnie od opisu ogĂłlnego formatu komunikatĂłw koniecznie jest podanie formatu wszystkich konkretnych komunikatĂłw wraz z celami, do jakich te komunikaty majÄ sĹuĹźyÄ oraz z opisem przetwarzania, jakie majÄ one powodowaÄ. KaĹźdy komunikat powinien mieÄ okreĹlonÄ symbolicznÄ nazwÄ. Nazwa ta powinna zawieraÄ napis MSG. Czasami dogodnie jest wprowadziÄ grupy komunikatĂłw. KaĹźda wprowadzona grupa komunikatĂłw powinna wymieniaÄ jednoznacznie komunikaty, ktĂłre do niej naleĹźÄ . Przy korzystaniu z grup komunikatĂłw moĹźna uĹźywaÄ notacji typu: * NAZWA_GRUPY + KOMUNIKAT - na oznaczenie zbioru komunikatĂłw zawierajÄ cego wszystkie komunikaty z grupy NAZWA_GRUPY oraz dodatkowo komunikat KOMUNIKAT, * NAZWA_GRUPY - KOMUNIKAT - na oznaczenie zbioru komunikatĂłw zawierajÄ cego wszystkie komunikaty z grupy NAZWA_GRUPY oprĂłcz komunikatu KOMUNIKAT, * NAZWA_GRUPY1 + NAZWA_GRUPY2 - na oznaczenie zbioru komunikatĂłw zawierajÄ cego wszystkie komunikaty z grupy NAZWA_GRUPY1 oraz wszystkie komunikaty grupy NAZWA_GRUPY2, * NAZWA_GRUPY1 - NAZWA_GRUPY2 - na oznaczenie zbioru komunikatĂłw zawierajÄ cego te komunikaty z grupy NAZWA_GRUPY1, ktĂłre nie naleĹźÄ do grupy NAZWA_GRUPY2. KaĹźda symboliczna nazwa grupy powinna zawieraÄ napis GRP. === Opis stanĂłw === Przy opisie protokoĹu czÄsto zdarza siÄ, Ĺźe w pewnych momentach sensownie mogÄ byÄ zinterpretowane tylko niektĂłre komunikaty. Naturalne w tym momencie staje siÄ wprowadzenie pojÄcia stanu. Stan okreĹlony jest przez sposĂłb reakcji na komunikaty oraz na inne zdarzenia (np. przekroczenie czasu, reakcja uĹźytkownika, reakcja systemu operacyjnego itp.). Opisy stanĂłw powinny zawieraÄ dokĹadne wyszczegĂłlnienie * zaĹoĹźeĹ * dziaĹaĹ, jakie powinny byÄ wykonywane w reakcji na zdarzenia. W szczegĂłlnoĹci jasno powinno byÄ okreĹlone: * jakie rodzaje zdarzeĹ sÄ dopuszczalne w danym stanie (oprĂłcz przyjĹcia komunikatu), * jak wyglÄ da reakcja na te zdarzenia, * jak powinna wyglÄ daÄ reakcja na wszystkie moĹźliwe komunikaty (nie tylko zgodne z pozytywnym scenariuszem dziaĹania protokoĹu). JeĹli protokóŠprzewiduje utrzymywanie jakichĹ dodatkowych zmiennych, to naleĹźy w kaĹźdym przejĹciu jawnie wskazywaÄ, jakie zmiany tych zmiennych majÄ nastÄ piÄ. TakĹźe, jeĹli wykonanie jakiejĹ akcji zaleĹźy od wartoĹci zmiennej, to naleĹźy to jasno opisaÄ. Dobrze teĹź, gdy opis protokoĹu zawiera rysunek przedstawiajÄ cy wszystkie stany w postaci automatu. Na rysunku tym stany powinny byÄ oznaczone w postaci zamkniÄtych obszarĂłw (kĂłĹ, prostokÄ tĂłw, owali itp.), zaĹ zdarzenia w postaci strzaĹek miÄdzy stanami. Zdarzenia inicjowane przez implementacjÄ (np. wysĹanie komunikatu, wypisanie czegoĹ na terminal) powinny byÄ dodatkowo oznaczane znakiem wykrzyknika (!), zaĹ zdarzenia odbierane przez implementacjÄ (np. odebranie komunikatu, wciĹniÄcie klawisza przez uĹźytkownika) za pomocÄ znaku zapytania (?). PrzykĹad: | USER_INITS? | x:=0 \|/ ---------------------- | DISCONNECTED_STATE | /____________ ---------------------- \ | | | | USER_STARTS? | | x:=x+1 | \|/ | ------------------------- | | INIT_CONNECTION_STATE | | ------------------------- | | | | CONNECT_MSG! | \|/ | ---------------------- | | WAIT_CONNECT_STATE | | ---------------------- | / |\ | TIMEOUT? / | \ TIMEOUT? | x>3 / | \ x<=3 | |/_ CONNECT_MSG?| \ | -------------- | \ | | ABORT | | ------------------- -------------- \|/ --------------------- | WORKING_STATE | --------------------- ... KaĹźda symboliczna nazwa stanu powinna zawieraÄ napis STATE. === Numery === W sekcji tej powinny byÄ zgromadzone skrĂłtowe opisy wszystkich uĹźytych w dokumencie wartoĹci symbolicznych wraz z odpowiadajÄ cymi im rzeczywistymi liczbami. JeĹli na przykĹad wprowadziliĹmy komunikat ALA_MSG, ktĂłremu przypisaliĹmy liczbowy typ o wartoĹci 3, to w tej sekcji powinien znaleĹşÄ siÄ opis w stylu: ALA_MSG=3 - typ komunikatu wysyĹanego przez AlÄ. === Uwagi koĹcowe === Nie narzucamy Ĺźadnego formatu tworzenia diagramĂłw automatĂłw (w szczegĂłlnoĹci nie narzucamy UML-a), szczegĂłĹy prezentacji automatĂłw sÄ do negocjacji z prowadzÄ cymi. ProwadzÄ cy moĹźe wymagaÄ, aby teksty byĹy zapisane w takim formacie, w ktĂłrym jednoznacznie sÄ reprezentowane polskie znaki diakrytyczne. Opis protokoĹu nie powinien byÄ zbyt obszerny - nalezy dÄ ĹźyÄ do zwiÄzĹego, ale peĹnego opisu. Dla lepszego zrozumienia potrzeby istnienia tego dokumentu warto obejrzeÄ nastÄpujÄ ce specyfikacje: * http://www.xmlrpc.com/spec - specyfikacja XMLRPC * http://www.gamers.org/dEngine/quake/Qdem/dem-1.0.2-5.html#ss5.3 - * http://wiki.theory.org/index.php/BitTorrentSpecification * ftp://sunsite.icm.edu.pl/pub/doc/rfc/rfc1661.txt * ftp://sunsite.icm.edu.pl/pub/doc/rfc/rfc2246.txt (sekcja 4)