TCP Retransmission שעוצר תקשורת עם מצלמה תעשייתית — איך מפרקים את זה

· עודכן בתאריך: · · TCP, רשתות, חקירת תקלות, פיתוח Windows, מצלמה תעשייתית

היסטוריית עדכונים (גרסה ראשונה, פורסמה בתאריך 11 Mar 2026)
פרסום ראשון
לצטט את המאמר הזה(DOI: 10.5281/zenodo.22173343)

מאמר זה מאוחסן בארכיון Zenodo. להלן גם ה-DOI שתמיד מפנה לגרסה האחרונה וגם ה-DOI המקובע לגרסה שאתם קוראים.

Go Komura (2026). TCP Retransmission שעוצר תקשורת עם מצלמה תעשייתית — איך מפרקים את זה. KomuraSoft LLC. https://doi.org/10.5281/zenodo.22173343 https://comcomponent.com/he/blog/tcp-retransmission-rfc1323-industrial-camera/

DOI (הגרסה האחרונה)
10.5281/zenodo.22173343
DOI (הגרסה הזו)
10.5281/zenodo.22173344

בתקשורת של מצלמות תעשייתיות ובקרת התקנים, התופעה הכי מעצבנת היא כשבממוצע הכול מהיר, אבל לפעמים התקשורת נתקעת לכמה שניות. שיעור השחזור נמוך, וברוב הזמן לא קורה כלום — אז UI, threads, GC, ה-SDK של המצלמה, ה-NIC וה-switch כולם מתחילים להיראות קצת חשודים.

המקרה כאן: TCP בין אפליקציה ששולטת במצלמה תעשייתית לבין ה-host, שבו לעיתים רחוקות התקשורת נעצרת לכמה שניות בלבד. בבדיקה התברר שהאשם לא היה stall של האפליקציה, אלא המתנה ל-TCP retransmission אחרי packet loss. בנוסף, הפעלת timestamps לפי RFC1323 (בסיווג הנוכחי RFC 7323) אפשרה במערכת הזו לצמצם את זמן ההמתנה למינימום.

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

תוכן עניינים

  1. השורה התחתונה
  2. איך הסימפטום נראה
    • 2.1. האפליקציה חיה, אבל התגובה נעצרת לכמה שניות
    • 2.2. בתדירות נמוכה, קשה לראות את זה רק מהלוגים
  3. מה באמת קרה (בתרשימים)
    • 3.1. מ-packet loss להמתנה ל-retransmission
    • 3.2. ה-stall בסדר גודל של שניות תאם את צורת ה-RTO
  4. מה בדקנו בחקירה
    • 4.1. קודם שוללים גורמי stall בתוך האפליקציה
    • 4.2. מאמתים retransmission ב-packet capture
    • 4.3. בודקים אילו TCP options סוכמו
  5. למה timestamps של RFC1323 עוזרים
    • 5.1. timestamps מיועדים ל-RTTM ול-PAWS
    • 5.2. אפשר להסיר את העמימות במדידת RTT בזמן retransmission
    • 5.3. למה במקרה הזה התקצר זמן ההמתנה
  6. מה עשינו בפועל
    • 6.1. הפעלת timestamps
    • 6.2. בדיקת TSopt ב-SYN / SYN-ACK
    • 6.3. איפה לבדוק כשזה עדיין לא עוזר
  7. נקודות בדיקה ב-Wireshark
  8. איך לבחור כיוון, בגדול
  9. סיכום
  10. מקורות

ב-diagram, solid line מציינת relation שתמיד מתקיים ו-dashed line מציינת relation מותנה (התנאים מופיעים בהסבר של כל relation ב-detail page). הרשימה המלאה של ה-relations (סה”כ 19, כולל evidence ו-certainty) וההגדרות של ה-concepts המרכזיים נמצאות ב-detail page של ה-knowledge map (ביפנית). Data: JSON-LD / Turtle

1. השורה התחתונה

  • תקשורת TCP שנעצרת לעיתים רחוקות לכמה שניות עשויה להיות לא stall של האפליקציה, אלא המתנה ל-retransmission אחרי packet loss
  • אם ב-packet capture רואים Retransmission ופער זמן גדול, ומשך ה-stall תואם את אופן ההמתנה של ה-RTO — זה חשוד מאוד
  • TCP timestamps option קיימת למדידת RTT ול-PAWS, והיא גם מאפשרת להסיר את העמימות במדידת RTT בזמן retransmission
  • במקרה הזה, הפעלת timestamps לפי RFC1323 קיצרה את הזמן שבו הערכת ה-RTO נשארת ישנה ושמרנית מדי, וכך צומצם ה-stall בסדר גודל של שניות למינימום
  • עם זאת, זו לא קסם שמעלים את ה-loss עצמו. השכבה הפיזית, NIC, switch, ציוד ביניים, דרייברים ותכנון buffer נבדקים בנפרד

בקיצור: אם הזהות האמיתית של “לפעמים נתקע לכמה שניות” היא זמן המתנה בתוך TCP, מאמץ שמושקע רק ב-retry באפליקציה מפספס את הליבה. מהיר יותר להסתכל קודם על ה-wire ולקבוע אם זו המתנה ל-retransmission.

זרימת המסקנה במאמרבתקשורת TCP שנעצרת לעיתים רחוקות לכמה שניות מסתכלים קודם על ה-wire וקובעים אם זו המתנה ל-retransmission. אם כן, לפעמים אפשר לקצר את ההמתנה עם timestamps, אבל חקירת מקור ה-packet loss נשארת נפרדת.תקשורת TCP שנעצרת מדי פעםקודם מסתכלים על ה-wireקובעים אם זו המתנה ל-retransmissiontimestamps עשויות לקצר המתנהחקירת מקור ה-loss נשארת נפרדת

איור 1: לפני שמשקיעים ב-retry באפליקציה, קודם קובעים ב-wire איפה ממתינים.

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

מונח שם מלא משמעות
ACK Acknowledgment אישור קבלה. מודיע לצד השני “קיבלתי עד כאן”
RTT Round-Trip Time זמן הלוך-ושוב. מהשליחה עד שחוזר ה-ACK
RTO Retransmission Timeout טיימר ה-retransmission. אם ה-ACK לא חוזר בתוך הזמן הזה, יש retransmission. מחושב מהערכת ה-RTT
RTTM Round-Trip Time Measurement מדידת RTT. אחת ממטרות timestamps
PAWS Protect Against Wrapped Sequences הגנה מפני wrap של sequence number. המטרה השנייה של timestamps
TSopt TCP Timestamps Option אחת ה-options בכותרת TCP. סוג 8, אורך 10 בתים, ונושאת שני ערכים
TSval Timestamp Value הערך שהצד השולח מכניס — השעון שלו
TSecr Timestamp Echo Reply השדה שמחזיר בדיוק את ה-TSval שהתקבל. כך יודעים לאיזו שליחה שייך ה-ACK
SACK Selective Acknowledgment המקבל מודיע באופן פרטני אילו טווחים התקבלו
Dup ACK Duplicate ACK כמה ACK שמצביעים על אותו sequence number. סימן שיש פער באמצע
fast retransmit — retransmission בלי לחכות ש-RTO יפוג, ברגע שמצטבר מספר מסוים של Dup ACK. ברירת המחדל ב-Windows: אחרי שלושה ACK לאותו sequence number (הראשון ועוד שניים כפולים)
האלגוריתם של Karn — הכלל שאסור לקחת מדגם RTT מ-segment שעבר retransmission, כי לא יודעים לאיזו שליחה שייך ה-ACK

2. איך הסימפטום נראה

2.1. האפליקציה חיה, אבל התגובה נעצרת לכמה שניות

מה שמבלבל בהתחלה: האפליקציה כולה לא נראית תקועה.

  • ה-UI לא מת לגמרי
  • ה-process לא קרס
  • גם ה-CPU לא תקוע
  • אבל רק התגובה לפקודות בקרת המצלמה נעלמת מדי פעם לכמה שניות

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

2.2. בתדירות נמוכה, קשה לראות את זה רק מהלוגים

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

אם עוקבים רק דרך לוגים, בדרך כלל קורה כך:

  • בלוג האפליקציה זה נעצר על “נשלח” ואז “לא חוזר”
  • בצד המקבל הלוג נראה כאילו “שום דבר לא הגיע”
  • באותו חלון זמן קורים במקרה גם אירועים אחרים, והחשוד מתפזר

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

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

איור 2: stall בתדירות נמוכה שעוקבים אחריו רק בלוגים מסתבך. מהיר יותר להסתכל דרך packets.

3. מה באמת קרה (בתרשימים)

3.1. מ-packet loss להמתנה ל-retransmission

התרחיש הפעם פשוט. packet נפל איפשהו בדרך, הצד השולח המתין ל-ACK, וכשזה לא הגיע הוא חיכה ש-RTO יפוג ואז ביצע retransmission.

ממעבר packet loss להמתנה ל-retransmissionפקודת בקרה נשלחת מה-host, ה-packet אובד ברשת, ה-host ממתין ש-RTO יפוג, מבצע retransmission, וה-packet המשודר מחדש מגיע למצלמה ומקבל ACK שמסמן חידוש התקשורת.צד המצלמההרשתאפליקציית ה-Hostצד המצלמההרשתאפליקציית ה-Hostכאן קורה ה-lossה-ACK לא מגיע, ולכן ממתיניםהשחזור של הבקשה הזו כולל המתנה ל-RTOכאן התקשורת מתחדשתפקודת בקרה (Seq=N)retransmission של פקודת הבקרהה-packet המשודר מחדש מגיעACKACK

איור 3: כש-packet נופל, ה-ACK לא חוזר וממתינים ש-RTO יפוג לפני retransmission. מהאפליקציה, פרק הזמן הזה נראה כ”עצירה של כמה שניות”.

מהאפליקציה זה נראה כ”עצירה של כמה שניות”, אבל מבחינת TCP זה פשוט “ה-ACK עדיין לא הגיע, ולכן ממתינים שטיימר ה-retransmission יפוג”. זה לא מרשים, אבל צורת stall כזו שכיחה למדי.

תקשורת הבקרה במקרה הזה כללה בעיקר request/response קטנים, ובכל חילופין לא נשלחה כמות גדולה של נתונים בלי ACK. לכן במקום שיצטברו מספיק Duplicate ACK כדי להיכנס ל-fast retransmit, המבנה נטה לחשוף קודם המתנה ל-RTO.

למה בתקשורת בקרה נחשפת בקלות המתנה ל-RTOבתקשורת בקרה שמבוססת בעיקר על request/response קטנים יש מעט נתונים בלי ACK, לכן Duplicate ACK לא מצטברים מספיק, קשה להיכנס ל-fast retransmit, ונחשפת המתנה ל-RTO.בעיקר request/response קטניםמעט נתונים בלי ACKDup ACK לא מצטברים מספיקקשה להיכנס ל-fast retransmitנחשפת המתנה ל-RTO

איור 4: בשונה מתקשורת שזורמים בה הרבה נתונים, loss בתקשורת בקרה נוטה להסתיים בהמתנה ש-RTO יפוג.

3.2. ה-stall בסדר גודל של שניות תאם את צורת ה-RTO

ההמתנה ל-TCP retransmission שמרנית באופייה, גם אם יש הבדלים בין מימושים. לפי RFC 6298, ה-RTO ההתחלתי מבוסס על שנייה אחת: אם תוצאת החישוב קטנה מזה, מעגלים כלפי מעלה ל-1 שנייה, וכל timeout מכפיל אותו.

מחזור ההכפלה של RTO עד לחידוש התקשורתpacket loss גורם להיעדר ACK, שמוביל להמתנה ל-RTO ואז ל-retransmission. אם ה-ACK חוזר התקשורת מתחדשת, ואם לא, ה-RTO מוכפל והמחזור חוזר על עצמו.כןלאpacket lossה-ACK לא מגיעהמתנה ל-RTOretransmissionה-ACK חוזר?התקשורת מתחדשתהכפלת ה-RTO

איור 5: ה-RTO מוכפל בכל פעם שה-ACK לא חוזר. צורת ההמתנה של שנייה, שתי שניות, ארבע שניות נובעת מהמנגנון הזה.

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

4. מה בדקנו בחקירה

4.1. קודם שוללים גורמי stall בתוך האפליקציה

בלי לקבוע מראש ש-TCP הוא האשם, קודם שללנו את הגורמים האופייניים בצד האפליקציה.

מה נבדק למה בדקנו המסקנה במקרה הזה
UI thread / worker threads בדיקת hang או המתנה הדדית לא היה הגורם העיקרי
ניצול CPU בדיקת עיכוב עיבוד בגלל עומס גבוה גם בזמן ה-stall ה-CPU לא היה תקוע
GC / לחץ זיכרון בדיקת השהיה זמנית צורת זמן ההשהיה לא תאמה
קריאות ל-SDK של המצלמה בדיקת המתנה בתוך ה-SDK לא תאם לעיכוב שנצפה ב-wire
packet capture בדיקת retransmission בשכבת התקשורת כאן נראה חוט הסיבה האמיתי

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

סדר הפירוק ששולל קודם גורמים בתוך האפליקציהבמקום לקבוע מראש ש-TCP הוא האשם, קודם שוללים גורמי stall אופייניים בתוך האפליקציה כמו threads, CPU, GC ו-SDK של המצלמה, ורק אז בודקים retransmission בשכבת התקשורת באמצעות packet capture.שוללים קודם threads, CPU, GC ו-SDKבודקים את שכבת התקשורת ב-packet captureמתגלה חוט הסיבה של ה-retransmissionלא לקבוע חשוד רק לפי זמני הלוג

איור 6: לא קובעים מראש. קודם שוללים גורמים אופייניים בתוך האפליקציה, ורק אז יורדים אל ה-wire.

4.2. מאמתים retransmission ב-packet capture

כשלכדנו את ה-packets, ראינו TCP Retransmission בדיוק בחלון הזמן של ה-stall, ומצאנו שממש לפני כן ה-ACK לא חזר.

אלה הנקודות שכדאי לבדוק:

  • האם מופיע retransmission לאותו Seq
  • האם פער הזמן עד ה-retransmission תואם את משך ה-stall
  • האם זה נראה כהמתנה ש-RTO יפוג, ולא כ-Dup ACK או Fast Retransmission
  • האם החיבור הבעייתי מופיע תמיד באותו tcp.stream

כשהנקודות האלה מתיישרות, ההשערה ש”TCP ממתין ל-retransmission” — ולא ש”האפליקציה נעצרת” — מתחזקת מאוד.

נקודות הבדיקה שקובעות המתנה ל-retransmissionשלוש נקודות — retransmission לאותו Seq, פער זמן שתואם את משך ה-stall, והופעה שנראית כהמתנה ש-RTO יפוג ולא כ-fast retransmission — כשמתיישרות מחזקות את ההשערה ש-TCP ממתין ל-retransmission ולא שהאפליקציה נעצרת.retransmission לאותו SeqTCP ממתין ל-retransmissionפער זמן שתואם את משך ה-stallנראה כהמתנה ש-RTO יפוגהאפליקציה לא נעצרת

איור 7: אם שלוש הנקודות האלה מתיישרות, ההשערה עוברת מ”האפליקציה נעצרת” ל”TCP ממתין ל-retransmission”.

4.3. בודקים אילו TCP options סוכמו

הדבר הבא שבדקנו היה ה-SYN / SYN-ACK בתחילת החיבור. timestamps מסוכמים ב-3-way handshake של חיבור TCP, ואם TSopt לא מופיע שם, הוא לא ישמש באותו חיבור.

משא ומתן על TSopt ב-3-way handshakeה-host שולח SYN עם TSopt אפשרי, המצלמה מחזירה SYN/ACK עם TSopt אפשרי, ורק אחרי שהמשא ומתן מצליח אפשר להשתמש ב-TSopt ב-segments הבאים.צד המצלמהה-hostצד המצלמהה-hostרק אחרי שהמשא ומתן הזה מצליח, אפשר להשתמש ב-TSopt ב-segments הבאיםSYN + TSopt?SYN/ACK + TSopt?ACK

איור 8: timestamps מסוכמים ב-3-way handshake. אם אין TSopt ב-SYN / SYN-ACK, הם לא ישמשו באותו חיבור.

אם משנים רק את הגדרות מערכת ההפעלה בלי לבדוק את זה, קורה תקלה שקטה נוספת: “הפעלתי, אבל זה לא עובד”. העובדה שנראית ב-wire חזקה יותר מערך ההגדרה.

5. למה timestamps של RFC1323 עוזרים

בפועל השם “timestamps של RFC1323” עדיין נפוץ, אבל הסיווג העדכני הוא RFC 7323. במאמר הזה כותבים RFC1323 לפי המקובל, אך הכוונה היא ל-TCP timestamps option.

5.1. timestamps מיועדים ל-RTTM ול-PAWS

TCP timestamps option משמשת בעיקר לשתי מטרות:

  • RTTM (Round-Trip Time Measurement)
  • PAWS (Protect Against Wrapped Sequences)

מה שעזר במקרה הזה הוא צד ה-RTTM. הצד השני מחזיר את ה-TSval של ה-segment שנשלח בתוך TSecr של ה-ACK, וכך הצד השולח יכול למדוד את ה-RTT בפירוט ובדיוק רבים יותר.

שתי המטרות של timestamps optionTCP timestamps option משמשת לשתי מטרות, RTTM שהיא מדידת round-trip time ו-PAWS שהיא הגנה מפני wrap של sequence number, ובמקרה הזה מה שעזר היה צד ה-RTTM.timestamps optionRTTM (מדידת round-trip time)PAWS (הגנה מפני wrap של sequence number)זה מה שעזר במקרה הזהמדידה בהחזרת TSval בתוך TSecr

איור 9: למטרת timestamps שני צדדים — RTTM ו-PAWS. במקרה הזה מה שעזר היה צד מדידת ה-RTT.

5.2. אפשר להסיר את העמימות במדידת RTT בזמן retransmission

כשנכנס retransmission, בלי timestamps נוצרת עמימות: “האם ה-ACK הזה שייך לשליחה הראשונה או ל-retransmission?” זו בדיוק הנקודה שהאלגוריתם של Karn מתייחס אליה.

לפי RFC 6298, אסור לקחת מדגם RTT מ-segment שעבר retransmission, כי לא יודעים לאיזו שליחה שייך ה-ACK. אבל כשיש timestamps option, אפשר להסיר את העמימות הזו: הסתכלות על TSecr שמגיע בתוך ה-ACK מאפשרת לזהות איזה segment, עם איזה TSval, הגיע.

זיהוי השליחה שאליה שייך ה-ACK באמצעות TSecrsegment עם TSval=1000 אובד, השולח ממתין ל-ACK, מבצע retransmission עם TSval=2000, ומקבל ACK עם TSecr=2000 שמאפשר לזהות בוודאות לאיזו שליחה הוא שייך.הצד המקבלהצד השולחהצד המקבלהצד השולחה-segment הזה אובדה-ACK לא מגיע, ולכן ממתיניםאפשר לזהות לאיזו שליחה זו התגובהSeq=N, TSval=1000retransmission עם Seq=N, TSval=2000ACK, TSecr=2000

איור 10: הסתכלות על TSecr מאפשרת לזהות אם ה-ACK הוא תגובה לשליחה הראשונה או ל-retransmission.

זה הליבה של השיפור במקרה הזה.

5.3. למה במקרה הזה התקצר זמן ההמתנה

במקרה הזה packet loss התרחש מדי פעם, ובכל פעם הערכות RTT/RTO נטו להיות שמרניות. הפעלת timestamps מקלה על עדכון הערכת ה-RTT גם ברגעים שכוללים retransmission, וכך מתקצר הזמן שבו הערכת ה-RTO ממשיכה להתנפח בלי עדכון.

זו נקודה שקל לדלג עליה בקפיצה, אז נפרק אותה בזהירות.

קודם כול, הגבול התחתון של ה-RTO עצמו לא משתנה לפי קיום או היעדר timestamps. RFC 6298 קובע שאם ה-RTO המחושב קטן משנייה, יש לעגל אותו כלפי מעלה לשנייה. יש מימושים עם גבול תחתון משלהם — ב-Windows זהו MinRtoMs שמופיע ב-Get-NetTCPSetting (בטווח 20 עד 300 מילישניות, בקפיצות של 10 מילישניות). כלומר, זה לא ש”הגבול התחתון ירד כי הוספנו timestamps”.

מה שבאמת עוזר קורה שלב לפני כן. RFC 6298 קובע שלושה דברים:

  1. בכל פעם שטיימר ה-retransmission פוקע, ה-RTO מוכפל (exponential backoff)
  2. ה-RTO שהוכפל חוזר לערכו כשמתקבלת מדידת RTT חדשה
  3. אותה “מדידת RTT חדשה” מתקבלת רק כשנתונים שלא עברו retransmission נשלחו וקיבלו ACK

יתרה מכך, לפי האלגוריתם של Karn, אסור לקחת מדגם RTT מ-segment שעבר retransmission. אבל כשמשתמשים ב-timestamps option, המגבלה הזו יורדת, כי כמו שהוסבר בסעיף 5.2, הסתכלות על TSecr מאפשרת לזהות לאיזו שליחה שייך ה-ACK.

כשמסדרים את זה ברצף, החוט מתגלה. במערכת שבה loss מתרחש מדי פעם, בלי timestamps קשה שהתנאים 2 ו-3 יתקיימו יחד, ולכן נשאר זמן ארוך שבו ה-RTO המוכפל לא חוזר לערכו על בסיס מדידה בפועל. אם באותו מצב מגיע loss נוסף, ההמתנה מתחילה לא משנייה אלא משתי שניות או ארבע שניות. כשיש timestamps, אפשר למדוד מחדש גם ב-segments שכוללים retransmission, כך שה”זמן שבו לא חוזרים לערך” מתקצר — וזה בדיוק המסלול שעבד במקרה הזה.

התנאים לחזרת ה-RTO המוכפל ואופן הפעולה של timestampsבכל timeout ה-RTO מוכפל וחוזר לערכו כשמתקבלת מדידת RTT חדשה, אבל המדידה מתקבלת רק מ-ACK על נתונים שלא עברו retransmission. כש-timestamps מורידות את המגבלה הזו וניתן למדוד גם ב-segments של retransmission, מתקצר הזמן שבו ה-RTO המוכפל לא חוזר לערכו.הכפלת ה-RTO בכל timeoutחזרה לערך עם מדידת RTT חדשההמדידה רק מ-ACK על נתונים שלא עברו retransmissiontimestamps מאפשרות מדידה גם ב-retransmissionיותר הזדמנויות למדידה מחדשמתקצר הזמן שבו ה-RTO המוכפל לא חוזר

איור 11: הליבה של אופן הפעולה היא לא ירידה של הגבול התחתון, אלא חזרה מהירה יותר של ה-RTO המוכפל על סמך מדידה בפועל.

בכנות: במאמר הזה לא נאספו ערכי RTO בפועל אחרי השיפור. מה שידוע הוא שהעצירות בסדר גודל של שניות ירדו לרמה שלא מהווה בעיה בשטח. אם רוצים להראות את האפקט במספרים, הדרך הקצרה ביותר היא להשתמש ב-display filters מפרק 7 ובעמודה Time delta from previous displayed packet כדי לרכז את התפלגות פערי הזמן עד ל-retransmission, לפני ואחרי.

במילים אחרות, מה שנעשה כאן אינו קסם שמאיץ את TCP, אלא צמצום הזמן שבו TCP ממשיך “לחכות ולראות” יותר מהנדרש.

כמובן, גם RFC 7323 לא טוען ש”יותר מדגמי RTT פותרים הכול בצורה נקייה”. יש היבטים שבהם התרומה לאופטימיזציה של ה-RTO מוגבלת. אבל היכולת להסיר את העמימות בזמן retransmission היא נקודה שיכולה לעבוד טוב במערכות כמו זו שתוארה כאן.

יש גם נקודות לתשומת לב:

  • זה תלוי בחלקו במימוש של ה-TCP stack
  • timestamps לבד לא מעלים את ה-packet loss עצמו
  • אם השכבה הפיזית או ציוד הביניים לקויים, הסיבה השורשית נמצאת במקום אחר
  • כדאי לבדוק בנפרד גם SACK, דרייבר ה-NIC, הגדרות offload ובעיות בצד ה-switch

עם זאת, במערכות שבהן “ה-loss לא אפס” אך “מה שכואב באמת זו ההמתנה בסדר גודל של שניות” — כמו במקרה הזה — זה יכול לעזור באופן משמעותי.

6. מה עשינו בפועל

6.1. הפעלת timestamps

כפתרון, וידאנו ששני קצות החיבור יכולים לסכם את timestamps option. במערכות Windows זה לפעמים מטופל כ-RFC 1323 option, והוא מושפע מהגדרות מערכת ההפעלה והרשת.

השלבים המדויקים. קודם בודקים מה המצב הנוכחי:

netsh interface tcp show global

בפלט מופיע פריט של RFC 1323 timestamps, ובודקים אם הוא מופעל. כדי להפעיל, ב-command prompt עם הרשאות Administrator:

netsh interface tcp set global timestamps=enabled

עבור timestamps אפשר לציין שלושה ערכים: disabled / enabled / default, כאשר default מחזיר לברירת המחדל של המערכת.

כדי לבדוק ולהגדיר דרך PowerShell:

Get-NetTCPSetting | Select-Object SettingName, Timestamps, MinRtoMs, InitialRtoMs
Set-NetTCPSetting -SettingName InternetCustom -Timestamps Enabled

עבור Timestamps אפשר לציין Enabled / Disabled. ה-SettingName שניתן לשנות משתנה לפי גרסת Windows, ולכן לא כדאי להריץ Set- ישר — קודם בודקים עם Get-NetTCPSetting אילו שמות קיימים בפועל. העברת שם שלא קיים תעצור את הפעולה שם.

בסביבות ישנות, אם בודקים ישירות דרך ה-Registry, מדובר בערך Tcp1323Opts (מסוג REG_DWORD) תחת המפתח הבא:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

המשמעות של הערכים: 0 —‏ RFC 1323 options מבוטלות, 1 —‏ window scaling בלבד, 2 —‏ timestamps בלבד, 3 — שניהם מופעלים. כדי לא להתבלבל, כדאי לזכור שביט 0 מתאים ל-window scaling וביט 1 מתאים ל-timestamps.

יש שלוש נקודות לתשומת לב בעת ההגדרה:

  • זה עובד רק על חיבורים חדשים. timestamps מסוכמים ב-3-way handshake, כך שזה לא משפיע על חיבורים שכבר קיימים. צריך לפתוח מחדש את החיבור בצד ההתקן
  • זה לא יעבוד אם שני הצדדים לא תומכים. גם אם מפעילים רק בצד ה-host, אם המצלמה לא מחזירה TSopt ב-SYN/ACK, זה לא ישמש באותו חיבור
  • ההגדרה גם משנה את אופי החיבור. timestamps מגדילות את כותרת TCP, כך שכמות הנתונים שנכנסת ל-segment אחד קטנה מעט

עם זאת, בפועל “TSopt מופיע בפועל ב-packet של SYN / SYN-ACK” חשוב יותר מ”מוצג כמופעל במסך ההגדרות”. זה באמת המצב.

שלוש נקודות לתשומת לב בהגדרת timestampsשלוש נקודות בהגדרת timestamps: ההגדרה עובדת רק על חיבורים חדשים כי היא מסוכמת ב-3-way handshake, שני הצדדים חייבים לתמוך בה, והכותרת גדלה כך שכמות הנתונים ב-segment קטנה מעט.שלוש נקודות לתשומת לבעובד רק מחיבורים חדשיםנדרשת תמיכה בשני הצדדיםהכותרת גדלה והנתונים קטנים מעטיש לפתוח מחדש את חיבור ההתקן

איור 12: ההגדרה לבדה לא מספיקה. צריך גם לפתוח מחדש את החיבור וגם לוודא תמיכה בצד השני.

6.2. בדיקת TSopt ב-SYN / SYN-ACK

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

  • האם יש TSopt ב-SYN של החיבור הבעייתי
  • האם גם צד ה-SYN/ACK מחזיר TSopt
  • האם TSopt ממשיך להופיע גם ב-data segments וב-ACK שבאים אחר כך

רק אחרי אימות הנקודות האלה אפשר לומר ש”timestamps באמת בשימוש בחיבור הזה”.

6.3. איפה לבדוק כשזה עדיין לא עוזר

גם אחרי הפעלת timestamps, במקרים הבאים השיפור עשוי להיות חלש:

  • שיעור ה-loss עצמו גבוה
  • ציוד ביניים שובר, מפיל או משנה TCP options
  • יש בעיה אחרת סביב ה-NIC / הדרייבר / הגדרות ה-offload
  • האפליקציה תולה את כל התהליך בקריאה סינכרונית בודדת, כך שהמתנה אחת נראית כ-stall כולל
  • בפועל הגורם העיקרי אינו TCP, אלא עצירת עיבוד בצד המצלמה או גודש בתור הפנימי של ההתקן

לכן, קל יותר להתקדם עם הטיפול לפי הסדר הבא:

  1. קודם כול, לוודא ב-wire שיש המתנה ל-retransmission
  2. לבדוק אם התבצע משא ומתן על TSopt
  3. להפעיל timestamps ולבדוק את הפער בשיפור
  4. אם עדיין נשאר, לטפל בנפרד במקור ה-loss ובתכנון האפליקציה
הסדר לביצוע הטיפולקודם בודקים ב-wire המתנה ל-retransmission, בודקים אם בוצע משא ומתן על TSopt, מפעילים timestamps ובודקים את פער השיפור, ואם עדיין נשארת בעיה מטפלים בנפרד במקור ה-loss ובתכנון האפליקציה.בדיקת המתנה ל-retransmission ב-wireבדיקת משא ומתן על TSoptהפעלת timestamps ובדיקת השיפוראם נשאר, טיפול נפרד במקור ה-loss ובתכנון

איור 13: סדר של בדיקה, משא ומתן, הפעלה ובדיקת מה שנשאר מקל על פירוק הגורם כשההפעלה לא עוזרת.

7. נקודות בדיקה ב-Wireshark

הנה display filters שנוחים לשימוש בפירוק:

tcp.stream eq <stream היעד>
tcp.analysis.retransmission
tcp.analysis.fast_retransmission
tcp.analysis.lost_segment
tcp.options.timestamp.tsval
tcp.options.timestamp.tsecr

יש כמה טיפים לאופן ההסתכלות:

  • מצמצמים ל-tcp.stream של החיבור היעד בלבד
  • מציגים את Time delta from previous displayed packet ורואים ישירות כמה שניות נמשך ה-stall
  • בודקים אם Retransmission מופיע ברגע הבעייתי
  • בודקים אם TSopt סוכם ב-SYN / SYN-ACK בתחילת החיבור
  • בודקים אם TSecr חוזר ב-ACK

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

היכן מסתכלים איך זה נראה
עמודת ה-Info ברשימת ה-packets על packets של retransmission מופיע [TCP Retransmission]
צבע השורה זה תואם לכלל הצביעה ברירת המחדל של Wireshark “Bad TCP”, כך שהשורה מקבלת רקע שחור וטקסט אדום. אפשר לתפוס את זה גם במבט חטוף
חלונית הפרטים בוחרים את השורה, פותחים את Transmission Control Protocol, ובתוכו את SEQ/ACK analysis — שם מופיע ציון שה-packet זוהה כ-retransmission
פער הזמן הצגת Time delta from previous displayed packet כעמודה מראה כמה שניות עברו מה-packet המוצג הקודם. כאן רואים רצף של שנייה, שתי שניות
ה-Options של ה-SYN בוחרים את שורת ה-SYN, פותחים את Options, ובודקים אם יש פריט Timestamps — כך יודעים אם יש TSopt

הרצף האופייני נראה כך: תחילה שורה עם אותו Seq מופיעה שוב אחרי שנייה, ואז שוב אחרי שתי שניות נוספות, ומיד אחרי השורה האחרונה חוזר ה-ACK, ומשם מתחדשים חילופי הדברים הרגילים. אם “פער השניות הריק” הזה תואם את הזמן שבו התגובה נעצרה בלוג האפליקציה, כמעט אפשר לקבוע את החשוד.

כשמצליבים בין הלוג לבין ה-packets, יש לשים לב גם להפרש בין בסיס הזמן של האפליקציה לבין בסיס הזמן של ה-capture. אם יש הסטה כאן, קל להאשים אירוע לא קשור.

התהליך לקביעת החשוד ב-Wiresharkמצמצמים ל-tcp.stream של החיבור היעד, מסתכלים על עמודת פער הזמן כדי לראות ישירות את משך ה-stall, מוודאים שורות retransmission לאותו Seq, ואם הפער תואם את זמן ה-stall בלוג האפליקציה החשוד כמעט מוכרע.כןלאצמצום ל-tcp.stream של החיבורהסתכלות על עמודת פער הזמןוידוא שורות retransmission לאותו Seqתואם את זמן ה-stall באפליקציה?החשוד כמעט מוכרעלחשוד בהפרש זמן או בגורם אחר

איור 14: לצמצם, להסתכל על פער הזמן, ולהצליב. בשלושה צעדים אלה קובעים את זהות “פער השניות הריק”.

8. איך לבחור כיוון, בגדול

סימפטום הגורם החשוד הראשון מה לבדוק תחילה
stall מדי פעם בסדר גודל של שניות המתנה ל-RTO ב-TCP לבדוק retransmission ופער זמן ב-packets
stall כמעט באותו תזמון בכל פעם המתנה בתוך האפליקציה, עיבוד בצד ההתקן, timeout קבוע לבדוק threads, קריאות SDK ולוגי התקן
מחמיר רק בעומס גבוה CPU, GC, גודש בתור לבדוק CPU, interrupts, זיכרון ואורך תור
גרוע בבת אחת על פני חיבורים רבים השכבה הפיזית, switch, ציוד ביניים לבדוק NIC, כבלים, סטטיסטיקת פורטים ולוגי ציוד ביניים
שינוי הגדרה לא שינה כלום TCP option לא סוכם בפועל לבדוק שוב את SYN / SYN-ACK

השורה האחרונה קורית ממש הרבה. תחושת הסיפוק מכך ששיחקתם עם ההגדרות, והעובדה שהיא באמת בשימוש ב-wire — הם שני דברים שונים.

9. סיכום

הנקודות העיקריות הפעם:

  • “לפעמים נתקע לכמה שניות” יכול להיות המתנה ל-TCP retransmission, ולא stall של האפליקציה
  • אם משך ה-stall תואם את אופן ההמתנה של ה-RTO ומופיע Retransmission, זו השערה חזקה למדי
  • TCP timestamps option היא מנגנון של RTTM ו-PAWS, שגם מסירה את העמימות במדידת RTT בזמן retransmission
  • במקרה הזה, הפעלת timestamps לפי RFC1323 קיצרה את הזמן שבו ה-RTO נשאר שמרני מדי

דרכי פעולה שכדאי להימנע מהן:

  • לקבוע את החשוד ל-stall בתקשורת רק לפי לוגי האפליקציה
  • להסתכל רק על הגדרות מערכת ההפעלה בלי לבדוק את ה-packets עצמם
  • לחשוב שהפעלת timestamps מעלים גם את מקור ה-loss

דרכי פעולה שעובדות בפועל:

  • קודם כול, להסתכל על ה-wire
  • לבדוק את הצורה של ה-retransmission וזמן ההמתנה
  • לוודא משא ומתן על TSopt
  • גם אחרי השיפור, לטפל בנפרד במקור ה-loss ובתכנון האפליקציה

במילים אחרות, בסוג הזה של תקלות עדיף קודם “לזהות איפה ממתינים” ולא “להאיץ”. רק אם לא מפספסים את הנקודה הזו, החקירה מתקצרת משמעותית.

10. מקורות

מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.

העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.

חקרי המקרה האלה מציגים גישה דומה לניתוח, לתעדוף או לעיצוב מחדש.

המאמר קשור ישירות לשירותים הבאים.

שאלות נפוצות

שאלות נפוצות בפניות בנושא המאמר.

מה זה TCP Retransmission?
מנגנון שבו TCP שולח שוב את אותם הנתונים כשה-ACK על packet שנשלח לא חוזר. אם packet נופל איפשהו בדרך, הצד השולח ממתין ל-ACK, ואם הוא לא מגיע — מחכים שטיימר ה-retransmission (RTO) יפוג ורק אז משדרים שוב. מהאפליקציה זה נראה כ"עצירה של כמה שניות", אבל מבחינת TCP זו פשוט המתנה לטיימר עד שה-ACK יגיע. זו צורת stall שכיחה. ב-packet capture רואים את זה כ-TCP Retransmission.
מה גורם ל-TCP Retransmission?
הטריגר הישיר הוא packet loss: ה-ACK לא חוזר, ולכן קורה retransmission. את מקור ה-loss בודקים בנפרד — השכבה הפיזית (כבלים ופורטים), ה-NIC והדרייבר או הגדרות ה-offload, ובעיות ב-switch או בציוד ביניים. הפעלת TCP timestamps יכולה לקצר את ההמתנה אחרי retransmission, אבל זה לא קסם שמעלים את ה-loss עצמו, ולכן חקירת מקור ה-loss נשארת נפרדת. יש גם מקרים שבהם ציוד ביניים שובר או מפיל TCP options, וגם מקרים שבהם הגורם העיקרי בפועל הוא עצירת עיבוד בצד ההתקן ולא TCP בכלל.
למה TCP retransmission עוצר תקשורת לכמה שניות?
כי טיימר ה-retransmission (RTO) של TCP ממתין באופן שמרני. לפי RFC 6298, ה-RTO ההתחלתי מבוסס על שנייה אחת; אם תוצאת החישוב קטנה מזה, מעגלים כלפי מעלה לשנייה, וכל timeout מכפיל את הערך. בתנאים גרועים רואים המתנה כמו שנייה, שתי שניות, ארבע שניות. בתקשורת בקרה שמבוססת בעיקר על request/response קטנים, לפני שמספיקים Duplicate ACK כדי להיכנס ל-fast retransmit, נוטה להיחשף קודם המתנה ל-RTO — וזה מופיע כעצירה נדירה של כמה שניות. הפעלת TCP timestamps option יכולה, במקרים מסוימים, להסיר את העמימות במדידת RTT בזמן retransmission ולקצר את הזמן שבו הערכת ה-RTO נשארת שמרנית מדי.
איך בודקים TCP Retransmission ב-Wireshark?
אפשר להשתמש ב-display filters tcp.analysis.retransmission, tcp.analysis.fast_retransmission ו-tcp.analysis.lost_segment. מצמצמים ל-tcp.stream של החיבור הרלוונטי, מציגים את Time delta from previous displayed packet כדי לראות ישירות כמה שניות נמשכה העצירה, ובודקים אם Retransmission מופיע ברגע הבעייתי ואם פער הזמן עד ה-retransmission תואם את משך ה-stall. האם משתמשים ב-TCP timestamps בודקים לפי משא ומתן על TSopt ב-SYN / SYN-ACK בתחילת החיבור. העובדה ש-TSopt נמצא בפועל ב-packets חשובה יותר מזה שההגדרה מוצגת כמופעלת במסך ההגדרות.

פרופיל הכותב

עמוד היכרות עם כותב המאמר.

Go Komura

מנהל KomuraSoft LLC

מתמחה בפיתוח תוכנה עבור Windows, ייעוץ טכני וחקירת תקלות, בעיקר בפרויקטים עם מערכות קיימות ובאגים שקשה לשחזר.

קישורים ציבוריים

חזרה לבלוג