11.03. UDP kontrolsumma

Pēdējais mainījis Administrator 2011-06-06 17:16

11.03. UDP kontrolsumma

UDP #term("kontrolsumma", "checksum") pārklāj UDP sākumposmu un UDP datus. Atcerēsimies, ka kontrolsumma IP sākumposmā pārklāj vienīgi IP sākumposmu - tā nepārklāj IP datagrammas datus. Gan UDP gan TCP lieto kontrolsummas savos sākumposmos, lai pārklātu savus sākumposmus un savus datus. UDP gadījumā kontrolsumma ir neobligāta, kamēr TCP gadījumā tā ir obligāta.

Lai gan UDP kontrolsummas aprēķina pamati ir līdzīgi tam, ko aprakstījām 3.2.nodaļā IP sākumposma kontrolsummai (vienu papildinājums 16-bitu vārdu summai), ir arī atšķirības. Pirmkārt, UDP datagrammas garums var būt nepāra skaits baitu, kamēr algoritms saskaita 16 bitu vārdus. Risinājums ir pievienot polsterējuma baitu ar nullēm paketes galā, ja nepieciešams, tikai kontrolsummas aprēķināšanai. (T.i., iespējamais polsterējuma baits netiek nosūtīts.)

Gan UDP gan TCP iekļauj 12-baitu pseido-sākumposmu ar UDP datagrammu (vai TCP segmentu) tikai kontrolsummas aprēķināšanai. Šis pseido-sākumposms iekļauj dažus laukus no IP sākumposma. Mērķis ir ļaut UDP vēlreiz pārbaudīt, ka dati ir ieradušies pareizajā #term("galapunktā", "destination"), t.i., ka IP nav pieņēmis datagrammu, kas nav domāta šai mītnei, un ka IP nav iedevis UDP slānim datagrammu, kas domāta citam augstākam slānim. 11.3.attēls parāda pseido-hederi kopā ar UDP datagrammu.

#pic("f_11_3.gif", "500")
11.3.attēls: Lauki, ko lieto UDP kontrolsummas aprēķināšanā

Šajā attēlā atklāti parādām datagrammu ar nepāra garumu, kam vajadzīgs polsterējuma baits kontrolsummas aprēķināšanai. Ievērojiet, ka UDP datagrammas garums parādās divreiz kontrolsummas aprēķinā.

Ja aprēķinātā kontrolsumma ir 0, to noglabā kā visus vieniniekus (65535), kas ir nulles ekvivalents vieninieku papildinājuma aritmētikā. Ja nosūtīta kontrolsumma ir 0, tad tas norāda, ka sūtītājs neaprēķināja kontrolsummu.

Ja sūtītājs aprēķināja kontrolsummu un saņēmējs konstatē kontrolsummas kļūdu, tad UDP datagrammu #term("klusām izmet", "silently_discard"). Netiek ģenerēts kļūdas ziņojums. (Tas pats notiek, ja IP slānis konstatē IP sākumposma kontrolsummas kļūdu.)

Šī UDP kontrolsumma ir #term("galapunktu kontrolsumma", "end_to_end_checksum"). To aprēķina sūtītājs un tad pārbauda saņēmējs. Tā ir projektēta, lai noķertu jebkādas netīšas UDP sākumposma vai datu izmaiņas, kas notiek starp sūtītāju un saņēmēju.

Lai gan UDP kontrolsummas ir neobligātas, patiesībā tām vienmēr būtu jābūt iespējotām. 1980-tajos gados daži datoru #term("izplatītāji", "vendor") izslēdza UDP kontrolsummas pēc noklusējuma, lai paātrinātu savu implementāciju Sun'a #term("Tīklu Failu Sistēmai", "Network_File_System") (NFS), kas izmanto UDP. Tas var būt pieņemami vienā LAN'ā, kur #term("cikliskās pārpalicības pārbaude", "cyclic_redundancy_check") (CRC) var konstatēt vairumu bojāto kadru. Toties tur kur datagrammas iet cauri maršrutētājiem, neko vairs nevar skaidri zināt. Ticiet vai nē, bet ir bijuši maršrutētāji ar programmatūras un aparatūras kļūdām, kas ir izmainījuši bitus maršrutējamās datagrammās. Šīs kļūdas UDP datagrammas līmenī nevar atrast, ja UDP #term("galapunktu kontrolsumma", "end_to_end_checksum") ir atspējota. Ņemiet vērā arī to, ka daži datu posma protokoli (piemēram, SLIP) neatbalsta nekāda veida datu slāņa kontrolsummu.

Mītnes prasību RFC prasa, lai UDP kontrolsummas būtu iespējotas pēc noklusējuma. Tas arī apgalvo, ka implementācijai ir jāpārbauda saņemtā kontrolsumma, ja sūtītājs tādu ir aprēķinājis, t.i. ja saņemtā kontrolsumma nav nulle. Daudzas implementācijas to neievēro, un tās pārbauda saņemto kontrolsummu tikai tad, ja izejošās kontrolsummas ir iespējotas.

tcpdump izvade

Ir grūti pārbaudīt, vai konkrētai sistēmai ir iespējotas UDP kontrolsummas. Parasti lietotnei ir neiespējami tieši piekļūt kontrolsummas laukam saņemtā UDP sākumposmā. Lai to apietu, autors pievienoja vēl vienu opciju tcpdump programmai, kas izvada saņemto UDP kontrolsummu. Ja izdrukātā vērtība ir 0, tas nozīmē, ka sūtošā mītne neaprēķināja kontrolsummu.

11.4.attēls parāda izvadi trim dažādām sistēmām mūsu izmēģinājumu tīklā (sk. attēlu uz #picref("f_COVER_1.gif", "iekšējā priekšējā vāka")). Darbinājām savu sock programmu (Pielikums C), kas sūtīja vienu UDP datagrammu ar 9 datu bitiem uz standarta atbalss (echo) servisu.

#pic("f_11_4.gif", "500")
11.4.attēls: tcpdump izvade, lai redzētu, vai citas mītnes pielieto UDP kontrolsummu

Varam redzēt no šī piemēra, ka divām no trim sistēmām UDP kontrolsummas bija #term("iespējotas", "enable").

Ievērojiet arī, ka šajā vienkāršajā piemērā izejošajai datagrammai ir tā pati kontrolsumma kas ienākošajai datagrammai (rindiņas 3 un 4, 5 un 6). Apskatot #picref("f_11_3.gif", "11.3.attēlu") redzam, ka divas IP adreses ir apmainījušās vietām tāpat kā atbilstošie portu numuri. Citi lauki pseido-sākumposmā un UDP sākumposmā ir tie paši, jo šie dati tiek atbalsoti. Tas pasvītro faktu, ka UDP kontrolsummas (tāpat kā visas citas kontrolsummas TCP/IP #term("protokolu komplektā", "protocol_suite")) ir vienkāršas 16-bitu summas. Tās nevar konstatēt kļūdu, kas apmaina vietām divas 16-bitu vērtības.

Autors arī veica DNS pieprasījumu katram no astoņiem saknes #term("vārdserveriem", "name_server"), kas aprakstīti 14.2.nodaļā?. DNS galvenokārt izmanto UDP, un tikai diviem no šiem serveriem bija iespējotas UDP kontrolsummas!

Nedaudz statistikas

[Mogul 1992] sniedz skaitu dažādām kontrolsummu kļūdām uz noslogota NFS (Network File System) servera, kurš darbināts 40 dienas. 11.5.attēls atspoguļo novēroto kļūdu kopskaitu:

#pic("f_11_5.gif", "500")
11.5.attēls: Sabojāto pakešu skaits, ko atklāj dažādas kontrolsummas

Beigu kolonna ir tikai aptuvena katras rindas skaitļu summa, jo Ethernet'a un IP slāņos izmanto arī citus protokolus. Piemēram, ne visi Ethernet'a #term("kadri", "frame") ir IP datagrammas, jo vismaz nedaudz Ethernet'ā izmanto arī ARP. Ne visas IP datarammas ir vai nu UDP vai TCP, jo ICMP arī izmanto IP.

Ievērojiet, ka ir daudz lielāks TCP kontrolsummu procents, salīdzinot ar UDP kontrolsummu kļūdām. Tas ir iespējams, jo TCP savienojumi šajā sistēmā mēdza būt "liela attāluma" (kas ceļo cauri daudziem maršrutētājiem, tiltiem, u.c.), kamēr UDP #term("trafiks", "traffic") bija lokāls.

Galvenais secinājums ir - pilnībā neuzticēties datu posma slāņa CRC (Ethernet'am, #term("žetonu aplim", "token_ring"), u.c.). Vajag visu laiku #term("iespējot", "enable") #term("no gala līdz galam", "end_to_end") kontrolsummas. Un tad, ja Jūsu dati ir vērtīgi, tad var pilnībā neuzticēties arī UDP vai TCP kontrolsummām, jo tās ir vienkāršas kontrolsummas un nav domātas pilnīgi visu iespējamo kļūdu noķeršanai.

Tagi:
Izveidojis Kalvis Apsītis 2008-06-22 13:18
    
This wiki is licensed under a Creative Commons 2.0 license
XWiki Enterprise 6.4 - Documentation