1. ספרייה
  2. TCP ו-UDP
  3. צלילה לעומק TCP

עודכן לפני חודש

מעצבי TCP ידעו שאינם יכולים לנבא את העתיד. הם לא ידעו על Ethernet גיגה-ביט, קישורי לוויין, או מרכזי נתונים שבהם מכונות יושבות מרחק מטרים אחת מהשנייה אך צריכות להעביר טרה-בייט. לכן הם בנו דלת מילוט: אפשרויות TCP. שדות כותרת אלה, שהם אופציונליים, מאפשרים לנקודות הקצה לנהל משא ומתן על יכולות שמעבר למפרט המקורי, ומסגלים פרוטוקול שנועד ל-ARPANET לרשתות שיוצריו מעולם לא דמיינו.

שדה האפשרויות

אפשרויות TCP נמצאות בכותרת, בין השדות הסטנדרטיים לבין המטען. כל אפשרות מצהירה על סוגה ואורכה, והשדה יכול להכיל עד 40 בייט בסך הכול. המשא ומתן הקריטי מתרחש במהלך לחיצת היד התלת-שלבית — שני הצדדים מפרסמים את מה שהם תומכים בו, מגיעים להסכמה על בסיס משותף, ומתחייבים לפרמטרים אלה לכל אורך חיי החיבור.

אם צד אחד אינו מכיר אפשרות מסוימת, הוא פשוט מתעלם ממנה. כלל פשוט זה הוא מה שהופך את TCP לכשיר להתפתח עם הזמן. יכולות חדשות ניתן לפרוס בהדרגה; מימושים ישנים לא נשברים — הם פשוט אינם נהנים מהן.

גודל מקטע מקסימלי (MSS)

MSS עונה על שאלה מעשית: עד כמה גדול יכול להיות מקטע TCP לפני שהוא גורם לבעיות?

הבעיה היא פרגמנטציה של IP. כאשר מנה עולה על יחידת העברה המקסימלית (MTU) של קישור רשת, נתבים חותכים אותה לחתיכות. זה פוגע בביצועים — אם אחד מהחלקים אובד, יש לשלוח מחדש את המנה כולה. גרוע מכך, חומות אש רבות מפילות חלקים כאלה לחלוטין, כשהן מתייחסות אליהם כחשודים.

MSS מונע זאת על ידי פרסום הגודל הגדול ביותר שאתה מוכן לקבל. החישוב פשוט: קח את ה-MTU של הממשק שלך (בדרך כלל 1500 בייט עבור Ethernet), הפחת 20 בייט לכותרת IP ו-20 ל-TCP, ותקבל 1460 בייט. כל נקודת קצה מפרסמת את ה-MSS שלה במהלך לחיצת היד, וכל כיוון יכול להיות שונה — אתה מכבד את מה שהמקבל מכריז.

Path MTU Discovery מרחיב זאת על ידי בדיקת כל הנתיב. כאשר נתב נתקל במנה גדולה מדי, הוא שולח חזרה הודעת ICMP מסוג "Fragmentation Needed". השולח מקטין את המקטעים שלו ומנסה שוב. זה חשוב במיוחד לנתיבים שעוברים דרך מנהרות VPN או חיבורי PPPoE, שבהם ה-MTU בפועל קטן מ-1500 הבייט הסטנדרטיים של Ethernet.

הרחבת חלון

שדה חלון הקבלה של TCP הוא בן 16 סיביות. ערך מקסימלי: 65,535 בייט.

בשנת 1981, זה נראה נדיב. איש לא דמיין שיידרש לשלוח יותר מ-64KB לפני שמקבלים אישור. כיום, זו צוואר בקבוק.

מכפלת רוחב-הסרט והעיכוב קובעת כמה נתונים יכולים להיות "בטיסה" — נשלחו אך טרם אושרו. חיבור טרנסאטלנטי עם זמן הלוך-חזור של 100ms ורוחב סרט של 1 Gbps יכול תיאורטית לשמור על 12.5 מגה-בייט בטיסה. אבל עם חלון של 64KB? שולחים 64KB, ואז ממתינים. שולחים 64KB, ממתינים. חלון של 64 קילו-בייט על קישור טרנסאטלנטי של גיגה-ביט הוא כמו לנסות למלא בריכת שחייה דרך קש — אפשר לשאוב מהר יותר, אבל ממתינים לאישור שכל טיפה הגיעה.

הרחבת חלון מתקנת זאת באמצעות מכפיל. במהלך לחיצת היד, כל צד מפרסם ספירת הזזה מ-0 עד 14. ערך החלון מוזז שמאלה בכמות זו. הזזה של 7 מכפילה ב-128, ומאפשרת חלונות עד 8 מגה-בייט. הזזה של 14 מאפשרת יותר מגיגה-בייט.

יש להסכים על כך במהלך לחיצת היד הראשונית — לא ניתן להפעיל זאת מאוחר יותר. שני הצדדים חייבים לתמוך בכך. אבל ברגע שמופעל, TCP יכול סוף סוף למצות קישורים ברוחב סרט גבוה ועיכוב גבוה.

חותמות זמן TCP

חותמות זמן פותרות שתי בעיות, והשנייה מוזרה יותר ממה שהייתם מצפים.

ראשית, מדידת זמן הלוך-חזור טובה יותר. ללא חותמות זמן, TCP מעריך את ה-RTT מתזמון ה-ACK, אבל זה הופך לדו-משמעי במהלך שידורים חוזרים — האם ה-ACK הגיב למקטע המקורי או לשידור החוזר? עם חותמות זמן, כל מקטע נושא חותמת זמן של השולח ואקו של חותמת הזמן האחרונה של המקבל. חישוב ה-RTT הופך לחד-משמעי.

שנית, הגנה מפני גלישת מספרי רצף. מספרי רצף של TCP הם בני 32 סיביות — הם גולשים לאחר 4 גיגה-בייט. בחיבור של 10 Gbps, אתה שורף את כל מרחב הרצף תוך פחות מארבע שניות. ללא חותמות זמן, TCP עלול לטעות ולזהות מנות ישנות כנתונים חדשים — מקטע מהגלישה הקודמת יכול להגיע מאוחר ולהתקבל כתקף. חותמת הזמן פועלת כמזהה משני, ומאפשרת ל-TCP להבחין בין מקטע לגיטימי לבין עותק מאוחר מחזור קודם.

אישור סלקטיבי (SACK)

אישורי TCP מסורתיים הם מצטברים: "קיבלתי הכול עד בייט 5000." זה יוצר בעיה כאשר מנות מגיעות שלא לפי הסדר או עם פערים.

דמיינו שמקטעים 1, 2, 4, ו-5 מגיעים, אבל מקטע 3 אבד. המקבל יכול לאשר רק עד מקטע 2. השולח יודע שמשהו לא בסדר, אבל מה בדיוק? האם מקטעים 3, 4, ו-5 כולם נעלמו? רק מקטע 3? ללא מידע נוסף, השולח או שולח מחדש הכול (בזבזני) או ממתין ובודק (איטי).

SACK מאפשר למקבל לציין בדיוק מה יש לו: "קיבלתי 1-2 בצורה מצטברת, ויש לי גם 4-5." השולח שולח מחדש רק את מקטע 3. ההתאוששות הופכת לכירורגית במקום ספקולטיבית.

SACK דורש משא ומתן עם אפשרות SACK-Permitted במהלך לחיצת היד. ברגע שמופעל, המקבל יכול לכלול בלוקי SACK המציינים עד שלושה או ארבעה טווחים לא-רצופים. ברשתות עם אובדן מנות — אלחוטיות, נתיבים עמוסים, כל מה שכרוך באובדן — SACK הוא ההבדל בין ביצועים סבירים לבין סבל ממשי.

ריקוד המשא ומתן

משא ומתן על אפשרויות עוקב אחר כוריאוגרפיה קפדנית:

  1. SYN: הלקוח מפרסם אפשרויות נתמכות עם הפרמטרים המועדפים עליו (MSS, ספירת הזזה של Window Scale, SACK-Permitted, חותמות זמן)
  2. SYN-ACK: השרת מגיב עם הפרמטרים שלו עבור אפשרויות משותפות
  3. ACK: מאשר את הפרמטרים שסוכמו

חלק מהאפשרויות יכולות להיות שונות לפי כיוון — לכל צד יש MSS משלו. אחרות דורשות תמיכה הדדית — Window Scaling ו-SACK מופעלים רק אם שני הצדדים מסכימים. חותמות זמן גמישות יותר; טכנית צד אחד יכול להשתמש בהן לבד, אבל בדרך כלל שני הצדדים מפעילים אותן יחד.

ברגע שלחיצת היד מסתיימת, הפרמטרים נעולים. לא ניתן להוסיף אפשרויות באמצע חיבור. זה הופך את המשא ומתן הראשוני לקריטי — וזו הסיבה שהתקני ביניים המסירים אפשרויות גורמים לבעיות ביצועים עדינות ומייגעות.

נקודות מפתח

  • אפשרויות TCP הן דלת המילוט שמאפשרת לפרוטוקול מהשנות השבעים לשרוד בעולם של גיגה-ביט — תואמות לאחור, ניתנות לפריסה הדרגתית, מוסכמות בנפרד לכל חיבור.
  • MSS מונע פרגמנטציה של IP על ידי פרסום גודל המקטע המקסימלי; Path MTU Discovery מרחיב זאת לבדיקת נתיב הרשת כולו.
  • הרחבת חלון שוברת את מחסום ה-64KB, ומאפשרת תפוקה גבוהה בקישורים עם עיכוב גבוה על ידי החזקת מגה-בייטים של נתונים בטיסה.
  • חותמות זמן משפרות את מדידת ה-RTT ומונעות גלישת מספרי רצף — חיוניות כאשר חיבורים יכולים לשרוף 4GB של מרחב רצף בשניות.
  • SACK הופך את ההתאוששות מאובדן מנות מניחוש לדיוק, ומאפשר לשולחים לדעת בדיוק אילו מקטעים לשלוח מחדש.
  • אפשרויות מוסכמות פעם אחת, במהלך לחיצת היד, ונעולות לכל אורך חיי החיבור — מה שהופך את חילופי המידע הראשוניים לקריטיים בשקט לביצועים.

שאלות נפוצות על אפשרויות TCP

מדוע לא ניתן לשנות אפשרויות TCP לאחר שהחיבור נוצר?

אפשרויות TCP משפיעות על פרמטרי חיבור בסיסיים — חישובי גודל חלון, סמנטיקה של אישורים, ואיך חותמות זמן מפורשות. שינוי אלה באמצע הזרם ידרוש משני הצדדים לסנכרן את השינוי בבייט המדויק באותו הזרם, דבר שהוא מסובך ביותר ורגיש לשגיאות. לחיצת היד היא הרגע היחיד שבו שני הצדדים מתואמים במפורש, מה שהופך אותה למקום הטבעי לנעילת פרמטרים.

מה קורה אם התקן ביניים מסיר אפשרויות TCP?

הביצועים יורדים, לעיתים קרובות באופן מסתורי. ללא הרחבת חלון, התפוקה בקישורים עם עיכוב גבוה נופלת לשבריר מהקיבולת. ללא SACK, ההתאוששות מאובדן מנות הופכת לאיטית ובזבזנית. ללא משא ומתן על MSS, אתה עלול לקבל פרגמנטציה של IP. החיבור עדיין עובד — תאימות לאחור של TCP מבטיחה זאת — אבל אתה מאבד את האופטימיזציות שהופכות רשתות מודרניות לנסבלות.

האם כל המערכות המודרניות תומכות באפשרויות אלה?

כן. MSS, הרחבת חלון, חותמות זמן ו-SACK הם סטנדרטיים כבר עשרות שנים. כל מערכת הפעלה מהעשרים שנה האחרונות מפעילה אותן כברירת מחדל. השאלה אינה האם נקודות הקצה תומכות בהן, אלא האם נתיב הרשת ביניהן מאפשר לאפשרויות לעבור ללא הפרעה.

האם דף זה היה מועיל?

😔
🤨
😃