Èíîñòðàííûé ÿçûê: Àëãîðèòìè ìàðøðóòèçàö³¿ â ìåðåæàõ, Äèïëîìíàÿ ðàáîòà

Êóðñîâà ðîáîòà

1. Âñòóï

 íàø ÷àñ êîìï’þòåðí³ ìåðåæ³ ïåðåáóâàþòü â ñòàí³ ðîçâèòêó é íàáóâàþòü øèðîêîãî ðîçïîâñþäæåííÿ. Ëèøå êîìï’þòåðíà ìåðåæà Internet â äàíèé ÷àñ ðîçðàõîâàíà íà 4.294.967.296 êîìï’þòåð³â, ÿê³ ìàòèìóòü IP àäðåñè. Äî öüîãî ÷èñëà ñë³ä äîäàòè ÷èëåíí³ ëîêàëüí³ òà êîðïîðàòèâí³ ìåðåæ³. Âñ³ ö³ êîìï’þòåðè áóëè ç’ºäíàí³ ç ìåòîþ îáì³íó ³íôîðìàö³ºþ ³ âëàñíèêè êîìï’þòåð³â æàäàþòü øâèäêî¿ ïåðåäà÷³ âåëèêî¿ ê³ëüêîñò³ ³íôîðìàö³¿ íà çíà÷í³ â³äñòàí³.

Âèìîãè êîðèñòóâà÷³â ìåðåæ³ çàäîâîëüíÿþòüñÿ ïîêðàùåííÿì ÿê³ñò³ êàíàë³â ïåðåäà÷³ äàíèõ íà çàì³íó òåëåôîííèì äðîòàì ïðèéøë³ îïòè÷íî-âîëîêîíí³ ë³í³¿, êàíàëè ïåðåäà÷³ äàíèõ çà äîïîìîãîþ ñóïóòíèêîâîãî çâ’ÿçêó òîùî. Àëå çíà÷íó ðîëü ïðè òàê³é ê³ëüêîñò³ ç’ºäíàíèõ â ìåðåæó êîìï’þòåð³â â³ä³ãðຠÿê³ñòü ïðîòîêîë³â, çà äîïîìîãîþ ÿêèõ çä³éñíþºòüñÿ ïåðåäà÷à äàíèõ ì³æ ñåðâåðàìè, ïðîòîêîë³â ìàðøðóòèçàö³¿, àëãîðèòì³â íà ÿêèõ âîíè ïîáóäîâàí³.

Âðàõîâóþ÷è, ùî 4-áàéòíó àäðåñàö³þ â ìåðåæ³ Internet áóäå çàì³íåíî 8-áàéòíîþ, òîáòî ìàêñèìàëüíà ê³ëüê³ñòü êîìï’þòåð³â ï³ä’ºäíàíèõ äî ìåðåæ³ çðîñòå ó 4.294.967.296 ðàç³â, ñë³ä çàçíà÷èòè, ùî íàéá³ëüøó ðîëü â³ä³ãðàâàòèìå ïîêðàùåííÿ ñàìå ìåõàí³çìó ìàðøðóòèçàö³¿ ïàêåò³â äàíèõ ì³æ ñåðâåðàìè ìåðåæ³ Internet.

Ìàðøðóòèçàö³ÿ – öå çàäà÷à çíàõîäæåííÿ øëÿõó ì³æ êîìï’þòåðîì, ùî â³äñèëຠäàí³ òà êîìï’þòåðîì-îäåðæóâà÷åì, àëå â çâ’ÿçàí³é ìîäåë³ IP öÿ çàäà÷à â îñíîâíîìó çâîäèòüñÿ äî ïîøóêó øëÿõ³â äî øëþç³â ì³æ ìåðåæàìè. Ïîêè ïàêåòè äàíèõ çíàõîäÿòüñÿ íà îêðåì³é ìåðåæ³ àáî ï³äìåðåæ³ ïðîáëåìè ìàðøðóòèçàö³¿ âèð³øóþòüñÿ çà òåõíîëî㳺þ, ñïåöèô³÷íîþ äëÿ ³íòåðôåéñó ö³º¿ ìåðåæ³. IP ìàðøðóòèçàö³ÿ ïî÷èíàºòüñÿ, êîëè ïîòð³áíî ïåðåäàòè äàí³ ì³æ ð³çíèìè ìåðåæàìè ç ð³çíèìè ³íòåðôåéñàìè. ßêùî ìåðåæ³ îòðèìóâà÷à òà â³äïðàâíèêà áåçïîñåðåäíüî çâ’ÿçàí³, òî äàí³ ìàþòü ïðîéòè ÷åðåç øëþç, ùî ç’ºäíóº ìåðåæ³. ßêùî ö³ ìåðåæ³ íå çâ’ÿçàí³ øëþçîì, äàí³ ìàþòü ïðîéòè ÷åðåç ìåðåæ³, ùî çíàõîäÿòüñÿ ì³æ â³äïðàâíèêîì ³ îäåðæóâà÷åì òà øëþçàìè ùî ¿õ ç’ºäíóþòü.ßê ò³ëüêè äàí³ äîõîäÿòü äî øëþçó íà ìåðåæ³ îòðèìóâà÷à, òåõíîëîã³ÿ ìàðøðóòèçàö³¿ ö³º¿ ìåðåæ³ ñïðÿìîâóº äàí³ äî îòðèìóâà÷à.

Äëÿ çíàõîäæåííÿ ìàðøðóòó äî êîìï’þòåðà-îòðèìóâà÷à ñèñòåìà çáåð³ãຠòàáëèö³ ìàðøðóòèçàö³¿, ÿê³ âèêîðèñòîâóþòüñÿ ïðîòîêîëàìè ìåðåæíîãî ð³âíÿ äëÿ âèáîðó ïîòð³áíîãî ìåðåæíîãî ³íòåðôåéñó. Ìàðøðóòèçàö³éíà ³íôîðìàö³ÿ çáåð³ãàºòüñÿ ó âèãëÿä³ äâîõ òàáëèöü: ïåðøà – äëÿ ìàðøðóò³â äî õîñò³â, äðóãà – äëÿ ìàðøðóò³â äî ìåðåæ. Òàêèé ï³äõ³ä äîçâîëÿº âèêîðèñòîâóâàòè óí³âåðñàëüí³ ìåõàí³çìè âèçíà÷åííÿ ìàðøðóò³â ÿê äëÿ ìåðåæ ³ç ðîçïîä³ëåíèì ñåðåäîâèùåì ïåðåäà÷³ äàíèõ , òàê ³ äëÿ ìåðåæ òèïó point-to-point. Âèçíà÷àþ÷è ìàðøðóò, ìîäóëü ìåðåæíîãî ïðîòîêîëó (IP) ñïî÷àòêó ïåðåãëÿäຠòàáëèö³ äëÿ õîñò³â, à ïîò³ì äëÿ ìåðåæ. ßêùî ïîøóê íå äຠðåçóëüòàòó, òî âèêîðèñòîâóºòüñÿ ìàðøðóò ïî çàìîâ÷óâàííþ.

Âèçíà÷åííÿ ìàðøðóòó ìîæå áàçóâàòèñÿ íà ð³çíîìàí³òíèõ ïîêàçíèêàõ àáî êîìá³íàö³ÿõ ïîêàçíèê³â. Ïðîãðàìí³ ðåàë³çàö³¿ àëãîðèòì³â ìàðøðóòèçàö³¿ âèðàõîâóþòü âàðò³ñòü ìàðøðóòó äëÿ âèçíà÷åííÿ îïòèìàëüíèõ ìàðøðóò³â äî ïóíêòó ïðèçíà÷åííÿ.

 òàáëèö³ 1 íàâåäåíî ïðèêëàä òàáëèö³ òèïó ïóíêò ïðèçíà÷åííÿ/íàñòóïíèé îá’ºêò äëÿ ïåðåñèëàííÿ ïàêåò³â.

Ìåðåæà ïðèçíà÷åííÿ Íàñòóïíèé îá’ºêò
57 âåðøèíà Ñ
24 âåðøèíà Â
26 âåðøèíà Â
18 âåðøèíà À
20 âåðøèíà Ñ
34 âåðøèíà À
28 âåðøèíà À

Òàáëèöÿ 1 : ìàðøðóòèçàö³éíà òàáëèöÿ òèïó ïóíêò ïðèçíà÷åííÿ/íàñòóïíèé îá’ºêò äëÿ ïåðåñèëàííÿ ïàêåò³â

²ñíóº áàãàòî ï³äõîä³â äî çàäà÷ ïîøóêó îïòèìàëüíèõ øëÿõ³â â ìåðåæ³, ùî ðåàë³çîâàí³ â ïðîòîêîëàõ, çà ÿêèìè â³äáóâàºòüñÿ ìàðøðóòèçàö³ÿ, òàêèõ ÿê Interior Gateway Protocols: OSPF (Open Shortest Path First), Dual IS-IS (Intermediate System to Intermediate System), RIP (Routing Information Protocol), GGP (Gateway to Gateway Protocol); Exterior Gateway Protocols: BGP (Border Gateway Protocol), EGP (Exterior Gateway Protocol), Inter-AS Routing without Exterior Gateway; Static Routing.

Íàéðîçïîâñþäæåí³øèìè â Internet º ðåàë³çàö³¿ àëãîðèòì³â âåêòîðó â³äñòàí³ òà â³äêðèòòÿ íàéêîðîòøîãî øëÿõó.

Àëãîðèòìè â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó, òàêîæ â³äîì³ ÿê àëãîðèòìè ñòàíó êàíàëà íàïðàâëÿþòü ïîòîêè ìàðøðóòèçàö³éíî¿ ³íôîðìàöèè äî âñ³õ âóçë³â îá'ºäíàíî¿ ìåðåæ³. Àëå êîæíèé ìàðøðóòèçàòîð â³äñèëຠëèøå òó ÷àñòèíó ìàðøðóòèçàö³éíî¿ òàáëèö³, êîòðà îïèñóº ñòàí éîãî âëàñíèõ êàíàë³â. Àëãîðèòìè âåêòîðó â³äñòàí³ (òàêîæ â³äîì³, ÿê àëãîðèòìè Áåëìàíà-Ôîðäà) âèìàãàþòü â³ä êîæíîão ìàðøðóòèçàòîðà â³äñèëêè âñ³º¿ àáî ÷àñòèíè ñâ ìàðøðóòèçàö³éíî¿ òàáëèö³, àëå ëèøå ñâî¿ì ñóñ³äàì. Àëãîðèòìè â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó ôàêòè÷íî íàïðàâëÿþòü íåâåëèê³ êîðåêö³¿ ïî âñ³õ íàïðÿìêàõ, â òîé ÷àñ ÿê àëãîðèòìè âåêòîðó â³äñòàí³ â³äñèëàþòü á³ëüø âåëèê³ êîðåêö³¿ ëèøå äî ñóñ³äí³õ ìàðøðóòèçàòîð³â.

³äð³çíÿþ÷èñü á³ëüø øâèäêîþ ñõîäèì³ñòþ, àëãîðèòìè â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó òðîõè ìåíøå ñõèëüí³ äî óòâîðåííÿ ïåòåëü ìàðøðóòèçàö³¿, í³æ àëãîðèòìè âåêòîðó â³äñòàí³. Ç ³íøîãî áîêó, àëãîðèòìè â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó õàðàêòåðèçóþòüñÿ á³ëüø ñêëàäíèìè ðîçðàõóíêàìè â ïîð³âíÿíí³ ç àëãîðèòìàìè âåêòîðó â³äñòàí³, ïîòðåáóþ÷è á³ëüøî¿ ïðîöåñîðíî¿ ïîòóæíîñò³ òà ïàì’ÿò³, í³æ àëãîðèòìè âåêòîðó â³äñòàí³.  çâ’ÿçêó ç öèì, ðåàë³çàö³ÿ òà ï³äòðèìêà àëãîðèòì³â â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó ìîæå áóòè á³ëüø äîðîãîþ. Íå äèâëÿ÷èñü íà ¿õí³ â³äì³ííîñò³, îáèäâà òèïè àëãîðèòì³â äîáðå ôóíêö³îíóþòü çà ñàìèõ ð³çíîìàí³òíèõ óìîâ.

 äîäàòêó íàâåäåíî òåêñò äåìîíó Routed, ÿêèé ðåàë³çîâàíèé ó ìàðøðóòèçàö³éíîìó ïðîòîêîë³ RIP íà îñíîâ³ àëãîðèòìó âåêòîðó â³äñòàí³.

2. Ìàðøðóòèçàö³éí³ ð³øåííÿ

2.1. RIP : Àëãîðèòìè âåêòîðó â³äñòàí³

Àëãîðèòìè âåêòîðó â³äñòàí³ îñíîâàí³ íà îáì³í³ ìàëî¿ ê³ëüêîñò³ ³íôîðìàö³¿. Êîæíèé îá’ºêò (øëþç àáî õîñò), ùî ïðèéìຠó÷àñòü â ìàðøðóòèçàö³¿, ìຠòðèìàòè ³íôîðìàö³þ ïðî âñ³ êîìï’þòåðè ñèñòåì³. Êîæíèé çàïèñ â òàáëèö³ ìàðøðóòèçàö³¿ âêëþ÷ຠíàñòóïíèé øëþç, íà ÿêèé äàí³, íàïðÿìëåí³ äî îá’ºêòó, ìàþòü áóòè â³äïðàâëåí³. Äî òîãî æ â³í ìຠì³ñòèòè çíà÷åííÿ, ùî õàðàêòåðèçóº çàãàëüíó â³äñòàíü äî îá’ºêòó. ³äñòàíü - öå óçàãàëüíåíà õàðàêòåðèñòèêà, ùî ìîæå â³äîáðàæàòè øâèäê³ñòü ïåðåäà÷³ äàíèõ, ãðîøîâó âàðò³ñòü ïåðåäà÷³ òîùî. Àëãîðèòìè âåêòîðó â³ñòàí³ ä³ñòàëè ñâîþ íàçâó â³ä òîãî, ùî âîíè ìîæóòü îá÷èñëèòè îïòèìàëüíèé ìàðøðóò êîëè çì³íþºòüñÿ ëèøå ñïèñîê â³äñòàíåé. Êð³ì òîãî, ìຠì³ñöå îáì³í ìàðøðóòèçàö³éíîþ ³íôîðìàö³ºþ ì³æ áåçïîñåðåäíüî çâ’ÿçàíèìè îá’ºêòàìè, òîáòî åëåìåíòàìè ñï³ëüíî¿ ìåðåæ³. Çàïèñè â òàáëèö³ ìàðøðóòèçàö³¿ ìàþòü ì³ñòèòè òàêó ³íôîðìàö³þ ïðî êîìï’þòåð-îòðèìóâà÷:

àäðåñà : â IP ðåàë³çàö³¿ öå ìຠáóòè IP àäðåñà õîñòà àáî ìåðåæ³;

øëþç : ïåðøèé øëþç íà öüîìó ìàðøðóò³;

³íòåðôåéñ : ³íòåðôåéñ, ùî ìຠáóòè âèêîðèñòîâàíèé, ùîá äîñÿãòè ïåðøîãî øëþçà;

ö³íà : ÷èñëî, ùî âèçíà÷ຠâ³äñòàíü äî êîìï’þòåðà-îòðèìóâà÷à;

òàéìåð : ïðîì³æîê ÷àñó ç òîãî ìîìåíòó êîëè ³íôîðìàö³ÿ áóëà âîñòàííº îíîâëåíà.

Íà äîäàòîê ìîæóòü áóòè äîäàí³ ð³çí³ ôëàãè òà ³íøà ³íôîðìàö³ÿ. Òàáëèöÿ ïî÷èíàºòüñÿ ç îïèñó îá’ºêò³â, ùî ïðÿìî ï³ä’ºäíàí³ äî ñèñòåìè. Âîíà îíîâëþºòüñÿ íà îñíîâ³ ³íôîðìàö³¿, ùî ïðèõîäèòü â³ä ñóñ³äí³õ øëþç³â. Íàéâàæëèâ³øà ³íôîðìàö³ÿ, ÿêîþ îáì³íþþòüñÿ õîñòè òà øëþçè ì³ñòèòüñÿ â çâ³òàõ îíîâëåííÿ. Êîæíèé îá’ºêò, ùî áåðå ó÷àñòü â ìàðøðóòèçàö³¿ ïîñèëຠçâ³òè îíîâëåííÿ, ùî îïèñóþòü òàáëèö³ ìàðøðóòèçàö³¿ â òîìó ñòàí³, â ÿêîìó âîíè çíàõîäÿòüñÿ íà äàíèé ìîìåíò. Ìîæëèâî âèçíà÷èòè îïòèìàëüíèé ìàðøðóò êîðèñòóþ÷èñü ëèøå ³íôîðìàö³ºþ îòðèìàíîþ â³ä ñóñ³äí³õ îá’ºêò³â.

Àëãîðèòìè âåêòîðó â³äñòàí³ áàçóþòüñÿ íà òàáëèö³ äàþ÷è íàéêðàùèé ìàðøðóò ç ì³ðêóâàíü ö³íè (áóäü-ÿêî¿ õàðàêòåðèñêè,ÿêó ìîæíà ïðåäñòàâèòè ó âèãëÿä³ ñóìè ðåáåð ãðàôó) . Ôîðìàëüíî, ÿêùî âåðøèíè i òà j ñóñ³äí³, òîä³ ö³íà d(i,j) ð³âíà ö³í³ ðåáðà ì³æ i òà j.  íîðìàëüíîìó âèïàäêó âñ³ îá’ºêòè íà äàí³é ìåðåæ³ îäíàêîâ³, d(i,j) îäíàêîâå äëÿ âñ³õ îá’ºêò³â äàíî³ ìåðåæ³ ³ âèçíà÷ຠö³íó âèêîðèñòîâóâàííÿ ö³º¿ ìåðåæ³. Ùîá ä³ñòàòè ö³íó âñüîãî ìàðøðóòó, ïîòð³áíî äîäàòè ö³íè âñ³õ ðåáåð, ùî ñêëàäàþòü öåé ìàðøðóò. Äëÿ çðó÷íîñò³ ïðèïóñòèìî, ùî ö³íà – äîäàòíº ö³ëå. Íåõàé D(i,j) âèçíà÷ຠö³íó êðàùîãî ìàðøðóòó ç âåðøèíè i äî âåðøèíè j. Âîíà ìຠáóòè âèçíà÷åíà äëÿ êîæíîãî ðåáðà. d(i,j) âèçíà÷àòèìå ö³íè îêðåìèõ êðîê³â. Ôîðìàëüíî, íåõàé d(i,j) âèçíà÷ຠö³íó ìàðøðóòó, éäó÷è ïðÿìî ç âåðøèíè i äî âåðøèíè j. Öå çíà÷åííÿ äîð³âíþº íåñê³í÷åííîñò³, ÿêùî i òà j íå ñóñ³äí³ âåðøèíè. (Ñë³ä çàóâàæèòè, ùî d(i,i) - íåñê³í÷åíí³ñòü. Öå òàê, ÿêùî íå áðàòè äî óâàãè, ùî âåðøèíà ìîæå ìàòè ïðÿìå ç’ºäíàííÿ äî ñàìî¿ ñåáå). Îñê³ëüêè ö³íè àäèòèâí³, òî ìîæíà ïîêàçàòè îòðèìàííÿ êðàùîãî ìàðøðóòó òàê :

D(i,i) = 0, äëÿ âñ³õ i

D(i,j) = min [d(i,k) + D(k,j)], ³íàêøå k

³ íàéêðàùèé ìàðøðóò òîé, ùî ïî÷èíàºòüñÿ ç âåðøèíè i äî òèõ âåðøèí k, äëÿ ÿêèõ d(i,k) + D(k,j) ì³í³ìàëüíå.

Ìè ìîæåìå îáìåæèòè äðóãå ð³âíÿííÿ äëÿ òèõ k, ùî º ñóñ³äàìè i. Äëÿ ³íøèõ d(i,k) íåñê³í÷åíí³ñòü, òîìó âîíè íå ìîæóòü äàòè ì³í³ìàëüíîãî çíà÷åííÿ.Íà îñíîâ³ öüîãî ìîæëèâî îá÷èñëèòè â³äñòàíü. Îá’ºêò i ïðèìóøóº éîãî ñóñ³ä³â k ïðèñëàòè ö³íó øëÿõó äî îá’ºêòó ïðèçíà÷åííÿ j. Êîëè i îòðèìóº ö³íó d(k,j) â³ä âñ³õ k, â³í äîäຠd(k,j) äî ö³íè øëÿõó D(i,k). Ïîò³ì ³ ïîð³âíþº çíà÷åííÿ â³ä âñ³õ ñóñ³ä³â ³ âèáèðຠíàéìåíøå.

Ðåàëüí³ ðåàë³çàö³¿ àëãîðèòìó çàïàì’ÿòîâóþòü íàéêðàùó ö³íó é ³äåíòèô³êàö³þ ñóñ³äà, ùî ¿¿ íàä³ñëàâ. ²íôîðìàö³ÿ çàì³ùàºòüñÿ, êîëè íàäñèëàºòüñÿ ìåíøà ö³íà. Öå äîçâîëÿº îáðàõîâóâàòè ì³í³ìóì, íå çáåð³ãàþ÷è ³íôîðìàö³þ â³ä âñ³õ ñóñ³ä³â. Àëå â âèïàäêó, êîëè ³íôîðìàö³ÿ íàäõîäèòü â³ä îá’ºêòà, ùî áóâ çàïèñàíèé â òàáëèö³ ÿê íàéêðàùèé, ³íôîðìàö³ÿ îíîâëþºòüñÿ â áóäü-ÿêîìó âèïàäêó. Ìåõàí³çì âèçíà÷åííÿ íàéêðàùîãî ìàðøðóòó ïåðåäáà÷ຠêðàõ îá’ºêòó íà ä³ëÿíö³ öüîãî ìàðøðóòó.  çâ’ÿçêó ç öèì âñòàíîâëåíî, ùî îá’ºêòè ìàþòü â³äñèëàòè îíîâëåíó ³íôîðìàö³³þ êîæí³ 30 ñåêóíä. ßêùî îá’ºêò, ùî äຠêðàùó ö³íó, íå â³äïîâ³äຠïðîòÿãîì 180 ñåêóíä (âðàõîâóºòüñÿ ìîæëèâ³ñòü âòðàòè ïàêåòó), ö³íà øëÿõó âñòàíîâëþºòüñÿ â äóæå âåëèêå çíà÷åííÿ.

2.2. OSPF, Dual IS-IS: Àëãîðèòì â³äêðèòòÿ íàéêîðîòøîãî øëÿõó

2.2.1. Îãëÿä àëãîðèòìó.

Àëãîðèòì â³äêðèòòÿ íàéêîðîòøîãî øëÿõó âèêîðèñòîâóºòüñÿ ÿê â IP, òàê ³ â OSI ñåðåäîâèù³. ³í ìຠñêëàäí³ñòü Î(N2).

Îñíîâíèé àëãîðèòì, ùî áóäóº PATHS ç íóëÿ, ïî÷èíຠäîäàâàííÿ ñèñòåì ç íàéâèã³äí³øèìè ìàðøðóòàìè ç îãëÿäîì íà PATHS (íå ìîæå ³ñíóâàòè êîðîòøîãî ìàðøðóòó äî SELF ). Ïîò³ì âèçíà÷àºòüñÿ TENT âèêîðèñòîâóþ÷è ëîêàëüí³ òàáëèö³ ç â³äîìîñòÿìè ïðî ñóñ³äí³ âåðøèíè.

Ñèñòåìà íå ìîæå áóòè ðîçì³ùåíîþ â PATHS äî òèõ ï³ð, ïîêè íå äîâåäåíî, ùî íå ³ñíóº ìàðøðóòó, êîðîòøîãî çà äàíèé. Êîëè ñèñòåìà N ðîçì³ùóºòüñÿ â PATHS, ïåðåâ³ðÿºòüñÿ ö³íà ìàðøðóòó äî êîæíî¿ âåðøèíè M ñóñ³äíüî¿ äî N ÷åðåç ñàìó âåðøèíó N. Öåé ìàðøðóò âèçíà÷àºòüñÿ ÿê ñóìà ö³íè ìàðøðóòó äî N òà ö³íè ä³ëÿíêè NM. ßêùî <M,*,*> ðîçì³ùåíèé â TENT òà íîâå çíà÷åííÿ áóäå á³ëüøèì, ìàðøðóò ³ãíîðóºòüñÿ.ßêùî <M,*,*> ðîçì³ùåíèé â TENT òà íîâå çíà÷åííÿ áóäå ìåíøèì, ñòàðèé çàïèñ çàì³ùóºòüñÿ íîâèì. ßêùî <M,*,*> ðîçì³ùåíèé â TENT òà íîâå çíà÷åííÿ òàêå æ ñàìå ÿê òå, ùî âæå º â TENT òî íàá³ð {Adj(M)} âñòàíîâëþºòüñÿ ÿê ïîºäíàííÿ ñòàðîãî çàïèñó (òîãî, ùî ì³ñòèòüñÿ â TENT) òà íîâîãî - {Adj(N)}. ßêùî M íå çíàõîäèòüñÿ â TENT, òî äàíèé ìàðøðóò äîäàºòüñÿ â TENT.

Ïîò³ì àëãîðèòì çíàõîäèòü òðèïëåòè <N,x,{Adj(N)}> in TENT ç ì³í³ìàëüíèì x.

2.2.2. Ðåàë³çàö³ÿ àëãîðèòìó â³äêðèòòÿ íàéêîðîòøîãî øëÿõó â DUAL IS-IS ñåðåäîâèù³

Êðîê 0: Âñòàíîâèìî TENT òà PATHS ÿê ïóñò³. Âñòàíîâèìî tentlength â 0.

(tentlength – öå äîâæèíà øëÿõó äîñë³äæóâàíèõ åëåìåíò³â TENT.)

1) Äîäàìî <SELF,0,W> äî PATHS, äå SELF – ïî÷àòêîâà ñèñòåìà, W –ñïåö³àëüíà âåëè÷èíà, ùî âèçíà÷ຠòðàô³ê äî SELF ùî ïðîéäåíèé, âêëþ÷àþ÷è âíóòð³øí³é ïðîöåñ.

2) Òåïåð çàãðóçèìî TENT ëîêàëüíèìè äàíèìè øëÿõ³â (Êîæåí çàïèñ â TENT ìຠáóòè âèçíà÷åíèé ÿê ìàðøðóòèçàòîð àáî ê³íöåâà ñèñòåìà OSI, ùîá äîçâîëèòè ïðàâèëüíó ïåðåâ³ðêó â Êðîö³ 2).

Äëÿ âñ³õ ñóì³æíèõ âåðøèí Adj(N) íà âñ³õ ìîæëèâèõ êàíàëàõ:

d(N) = ö³íà ìàðøðóòó, ùî ïðîõîäèòü ÷åðåç (N)

Adj(N) = ê³ëüê³ñòü âåðøèí ñóñ³äí³õ N.

3) ßêùî òðèïëåò <N,x,{Adj(M)}> â TENT, òî

ßêùî x = d(N), òî {Adj(M)} := {Adj(M)} U {Adj(N)}.

4) ßêùî N – ìàðøðóòèçàòîð àáî ê³íöåâà ñèñòåìà OSI, ³ á³ëüøå íå ³ñíóº ñóì³æíèõ âåðøèí {Adj(M)} òî âèäàëèìî íàäëèøêîâó âåðøèíó.

5) ßêùî x < d(N), í³÷îãî.

6) ßêùî x > d(N), âèäàëèòè <N,x,{Adj(M)}> ç TENT ³ äîäàòè òðèïëåò <N,d(N),{Adj(N)}>.

7) ßêùî <N,x,{Adj(M)}> íå â TENT, òî äîäàòè <N,d(N),{Adj(N)}> â TENT.

8) Òåïåð äîäàþòüñÿ ñèñòåìè, äëÿ ÿêèõ ëîêàëüíèé ìàðøðóòèçàòîð íå ìຠñóì³æíèõ âåðøèí, àëå âîíè çãàäàí³ â ñóñ³äí³õ ïñåâäîâåðøèíàõ LSP. Ñóì³æí³ñòü äëÿ òàêèõ ñèñòåì âèçíà÷àºòüñÿ ìàðøðóòèçàòîðîì.

9) Äëÿ âñ³õ øèðîêîâºùàòåëüíèõ êàíàë³â â àêòèâíîìó ñòàí³, çíàéòè ïñåâäîâåðøèíó LSP äëÿ öüîãî êàíàëó. ßêùî òàêà ³ñíóº, äëÿ âñ³õ ñóñ³ä³â N, ïðî ÿê³ çãàäóâàºòüñÿ íà ö³é âåðøèí³ ³ íå âèçíà÷åí³ â TENT, äîäàòè çàïèñ:

<N,d(N),{Adj(N)}> to TENT, where:

d(N) = ö³íà ïðîì³æêó .

Adj(N) = ê³ëüê³ñòü âåðøèí, ùî ñòîÿòü íà øëÿõó äî çàäàíîãî ìàðøðóòèçàòîðà.

10) Ïåðåéòè â Êðîê 2.

Êðîê 1: Âèçíà÷èòè íóëüîâèé PDU â LSP ñèòåìè, ùîéíî äîäàíî¿ â PATHS

1)dist(P,N) = d(P) + metric.k(P,N) äëÿ êîæíîãî ñóñ³äà N (ÿê äëÿ ê³íöåâî¿ ñèñòåìè, òàê ³ äëÿ ìàðøðóòèçàòîðà) ñèñòåìè P.

2) ßêùî dist(P,N) >ìàêñèìàëüíî¿ ö³íè ïðîì³æêó, í³÷îãî.

3) ßêùî <N,d(N),{Adj(N)}> º â PATHS, í³÷îãî.

d(N) ïîâèííå áóòè ìåíøèì í³æ dist(P,N), àáî N íå ïîâèííå áóòè â PATHS. Çà áàæàííÿì ìîæíà çðîáèòè äîäàòêîâó ïåðåâ³ðêó ÷è º d(N) ìåíøèì çà dist(P,N).

4) ßêùî òðèïëåò <N,x,{Adj(N)}> â TENT, òîä³:

a) ßêùî x = dist(P,N) òîä³ {Adj(N)}:= {Adj(N)} U {Adj(P)}.

b) ßêùî N – ìàðøðóòèçàòîð àáî ê³íöåâà ñèñòåìà OSI, ³ á³ëüøå íå ³ñíóº ñóì³æíèõ âåðøèí {Adj(M)}, òî âèäàëèìî íàäëèøêîâó âåðøèíó.

c) ßêùî x < dist(P,N), í³÷îãî.

d) ßêùî x > dist(P,N), âèäàëèòè <N,x,{Adj(N)}> ç TENT, òà äîäàòè <N,dist(P,N),{Adj(P)}>

5) ßêùî <N,x,{Adj(N)}> íå â TENT, äîäàòè <N,dist(P,N),{Adj(P)}> â TENT.

Êðîê 2: ßêùî TENT ïóñòèé, çóïèíèòèñÿ. ²íàêøå:

1) Çíàéòè åëåìåíò <P,x,{Adj(P)}>, ç ì³í³ìàëüíèì x òàêèì ÷èíîì:

a)ßêùî åëåìåíò <*,tentlength,*> çàëèøèâñÿ â TENT â ñïèñêó äëÿ tentlength, âèáðàòè öåé åëåìåíò. ßêùî â ñïèñêó ³ñíóº á³ëüøå îäíîãî åëåìåíòó, âèáðàòè îäèí ç öèõ åëåìåíò³â äëÿ ñèñòåìè, ùî º ïñåâäîâåðøèíîþ, âèáðàòè òó, ùî íå º ïñåâäîâåðøèíîþ. ßêùî á³ëüøå íåìà åëåìåíò³â â ñïèñêó äëÿ tentlength, çá³ëüøèòè tentlength ³ ïîâòîðèòè Êðîê 2.

b)Âèäàëèòè <P,tentlength,{Adj(P)}> ç TENT.

c) Äîäàòè <P,d(P),{Adj(P)}> â PATHS.

d) ßêùî ñèñòåìà ò³ëüêè ùî äîäàíà â PATHS – ê³íöåâà ñèñòåìà, òî ïåðåéòè â Êðîê 2. ²íàêøå : ïåðåéòè â Êðîê 1.

Ïîçíà÷åííÿ:

PATHS – ïðåäñòàâëÿº àöèêë³÷íèé ãðàô íàéêîðîòøèõ øëÿõ³â â³ä ñèñòåìè S. ³í ïðåäñòàâëÿºòüñÿ ÿê íàá³ð òðèïëåò³â <N,d(N),{Adj(N)}>, äå N ³äåíòèô³êàòîð ñèñòåìè. d(N) çàãàëüíà â³äñòàíü â³ä N äî S).

{Adj(N)} –íàá³ð ïðàöþþ÷èõ ñóñ³ä³â S, ùî ¿õ ìîæíà âèêîðèñòàòè N. ßêùî ñèñòåìà º â PATHS, øëÿõè, ùî â³äïîâ³äàþòü öüîìó ì³ñöþ º íàéêîðîòøèìè.

TENT – ñïèñîê òðèïëåò³â ó âèãëÿä³ <N,d(N),{Adj(N)}>, äå N, d(N) òà {Adj(N)} â³äïîâ³äàþòü âèçíà÷åíèì â PATHS.

TENT ìîæå áóòè ³íòó³òèâíî ïðåäñòàâëåíèé ÿê ì³ñöå ñèñòåìè â PATHS. ²íøèìè ñëîâàìè, òðèïëåò <N,x,{A}> â TENT ãîâîðèòü, ùî, ÿêùî N º â PATHS, d(N) â³äïîâ³äຠx, àëå N íå ìîæå áóòè ðîçì³ùåíå â PATHS ïîêè íå äîâåäåíî, ùî íå ³ñíóº øëÿõ³â, êîðîòøèõ çà x .

Òàê ñàìî <N,x,{A,B}> â TENT çíà÷èòü, ùî ÿêùî N º â PATHS, òîä³ d(N) áóäå äîð³âíþâàòè x äëÿ ìàðøðóò³â, ùî ïðîõîäÿòü ÷åðåç ñóì³æíó âåðøèíó A àáî ÷åðåç ñóì³æíó âåðøèíó B.

 Çàïðîïîíîâàíî â ðåàëüí³é ðåàë³çàö³¿ òàáëèö³ TENT ïðîâîäèòè ñîðòóâàííÿ çà õàðàêòåðèñòèêîþ d(N).

3. Âèñíîâêè

Ìàðøðóòèçàö³éí³ àëãîðèòìè ðåàë³çîâàí³ íà ð³çíèõ òèïàõ ìåðåæ â³ä ëîêàëüíèõ äî ãëîáàëüíèõ. Øèðîêî ðîçïîâñþäæåíèì º äåìîí Routed ç äèñòðèóòèâó óí³âåðñèòåòó Êàë³ôîðí³¿ â Áåðêë³ â³í ðåàë³çîâàíèé â ïðîòîêîë³ RIP. Òàêîæ âåëèêå çíà÷åííÿ ìàþòü ðåàë³çàö³¿ àëãîðèòìó â³äêðèòòÿ íàéêîðîòøîãî ìàðøðóòó äëÿ ïîäâ³éíîãî ñåðåäîâèùà OSI òà TCP/IP â ïëàí³ çíàõîäæåííÿ ìàðøðóò³â ì³æ ³íòåð-àâòîíîìíèìè ñèñòåìàìè òà ìàðøðóòèçàòîðàìè TCP/IP àðõèòåêòóðè.

Ãëîññàð³é

OSI – ìåðåæíà ìîäåëü, çàïðîïîíîâàíà îðãàí³çàö³ºþ ïî ñòàíäàðòèçàö³¿ ISO

IS – Interautonomous system – ³íòåðàâòîíîìíà ñèñòåìà, ñèñòåìà, ùî ïðèéìຠó÷àñòü â ìàðøðóòèçàö³¿ â ìîäåë³ OSI

ES - End System-ê³íöåâà ñèñòåìà, ñèñòåìà, ùî íå ïðèéìຠó÷àñò³ â ìàðøðóòèçàö³¿ â ìîäåë³ OSI

Router – ìàðøðóòèçàòîð, îá’ºêò ìàðøðóòèçàö³¿

Gateway – øëþç, ñèñòåìà, ùî ìຠäåê³ëüêà ìåðåæíèõ ³íòåðôåéñ³â

RIP (Routing Information Protocol) – ìàðøðóòèçàö³éíèé ³íôîðìàö³éíèé ïðîòîêîë

OSPF (Open Shortest Path First) – Ìàðøðóòèçàö³éíèé ïðîòîêîë â³äêðèòòÿ íàéêîðîòøîãî øëÿõó

Ñïèñîê ëèòåðàòóðû

C.L. Hedrick. Routing Information Protocol. RFC 1058 Jun-01-1988.

D. Waitzman, C.Partridge, S.E. Deering. Distance Vector Multicast Routing Protocol. RFC 1075 Nov-01-1988.

R.W. Callon. Use of OSI IS-IS for routing in TCP/IP and dual environments.

RFC 1195 Dec-01-1990.

P. Almquist, F. Kastenholz. Towards Requirements for IP Routers. RFC 1716 November 1994.

J. Moy. , OSPF Version 2. RFC 2178 July 1997.

A. Ballardie. Core Based Trees (CBT) Multicast Routing Architecture. RFC 2201September 1997.

Bellman, R. E., "Dynamic Programming", Princeton University Press, Princeton, N.J., 1957.

Bertsekas, D. P., and Gallaher, R. G., "Data Networks",Prentice-Hall, Englewood Cliffs, N.J., 1987.

Braden, R., and Postel, J., "Requirements for Internet Gateways", USC/Information Sciences Institute, RFC-1009, June 1987.

Boggs, D. R., Shoch, J. F., Taft, E. A., and Metcalfe, R. M.,"Pup: An Internetwork Architecture", IEEE Transactions on Communications, April 1980.

Clark, D. D., "Fault Isolation and Recovery," MIT-LCS, RFC-816, July 1982.

Xerox Corp., "Internet Transport Protocols", Xerox System Integration Standard XSIS 028112, December 1981.

Ford, L.R. Jr., and Fulkerson, D.R.,"Flows in Networks", Princeton University Press, Princeton, N.J., 1962.

"Intermediate System to Intermediate System Intra-Domain Routeing Exchange Protocol for use in Conjunction with the Protocol for Providing the Connectionless-mode Network Service (ISO 8473)", ISO DP 10589, February 1990.

"Protocol for Providing the Connectionless-Mode Network Service", ISO 8473, March 1987.

”End System to Intermediate System Routeing Exchange Protocol for Use in Conjunction with the Protocol for Providing the Connectionless-Mode Network Service (ISO 8473)", ISO 9542, March 1988.

Braden,R., and Postel,J., "Requirements for Internet Gateways", RFC 1009, June 1987.

Moy,J., "The OSPF Specification", RFC 1131, October 1989.

Postel,J., "Internetwork Protocol", RFC 791, September 1981.

Postel,J., "Internet Control Message Protocol", RFC 792, September 1981.

20. GOSIP Advanced Requirements Group, "Government Open Systems

Interconnection Profile (GOSIP) Version 2.0 [Final Text]", Federal Information Processing Standard, U.S. Department of Commerce, National Institute of Standards and Technology, Gaithersburg, MD, October 1990.

21. "Standard for Local Area Networks and Metropolitan Area Networks: Overview and Architecture of Network Standards",IEEE Standard 802.1a-1990.

Äîäàòîê

#include "defs.h"

#include "pathnames.h"

#ifdef sgi

#include "math.h"

#endif

#include <signal.h>

#include <fcntl.h>

#include <sys/file.h>

pid_t      mypid;

naddr     myaddr;                                               /* system address */

char        myname[MAXHOSTNAMELEN+1];

int          supplier;                                   /* supply or broadcast updates */

int          supplier_set;

int          ipforwarding = 1;                    /* kernel forwarding on */

int          default_gateway;                    /* 1=advertise default */

int          background = 1;

int          ridhosts;                                  /* 1=reduce host routes */

int          mhome;                                               /* 1=want multi-homed host route */

int          advertise_mhome;                   /* 1=must continue adverising it */

int          auth_ok = 1;                            /* 1=ignore auth if we do not care */

struct timeval epoch;                             /* when started */

struct timeval clk, prev_clk;

struct timeval now;                                /* current idea of time */

time_t    now_stale;

time_t    now_expire;

time_t    now_garbage;

struct timeval next_bcast;                      /* next general broadcast */

struct timeval no_flash = {EPOCH+SUPPLY_INTERVAL}; /* inhibit flash update */

fd_set    fdbits;

int          sock_max;

int          rip_sock = -1;                          /* RIP socket */

struct interface *rip_sock_mcast;          /* current multicast interface */

int          rt_sock;                                   /* routing socket */

int          rt_sock_seqno;

static int get_rip_sock(naddr, int);

static void timevalsub(struct timeval *, struct timeval *, struct timeval *);

int

main(int argc,

char *argv[])

{

   int n, mib[4], off;

   size_t len;

   char *p, *q;

   struct timeval wtime, t2;

   time_t dt;

   fd_set ibits;

   naddr p_net, p_mask;

   struct interface *ifp;

   struct parm parm;

   char *tracename = 0;

   /* Some shells are badly broken and send SIGHUP to backgrounded

    * processes.

    */

   signal(SIGHUP, SIG_IGN);

   openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);

   ftrace = stdout;

   gettimeofday(&clk, 0);

   prev_clk = clk;

   epoch = clk;

   epoch.tv_sec -= EPOCH;

   now.tv_sec = EPOCH;

   now_stale = EPOCH - STALE_TIME;

   now_expire = EPOCH - EXPIRE_TIME;

   now_garbage = EPOCH - GARBAGE_TIME;

   wtime.tv_sec = 0;

   (void)gethostname(myname, sizeof(myname)-1);

   (void)gethost(myname, &myaddr);

   while ((n = getopt(argc, argv, "sqdghmAtT:F:P:")) != -1) {

               switch (n) {

               case 's':

                           supplier = 1;

                           supplier_set = 1;

                           break;

               case 'q':

                           supplier = 0;

                           supplier_set = 1;

                           break;

               case 'd':

                           background = 0;

                           break;

               case 'g':

                           bzero(&parm, sizeof(parm));

                           parm.parm_d_metric = 1;

                           p = check_parms(&parm);

                           if (p != 0)

                                       msglog("bad -g: %s", p);

                           else

                                       default_gateway = 1;

                           break;

               case 'h':                        /* suppress extra host routes */

                           ridhosts = 1;

                           break;

               case 'm':                       /* advertise host route */

                           mhome = 1;     /* on multi-homed hosts */

                           break;

               case 'A':

                           /* Ignore authentication if we do not care.

                            * Crazy as it is, that is what RFC 1723 requires.

                            */

                           auth_ok = 0;

                           break;

               case 't':

                           new_tracelevel++;

                           break;

               case 'T':

                           tracename = optarg;

                           break;

               case 'F':                        /* minimal routes for SLIP */

                           n = FAKE_METRIC;

                           p = strchr(optarg,',');

                           if (p && *p != '\0') {

                                       n = (int)strtoul(p+1, &q, 0);

                                       if (*q == '\0'

                                        && n <= HOPCNT_INFINITY-1

                                        && n >= 1)

                                                   *p = '\0';

                           }

                           if (!getnet(optarg, &p_net, &p_mask)) {

                                       msglog("bad network; \"-F %s\"",

                                        optarg);

                                       break;

                           }

                           bzero(&parm, sizeof(parm));

                           parm.parm_net = p_net;

                           parm.parm_mask = p_mask;

                           parm.parm_d_metric = n;

                           p = check_parms(&parm);

                           if (p != 0)

                                       msglog("bad -F: %s", p);

                           break;

               case 'P':

                           /* handle arbirary, (usually) per-interface

                            * parameters.

                            */

                           p = parse_parms(optarg, 0);

                           if (p != 0) {

                                       if (strcasecmp(p,optarg))

                                                   msglog("%s in \"%s\"", p, optarg);

                                       else

                                                   msglog("bad \"-P %s\"", optarg);

                           }

                           break;

               default:

                           goto usage;

               }

   }

   argc -= optind;

   argv += optind;

   if (tracename == 0 && argc >= 1) {

               tracename = *argv++;

               argc--;

   }

   if (tracename != 0 && tracename[0] == '\0')

               goto usage;

   if (argc != 0) {

usage:

               logbad(0, "usage: routed [-sqdghmAt] [-T tracefile]"

                " [-F net[/mask[,metric]]] [-P parms]");

   }

   if (geteuid() != 0)

               logbad(0, "requires UID 0");

   mib[0] = CTL_NET;

   mib[1] = PF_INET;

   mib[2] = IPPROTO_IP;

   mib[3] = IPCTL_FORWARDING;

   len = sizeof(ipforwarding);

   if (sysctl(mib, 4, &ipforwarding, &len, 0, 0) < 0)

               LOGERR("sysctl(IPCTL_FORWARDING)");

   if (!ipforwarding) {

               if (supplier)

                           msglog("-s incompatible with ipforwarding=0");

               if (default_gateway) {

                           msglog("-g incompatible with ipforwarding=0");

                           default_gateway = 0;

               }

               supplier = 0;

               supplier_set = 1;

   }

   if (default_gateway) {

               if (supplier_set && !supplier) {

                           msglog("-g and -q incompatible");

               } else {

                           supplier = 1;

                           supplier_set = 1;

               }

   }

   signal(SIGALRM, sigalrm);

   if (!background)

               signal(SIGHUP, sigterm); /* SIGHUP fatal during debugging */

   signal(SIGTERM, sigterm);

   signal(SIGINT, sigterm);

   signal(SIGUSR1, sigtrace_on);

   signal(SIGUSR2, sigtrace_off);

   /* get into the background */

#ifdef sgi

   if (0 > _daemonize(background ? 0 : (_DF_NOCHDIR|_DF_NOFORK),

                            new_tracelevel == 0 ? -1 : STDOUT_FILENO,

                            new_tracelevel == 0 ? -1 : STDERR_FILENO,

                            -1))

               BADERR(0, "_daemonize()");

#else

   if (background && daemon(0, new_tracelevel) < 0)

               BADERR(0,"daemon()");

#endif

   mypid = getpid();

   srandom((int)(clk.tv_sec ^ clk.tv_usec ^ mypid));

   /* prepare socket connected to the kernel.

    */

   rt_sock = socket(AF_ROUTE, SOCK_RAW, 0);

   if (rt_sock < 0)

               BADERR(1,"rt_sock = socket()");

   if (fcntl(rt_sock, F_SETFL, O_NONBLOCK) == -1)

               logbad(1, "fcntl(rt_sock) O_NONBLOCK: %s", strerror(errno));

   off = 0;

   if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK,

                &off,sizeof(off)) < 0)

               LOGERR("setsockopt(SO_USELOOPBACK,0)");

   fix_select();

   if (background && new_tracelevel == 0)

               ftrace = 0;

   if (tracename != 0) {

               strncpy(inittracename, tracename, sizeof(inittracename)-1);

               set_tracefile(inittracename, "%s\n", -1);

   } else {

               tracelevel_msg("%s\n", -1); /* turn on tracing to stdio */

   }

   bufinit();

   /* initialize radix tree */

   rtinit();

   /* Pick a random part of the second for our output to minimize

    * collisions.

    *

    * Start broadcasting after hearing from other routers, and

    * at a random time so a bunch of systems do not get synchronized

    * after a power failure.

    */

   intvl_random(&next_bcast, EPOCH+MIN_WAITTIME, EPOCH+SUPPLY_INTERVAL);

   age_timer.tv_usec = next_bcast.tv_usec;

   age_timer.tv_sec = EPOCH+MIN_WAITTIME;

   rdisc_timer = next_bcast;

   ifinit_timer.tv_usec = next_bcast.tv_usec;

   /* Collect an initial view of the world by checking the interface

    * configuration and the kludge file.

    */

   gwkludge();

   ifinit();

   flush_kern();

   /* Ask for routes */

   rip_query();

   rdisc_sol();

   /* Loop forever, listening and broadcasting.

    */

   for (;;) {

               prev_clk = clk;

               gettimeofday(&clk, 0);

               timevalsub(&t2, &clk, &prev_clk);

               if (t2.tv_sec < 0

                || t2.tv_sec > wtime.tv_sec + 5) {

                           /* Deal with time changes before other housekeeping to

                            * keep everything straight.

                            */

                           dt = t2.tv_sec;

                           if (dt > 0)

                                       dt -= wtime.tv_sec;

                           trace_act("time changed by %d sec", dt);

                           epoch.tv_sec += dt;

               }

               timevalsub(&now, &clk, &epoch);

               now_stale = now.tv_sec - STALE_TIME;

               now_expire = now.tv_sec - EXPIRE_TIME;

               now_garbage = now.tv_sec - GARBAGE_TIME;

               /* deal with signals that should affect tracing */

               set_tracelevel();

               if (stopint != 0) {

                           rip_bcast(0);

                           rdisc_adv();

                           trace_off("exiting with signal %d\n", stopint);

                           exit(stopint | 128);

               }

               /* look for new or dead interfaces */

               timevalsub(&wtime, &ifinit_timer, &now);

               if (wtime.tv_sec <= 0) {

                           wtime.tv_sec = 0;

                           ifinit();

                           rip_query();

                           continue;

               }

               /* If it is time, then broadcast our routes.

                */

               if (supplier || advertise_mhome) {

                           timevalsub(&t2, &next_bcast, &now);

                           if (t2.tv_sec <= 0) {

                                       /* Synchronize the aging and broadcast

                                        * timers to minimize awakenings

                                        */

                                       age(0);

                                       rip_bcast(0);

                                       /* It is desirable to send routing updates

                                        * regularly. So schedule the next update

                                        * 30 seconds after the previous one was

                                        * secheduled, instead of 30 seconds after

                                        * the previous update was finished.

                                        * Even if we just started after discovering

                                        * a 2nd interface or were otherwise delayed,

                                        * pick a 30-second aniversary of the

                                        * original broadcast time.

                                        */

                                       n = 1 + (0-t2.tv_sec)/SUPPLY_INTERVAL;

                                       next_bcast.tv_sec += n*SUPPLY_INTERVAL;

                                       continue;

                           }

                           if (timercmp(&t2, &wtime, <))

                                       wtime = t2;

               }

               /* If we need a flash update, either do it now or

                * set the delay to end when it is time.

                *

                * If we are within MIN_WAITTIME seconds of a full update,

                * do not bother.

                */

               if (need_flash

                && supplier

                && no_flash.tv_sec+MIN_WAITTIME < next_bcast.tv_sec) {

                           /* accurate to the millisecond */

                           if (!timercmp(&no_flash, &now, >))

                                       rip_bcast(1);

                           timevalsub(&t2, &no_flash, &now);

                           if (timercmp(&t2, &wtime, <))

                                       wtime = t2;

               }

               /* trigger the main aging timer.

                */

               timevalsub(&t2, &age_timer, &now);

               if (t2.tv_sec <= 0) {

                           age(0);

                           continue;

               }

               if (timercmp(&t2, &wtime, <))

                           wtime = t2;

               /* update the kernel routing table

                */

               timevalsub(&t2, &need_kern, &now);

               if (t2.tv_sec <= 0) {

                           age(0);

                           continue;

               }

               if (timercmp(&t2, &wtime, <))

                           wtime = t2;

               /* take care of router discovery,

                * but do it to the millisecond

                */

               if (!timercmp(&rdisc_timer, &now, >)) {

                           rdisc_age(0);

                           continue;

               }

               timevalsub(&t2, &rdisc_timer, &now);

               if (timercmp(&t2, &wtime, <))

                           wtime = t2;

               /* wait for input or a timer to expire.

                */

               trace_flush();

               ibits = fdbits;

               n = select(sock_max, &ibits, 0, 0, &wtime);

               if (n <= 0) {

                           if (n < 0 && errno != EINTR && errno != EAGAIN)

                                       BADERR(1,"select");

                           continue;

               }

               if (FD_ISSET(rt_sock, &ibits)) {

                           read_rt();

                           n--;

               }

               if (rdisc_sock >= 0 && FD_ISSET(rdisc_sock, &ibits)) {

                           read_d();

                           n--;

               }

               if (rip_sock >= 0 && FD_ISSET(rip_sock, &ibits)) {

                           read_rip(rip_sock, 0);

                           n--;

               }

               for (ifp = ifnet; n > 0 && 0 != ifp; ifp = ifp->int_next) {

                           if (ifp->int_rip_sock >= 0

                            && FD_ISSET(ifp->int_rip_sock, &ibits)) {

                                       read_rip(ifp->int_rip_sock, ifp);

                                       n--;

                           }

               }

   }

}

/* ARGSUSED */

void

sigalrm(int s)

{

   /* Historically, SIGALRM would cause the daemon to check for

    * new and broken interfaces.

    */

   ifinit_timer.tv_sec = now.tv_sec;

   trace_act("SIGALRM");

}

/* watch for fatal signals */

void

sigterm(int sig)

{

   stopint = sig;

   (void)signal(sig, SIG_DFL);   /* catch it only once */

}

void

fix_select(void)

{

   struct interface *ifp;

   FD_ZERO(&fdbits);

   sock_max = 0;

   FD_SET(rt_sock, &fdbits);

   if (sock_max <= rt_sock)

               sock_max = rt_sock+1;

   if (rip_sock >= 0) {

               FD_SET(rip_sock, &fdbits);

               if (sock_max <= rip_sock)

                           sock_max = rip_sock+1;

   }

   for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) {

               if (ifp->int_rip_sock >= 0) {

                           FD_SET(ifp->int_rip_sock, &fdbits);

                           if (sock_max <= ifp->int_rip_sock)

                                       sock_max = ifp->int_rip_sock+1;

               }

   }

   if (rdisc_sock >= 0) {

               FD_SET(rdisc_sock, &fdbits);

               if (sock_max <= rdisc_sock)

                           sock_max = rdisc_sock+1;

   }

}

void

fix_sock(int sock,

    char *name)

{

   int on;

#define MIN_SOCKBUF (4*1024)

   static int rbuf;

   if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)

               logbad(1, "fcntl(%s) O_NONBLOCK: %s",

                name, strerror(errno));

   on = 1;

   if (setsockopt(sock, SOL_SOCKET,SO_BROADCAST, &on,sizeof(on)) < 0)

               msglog("setsockopt(%s,SO_BROADCAST): %s",

                name, strerror(errno));

#ifdef USE_PASSIFNAME

   on = 1;

   if (setsockopt(sock, SOL_SOCKET, SO_PASSIFNAME, &on,sizeof(on)) < 0)

               msglog("setsockopt(%s,SO_PASSIFNAME): %s",

                name, strerror(errno));

#endif

   if (rbuf >= MIN_SOCKBUF) {

               if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,

                            &rbuf, sizeof(rbuf)) < 0)

                           msglog("setsockopt(%s,SO_RCVBUF=%d): %s",

                            name, rbuf, strerror(errno));

   } else {

               for (rbuf = 60*1024; ; rbuf -= 4096) {

                           if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,

                                        &rbuf, sizeof(rbuf)) == 0) {

                                       trace_act("RCVBUF=%d", rbuf);

                                       break;

                           }

                           if (rbuf < MIN_SOCKBUF) {

                                       msglog("setsockopt(%s,SO_RCVBUF = %d): %s",

                                        name, rbuf, strerror(errno));

                                       break;

                           }

               }

   }

}

/* get a rip socket

*/

static int                                     /* <0 or file descriptor */

get_rip_sock(naddr addr,

    int serious)                  /* 1=failure to bind is serious */

{

   struct sockaddr_in sin;

   unsigned char ttl;

   int s;

   if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

               BADERR(1,"rip_sock = socket()");

   bzero(&sin,sizeof(sin));

#ifdef _HAVE_SIN_LEN

   sin.sin_len = sizeof(sin);

#endif

   sin.sin_family = AF_INET;

   sin.sin_port = htons(RIP_PORT);

   sin.sin_addr.s_addr = addr;

   if (bind(s, (struct sockaddr *)&sin,sizeof(sin)) < 0) {

               if (serious)

                           BADERR(errno != EADDRINUSE, "bind(rip_sock)");

               return -1;

   }

   fix_sock(s,"rip_sock");

   ttl = 1;

   if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,

                &ttl, sizeof(ttl)) < 0)

               DBGERR(1,"rip_sock setsockopt(IP_MULTICAST_TTL)");

   return s;

}

/* turn off main RIP socket */

void

rip_off(void)

{

   struct interface *ifp;

   register naddr addr;

   if (rip_sock >= 0 && !mhome) {

               trace_act("turn off RIP");

               (void)close(rip_sock);

               rip_sock = -1;

               /* get non-broadcast sockets to listen to queries.

                */

               for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {

                           if (ifp->int_state & IS_REMOTE)

                                       continue;

                           if (ifp->int_rip_sock < 0) {

                                       addr = ((ifp->int_if_flags & IFF_POINTOPOINT)

                                                   ? ifp->int_dstaddr

                                                   : ifp->int_addr);

                                       ifp->int_rip_sock = get_rip_sock(addr, 0);

                           }

               }

               fix_select();

               age(0);

   }

}

/* turn on RIP multicast input via an interface

*/

static void

rip_mcast_on(struct interface *ifp)

{

   struct ip_mreq m;

   if (!IS_RIP_IN_OFF(ifp->int_state)

    && (ifp->int_if_flags & IFF_MULTICAST)

#ifdef MCAST_PPP_BUG

    && !(ifp->int_if_flags & IFF_POINTOPOINT)

#endif

    && !(ifp->int_state & IS_ALIAS)) {

               m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP);

               m.imr_interface.s_addr = ((ifp->int_if_flags & IFF_POINTOPOINT)

                                                    ? ifp->int_dstaddr

                                                    : ifp->int_addr);

               if (setsockopt(rip_sock,IPPROTO_IP, IP_ADD_MEMBERSHIP,

                            &m, sizeof(m)) < 0)

                           LOGERR("setsockopt(IP_ADD_MEMBERSHIP RIP)");

   }

}

/* Prepare socket used for RIP.

*/

void

rip_on(struct interface *ifp)

{

   /* If the main RIP socket is already alive, only start receiving

    * multicasts for this interface.

    */

   if (rip_sock >= 0) {

               if (ifp != 0)

                           rip_mcast_on(ifp);

               return;

   }

   /* If the main RIP socket is off and it makes sense to turn it on,

    * then turn it on for all of the interfaces.

    */

   if (rip_interfaces > 0 && !rdisc_ok) {

               trace_act("turn on RIP");

               /* Close all of the query sockets so that we can open

                * the main socket. SO_REUSEPORT is not a solution,

                * since that would let two daemons bind to the broadcast

                * socket.

                */

               for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {

                           if (ifp->int_rip_sock >= 0) {

                                       (void)close(ifp->int_rip_sock);

                                       ifp->int_rip_sock = -1;

                           }

               }

               rip_sock = get_rip_sock(INADDR_ANY, 1);

               rip_sock_mcast = 0;

               /* Do not advertise anything until we have heard something

                */

               if (next_bcast.tv_sec < now.tv_sec+MIN_WAITTIME)

                           next_bcast.tv_sec = now.tv_sec+MIN_WAITTIME;

               for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) {

                           ifp->int_query_time = NEVER;

                           rip_mcast_on(ifp);

               }

               ifinit_timer.tv_sec = now.tv_sec;

   } else if (ifp != 0

                && !(ifp->int_state & IS_REMOTE)

                && ifp->int_rip_sock < 0) {

               /* RIP is off, so ensure there are sockets on which

                * to listen for queries.

                */

               ifp->int_rip_sock = get_rip_sock(ifp->int_addr, 0);

   }

   fix_select();

}

/* die if malloc(3) fails

*/

void *

rtmalloc(size_t size,

    char *msg)

{

   void *p = malloc(size);

   if (p == 0)

               logbad(1,"malloc() failed in %s", msg);

   return p;

}

/* get a random instant in an interval

*/

void

intvl_random(struct timeval *tp,           /* put value here */

    u_long lo,                               /* value is after this second */

    u_long hi)                               /* and before this */

{

   tp->tv_sec = (time_t)(hi == lo

                            ? lo

                            : (lo + random() % ((hi - lo))));

   tp->tv_usec = random() % 1000000;

}

void

timevaladd(struct timeval *t1,

    struct timeval *t2)

{

   t1->tv_sec += t2->tv_sec;

   if ((t1->tv_usec += t2->tv_usec) > 1000000) {

               t1->tv_sec++;

               t1->tv_usec -= 1000000;

   }

}

/* t1 = t2 - t3

*/

static void

timevalsub(struct timeval *t1,

    struct timeval *t2,

    struct timeval *t3)

{

   t1->tv_sec = t2->tv_sec - t3->tv_sec;

   if ((t1->tv_usec = t2->tv_usec - t3->tv_usec) < 0) {

               t1->tv_sec--;

               t1->tv_usec += 1000000;

   }

}

/* put a message into the system log

*/

void

msglog(char *p, ...)

{

   va_list args;

   trace_flush();

   va_start(args, p);

   vsyslog(LOG_ERR, p, args);

   if (ftrace != 0) {

               if (ftrace == stdout)

                           (void)fputs("routed: ", ftrace);

               (void)vfprintf(ftrace, p, args);

               (void)fputc('\n', ftrace);

   }

}

/* Put a message about a bad system into the system log if

* we have not complained about it recently.

*

* It is desirable to complain about all bad systems, but not too often.

* In the worst case, it is not practical to keep track of all bad systems.

* For example, there can be many systems with the wrong password.

*/

void

msglim(struct msg_limit *lim, naddr addr, char *p, ...)

{

   va_list args;

   int i;

   struct msg_sub *ms1, *ms;

   char *p1;

   va_start(args, p);

   /* look for the oldest slot in the table

    * or the slot for the bad router.

    */

   ms = ms1 = lim->subs;

   for (i = MSG_SUBJECT_N; ; i--, ms1++) {

               if (i == 0) {

                           /* Reuse a slot at most once every 10 minutes.

                            */

                           if (lim->reuse > now.tv_sec) {

                                       ms = 0;

                           } else {

                                       ms = ms1;

                                       lim->reuse = now.tv_sec + 10*60;

                           }

                           break;

               }

               if (ms->addr == addr) {

                           /* Repeat a complaint about a given system at

                            * most once an hour.

                            */

                           if (ms->until > now.tv_sec)

                                       ms = 0;

                           break;

               }

               if (ms->until < ms1->until)

                           ms = ms1;

   }

   if (ms != 0) {

               ms->addr = addr;

               ms->until = now.tv_sec + 60*60;       /* 60 minutes */

               trace_flush();

               for (p1 = p; *p1 == ' '; p1++)

                           continue;

               vsyslog(LOG_ERR, p1, args);

   }

   /* always display the message if tracing */

   if (ftrace != 0) {

               (void)vfprintf(ftrace, p, args);

               (void)fputc('\n', ftrace);

   }

}

void

logbad(int dump, char *p, ...)

{

   va_list args;

   trace_flush();

   va_start(args, p);

   vsyslog(LOG_ERR, p, args);

   (void)fputs("routed: ", stderr);

   (void)vfprintf(stderr, p, args);

   (void)fputs("; giving up\n",stderr);

   (void)fflush(stderr);

   if (dump)

               abort();

   exit(1);

}

Ñïèñîê ëèòåðàòóðû

Äëÿ ïîäãîòîâêè äàííîé ðàáîòû áûëè èñïîëüçîâàíû ìàòåðèàëû ñ ñàéòà http://www.referaty.com.ua/


Åùå èç ðàçäåëà Èíîñòðàííûé ÿçûê:


 Ýòî èíòåðåñíî
 Ðåêëàìà
 Ïîèñê ðåôåðàòîâ
 
 Àôîðèçì
Äàæå åñëè âàñ ñúåëè, ó âàñ åñòü äâà âûõîäà.
 Ãîðîñêîï
Ãîðîñêîïû
 Ñ÷¸ò÷èêè
bigmir)net TOP 100