এই পর্বে যা শিখবেন
- Distance vector-এর মূল ধারণা আর Bellman-Ford সমীকরণ — কেন তা সঠিক, তার ছোট প্রমাণসহ
- বিতরণকৃত, পুনরাবৃত্ত, asynchronous algorithm: কে কী রাখে, কখন পাঠায় (periodic আর triggered)
- পাঁচ router-এর নেটওয়ার্কে round ধরে প্রতিটি টেবিল হিসাব — পরীক্ষার ক্লাসিক প্রশ্ন, হাতে আর simulator-এ
- Count-to-infinity কেন হয়, আর split horizon, poison reverse, hold-down কতটা ঠেকায়
- RIPv1, RIPv2, RIPng, EIGRP-র DUAL, আর distance vector বনাম link state-এর তুলনা
১ · ধারণা — প্রতিবেশীর মুখে শোনা পথ
পর্ব ১৫-এ দেখেছেন, routing হলো control plane-এর কাজ: পুরো নেটওয়ার্ক মিলিয়ে প্রতিটি router-এর routing table ভরা। পর্ব ২২-এ দেখেছেন টেবিলের গঠন, হাতে বসানো static route, আর routing protocol-এর দুই বড় ভাগ — একটি প্রতিষ্ঠানের ভেতরের IGP আর প্রতিষ্ঠানগুলোর মাঝের EGP. এবার প্রশ্ন: router-রা নিজেরা কীভাবে টেবিল বানায়? দুটি বড় পরিবার আছে। এই পর্বে প্রথমটি — distance vector; পরের পর্বে দ্বিতীয়টি, link state.
পুরান ঢাকার অচেনা গলিতে আপনি সদরঘাট খুঁজছেন। হাতে মানচিত্র নেই। মোড়ের চায়ের দোকানদারকে জিজ্ঞেস করলেন। তিনিও পুরো শহরের মানচিত্র জানেন না; জানেন শুধু, “ডানের গলি দিয়ে গেলে লক্ষ্মীবাজারের মোড়, ওখান থেকে সদরঘাট দশ মিনিট — ওই মোড়ের লোকেরা তাই বলে।” তিনি পাশের মোড়গুলোর দাবি শুনেছেন, নিজের গলির হাঁটার সময় যোগ করেছেন, আর সবচেয়ে কমটি বলছেন। প্রতিটি মোড় একটি router, প্রতিটি গলি একটি link, আর “ওখান থেকে দশ মিনিট” হলো প্রতিবেশীর ঘোষণা করা দূরত্ব। কেউ পুরো ছবি দেখে না — সবাই প্রতিবেশীর কথায় বিশ্বাস করে।
এই বিশ্বাসই distance vector-এর শক্তি আর দুর্বলতা। শক্তি: প্রতিটি router-এর কাজ খুব সরল, মেমরি কম লাগে, কোনো কেন্দ্র লাগে না। দুর্বলতা: প্রতিবেশী পুরোনো বা ভুল খবর দিলে সেই ভুলও ছড়ায়। তাই এর ডাকনাম “routing by rumour” — গুজবে চলা routing.
নামের মানে সোজা। প্রতিটি router-এর কাছে একটি তালিকা থাকে: প্রতিটি গন্তব্যের দূরত্ব (distance). সেই তালিকাকে গণিতের ভাষায় একটি vector ধরা হয় — তাই distance vector. দূরত্ব মাপা হয় একটি metric দিয়ে: কখনো শুধু কতগুলো hop, কখনো link-এর খরচ, delay বা bandwidth থেকে হিসাব করা একটি সংখ্যা।
Router A-এর distance vector (গন্তব্য → দূরত্ব, পরের hop)
┌──────────┬────────┬──────────┐
│ গন্তব্য │ দূরত্ব │ next hop │
├──────────┼────────┼──────────┤
│ A │ 0 │ — │
│ B │ 1 │ B │
│ C │ 3 │ B │
│ D │ 6 │ B │
│ E │ 7 │ B │
└──────────┴────────┴──────────┘
প্রতিবেশীকে পাঠানো হয় শুধু প্রথম দুই কলাম: “আমার থেকে কে কত দূরে”
২ · Bellman-Ford সমীকরণ — একটি লাইনে পুরো যুক্তি
কিছু চিহ্ন ঠিক করি। নেটওয়ার্ককে একটি graph ধরুন: router হলো বিন্দু, link হলো রেখা। c(x,v) = router x থেকে প্রতিবেশী v-এর সরাসরি link-এর খরচ। dx(y) = x থেকে y পর্যন্ত সবচেয়ে কম খরচের পথের মোট খরচ। তাহলে:
বাংলায়: “y পর্যন্ত আমার সবচেয়ে ছোট পথ = প্রতিটি প্রতিবেশী v-এর জন্য (v পর্যন্ত আমার link-এর খরচ + v থেকে y-এর সবচেয়ে ছোট দূরত্ব) — এদের মধ্যে সবচেয়ে ছোটটি।” যে v-তে সবচেয়ে ছোট মান আসে, সেই v-ই y-এর জন্য x-এর next hop.
কেন সমীকরণটি সঠিক — ছোট প্রমাণ
x থেকে y-এর যেকোনো পথ প্রথমে x-এর কোনো একটি প্রতিবেশী v-তে যায়। দুটি দিক দেখাতে হবে।
- বাঁ দিক ≤ ডান দিক: যেকোনো প্রতিবেশী v-এর জন্য “x থেকে v, তারপর v-এর সবচেয়ে ছোট পথে y” একটি বৈধ পথ, যার খরচ c(x,v) + dv(y). সবচেয়ে ছোট পথ কোনো বৈধ পথের চেয়ে বেশি হতে পারে না।
- বাঁ দিক ≥ ডান দিক: ধরুন x থেকে y-এর সবচেয়ে ছোট পথের প্রথম hop v*. পথের বাকি অংশ v* থেকে y-এর একটি পথ, তাই তার খরচ অন্তত dv*(y). অতএব dx(y) ≥ c(x,v*) + dv*(y) ≥ ডান দিকের minimum.
দুই দিক মিলে সমতা। এর পেছনের নীতিটি optimal substructure: সবচেয়ে ছোট পথের প্রতিটি অংশও সবচেয়ে ছোট। (ধরে নেওয়া হচ্ছে খরচ ঋণাত্মক নয়, যা নেটওয়ার্কে সবসময় সত্য।) Graph algorithm হিসেবে Bellman-Ford-এর পূর্ণ রূপ আর তার জটিলতা দেখতে পারেন DSA কোর্সের Bellman-Ford আর Floyd-Warshall পর্বে।
সমীকরণটির নাম দুই গবেষকের নামে। Richard Bellman ১৯৫৮ সালে “On a Routing Problem” নামে একটি ছোট প্রবন্ধে dynamic programming দিয়ে সবচেয়ে ছোট পথের সমস্যা সমাধান করেন; Lester Ford Jr. কাছাকাছি সময়ে RAND Corporation-এ একই ধরনের পদ্ধতি দেন। সমীকরণটি যে একসাথে নয়, প্রতিটি বিন্দুতে আলাদাভাবে, প্রতিবেশীর তথ্য দিয়ে চালানো যায় — এই বিতরণকৃত রূপটিকে সাধারণত Ford আর Fulkerson-এর পরের কাজের সাথে যুক্ত করা হয়। ১৯৬৯ সালে চালু হওয়া ARPANET-এর প্রথম routing algorithm ছিল এই ধাঁচের distance vector, যেখানে দূরত্ব মাপা হতো queue-র দৈর্ঘ্য থেকে আন্দাজ করা delay দিয়ে।
এবার সমীকরণটি একটি router-এ চালিয়ে দেখি। নিচের পাঁচ router-এর নেটওয়ার্ক পুরো পর্বে ব্যবহার হবে (সংখ্যাগুলো link-এর খরচ):
A
1 ╱ ╲ 4
╱ ╲
B──2──C
│ ╱ ╲
7│ 3╱ ╲6
│ ╱ ╲
D────1────E
Link: A–B 1, A–C 4, B–C 2, B–D 7, C–D 3, C–E 6, D–E 1
শুরুতে (round ০) প্রতিটি router শুধু নিজের link-গুলো জানে। A-র vector: A = ০, B = ১, C = ৪, D = ∞, E = ∞ (∞ মানে “জানি না” বা “পৌঁছানো যায় না”). B আর C তাদের round ০-এর vector A-কে পাঠাল। A এখন সমীকরণটি প্রতিটি গন্তব্যে চালায়:
| গন্তব্য B | |
| গন্তব্য C | |
| গন্তব্য D | |
| গন্তব্য E | |
| A-র vector |
- শুরু: A-র হাতে তিনটি জিনিস। নিজের link-এর খরচ (B পর্যন্ত ১, C পর্যন্ত ৪), নিজের পুরোনো vector, আর দুই প্রতিবেশীর সদ্য পাওয়া vector. D আর E-এর সাথে A-র সরাসরি link নেই, তাই এখন ∞.
- গন্তব্য B. B হয়ে: ১ + ০ = ১. C হয়ে: ৪ + ২ = ৬. ছোটটি ১, next hop B — কিছু বদলাল না।
- গন্তব্য C — ঘুরপথ জিতল। সরাসরি link-এ ৪, কিন্তু B হয়ে ১ + ২ = ৩. তাই C-এর জন্য A এখন সরাসরি না পাঠিয়ে B-কে দেবে। সরাসরি link মানেই সবচেয়ে ছোট পথ নয়।
- গন্তব্য D — নতুন খবর। B হয়ে ১ + ৭ = ৮, C হয়ে ৪ + ৩ = ৭. A এই প্রথম D-এর কথা জানল: দূরত্ব ৭, next hop C.
- গন্তব্য E. B এখনো E চেনে না (∞), তাই B হয়ে ∞. C হয়ে ৪ + ৬ = ১০. দূরত্ব ১০, next hop C. এটি এখনো সবচেয়ে ছোট পথ নয় — পরের round-গুলোতে কমবে।
- Vector বদলেছে, তাই জানানো। নতুন vector [০ ১ ৩ ৭ ১০] পুরোনোর থেকে আলাদা, তাই A তা B আর C-কে পাঠায়। Vector না বদলালে নতুন করে পাঠানোর দরকার হতো না (শুধু নিয়মিত periodic update ছাড়া)।
৩ · বিতরণকৃত, পুনরাবৃত্ত, asynchronous — algorithm-টি
Distance vector algorithm-কে তিনটি বিশেষণে বর্ণনা করা হয়, আর পরীক্ষায় এই তিনটিই প্রায়ই জিজ্ঞেস করা হয়:
- বিতরণকৃত (distributed): প্রতিটি router শুধু সরাসরি প্রতিবেশীর কাছ থেকে তথ্য পায়, হিসাব করে, আর ফল শুধু প্রতিবেশীকে জানায়। কোনো router পুরো topology জানে না।
- পুনরাবৃত্ত (iterative): বিনিময় আর হিসাব চলতেই থাকে, যতক্ষণ না কারও কাছে নতুন কিছু বলার থাকে। তারপর algorithm নিজে থেমে যায় — কেউ আলাদা করে থামার সংকেত দেয় না।
- Asynchronous: সব router একসাথে ঘড়ি মিলিয়ে কাজ করে না। যার কাছে যখন নতুন vector আসে, সে তখন হিসাব করে।
প্রতিটি router x তিনটি জিনিস রাখে: (১) প্রতিটি প্রতিবেশী v পর্যন্ত link-এর খরচ c(x,v); (২) নিজের distance vector Dx = [Dx(y) : প্রতিটি গন্তব্য y]; (৩) প্রতিটি প্রতিবেশীর সবশেষ পাওয়া vector Dv. পুরো algorithm:
প্রতিটি router x-এ:
শুরু: প্রতিটি গন্তব্য y-এর জন্য
D_x(y) = c(x,y) (y প্রতিবেশী হলে), নইলে ∞; D_x(x) = 0
নিজের vector সব প্রতিবেশীকে পাঠানো
চিরকাল:
অপেক্ষা — (ক) কোনো link-এর খরচ বদলাল, বা
(খ) কোনো প্রতিবেশী নতুন vector পাঠাল, বা
(গ) periodic timer বাজল
প্রতিটি গন্তব্য y-এর জন্য:
D_x(y) = min over v { c(x,v) + D_v(y) }, next_hop(y) = সেই v
যদি কোনো D_x(y) বদলে থাকে → সব প্রতিবেশীকে নতুন vector পাঠানো (triggered)
timer বাজলে → বদল না হলেও vector পাঠানো (periodic)
কখন পাঠাবে — periodic আর triggered update
Periodic update
নির্দিষ্ট বিরতিতে (RIP-এ ৩০ সেকেন্ড) পুরো vector পাঠানো, কিছু না বদলালেও। এটি “আমি বেঁচে আছি” সংকেতও: অনেকক্ষণ কোনো প্রতিবেশীর update না এলে তার দেওয়া route বাতিল ধরা হয়।
নিয়মিত · নিরাপদ, কিন্তু ধীরTriggered update
Vector বদলালেই সাথে সাথে পাঠানো, পরের timer-এর অপেক্ষা না করে। খবর দ্রুত ছড়ায়। কিন্তু বদলের ঝড়ে বার্তার বন্যা যেন না হয়, তাই RIP-এ triggered update-এর মাঝে ১ থেকে ৫ সেকেন্ডের এলোমেলো বিরতি রাখার নিয়ম।
দ্রুত · কিন্তু সীমিত হারেকেন শেষ পর্যন্ত থামে — convergence-এর যুক্তি
সব router যদি একসাথে round ধরে কাজ করে (synchronous মডেল, পরীক্ষার হিসাবে এটিই ধরা হয়), তাহলে একটি সুন্দর সত্য প্রমাণ করা যায়: round k-এর পর প্রতিটি Dx(y) হলো সর্বোচ্চ k + ১টি link ব্যবহার করা পথগুলোর মধ্যে সবচেয়ে ছোটটির খরচ। Round ০-এ এটি সত্য (শুধু ১ link-এর পথ)। Round k-তে সত্য হলে round k + ১-এ x প্রতিবেশী v-এর “k + ১ link পর্যন্ত” মানের সাথে ১টি link যোগ করছে — ঠিক k + ২ link পর্যন্ত পথ। N টি router-এর নেটওয়ার্কে কোনো সবচেয়ে ছোট পথে N − ১-এর বেশি link থাকে না (থাকলে কোনো router দুবার আসত, অর্থাৎ একটি loop, যা বাদ দিলে খরচ কমে বা সমান থাকে)। তাই সর্বোচ্চ N − ২ round-এ সব ঠিক হয়ে যায়, আর পরের round-এ কিছুই বদলায় না — সেটিই থামার সংকেত। Router-রা asynchronous হলেও, খরচ স্থির থাকলে আর বার্তা শেষ পর্যন্ত পৌঁছালে algorithm একই উত্তরে পৌঁছায় — Bertsekas আর Gallager-এর “Data Networks” বইয়ে এর প্রমাণ আছে। এই স্থির অবস্থায় পৌঁছানোকে বলে convergence.
৪ · পূর্ণ উদাহরণ — round ধরে পাঁচটি টেবিল
বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় সবচেয়ে প্রচলিত প্রশ্ন: “এই graph-এ distance vector চালান; প্রতিটি round-এর পর প্রতিটি router-এর টেবিল দেখান।” আগের পাঁচ router-এর নেটওয়ার্কে synchronous মডেলে হিসাব করি: প্রতি round-এ সবাই আগের round-এর vector পাঠায়, তারপর সবাই একসাথে নতুন করে হিসাব করে। প্রতিটি ঘরে লেখা “দূরত্ব (next hop)”; এই round-এ বদলানো ঘর মোটা অক্ষরে।
| Router | → A | → B | → C | → D | → E |
|---|---|---|---|---|---|
| A | 0 | 1 (B) | 4 (C) | ∞ | ∞ |
| B | 1 (A) | 0 | 2 (C) | 7 (D) | ∞ |
| C | 4 (A) | 2 (B) | 0 | 3 (D) | 6 (E) |
| D | ∞ | 7 (B) | 3 (C) | 0 | 1 (E) |
| E | ∞ | ∞ | 6 (C) | 1 (D) | 0 |
প্রত্যেকে শুধু সরাসরি প্রতিবেশীকে চেনে। পাঁচটি ∞ — A আর E একে অপরকে চেনে না, A–D আর B–E-ও না।
| Router | → A | → B | → C | → D | → E |
|---|---|---|---|---|---|
| A | 0 | 1 (B) | 3 (B) | 7 (C) | 10 (C) |
| B | 1 (A) | 0 | 2 (C) | 5 (C) | 8 (C) |
| C | 3 (B) | 2 (B) | 0 | 3 (D) | 4 (D) |
| D | 7 (C) | 5 (C) | 3 (C) | 0 | 1 (E) |
| E | 10 (C) | 8 (C) | 4 (D) | 1 (D) | 0 |
এখন প্রত্যেকে সর্বোচ্চ ২ link-এর পথ জানে। ∞ আর নেই। A-র সারিটি stepper-এর ফল। লক্ষ করুন C → E: সরাসরি ৬-এর বদলে D হয়ে ৩ + ১ = ৪.
| Router | → A | → B | → C | → D | → E |
|---|---|---|---|---|---|
| A | 0 | 1 (B) | 3 (B) | 6 (B) | 8 (C) |
| B | 1 (A) | 0 | 2 (C) | 5 (C) | 6 (C) |
| C | 3 (B) | 2 (B) | 0 | 3 (D) | 4 (D) |
| D | 6 (C) | 5 (C) | 3 (C) | 0 | 1 (E) |
| E | 8 (D) | 6 (D) | 4 (D) | 1 (D) | 0 |
A → D: B হয়ে ১ + ৫ = ৬ (B round ১-এ শিখেছিল D = ৫). A → E এখনো C হয়ে ৪ + ৪ = ৮; B হয়ে হতো ১ + ৮ = ৯, কারণ B-এর round ১-এর E-মান ছিল ৮.
| Router | → A | → B | → C | → D | → E |
|---|---|---|---|---|---|
| A | 0 | 1 (B) | 3 (B) | 6 (B) | 7 (B) |
| B | 1 (A) | 0 | 2 (C) | 5 (C) | 6 (C) |
| C | 3 (B) | 2 (B) | 0 | 3 (D) | 4 (D) |
| D | 6 (C) | 5 (C) | 3 (C) | 0 | 1 (E) |
| E | 7 (D) | 6 (D) | 4 (D) | 1 (D) | 0 |
A → E শেষ পর্যন্ত ৭: A–B–C–D–E, ১ + ২ + ৩ + ১, চারটি link — তাই round ৩-এ (৪ link = ৩ + ১). Round ৪-এ কিছুই বদলায় না: convergence. N = ৫, তাই সীমা ছিল N − ২ = ৩ round-এ সব ঠিক হওয়া — ঠিক তাই হলো।
লক্ষ করুন A → E-এর মান: ∞ → ১০ → ৮ → ৭. প্রতিটি round-এ পথ একটি করে link লম্বা হওয়ার সুযোগ পায়, আর দূরত্ব শুধু কমে। এই হিসাব simulator-এ চালাই। কোডটি ঠিক উপরের নিয়ম মানে: প্রতি round-এ প্রত্যেকে আগের round-এর (old) vector দেখে নতুন হিসাব করে, আর কোনো মান না বদলালে থামে।
// Synchronous distance vector: once per round every router sends its vector
// to its neighbours, then every router recomputes with Bellman-Ford.
const links = [["A","B",1], ["A","C",4], ["B","C",2], ["B","D",7],
["C","D",3], ["C","E",6], ["D","E",1]];
const R = ["A", "B", "C", "D", "E"];
const cost = {}; // cost[x][v] = cost of link x--v
R.forEach(x => cost[x] = {});
links.forEach(([u, v, c]) => { cost[u][v] = c; cost[v][u] = c; });
let D = {}; const hop = {}; // D[x][y] = distance, hop[x][y] = next hop
R.forEach(x => { D[x] = {}; hop[x] = {};
R.forEach(y => { D[x][y] = x === y ? 0 : (cost[x][y] ?? Infinity);
hop[x][y] = cost[x][y] !== undefined ? y : "-"; }); });
const fmt = d => (d === Infinity ? "inf" : String(d)).padStart(5);
function show(r) {
console.log("round " + r + " to:" + R.map(y => y.padStart(5)).join(""));
R.forEach(x => console.log(" " + x + " knows " + R.map(y => fmt(D[x][y])).join("")));
}
show(0);
for (let r = 1; ; r++) {
const old = D; let changed = false; D = {};
R.forEach(x => { D[x] = {};
R.forEach(y => {
if (x === y) { D[x][y] = 0; return; }
let best = Infinity; // d_x(y) = min over v of c(x,v) + d_v(y)
for (const v in cost[x]) {
const via = cost[x][v] + old[v][y];
if (via < best) { best = via; hop[x][y] = v; }
}
D[x][y] = best; if (best !== old[x][y]) changed = true;
}); });
if (!changed) { console.log("round " + r + ": nothing changed -> converged"); break; }
show(r);
}
R.forEach(x => console.log("next hops of " + x + ": " +
R.filter(y => y !== x).map(y => y + "->" + hop[x][y]).join(" ")));আউটপুট:
round 0 to: A B C D E
A knows 0 1 4 inf inf
B knows 1 0 2 7 inf
C knows 4 2 0 3 6
D knows inf 7 3 0 1
E knows inf inf 6 1 0
round 1 to: A B C D E
A knows 0 1 3 7 10
B knows 1 0 2 5 8
C knows 3 2 0 3 4
D knows 7 5 3 0 1
E knows 10 8 4 1 0
round 2 to: A B C D E
A knows 0 1 3 6 8
B knows 1 0 2 5 6
C knows 3 2 0 3 4
D knows 6 5 3 0 1
E knows 8 6 4 1 0
round 3 to: A B C D E
A knows 0 1 3 6 7
B knows 1 0 2 5 6
C knows 3 2 0 3 4
D knows 6 5 3 0 1
E knows 7 6 4 1 0
round 4: nothing changed -> converged
next hops of A: B->B C->B D->B E->B
next hops of B: A->A C->C D->C E->C
next hops of C: A->B B->B D->D E->D
next hops of D: A->C B->C C->C E->E
next hops of E: A->D B->D C->D D->D
Round ০ থেকে ৩-এর টেবিল হুবহু উপরের হাতের হিসাবের সাথে মেলে, আর round 4: nothing changed -> converged — চতুর্থ round-এ কেউ নতুন কিছু শেখেনি। শেষের পাঁচ লাইন হলো প্রতিটি router-এর forwarding table: A সবকিছু B-কে দেয় (C->B D->B E->B), E সবকিছু D-কে। ফলে A থেকে E-এর packet যায় A → B → C → D → E — প্রতিটি router শুধু নিজের next hop জানে, তবু মিলে পুরো সবচেয়ে ছোট পথ তৈরি হয়। নিজে চেষ্টা করুন: ["C","E",6]-কে ["C","E",1] করে চালান — A → E কত হবে আর কত round লাগবে, আগে খাতায় ভাবুন।
সাবধান — পরীক্ষার খাতায় মডেলটি লিখে দিন: বইভেদে “round” গোনার ধরন আলাদা — কেউ শুরুর অবস্থাকে round ০ বলেন, কেউ ১; কেউ asynchronous ঘটনা ধরে একটি একটি করে বার্তা গোনেন। তাই উত্তরের শুরুতে লিখে দিন “synchronous মডেল, round ০ = শুধু সরাসরি link”. তাহলে সংখ্যা সামান্য আলাদা হলেও যুক্তি স্পষ্ট থাকে।
৫ · ভালো খবর দ্রুত, খারাপ খবর ধীরে — count-to-infinity
Convergence-এর প্রমাণ ধরে নিয়েছিল খরচ স্থির। বাস্তবে link-এর খরচ বদলায়, link নষ্টও হয়। তখন যা ঘটে, তা distance vector-এর সবচেয়ে বিখ্যাত দুর্বলতা।
ভালো খবর: খরচ কমলে
তিন router x, y, z: c(x,y) = ৪, c(y,z) = ১, c(x,z) = ৫০. গন্তব্য x. স্থির অবস্থায় y → x = ৪ (সরাসরি), z → x = ৫ (y হয়ে). এখন c(x,y) কমে ১ হলো। Round ১-এ y দেখে সরাসরি ১, জানিয়ে দেয়। Round ২-এ z হিসাব করে ১ + ১ = ২. Round ৩-এ কিছু বদলায় না। দুই round-এই সবাই জানল। ভালো খবর সবচেয়ে ছোট পথ ধরে এক round-এ এক hop করে ছড়ায়, কারণ কম মান সবসময় পুরোনো বেশি মানকে হারিয়ে দেয়।
খারাপ খবর: খরচ বাড়লে বা link নষ্ট হলে
একই নেটওয়ার্কে এবার c(x,y) বেড়ে ৬০ হলো। y দেখে: সরাসরি এখন ৬০, কিন্তু z তো বলেছিল “x আমার থেকে ৫”! y জানে না যে z-এর সেই ৫ আসলে y-এর নিজের ওপর দিয়েই। তাই y ধরে নেয় z হয়ে ১ + ৫ = ৬. z তখন y-এর নতুন ৬ শুনে নিজেকে ৭ করে, y তারপর ৮… দুজনে একে অপরের পুরোনো খবরে ভর করে প্রতি দুই round-এ ২ করে বাড়ায়। থামে তখনই, যখন z-এর হিসাবে y হয়ে খরচ সরাসরি link-এর ৫০ ছাড়িয়ে যায়। এই পর্বের synchronous মডেলে (round ১-এ y = ৬, শেষ বদল পর্যন্ত গুনে) বদল চলে ৪৭ round: round ৪৬-এ z সরাসরি ৫০-এ ফেরে, round ৪৭-এ y হয় ৫১ (z হয়ে), আর round ৪৮-এ কিছুই বদলায় না। Kurose ও Ross-এর পাঠ্যবইয়ে ঠিক এই উদাহরণের জন্য বলা আছে প্রায় ৪৪টি iteration (y আর z-এর বার্তা বিনিময়) — সেখানে গোনার ধরন আলাদা, তাই দুই সংখ্যা মেলানোর দরকার নেই। মূল কথা একই: দূরত্বের ফারাক যত বড়, তত বেশি round. আর এই পুরো সময় y আর z-এর মাঝে x-গামী packet একটি routing loop-এ ঘুরতে থাকে, যতক্ষণ না TTL শেষ হয় (পর্ব ২০)।
সবচেয়ে খারাপ অবস্থা: link পুরোপুরি নষ্ট আর কোনো বিকল্প পথই নেই। তখন থামার কোনো “৫০” নেই — দূরত্ব বাড়তেই থাকে অসীমের দিকে। একেই বলে count-to-infinity. সবচেয়ে সহজ উদাহরণ: তিনটি router একটি লাইনে, A — B — C, প্রতিটি link-এর খরচ ১ (hop count), গন্তব্য C.
- A
C-এর পথ: B হয়েপ্রতিবেশী শুধু B - B
C-এর পথ: সরাসরিপ্রতিবেশী A, C - C
B–C link নষ্টগন্তব্য
| B-র টেবিল | |
| A-র টেবিল | |
| A বলছে B-কে | |
| C-গামী packet | |
| Round |
- আগে: সব ঠিক। B → C সরাসরি ১. A → C, B হয়ে ২. A নিয়মিত B-কে বলে “C আমার থেকে ২”. কিন্তু সেই ২-এর পথ যে B-এর ওপর দিয়েই, তা A-র ঘোষণায় লেখা থাকে না — distance vector-এ শুধু দূরত্ব যায়, পথ নয়।
- B–C link নষ্ট। B নিজের interface-এ টের পেল সরাসরি পথ নেই। A এখনো কিছু জানে না, আর তার শেষ ঘোষণা “C = ২” B-এর কাছে জমা আছে।
- Round ১: B গুজব বিশ্বাস করল। B-এর একমাত্র বিকল্প A, আর A বলেছে C = ২. তাই B: ১ + ২ = ৩, next hop A. অথচ A-র ২ ছিল B-এর ওপর ভর করেই! এখন C-গামী packet A থেকে B, B থেকে A — loop.
- Round ২: A ঠিক করল। A শুনল B বলছে C = ৩. A-র একমাত্র পথ B, তাই A: ১ + ৩ = ৪. কেউ ভুল নিয়ম মানছে না — প্রত্যেকে Bellman-Ford ঠিকঠাক চালাচ্ছে, শুধু তথ্যটি বাসি।
- Round ৩: আবার B. B: ১ + ৪ = ৫. এই ঢঙে প্রতি দুই round-এ দুজনের মান ২ করে বাড়ে। প্রতিটি round-এ C-এর জন্য দুজনই একে অপরকে next hop ধরে আছে।
- Round ১৪: A ছুঁলো ১৬. B-এর মান ১৫ ছিল, A: ১ + ১৫ = ১৬. RIP-এ ১৬ মানে অসীম, অর্থাৎ পৌঁছানো যায় না। A route বাতিল করল।
- Round ১৫: B-ও ১৬ — অবশেষে শান্তি। B শুনল A বলছে ১৬, তাই B: min(১৬, ১ + ১৬) = ১৬. মোট ১৫ round. শুধু ৩০ সেকেন্ডের periodic update থাকলে সেটি কয়েক মিনিটের ব্যাপার; এই পুরো সময় packet loop-এ ঘুরে TTL শেষ করে। অসীমকে ছোট (১৬) রাখার কারণেই গোনা থামল — নইলে চলতেই থাকত।
কত round লাগে — ছোট হিসাব
Link-এর খরচ ১ আর অসীম = I ধরুন। ঘটনার পর round r-এ (r বিজোড় হলে B, জোড় হলে A) যার মান বদলায়, তার মান হয় r + ২: B-এর ৩, ৫, ৭…; A-র ৪, ৬, ৮… A-র মান I ছোঁয় যখন r + ২ = I, অর্থাৎ r = I − ২; পরের round-এ B. মোট I − ১ round — RIP-এ ১৫. সাধারণভাবে, loop-এর দুই প্রান্তের link-খরচ যত কম আর অসীম (বা বিকল্প পথের খরচ) যত বড়, তত বেশি round. তাই খারাপ খবরের ক্ষেত্রে convergence-এর সময়ের কোনো ভালো সীমা নেই, যেখানে ভালো খবর N − ২ round-এর মধ্যে পৌঁছায়।
নিচের simulator দুটি ঘটনা পাশাপাশি চালায়: সাধারণ distance vector, আর poison reverse (পরের অংশে বিস্তারিত) চালু করে। tell() ঠিক করে একজন প্রতিবেশীকে কী দূরত্ব বলা হবে।
// Line A --1-- B --1-- C, metric = hop count, destination C.
// At time 0 the link B--C fails. In every round each router recomputes from
// the distance its neighbour told it in the previous round.
const INF = 16; // RIP: 16 means unreachable
function run(poison) {
let A = { d: 2, via: "B" }, B = { d: 1, via: "C" }; // converged before failure
// poison reverse: never tell a neighbour a real distance if you route via it
const tell = (r, to) => (poison && r.via === to ? INF : r.d);
let aHears = tell(B, "A"), bHears = tell(A, "B");
const rows = [];
for (let round = 1; round <= 20; round++) {
const nb = Math.min(INF, 1 + bHears); // B's only neighbour now: A
const na = Math.min(INF, 1 + aHears); // A's only neighbour: B
const nA = { d: na, via: na < INF ? "B" : "-" };
const nB = { d: nb, via: nb < INF ? "A" : "-" };
if (nA.d === A.d && nB.d === B.d) break; // nothing changed: stable
A = nA; B = nB; rows.push([A, B]);
aHears = tell(B, "A"); bHears = tell(A, "B");
}
return rows;
}
const show = r => r ? (r.d + "(" + r.via + ")").padEnd(7) : "".padEnd(7);
const plain = run(false), poisoned = run(true);
console.log("round | plain DV: A B | poison reverse: A B");
plain.forEach((p, i) => {
const q = poisoned[i] || [];
console.log(String(i + 1).padStart(5) + " | " + show(p[0]) + show(p[1]) +
("| " + show(q[0]) + show(q[1])).trimEnd());
});
console.log("plain DV needed " + plain.length + " rounds, poison reverse " +
poisoned.length + " rounds to reach " + INF + " (unreachable)");আউটপুট:
round | plain DV: A B | poison reverse: A B
1 | 2(B) 3(A) | 2(B) 16(-)
2 | 4(B) 3(A) | 16(-) 16(-)
3 | 4(B) 5(A) |
4 | 6(B) 5(A) |
5 | 6(B) 7(A) |
6 | 8(B) 7(A) |
7 | 8(B) 9(A) |
8 | 10(B) 9(A) |
9 | 10(B) 11(A) |
10 | 12(B) 11(A) |
11 | 12(B) 13(A) |
12 | 14(B) 13(A) |
13 | 14(B) 15(A) |
14 | 16(-) 15(A) |
15 | 16(-) 16(-) |
plain DV needed 15 rounds, poison reverse 2 rounds to reach 16 (unreachable)
বাঁ দিকের কলাম stepper-এর গল্প: B আর A পালা করে ৩, ৪, ৫, ৬… করে উঠছে (বন্ধনীতে next hop — দুজন দুজনকে দেখাচ্ছে, অর্থাৎ loop), round ১৪-এ A ১৬, round ১৫-এ B ১৬; শেষ লাইন বলছে plain DV needed 15 rounds — ঠিক I − ১. ডান দিকে poison reverse: round ১-এই B সরাসরি 16(-), round ২-এ A-ও — poison reverse 2 rounds, কোনো loop নেই। run() থেকে বেরোনোর শর্ত “কিছুই বদলায়নি”, তাই ডান কলাম দুই সারির পরে ফাঁকা।
৬ · প্রতিকার — split horizon, poison reverse, অসীম ১৬, hold-down
সমস্যার মূল: A, B-কে এমন একটি পথের কথা বলছে যা B-এর ওপর দিয়েই যায়। কয়েকটি কৌশল মিলে এটি কমানো হয়।
| কৌশল | নিয়ম | কী ঠেকায় | সীমা |
|---|---|---|---|
| Split horizon | যে প্রতিবেশীর কাছ থেকে route শিখেছেন, তাকে সেই route আর ঘোষণা না করা | দুই router-এর loop (A ⇄ B) | B ঘোষণা না পেয়ে route পুরোনো হওয়া পর্যন্ত (timeout) অপেক্ষা করে |
| Poison reverse | চুপ না থেকে সেই প্রতিবেশীকে স্পষ্ট বলা “আমার থেকে এটি ∞ (১৬)” | দুই router-এর loop, timeout-এর অপেক্ষা ছাড়াই | বার্তা বড় হয়; তিন বা বেশি router-এর loop ঠেকায় না |
| ছোট অসীম | RIP-এ metric ১৬ = পৌঁছানো যায় না | গোনা অনন্তকাল চলা | নেটওয়ার্কের ব্যাস সর্বোচ্চ ১৫ hop |
| Triggered update | বদল হলেই সাথে সাথে জানানো | খারাপ খবর ৩০ সেকেন্ড বসে থাকা | বার্তা পথে হারালে বা একসাথে আসলে loop তবু হতে পারে |
| Hold-down timer | Route নষ্ট ঘোষণার পর কিছু সময় সেই গন্তব্যের অন্য, বেশি খরচের খবর গ্রহণ না করা | বাসি “ভালো” খবরে ফেরত বিশ্বাস | সত্যিকারের বিকল্প পথও দেরিতে নেয়; এটি মূলত vendor-এর বাস্তবায়ন (যেমন Cisco), RIP-এর RFC-তে বাধ্যতামূলক নয় |
দুটি শব্দ গুলিয়ে ফেলবেন না: route poisoning মানে যে router-এর route নষ্ট হলো, সে নিজেই সবাইকে metric ১৬ দিয়ে তা ঘোষণা করে; poison reverse মানে প্রতিবেশীকে তারই দিকের পথের জন্য ১৬ বলা। এবার poison reverse একই A — B — C লাইনে:
| A বলছে B-কে | |
| B-র টেবিল | |
| B বলছে A-কে | |
| A-র টেবিল | |
| Loop? |
- আগে থেকেই বিষ দেওয়া। A-র C-এর পথ B হয়ে, তাই A নিয়মিত B-কে বলে “C আমার থেকে ১৬”. B-এর চোখে A দিয়ে C-তে যাওয়ার কোনো পথ কখনো ছিলই না। অন্যদিকে B-এর পথ সরাসরি, তাই B, A-কে সত্যি দূরত্ব ১ বলে।
- B–C link নষ্ট। B-এর সরাসরি পথ গেল। এবার B-এর কাছে জমা আছে শুধু A-র “C = ১৬”.
- Round ১: B সাথে সাথে বুঝল। A হয়ে ১ + ১৬ = ১৬, অর্থাৎ পৌঁছানো যায় না। কোনো ভুল বিকল্প নেই, তাই কোনো loop-ও নেই। B, triggered update-এ A-কে জানাল “C = ১৬”.
- Round ২: A-ও বুঝল। A-র একমাত্র পথ B, আর B বলছে ১৬: ১ + ১৬ = ১৬. A-ও route বাতিল করল।
- Round ৩: কিছু বদলায় না। মাত্র দুই round-এ convergence — আগে লেগেছিল ১৫. শুধু split horizon (চুপ থাকা) হলেও এখানে ফল একই, কারণ B-এর কাছে A-র কোনো ঘোষণাই থাকত না; পার্থক্য হলো poison reverse “নেই” কথাটি স্পষ্ট করে বলে, ফলে কোনো পুরোনো ঘোষণা timeout-এর অপেক্ষায় পড়ে থাকে না।
যেখানে poison reverse হার মানে — তিন router-এর loop
Poison reverse শুধু “যে আমাকে route দিয়েছে, তাকে ফেরত বলব না” — অর্থাৎ শুধু দুই router-এর loop ভাঙে। তিনটি router একটি ত্রিভুজে থাকলে গুজব ঘুরপথে ফেরে। নিচের নেটওয়ার্কে A, B, C একটি ত্রিভুজ, আর D যুক্ত শুধু C-এর সাথে; সব link-এর খরচ ১. A আর B দুজনেই D-তে যায় C হয়ে (দূরত্ব ২)। এবার C–D link নষ্ট:
A ─── B
╲ ╱
╲ ╱
C ──✂── D গন্তব্য D · poison reverse সব জায়গায় চালু
// Triangle A-B-C with router D hanging off C; every link costs 1 (hops).
// Destination D. Split horizon with poison reverse is ON everywhere.
// At time 0 the link C--D fails.
const INF = 16;
const nbr = { A: ["B", "C"], B: ["A", "C"], C: ["A", "B"] }; // after failure
let st = { A: { d: 2, via: "C" }, B: { d: 2, via: "C" }, C: { d: 1, via: "D" } };
const advert = (from, to) => (st[from].via === to ? INF : st[from].d);
const heard = {}; // heard[x][v] = distance v last told x
for (const x in nbr) { heard[x] = {}; nbr[x].forEach(v => heard[x][v] = advert(v, x)); }
const show = r => console.log(String(r).padStart(5) + " " +
["A", "B", "C"].map(x => (st[x].d + " via " + st[x].via).padEnd(11)).join("").trimEnd());
console.log("round A B C");
show(0);
for (let r = 1; r <= 25; r++) {
const next = {};
for (const x in nbr) {
let best = { d: INF, via: "-" };
nbr[x].forEach(v => {
const c = Math.min(INF, 1 + heard[x][v]);
if (c < best.d) best = { d: c, via: v };
});
next[x] = best;
}
const same = Object.keys(st).every(x => st[x].d === next[x].d && st[x].via === next[x].via);
if (same) { console.log("round " + r + ": no change, all three say 16"); break; }
st = next; show(r);
for (const x in nbr) nbr[x].forEach(v => heard[x][v] = advert(v, x));
}আউটপুট:
round A B C
0 2 via C 2 via C 1 via D
1 2 via C 2 via C 16 via -
2 3 via B 3 via A 16 via -
3 16 via - 16 via - 4 via A
4 16 via - 5 via C 16 via -
5 6 via B 16 via - 16 via -
6 16 via - 16 via - 7 via A
7 16 via - 8 via C 16 via -
8 9 via B 16 via - 16 via -
9 16 via - 16 via - 10 via A
10 16 via - 11 via C 16 via -
11 12 via B 16 via - 16 via -
12 16 via - 16 via - 13 via A
13 16 via - 14 via C 16 via -
14 15 via B 16 via - 16 via -
15 16 via - 16 via - 16 via -
round 16: no change, all three say 16
Round ১: C-এর কাছে A আর B দুজনেই বিষ দেওয়া ঘোষণা পাঠিয়েছিল (তাদের পথ C হয়ে), তাই C সঠিকভাবে ১৬. Round ২: সমস্যা শুরু। A শুনেছে C = ১৬, কিন্তু B-এর শেষ ঘোষণা “D = ২” — B-এর পথ C হয়ে, A হয়ে নয়, তাই B, A-কে বিষ দেয়নি! A ধরে নিল B হয়ে ৩; একইভাবে B ধরল A হয়ে ৩. Round ৩: A আর B এখন একে অপরকে বিষ দেয়, তাই দুজনেই ১৬ — কিন্তু ততক্ষণে A, C-কে বলে ফেলেছে “৩” (A-র পথ তখন B হয়ে, C হয়ে নয়, তাই C-কে বিষ দেয়নি)। C নিল 4 via A. তারপর গুজবটি ত্রিভুজ ঘুরে চলে: 5 via C (B), 6 via B (A), 7 via A (C)… প্রতি পাক ৩ করে বাড়ে, round ১৪-এ A ১৫, round ১৫-এ সবাই ১৬, আর round ১৬-এ no change. এখানে বাঁচিয়েছে শুধু “অসীম = ১৬” — poison reverse নয়। RIP-এর মান (RFC 2453)-ও স্বীকার করে যে split horizon তিন বা বেশি router জড়িত loop ঠেকায় না।
Distance vector-এ শুধু দূরত্ব যায়, পথ যায় না — তাই কেউ বুঝতে পারে না যে প্রতিবেশীর “ভালো খবর” তার নিজের ওপর দিয়েই আসছে। Split horizon আর poison reverse দুই router-এর ক্ষেত্রে এটি ঠেকায়, ছোট অসীম ক্ষতির সময় সীমিত রাখে। পুরো সমাধানের দুটি পথ: পুরো পথ পাঠানো (BGP-র path vector, পর্ব ২৫), অথবা loop-মুক্ত হওয়ার শর্ত যাচাই করা (EIGRP-র DUAL, অংশ ৮)।
৭ · RIP বাস্তবে — v1, v2, RIPng আর timer
RIP (Routing Information Protocol) distance vector-এর সবচেয়ে পরিচিত রূপ। এর শিকড় Xerox-এর XNS নেটওয়ার্কের একটি protocol-এ; আশির দশকে BSD Unix-এর routed প্রোগ্রামের মাধ্যমে এটি ব্যাপকভাবে ছড়ায়, আর ১৯৮৮ সালে RFC 1058-এ লিখিত মান পায়। Metric = hop count: প্রতিটি router পেরোলে ১; ১৬ মানে অসীম।
| বিষয় | RIPv1 | RIPv2 | RIPng |
|---|---|---|---|
| মূল RFC | RFC 1058 (১৯৮৮) | RFC 2453 (১৯৯৮; আগের খসড়া RFC 1388, 1723) | RFC 2080 (১৯৯৭) |
| ঠিকানা | IPv4, classful — subnet mask পাঠায় না | IPv4, প্রতিটি route-এর সাথে mask (CIDR, VLSM চলে) | IPv6 prefix |
| কোথায় পাঠায় | Broadcast 255.255.255.255 | Multicast 224.0.0.9 | Multicast FF02::9 |
| Transport | UDP port 520 | UDP port 520 | UDP port 521 |
| Next hop ঘর | নেই | আছে | আলাদা বিশেষ entry-তে |
| Authentication | নেই | আছে — সাধারণ password, পরে MD5 ও শক্তিশালী hash (RFC 2082, RFC 4822) | নিজের নেই; IPv6-এর IPsec-এর ওপর নির্ভর |
RIPv2-এর একটি বার্তা UDP-র ভেতরে এমন দেখায় (RFC 2453 অনুযায়ী; প্রতিটি সারি ৩২ bit):
0 8 16 31
┌───────────────┬───────────────┬───────────────────────────────┐
│ Command (1/2) │ Version (2) │ must be zero │ ← header, 4 byte
├───────────────┴───────────────┼───────────────────────────────┤
│ Address Family (2 = IPv4) │ Route Tag │ ┐
├───────────────────────────────┴───────────────────────────────┤ │
│ IP Address (গন্তব্য) │ │ একটি route
├───────────────────────────────────────────────────────────────┤ │ = 20 byte;
│ Subnet Mask │ │ এক বার্তায়
├───────────────────────────────────────────────────────────────┤ │ সর্বোচ্চ 25টি
│ Next Hop │ │
├───────────────────────────────────────────────────────────────┤ │
│ Metric (1–16) │ ┘
└───────────────────────────────────────────────────────────────┘
Command 1 = request ("আপনার টেবিল পাঠান"), 2 = response (vector)
Command ১ (request) পাঠায় সদ্য চালু হওয়া router — প্রতিবেশীর পুরো টেবিল চেয়ে; command ২ (response) হলো আসল vector. এক বার্তায় সর্বোচ্চ ২৫টি route, তাই সর্বোচ্চ ৪ + ২৫ × ২০ = ৫০৪ byte ডেটা; বড় টেবিল কয়েকটি বার্তায় যায়।
RIP-এর তিনটি timer
| Timer | মান (RFC 2453) | কাজ |
|---|---|---|
| Update | ৩০ সেকেন্ড (একটু এলোমেলো করে) | পুরো vector সব প্রতিবেশীকে পাঠানো |
| Timeout | ১৮০ সেকেন্ড | এতক্ষণ একটি route-এর খবর না এলে metric ১৬ করে দেওয়া (route অচল) |
| Garbage-collection | ১২০ সেকেন্ড | অচল route আরও এতক্ষণ “১৬” হিসেবে ঘোষণা করে তারপর টেবিল থেকে মুছে ফেলা |
সংখ্যাগুলো RFC-র প্রস্তাবিত মান; বাস্তবায়নভেদে নাম আর মান আলাদা হতে পারে — যেমন Cisco-র ডকুমেন্টেশনে ডিফল্ট update ৩০, invalid ১৮০, hold-down ১৮০ আর flush ২৪০ সেকেন্ড। নিজের যন্ত্রের ডকুমেন্টেশন দেখে নেবেন। ৩০ সেকেন্ডের update “একটু এলোমেলো” করার কারণ আছে: সব router একসাথে update পাঠালে নেটওয়ার্কে একসাথে ঝাপটা আসে, আর পরস্পরের প্রভাবে router-গুলো নিজে থেকেই একই তালে চলে আসতে পারে — Sally Floyd আর Van Jacobson নব্বইয়ের দশকের শুরুতে periodic routing বার্তার এই synchronization নিয়ে একটি পরিচিত গবেষণা প্রকাশ করেন।
Hop count-এর দুর্বলতা
RIP-এর চোখে ১০ Gbps fiber আর ধীর পুরোনো লাইন দুটোই “১ hop”. দুই hop-এর ১০ Gbps পথ আর এক hop-এর ২ Mbps পথ থাকলে RIP বেছে নেবে ধীরটি। Offset বা কৃত্রিমভাবে metric বাড়িয়ে এটি কিছুটা সামলানো যায়, কিন্তু মূল সমস্যা থাকে। আর সর্বোচ্চ ১৫ hop — বড় নেটওয়ার্কে চলে না। এ কারণেই প্রতিষ্ঠানের ভেতরে OSPF বা IS-IS (পর্ব ২৪) বা EIGRP বেশি দেখা যায়।
Router-এ RIP চালু করা দেখতে এমন (উদাহরণ, Cisco IOS-ধাঁচের কনফিগারেশন; অন্য vendor-এর কমান্ড আলাদা):
! উদাহরণ — Cisco IOS-ধাঁচের কনফিগারেশন (ল্যাবে)
router rip
version 2
network 10.0.0.0
no auto-summary
passive-interface GigabitEthernet0/2
R1# show ip route rip
R 10.1.3.0/24 [120/2] via 10.1.12.2, 00:00:12, GigabitEthernet0/0
R 10.1.4.0/24 [120/1] via 10.1.14.4, 00:00:05, GigabitEthernet0/1
R মানে route-টি RIP থেকে শেখা। [120/2]-এর প্রথম সংখ্যা Cisco-তে RIP-এর administrative distance (একাধিক protocol একই prefix দিলে কাকে বিশ্বাস — পর্ব ২২), দ্বিতীয়টি metric (২ hop). 00:00:12 হলো শেষ update কতক্ষণ আগে এসেছে — ১৮০ সেকেন্ড পেরোলে route অচল। no auto-summary RIPv2-কে classful সংক্ষেপ করা থেকে থামায়; passive-interface সেই interface-এ update পাঠানো বন্ধ রাখে (যেমন ব্যবহারকারীদের LAN-এর দিকে) — নিরাপত্তার জন্যও ভালো অভ্যাস।
Linux-এ RIP চালাতে লাগে আলাদা routing daemon, যেমন FRRouting-এর ripd বা BIRD; kernel নিজে কোনো routing protocol চালায় না, শুধু টেবিল রাখে। এই পাতার কোড-চালানোর container-এ যাচাই করি — কোনো routing daemon চলছে কি, কেউ UDP 520-এ শুনছে কি:
echo "== routing daemons (RIP, OSPF, BGP...) in this container? =="
found=0
for p in /proc/[0-9]*; do
name=$(cat "$p/comm" 2>/dev/null) || continue
case "$name" in
ripd|ripngd|routed|zebra|ospfd|bgpd|bird|bird6|watchfrr)
echo " found: $name (pid ${p#/proc/})"; found=1 ;;
esac
done
if [ "$found" -eq 0 ]; then echo " none: no ripd, routed, bird or frr process"; fi
echo " processes visible: $(ls -d /proc/[0-9]* | wc -l)"
if command -v ps >/dev/null; then ps -eo pid,comm | head -n 6; else echo " (ps not installed)"; fi
echo "== RIP's port in /etc/services =="
grep -wE '^(router|ripng)' /etc/services 2>/dev/null || echo " (no entry or no /etc/services)"
echo "== any socket on UDP port 520 (hex 0208)? =="
if awk 'NR > 1 { split($2, a, ":"); if (a[2] == "0208") f = 1 } END { exit !f }' /proc/net/udp
then echo " yes"; else echo " no - nobody here listens for RIP"; fi
echo "== the kernel's table: /proc/net/route =="
cat /proc/net/routeআসল রানের আউটপুট:
== routing daemons (RIP, OSPF, BGP...) in this container? ==
none: no ripd, routed, bird or frr process
processes visible: 4
PID COMMAND
1 podman-init
2 bash
10 ps
11 head
== RIP's port in /etc/services ==
(no entry or no /etc/services)
== any socket on UDP port 520 (hex 0208)? ==
no - nobody here listens for RIP
== the kernel's table: /proc/net/route ==
Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
tap0 00000000 0202000A 0003 0 0 0 00000000 0 0 0
tap0 0002000A 00000000 0001 0 0 0 00FFFFFF 0 0 0
Routing daemon নেই: container-এ দেখা যাচ্ছে মাত্র চারটি process — container-এর init (podman-init), আমাদের bash, আর স্ক্রিপ্টের নিজের ps ও head. ripd, bird বা FRR-এর কিছুই নেই, তাই এখানে কেউ distance vector বিনিময় করছে না। /etc/services: এই ছোট container-এ ফাইলটিই নেই, তাই guard-এর বার্তা ছাপা হলো। সাধারণ Debian বা Ubuntu যন্ত্রে একই grep সাধারণত দেখায় router 520/udp route routed # RIP আর ripng 521/udp (উদাহরণ, এই রানের নয়)। UDP 520: /proc/net/udp-এ port hex-এ লেখা থাকে (520 = 0x0208); কোনো socket নেই, অর্থাৎ কেউ RIP-এর বার্তা শুনছে না।
/proc/net/route: মাত্র দুটি সারি — 0202000A উল্টে পড়লে 10.0.2.2, অর্থাৎ default route (0003 = চালু + gateway), আর mask 00FFFFFF মানে 10.0.2.0/24 সরাসরি tap0-এ (পর্ব ১৫-এর decode-এর মতো)। দুটিই ঠিকানা বসানোর সময় তৈরি, কোনো routing protocol থেকে শেখা নয়। Linux kernel টেবিল রাখে, কিন্তু টেবিল ভরার কোনো protocol চালায় না — সেটি user space-এর daemon-এর কাজ। FRRouting-এর ripd চলা একটি যন্ত্রে ip route-এ RIP থেকে শেখা সারির পাশে proto rip লেখা দেখা যায়।
RIP আজ কোথায়? সাধারণভাবে বলা যায়: ছোট নেটওয়ার্ক, ল্যাব আর প্রশিক্ষণ, কিছু পুরোনো বা সরল যন্ত্র, আর routing শেখার প্রথম ধাপ। বড় প্রতিষ্ঠান বা ISP-র ভেতরে এর জায়গা অনেক আগেই OSPF, IS-IS আর EIGRP নিয়েছে — তবে কোথায় ঠিক কতটা চলে, তার নির্ভরযোগ্য পরিসংখ্যান নেই। পরীক্ষা আর ইন্টারভিউতে অবশ্য RIP এখনো খুব প্রিয়, কারণ distance vector-এর সব ধারণা এতে স্পষ্ট দেখা যায়।
৮ · EIGRP-র DUAL আর distance vector বনাম link state
EIGRP — loop-মুক্ত distance vector
EIGRP (Enhanced Interior Gateway Routing Protocol) Cisco-র তৈরি, নব্বইয়ের দশকে আগের IGRP-র উত্তরসূরি হিসেবে আসে; দীর্ঘদিন শুধু Cisco-র যন্ত্রে চলত, পরে ২০১৬ সালে এর মূল অংশ একটি informational RFC (RFC 7868) হিসেবে প্রকাশ হয় — তবু অন্য vendor-এর সমর্থন সীমিত। ভেতরে এটি distance vector: প্রতিবেশীরা দূরত্ব জানায়, পুরো মানচিত্র নয়। কিন্তু এর কেন্দ্রে J.J. Garcia-Luna-Aceves-এর DUAL (Diffusing Update Algorithm), যার লক্ষ্য কোনো মুহূর্তেই loop না হতে দেওয়া। Metric-ও hop count নয় — ডিফল্টে মূলত পথের সবচেয়ে কম bandwidth আর মোট delay থেকে হিসাব। আর periodic নয়, শুধু বদল হলে আংশিক update.
DUAL-এর মূল কৌশল feasibility condition. দুটি শব্দ লাগবে: প্রতিবেশী v নিজে গন্তব্য পর্যন্ত যে দূরত্ব জানায়, তা reported distance (RD); আর আমার এখনকার সবচেয়ে ভালো মোট দূরত্ব feasible distance (FD). শর্ত: RDv < FD হলে v-কে বিকল্প হিসেবে নিরাপদে নেওয়া যায়। যুক্তি: v-এর নিজের দূরত্ব আমার চেয়ে কম, তাই v-এর পথ আমার ওপর দিয়ে আসতে পারে না — এলে v-এর দূরত্ব আমার দূরত্বের চেয়ে বেশি হতো। এই শর্ত পূরণ করা বিকল্পকে বলে feasible successor; মূল পথ নষ্ট হলে router কাউকে জিজ্ঞেস না করেই সাথে সাথে তাতে চলে যায়। কোনো feasible successor না থাকলে router প্রতিবেশীদের “query” পাঠায় আর উত্তর না আসা পর্যন্ত route-টি “active” রাখে — অপেক্ষা করে, কিন্তু loop বানায় না।
আমাদের A — B — C লাইনে ভাবুন: A-র FD ২ (C পর্যন্ত)। B-এর জন্য A-র reported distance ২, আর B-এর FD ছিল ১. শর্ত ২ < ১ মিথ্যা — তাই A কখনো B-এর বিকল্প হতে পারে না। Count-to-infinity-র প্রথম ভুল পদক্ষেপটাই আটকে গেল। একই ধারণা পরে খোলা মানের Babel protocol-ও ব্যবহার করে (RFC 8966), যা mesh নেটওয়ার্কে দেখা যায়।
Distance vector বনাম link state — পাঠ্যবইয়ের তুলনা
Link state-এ (পর্ব ২৪) প্রতিটি router নিজের link-এর খবর পুরো নেটওয়ার্কে ছড়িয়ে দেয় (flooding), ফলে সবাই পুরো মানচিত্র পায় আর প্রত্যেকে নিজে Dijkstra চালায়। দুটির পার্থক্য (N = router-সংখ্যা, E = link-সংখ্যা):
| বিষয় | Distance vector (RIP, EIGRP) | Link state (OSPF, IS-IS) |
|---|---|---|
| কে কী জানে | শুধু প্রতিবেশী আর তাদের দাবি করা দূরত্ব | পুরো topology-র মানচিত্র |
| কাকে পাঠায় | শুধু প্রতিবেশীকে, নিজের পুরো vector | সবাইকে (flooding), শুধু নিজের link-এর খবর |
| বার্তার জটিলতা | প্রতি বিনিময়ে শুধু প্রতিবেশীদের মাঝে; কিন্তু কত round লাগবে তা নির্ভর করে topology আর ঘটনার ওপর | প্রতিটি router-এর খবর সব link-এ — মোট প্রায় O(N·E) বার্তা |
| হিসাবের খরচ | প্রতি update-এ প্রতিটি গন্তব্যের জন্য প্রতিবেশী-সংখ্যার সমান যোগ-তুলনা | Dijkstra: সাধারণ রূপে O(N²), heap দিয়ে O(E log N) |
| Convergence-এর গতি | ধীর হতে পারে; খারাপ খবরে loop আর count-to-infinity | সাধারণত দ্রুত; flooding শেষ হলেই সবাই একই ছবি দেখে (মাঝে ক্ষণস্থায়ী অমিল থাকতে পারে) |
| মজবুতি (ভুল router) | একজনের ভুল দূরত্ব হিসাবের মধ্য দিয়ে পুরো নেটওয়ার্কে ছড়ায় | একজন শুধু নিজের link-এর ভুল ঘোষণা করতে পারে; বাকিরা নিজেরাই হিসাব করে, তাই ক্ষতি তুলনামূলক সীমিত |
| মেমরি আর CPU | কম — ছোট যন্ত্রেও চলে | বেশি — পুরো মানচিত্র রাখতে আর Dijkstra চালাতে হয় |
| কনফিগারেশন | খুব সহজ | বেশি ভাবতে হয় (area, router ID…) |
তৃতীয় একটি পরিবারও আছে: path vector, যার প্রধান উদাহরণ BGP. এটি distance vector-এর মতোই প্রতিবেশীকে route জানায়, কিন্তু সাথে পুরো পথের তালিকা (কোন কোন autonomous system পেরিয়ে) পাঠায়। নিজের নাম পথের তালিকায় দেখলে router সেই route ফেলে দেয় — loop ধরার সবচেয়ে সরাসরি উপায়। বিস্তারিত পর্ব ২৫-এ।
আরও গভীরে: RFC 2453 RIP-এর জন্য split horizon with poison reverse সুপারিশ করে, আর triggered update-কে ১ থেকে ৫ সেকেন্ডের এলোমেলো বিরতিতে সীমিত রাখতে বলে, যাতে একটি বদলের ঢেউ নেটওয়ার্ক ডুবিয়ে না দেয়। ওয়্যারলেস ad hoc নেটওয়ার্কের জন্য ১৯৯৪ সালে Perkins আর Bhagwat-এর DSDV প্রতিটি route-এ গন্তব্যের দেওয়া sequence number যোগ করে — পুরোনো sequence-এর খবর বাসি বলে বাদ, ফলে loop হয় না। এই ধারণা পরে AODV আর Babel-এ আসে। Linux-এ FRRouting-এর ripd, ripngd আর eigrpd এই protocol-গুলোর খোলা বাস্তবায়ন — VM-এ বা container-এ নিজের ল্যাব বানিয়ে চালিয়ে দেখা যায়।
পরীক্ষা ও ইন্টারভিউতে এই বিষয়ে প্রায়ই যা জিজ্ঞেস করা হয়:
- Bellman-Ford সমীকরণ লিখুন ও ব্যাখ্যা করুন। — dx(y) = minv { c(x,v) + dv(y) }; প্রতিবেশীর দাবি করা দূরত্ব + নিজের link-এর খরচ, সবচেয়ে ছোটটি; সেই v-ই next hop.
- Count-to-infinity কী? — Link নষ্ট হলে router-রা একে অপরের বাসি দূরত্ব বিশ্বাস করে loop বানায় আর মান ধাপে ধাপে অসীম পর্যন্ত বাড়ায়; “bad news travels slowly”.
- Split horizon আর poison reverse-এর পার্থক্য? — Split horizon: যার কাছ থেকে শিখেছি তাকে route বলি না; poison reverse: তাকে স্পষ্ট ∞ (১৬) বলি। দুটিই শুধু দুই router-এর loop ঠেকায়।
- RIP-এর মূল সংখ্যাগুলো? — UDP 520, update ৩০ s, timeout ১৮০ s, garbage-collection ১২০ s, সর্বোচ্চ ১৫ hop, ১৬ = অসীম; RIPv2 multicast 224.0.0.9.
- Distance vector আর link state-এর তিনটি পার্থক্য? — কী জানে (প্রতিবেশীর দূরত্ব বনাম পুরো মানচিত্র), কাকে পাঠায় (প্রতিবেশী বনাম সবাই), convergence (ধীর, loop সম্ভব বনাম সাধারণত দ্রুত)।
৯ · AI-এর যুগে distance vector
“এই graph-এ distance vector-এর টেবিল বানিয়ে দিন” — AI এই কাজ দ্রুত করে, কিন্তু round গোনা আর tie-breaking-এ প্রায়ই ভুল করে, আর ভুলগুলো সুন্দর টেবিলে সাজানো থাকে বলে চোখে পড়ে না:
| AI-এর ভুল | কেন ভুল | কীভাবে ধরবেন |
|---|---|---|
| Round ১-এই সব router-এর চূড়ান্ত টেবিল দেখানো | এক round-এ পথ মাত্র এক link লম্বা হয়; N − ২ round পর্যন্ত লাগতে পারে | অংশ ৪-এর simulator-এ একই graph চালিয়ে মেলান |
| নতুন মান হিসাবে একই round-এর অন্যদের নতুন মান ব্যবহার | Synchronous মডেলে শুধু আগের round-এর vector | প্রতিটি ঘরে কোন round-এর কোন মান যোগ হলো লিখিয়ে নিন |
| “Poison reverse সব loop ঠেকায়” | তিন বা বেশি router-এর loop ঠেকায় না (RFC 2453-ও বলে) | অংশ ৬-এর ত্রিভুজ simulator চালান |
| “RIP TCP port 520 ব্যবহার করে” বা “RIPv2 broadcast করে” | RIP UDP-তে; v2 multicast 224.0.0.9, v1 broadcast | RFC 2453 আর /etc/services দেখুন |
Cisco-র hold-down বা [120/x]-কে RIP-এর সর্বজনীন নিয়ম বলা | এগুলো vendor-এর বাস্তবায়ন; RFC-তে timer আলাদা নামে | RFC আর নিজের vendor-এর ডকুমেন্টেশন মিলিয়ে দেখুন |
AI-কে distance vector-এর প্রশ্ন দিলে মডেল আর যাচাইয়ের শর্তসহ দিন:
AI-এর উত্তর মানার আগে — চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১ARPANET-এর প্রথম routing ছিল distance vector, অথচ ১৯৮০ সালের দিকে তা বদলে link state করা হয়। কী সমস্যা দেখা দিয়েছিল, আর এই অভিজ্ঞতা থেকে কী শেখা যায়?
১৯৬৯ সালে চালু হওয়া ARPANET-এর packet switch-গুলো (IMP) একটি distance vector algorithm চালাত। দূরত্ব মাপা হতো delay দিয়ে, আর delay আন্দাজ করা হতো প্রতিটি link-এর queue-তে কতগুলো packet অপেক্ষা করছে তা গুনে। প্রতিটি IMP খুব ঘন ঘন প্রতিবেশীদের নিজের পুরো টেবিল পাঠাত। নেটওয়ার্ক ছোট থাকতে এটি চলেছে।
নেটওয়ার্ক বড় হওয়ার সাথে সমস্যাগুলো স্পষ্ট হলো। প্রথমত, queue-র দৈর্ঘ্য delay-এর খারাপ মাপ: একটি ধীর link আর একটি দ্রুত link-এ একই সংখ্যক packet থাকলে delay আলাদা, অথচ মাপ একই। দ্বিতীয়ত, মাপটি খুব দ্রুত ওঠানামা করত, ফলে route-ও দোলাচলে থাকত — এক পথ ভালো দেখালে সবাই সেদিকে যায়, তাতে সেই পথের queue বাড়ে, পরের মুহূর্তে সবাই উল্টো দিকে। তৃতীয়ত, এই পর্বের count-to-infinity: খারাপ খবর ধীরে ছড়াত, আর loop তৈরি হতো। টেবিল বড় হওয়ায় নিয়মিত পুরো টেবিল পাঠানোও খরুচে হয়ে উঠছিল।
১৯৭৯–৮০ সালে BBN-এর John McQuillan, Ira Richer আর Eric Rosen একটি নতুন algorithm চালু করেন এবং “The New Routing Algorithm for the ARPANET” নামে প্রকাশ করেন। এতে প্রতিটি switch নিজের link-গুলোর মাপা গড় delay সবাইকে flooding করে জানায়, আর প্রত্যেকে পুরো মানচিত্রে shortest path হিসাব করে — অর্থাৎ link state. পরে দেখা যায় শুধু delay-ভিত্তিক metric ভারী load-এ আবার দোলাচল তৈরি করে, তাই আশির দশকের শেষ দিকে metric-কে সংশোধন করে সীমিত পরিসরে রাখা হয় (Khanna আর Zinky-র কাজ)। এই ধারাবাহিকতা থেকেই পরে OSPF আর IS-IS এসেছে।
দুটি শিক্ষা আছে। এক, algorithm একা যথেষ্ট নয় — metric কী মাপছে আর কত দ্রুত বদলায়, তা স্থিতিশীলতার জন্য সমান গুরুত্বপূর্ণ। দুই, “প্রতিবেশীর দাবি বিশ্বাস করা” ছোট নেটওয়ার্কে সরল আর সস্তা, কিন্তু নেটওয়ার্ক বড় আর পরিবর্তনশীল হলে পুরো ছবি জানার দাম দিয়েও link state বেছে নেওয়া যুক্তিসংগত হয়ে ওঠে।
মূল উপলব্ধি: ARPANET-এর অভিজ্ঞতা দেখায়, routing-এর নকশা শুধু সঠিক shortest path নয় — বদলের সময় স্থিতিশীলতা, metric-এর মান আর বার্তার খরচও সমান গুরুত্বপূর্ণ।
প্র ০২RIP-এ অসীম = ১৬ কেন? এটি কি নকশার দুর্বলতা, নাকি সচেতন আপস? অসীম বড় বা ছোট করলে কী হতো?
Count-to-infinity-তে দুই router ধাপে ধাপে মান বাড়াতে থাকে। অসীম যত বড়, তত বেশি round লাগে থামতে — A — B — C উদাহরণে ঠিক I − ১ round. ৩০ সেকেন্ডের periodic update-এ অসীম ১০০০ হলে loop থাকত কয়েক ঘণ্টা; এই পুরো সময় packet ঘুরত, link ভরে থাকত। অন্যদিকে অসীম খুব ছোট হলে নেটওয়ার্কের আকার সীমিত হয় — RIP-এ কোনো গন্তব্য ১৫ hop-এর বেশি দূরে থাকতে পারে না।
RFC 1058-এ লেখকেরা এই আপস স্পষ্ট করেই বলেছিলেন: RIP ছোট বা মাঝারি নেটওয়ার্কের জন্য, বড় নেটওয়ার্কের জন্য নয়। আশির দশকের ক্যাম্পাস আর অফিস নেটওয়ার্কে ১৫ hop যথেষ্ট ছিল। ১৬ বেছে নেওয়া মানে count-to-infinity-র সবচেয়ে খারাপ অবস্থাও কয়েক মিনিটে শেষ, বিশেষ করে triggered update থাকলে আরও দ্রুত।
আরেকটি সূক্ষ্ম দিক আছে। ছোট অসীম চলে কারণ RIP-এর metric hop count, অর্থাৎ প্রতিটি link-এর খরচ ১. কেউ যদি ধীর link-কে বেশি খরচ (ধরুন ১০) দিতে চান, তবে দুটি এমন link-ই মোট ২০ — অসীম পেরিয়ে যায়। তাই ছোট অসীম আর সূক্ষ্ম metric একসাথে চলে না। EIGRP এই সমস্যা এড়ায় বড় metric পরিসর ব্যবহার করে, আর count-to-infinity-কে মূল থেকেই ঠেকায় DUAL দিয়ে — তখন অসীমের আকার আর সময়ের প্রশ্ন নয়।
বিকল্পগুলো ভাবলে দেখা যায়, অসীম বাড়ানো সমস্যার মূলে হাত দেয় না, শুধু ক্ষতির সময় বাড়ায় বা কমায়। মূল সমাধান তথ্যের ধরনে: পুরো পথ পাঠানো (path vector), loop-মুক্তির শর্ত (feasibility condition), বা গন্তব্যের sequence number (DSDV আর Babel-এ)। অর্থাৎ ১৬ একটি সাময়িক রক্ষাকবচ, প্রতিকার নয়।
মূল উপলব্ধি: RIP-এর ১৬ একটি সচেতন আপস — loop-এর সময় সীমিত রাখার বিনিময়ে নেটওয়ার্কের আকার আর metric-এর সূক্ষ্মতা ছেড়ে দেওয়া; আসল সমাধান আসে তথ্যের নকশা বদলে।
প্র ০৩Distance vector-এ একটি router ভুল করে বা ইচ্ছাকৃতভাবে “সব গন্তব্য আমার থেকে ০ দূরে” ঘোষণা করলে কী হবে? Link state বা BGP-তে একই ধরনের ঝুঁকি কেমন?
Distance vector-এ প্রত্যেকে প্রতিবেশীর দাবি যাচাই না করেই ব্যবহার করে। একটি router যদি বলে “সব গন্তব্য আমার থেকে ০”, তবে তার প্রতিবেশীরা হিসাব করবে c(x,v) + ০ — প্রায় সব গন্তব্যের জন্য এটিই সবচেয়ে ছোট। তারা নিজেদের vector আপডেট করে ছড়াবে, আর কয়েক round-এ নেটওয়ার্কের বড় অংশের traffic সেই এক router-এর দিকে যাবে। সে যদি এগুলো ফেলে দেয়, তবে একটি “black hole”; যদি গোপনে দেখে, তবে একটি নজরদারির বিন্দু। একজনের ভুল হিসাবের মধ্য দিয়েই সবার টেবিলে ঢুকে যায় — এটিই পাঠ্যবইয়ের “robustness” তুলনার মূল কথা।
Link state-এ ক্ষতি তুলনামূলক সীমিত। প্রতিটি router শুধু নিজের link-এর খবর ঘোষণা করে, আর প্রত্যেকে নিজে Dijkstra চালায়। একটি ভুল router নিজের link-এর খরচ ভুল বলতে পারে, এমনকি অস্তিত্বহীন link দাবি করতে পারে — তাতেও কিছু traffic সরে যায়। কিন্তু সে অন্যদের link-এর খবর বদলাতে পারে না, আর দুই প্রান্তের দাবি মিলিয়ে দেখার সুযোগ থাকে।
ইন্টারনেট-জুড়ে এই ঝুঁকির সবচেয়ে বিখ্যাত উদাহরণ BGP-তে, যা path vector — distance vector-এর আত্মীয়। ১৯৯৭ সালে একটি ছোট ISP-র ভুল কনফিগারেশনে অসংখ্য prefix-কে নিজের বলে ঘোষণা করা হয়েছিল, আর ইন্টারনেটের বড় অংশের traffic কিছু সময়ের জন্য বিপথে যায় — ঘটনাটি “AS 7007 incident” নামে পরিচিত। পরেও এমন route leak আর hijack বারবার ঘটেছে। প্রতিরক্ষা হিসেবে এসেছে প্রতিবেশীর ঘোষণায় filter, prefix-এর মালিকানা যাচাইয়ের ব্যবস্থা RPKI, আর নিজের নেটওয়ার্কে routing protocol-এ authentication.
ছোট নেটওয়ার্কের জন্য শিক্ষা: RIPv2-তে authentication চালু রাখা, ব্যবহারকারীদের LAN-এর দিকের interface-কে passive রাখা, যাতে কোনো ল্যাপটপ থেকে আসা RIP বার্তা router গ্রহণ না করে। এগুলো প্রতিরক্ষামূলক ভালো অভ্যাস; নিজের অনুমতিপ্রাপ্ত ল্যাবেই পরীক্ষা করবেন।
মূল উপলব্ধি: যে protocol যত বেশি “অন্যের দাবি বিশ্বাস করে” হিসাব করে, একজনের ভুল তত দূর ছড়ায় — তাই বিশ্বাসের সাথে যাচাই, filter আর authentication লাগে।
প্র ০৪Count-to-infinity-র সমাধানে তিনটি ভিন্ন দর্শন — বিষ দেওয়া (poison reverse), পথ পাঠানো (BGP-র path vector) আর শর্ত যাচাই (EIGRP-র DUAL) — প্রতিটির দাম কী?
সমস্যাটি এক বাক্যে: distance vector-এ একটি router জানে না যে প্রতিবেশীর দেওয়া পথ তার নিজের ওপর দিয়ে যায় কি না। তিনটি সমাধান তিনভাবে এই অজ্ঞতা কাটায়।
Poison reverse সবচেয়ে সস্তা: কোনো নতুন তথ্য লাগে না, শুধু প্রতিবেশীকে বলার নিয়ম বদলায়। দাম হলো অসম্পূর্ণতা — দুই router-এর loop ঠেকে, তিন বা বেশি router-এর loop ঠেকে না, যা অংশ ৬-এর ত্রিভুজে দেখেছেন। তাই RIP-কে তবু ছোট অসীম আর timer-এর ওপর নির্ভর করতে হয়।
Path vector সবচেয়ে সরাসরি: প্রতিটি route-এর সাথে পুরো পথ (BGP-তে autonomous system-এর তালিকা) যায়, তাই নিজের নাম দেখলেই loop ধরা পড়ে। দাম বার্তা আর মেমরিতে — প্রতিটি route-এর সাথে একটি তালিকা। BGP-র ক্ষেত্রে আরেকটি লাভ আছে: পথ জানা থাকায় প্রতিষ্ঠানগুলো নিজেদের ব্যবসায়িক নীতি অনুযায়ী route বাছতে পারে — ইন্টারনেটের মতো বহু-মালিকের নেটওয়ার্কে এটি অপরিহার্য। তবে path vector-এরও নিজস্ব ধীর convergence-এর সমস্যা আছে; BGP-তে route বাতিল হওয়ার পর বিকল্প পথগুলো একে একে চেষ্টা করার ঘটনা গবেষণায় বিস্তারিত দেখা গেছে।
DUAL সবচেয়ে সূক্ষ্ম: feasibility condition দিয়ে শুধু সেই বিকল্প নেওয়া হয়, যার loop-এ পড়া গাণিতিকভাবে অসম্ভব। কোনো নিরাপদ বিকল্প না থাকলে router প্রতিবেশীদের জিজ্ঞেস করে উত্তরের অপেক্ষা করে — “diffusing computation”. দাম জটিলতায়: query আর reply-র হিসাব রাখা, আর বড় নেটওয়ার্কে কোনো query-র উত্তর অনেকক্ষণ না এলে route আটকে থাকা — Cisco-র পরিভাষায় “stuck in active” পরিস্থিতি সুপরিচিত। নকশায় query-র পরিসর সীমিত রাখতে হয়।
লক্ষ করুন, তিনটির মধ্যে কেউই “সবার মানচিত্র” চায় না — সেটি link state-এর পথ। প্রতিটি সমাধান ঠিক করে, কতটুকু বাড়তি তথ্য বা সমন্বয়ের দাম দিয়ে কতটুকু নিশ্চয়তা কেনা হবে।
মূল উপলব্ধি: Loop ঠেকানোর নিশ্চয়তা বিনামূল্যে আসে না — বিষ সস্তা কিন্তু অসম্পূর্ণ, পথ পাঠানো নিশ্চিত কিন্তু ভারী, শর্ত যাচাই নিখুঁত কিন্তু জটিল।
প্র ০৫একসময় সেকেলে ভাবা distance vector-এর ধারণা আজ data center আর বেতার mesh নেটওয়ার্কে কীভাবে ফিরে এসেছে?
নব্বইয়ের দশক থেকে প্রতিষ্ঠানের ভেতরে link state (OSPF, IS-IS) প্রধান হয়ে ওঠে, আর distance vector-কে অনেকে “ছোট নেটওয়ার্কের পুরোনো প্রযুক্তি” ভাবতে শুরু করেন। কিন্তু মূল ধারণা — প্রতিবেশীর সাথে শুধু নিজের সেরা route বিনিময় — দুটি ভিন্ন জায়গায় নতুন জীবন পেয়েছে।
প্রথম, বড় data center. অনেক বড় data center-এর leaf-spine নেটওয়ার্কে (পর্ব ৫২) ভেতরের routing-এর জন্যও BGP ব্যবহার হয় — একটি path vector protocol, যা প্রতিবেশীদের সাথে route বিনিময়ের distance vector-ঘরানার আচরণই রাখে। এই নকশার সুপারিশ RFC 7938 (২০১৬)-এ লেখা আছে। কারণগুলো ব্যবহারিক: নকশা সরল ও নিয়মিত, প্রতিটি switch-এর state কম, link state-এর মতো পুরো নেটওয়ার্কে flooding নেই, আর একটি protocol দিয়েই ভেতর-বাইরে চলে। আবার উল্টো দিকে কিছু প্রকল্প link state-এর flooding কমানোর চেষ্টা করছে — দুই পরিবার একে অপরের ভালো দিক নিচ্ছে।
দ্বিতীয়, বেতার mesh আর ad hoc নেটওয়ার্ক। সেখানে link খুব ঘন ঘন বদলায়, যন্ত্র ছোট, ব্যাটারি সীমিত — পুরো মানচিত্র রাখা আর ঘন ঘন flooding খরুচে। DSDV, AODV আর পরে Babel distance vector-এর ধারণায় sequence number বা feasibility condition যোগ করে loop ঠেকিয়েছে। Babel (RFC 8966) কিছু community mesh নেটওয়ার্কে ব্যবহারের কথা জানা যায়, আর এর metric শুধু hop নয় — বেতার link-এর মানও হিসাবে নেয়।
বাংলাদেশের প্রেক্ষাপটেও ভাবা যায়: দুর্যোগে মোবাইল টাওয়ার বন্ধ হলে স্বেচ্ছাসেবী দলের ল্যাপটপ আর ছোট router দিয়ে অস্থায়ী mesh নেটওয়ার্ক বানানো হলে, সেখানে এমন হালকা, প্রতিবেশী-ভিত্তিক routing-ই বেশি মানানসই — যদিও এমন কোনো নির্দিষ্ট ব্যবহারের পরিসংখ্যান এখানে দাবি করছি না।
মূল উপলব্ধি: প্রযুক্তি পুরোনো হয় না, পরিবেশ বদলায় — যেখানে সরলতা, কম state আর স্থানীয় সিদ্ধান্ত বেশি দামি, সেখানে distance vector-এর ধারণা loop-রক্ষার নতুন কৌশল নিয়ে ফিরে আসে।
অনুশীলন
খাতা-কলম নিন — প্রতিটি ঘর Bellman-Ford সমীকরণে হিসাব করুন, তারপর উত্তর মেলান।
-
একটি router-এর নতুন টেবিল (হাতে হিসাব): Router X-এর তিন প্রতিবেশী: P (link-খরচ ২), Q (৫), R (১). তারা নিচের vector পাঠিয়েছে (গন্তব্য P, Q, R, S, T-এর দূরত্ব): P: [০, ৪, ৩, ৬, ৯], Q: [৪, ০, ৫, ১, ২], R: [৩, ৫, ০, ৭, ৮]. X-এর নতুন distance vector আর প্রতিটি গন্তব্যের next hop বের করুন।
প্রতিটি গন্তব্যে তিনটি প্রার্থী: ২ + P-এর মান, ৫ + Q-এর মান, ১ + R-এর মান।
গন্তব্য P হয়ে Q হয়ে R হয়ে ফল P 2 + 0 = 2 5 + 4 = 9 1 + 3 = 4 2 (P) Q 2 + 4 = 6 5 + 0 = 5 1 + 5 = 6 5 (Q) R 2 + 3 = 5 5 + 5 = 10 1 + 0 = 1 1 (R) S 2 + 6 = 8 5 + 1 = 6 1 + 7 = 8 6 (Q) T 2 + 9 = 11 5 + 2 = 7 1 + 8 = 9 7 (Q) X-এর নতুন vector: [২, ৫, ১, ৬, ৭], next hop [P, Q, R, Q, Q]. লক্ষ করুন, R সবচেয়ে কাছের প্রতিবেশী (খরচ ১), তবু S আর T-এর জন্য জেতে Q — প্রতিবেশীর নিজের দূরত্বও সমান গুরুত্বপূর্ণ।
-
Round ধরে পুরো trace: চার router W, X, Y, Z. Link: W–X ২, X–Y ৩, Y–Z ১, W–Z ৯, X–Z ৬. Synchronous মডেলে (round ০ = শুধু সরাসরি link) প্রতিটি round-এর পর চারটি টেবিল লিখুন, convergence পর্যন্ত। কোন round-এ কিছু বদলায় না?
ঘরে “দূরত্ব (next hop)”, কলাম গন্তব্য W, X, Y, Z:
Round 0: W: 0 2(X) ∞ 9(Z) X: 2(W) 0 3(Y) 6(Z) Y: ∞ 3(X) 0 1(Z) Z: 9(W) 6(X) 1(Y) 0 Round 1: W: 0 2(X) 5(X) 8(X) W→Y: X হয়ে 2+3; W→Z: X হয়ে 2+6 X: 2(W) 0 3(Y) 4(Y) X→Z: Y হয়ে 3+1 = 4 < 6 Y: 5(X) 3(X) 0 1(Z) Z: 8(X) 4(Y) 1(Y) 0 Z→W: X হয়ে 6+2; Z→X: Y হয়ে 1+3 Round 2: W: 0 2(X) 5(X) 6(X) W→Z: X-এর নতুন 4 থেকে 2+4 Z: 6(Y) 4(Y) 1(Y) 0 Z→W: Y-এর 5 থেকে 1+5 (X আর Y বদলায়নি) Round 3: কিছুই বদলায় না → convergedW → Z-এর মান ৯ → ৮ → ৬: সরাসরি link (৯)-এর চেয়ে W–X–Y–Z (২ + ৩ + ১ = ৬) ভালো, আর তিন link-এর পথ বলে round ২-এ ধরা পড়ে। N = ৪, সীমা N − ২ = ২ round — মিলে গেছে। অংশ ৪-এর simulator-এ
linksআরRবদলে যাচাই করতে পারেন। -
খারাপ খবর গোনা (numerical): তিন router x, y, z; c(x,y) = ৩, c(y,z) = ১, c(x,z) = ২০; গন্তব্য x. (ক) c(x,y) কমে ১ হলে কত round-এ সবাই স্থির? (খ) c(x,y) বেড়ে ৪০ হলে, poison reverse ছাড়া, y আর z-এর মান প্রথম চার round-এ কী, আর চূড়ান্ত মান কী? (গ) Poison reverse থাকলে?
শুরুতে y → x = ৩ (সরাসরি), z → x = ৪ (y হয়ে, ১ + ৩ < ২০)।
(ক) Round ১: y = ১ (সরাসরি)। Round ২: z = ১ + ১ = ২. Round ৩-এ কিছু বদলায় না — ২ round.
(খ) y জানে z বলেছে ৪ (z-এর পথ যে y হয়ে, y জানে না)। Round ১: y = min(৪০, ১ + ৪) = ৫ (z হয়ে); z = ৪. Round ২: z = ১ + ৫ = ৬. Round ৩: y = ৭. Round ৪: z = ৮. প্রতি দুই round-এ ২ করে বাড়ে। z থামে যখন y হয়ে খরচ সরাসরি ২০-কে ছাড়ায়: round ১৫-এ y = ১৯, round ১৬-এ z = min(২০, ১ + ১৯) = ২০ (সরাসরি), round ১৭-এ y = ১ + ২০ = ২১ (z হয়ে); round ১৮-এ কিছু বদলায় না। মোট ১৭টি round-এ বদল — এই পুরো সময় x-গামী packet y ⇄ z loop-এ।
(গ) z-এর পথ y হয়ে, তাই z, y-কে বলে ∞. Round ১: y = min(৪০, ∞) = ৪০ (সরাসরি)। Round ২: z শোনে y = ৪০ → min(২০, ৪১) = ২০ (সরাসরি)। Round ৩: z-এর পথ এখন সরাসরি, তাই y-কে সত্যি ২০ বলে → y = min(৪০, ২১) = ২১ (z হয়ে)। ৩ round, কোনো loop নেই। ফল (খ)-এর সমান, সময় অনেক কম।
-
আউটপুট অনুমান করুন: অংশ ৫-এর
count_to_infinity.js-এ শুধুconst INF = 16;বদলেconst INF = 6;করা হলো। পুরো আউটপুট কী হবে? এমন ছোট অসীমের লাভ আর ক্ষতি কী?Plain-এ মান আগের মতোই ৩, ৪, ৫… করে বাড়ে, কিন্তু ৬-এ থামে: round ৪-এ A = min(৬, ১ + ৫) = ৬, round ৫-এ B = ৬. Poison reverse-এ round ১-এ B = ৬, round ২-এ A = ৬. চালিয়ে পাওয়া আউটপুট:
round | plain DV: A B | poison reverse: A B 1 | 2(B) 3(A) | 2(B) 6(-) 2 | 4(B) 3(A) | 6(-) 6(-) 3 | 4(B) 5(A) | 4 | 6(-) 5(A) | 5 | 6(-) 6(-) | plain DV needed 5 rounds, poison reverse 2 rounds to reach 6 (unreachable)সূত্র মিলছে: I − ১ = ৫ round. লাভ: loop অনেক কম সময় থাকে। ক্ষতি: এখন কোনো গন্তব্য ৫ hop-এর বেশি দূরে হলে তা “পৌঁছানো যায় না” — নেটওয়ার্কের ব্যাস সর্বোচ্চ ৫. RIP-এর ১৬ এই দুইয়ের মাঝের আপস (ভাবনার প্রশ্ন ০২)।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি distance vector router প্রতিবেশীর update পেলে যা করে — ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- প্রতিবেশীর কাছ থেকে নতুন distance vector আসে
- সেই প্রতিবেশীর সবশেষ vector হিসেবে তা জমা রাখা হয়
- প্রতিটি গন্তব্যের জন্য c(x,v) + Dv(y)-এর minimum হিসাব হয়
- যে প্রতিবেশীতে minimum এলো, তাকে next hop ধরে টেবিল হালনাগাদ হয়
- নিজের vector বদলে থাকলে triggered update-এ প্রতিবেশীদের জানানো হয়
Router R-এর তিন প্রতিবেশী: S (link-খরচ ৩), T (২), U (৬). গন্তব্য Z পর্যন্ত S দাবি করে ৫, T দাবি করে ৭, U দাবি করে ১. Distance vector অনুযায়ী R → Z-এর দূরত্ব আর next hop কী?
- ৮, next hop S
- ৭, next hop U
- ১, next hop U
- ৯, next hop T
RIP-এ metric ১৬ কী বোঝায়?
- গন্তব্য ঠিক ১৬ hop দূরে
- ১৬ সেকেন্ড পর route মুছে যাবে
- গন্তব্যে পৌঁছানো যায় না (অসীম)
- এক বার্তায় ১৬টি route আছে
তিন router একটি লাইনে: A — B — C. A-র C-এর route B হয়ে, দূরত্ব ২. Split horizon with poison reverse চালু থাকলে A, B-কে C-এর দূরত্ব কত বলে (RIP-এর হিসাবে)?
- ১৬
- ২
- কিছুই না — route-টি বাদ দেয়
- ১
RIPv2 নিয়ে কোন বক্তব্যটি সঠিক?
- TCP port 520-এ চলে
- 255.255.255.255-এ broadcast করে update পাঠায়
- Subnet mask পাঠায় না, তাই VLSM চলে না
- Multicast 224.0.0.9-এ UDP port 520 দিয়ে update পাঠায়
একটি synchronous distance vector নেটওয়ার্কে ৬টি router, সব link-এর খরচ ধনাত্মক আর স্থির। round ০-এ প্রত্যেকে শুধু সরাসরি link জানে। সর্বোচ্চ কত round-এর পর সব সবচেয়ে ছোট পথ নিশ্চিতভাবে জানা হয়ে যায়?
- ১
- ৪
- ৬
- কোনো সীমা নেই
Distance vector আর link state routing-এর তুলনায় কোনটি সঠিক?
- Distance vector-এ প্রতিটি router পুরো topology জানে
- Link state-এ count-to-infinity বেশি হয়
- Distance vector-এ router শুধু প্রতিবেশীর সাথে বার্তা বিনিময় করে, আর একজনের ভুল দূরত্ব পুরো নেটওয়ার্কে ছড়াতে পারে
- OSPF distance vector আর RIP link state protocol
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Distance vector = প্রতিবেশীর দাবি + নিজের link-এর খরচ: dx(y) = minv { c(x,v) + dv(y) }; যে v-তে minimum, সে next hop. কেউ পুরো মানচিত্র জানে না।
- বিতরণকৃত, পুনরাবৃত্ত, asynchronous: বদল হলে triggered update, নিয়মিত periodic update; synchronous মডেলে round k-এ k + ১ link পর্যন্ত পথ জানা, তাই সর্বোচ্চ N − ২ round.
- ভালো খবর দ্রুত, খারাপ খবর ধীরে: link নষ্ট হলে বাসি দূরত্বে loop আর count-to-infinity; A — B — C লাইনে I − ১ round (RIP-এ ১৫)।
- প্রতিকার: split horizon (চুপ), poison reverse (স্পষ্ট ১৬), অসীম = ১৬, triggered update, hold-down; তিন বা বেশি router-এর loop-এ poison reverse অকার্যকর।
- RIP: UDP 520, প্রতি ৩০ s, timeout ১৮০ s, garbage-collection ১২০ s, metric hop count (bandwidth দেখে না); v1 classful broadcast, v2 mask + multicast 224.0.0.9 + authentication, RIPng IPv6-এ UDP 521. EIGRP-র DUAL feasibility condition (RD < FD) দিয়ে loop ঠেকায়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ২৪ · Link state routing — Dijkstra আর OSPFপরবর্তী পর্বপুরো মানচিত্র, flooding আর Dijkstra — distance vector-এর বিপরীত দর্শন।
- পর্ব ২২ · Routing-এর ভিত্তি — routing table, static route আর longest prefix matchআগের পর্বটেবিলের গঠন, administrative distance আর IGP বনাম EGP.
- পর্ব ২৫ · BGP আর ইন্টারনেটের গঠন — autonomous system, peering আর IXPএই মডিউলPath vector: পুরো পথ পাঠিয়ে loop ধরা।
- পর্ব ১৫ · Network layer — forwarding, routing আর router-এর ভেতরভিত্তিControl plane আর data plane — এই পর্বের প্রেক্ষাপট।
- কম্পিউটার নেটওয়ার্ক · কোর্স হোম৬২টি পর্বপুরো রোডম্যাপ।
- DSA · Bellman-Ford আর Floyd-Warshallপাশের ট্র্যাকএকই algorithm, graph-এর দিক থেকে — negative edge আর জটিলতাসহ।
- DSA · Dijkstraপাশের ট্র্যাকপরের পর্বের link state-এর প্রস্তুতি।