הסיבה לכך ששידור חוזר ב-TCP עוצר תקשורת עם מצלמה תעשייתית, ואיך מבודדים אותה
· עודכן בתאריך: · Go Komura · TCP, רשתות, חקירת תקלות, פיתוח Windows, מצלמה תעשייתית
בתקשורת עם מצלמות תעשייתיות ובבקרת התקנים, התופעה הכי מטרידה היא כשבממוצע הכול מהיר, אבל לפעמים יש עצירה של כמה שניות. שיעור השחזור נמוך, ורוב הזמן שום דבר לא קורה, כך שה-UI, התהליכונים, ה-GC, ה-SDK של המצלמה, ה-NIC והמתג — כולם מתחילים להיראות קצת חשודים.
במקרה הזה מדובר בתקשורת TCP בין אפליקציה ששולטת במצלמה תעשייתית לבין ה-host, שבה לעיתים נדירות התקשורת נעצרת לכמה שניות בלבד. כשבדקנו, התברר שהאשם אינו עצירה של האפליקציה, אלא המתנה לשידור חוזר ב-TCP שנובעת מאובדן מנות. יתרה מכך, הפעלה של פונקציית חותמות הזמן מסדרת RFC1323 (בסיווג הנוכחי — RFC 7323) אפשרה לצמצם את זמן ההמתנה למינימום במערכת הזו.
שמות ההתקנים, התצורה והמספרים הוכללו, אבל אופן החשיבה ישים ישירות בעבודה בפועל.
תוכן עניינים
- קודם כול, המסקנה (במשפט אחד)
- איך התסמין נראה
- 2.1. האפליקציה חיה, אבל התגובה נעצרת לכמה שניות
- 2.2. בתדירות נמוכה, קשה לראות רק מהלוגים
- מה קרה בפועל (בתרשימים)
- 3.1. מאובדן מנות להמתנה לשידור חוזר
- 3.2. העצירה בסדר גודל של שניות תאמה לצורת ה-RTO
- נקודות שנבדקו בחקירה
- 4.1. קודם כול, לשלול גורמי עצירה בתוך האפליקציה
- 4.2. אימות שידור חוזר בלכידת מנות
- 4.3. בדיקת אפשרויות ה-TCP שסוכמו
- הסיבה לכך שחותמות הזמן של RFC1323 עוזרות
- 5.1. חותמות הזמן נועדו ל-RTTM ול-PAWS
- 5.2. אפשר להסיר את העמימות במדידת RTT בעת שידור חוזר
- 5.3. הסיבה לכך שבמקרה הזה הצטמצם זמן ההמתנה
- הפעולות שבוצעו בפועל
- 6.1. הפעלת חותמות הזמן
- 6.2. בדיקת TSopt ב-SYN / SYN-ACK
- 6.3. איפה לבדוק כשזה עדיין לא עוזר
- נקודות בדיקה ב-Wireshark
- חלוקה גסה בין המצבים
- סיכום
- מקורות
מפת הידע של המאמר
מאמר שמפרק את הסיבה לכך שבאפליקציית בקרה למצלמה תעשייתית, לעיתים רחוקות התקשורת נעצרת לכמה שניות בלבד. הסיבה לא הייתה עצירה של האפליקציה, אלא המתנה לשידור חוזר — אובדן חבילה מנע חזרת ACK, ו-TCP המתין לפקיעת טיימר השידור החוזר (RTO). מכיוון ש-RTO מוכפל בכל כישלון החל מערך התחלתי של שנייה אחת, בתנאים גרועים זה נראה כעצירה בסדר גודל של כמה שניות. הפעלת אופציית חותמת הזמן של TCP (RFC1323/RFC7323) מסירה את המגבלה שאלגוריתם Karn אוסר — מדידת RTT מתוך מקטע ששודר מחדש — וכך מקטינה את משך הזמן שבו ה-RTO נשאר שמרני יתר על המידה, אבל זה לא מנגנון שמבטל את אובדן החבילה עצמו. בדיקת השידור החוזר וזמן ההמתנה ב-Wireshark, ואימות משא ומתן ה-TSopt ב-SYN/SYN-ACK, הם הבסיס לפירוק הבעיה.
flowchart LR
accTitle: מפת הידע של שידור חוזר ב-TCP ואופציית חותמת הזמן של RFC1323
accDescr: תרשים שמראה איך אובדן חבילה גורם לשידור חוזר ב-TCP ולהמתנה ל-RTO, שנראית כעצירת תקשורת של כמה שניות; איך אופציית חותמת הזמן של TCP מסירה את המגבלה של אלגוריתם Karn ומקטינה את חוסר הוודאות במדידת ה-RTT בזמן שידור חוזר; והקשר לשלבי הבדיקה ב-Wireshark.
tcp_retransmission["שידור חוזר ב-TCP (TCP Retransmission)"]
tcp_rto["RTO (טיימר השידור החוזר)"]
tcp_timestamps_option["אפשרות חותמות הזמן של TCP"]
packet_loss["אובדן מנות"]
tcp_rtt["RTT (זמן הלוך-ושוב)"]
intermittent_communication_stall["עצירות תקשורת לסירוגין של שניות בודדות"]
wireshark["Wireshark"]
rttm["RTTM (מדידת זמן הלוך-ושוב)"]
paws["PAWS (הגנה מפני מחזור מספרי הרצף)"]
karn_algorithm["האלגוריתם של Karn"]
retransmission_rtt_ambiguity["עמימות מדידת ה-RTT בעת שידור חוזר"]
fast_retransmit["fast retransmit (שידור חוזר מהיר)"]
duplicate_ack["Duplicate ACK (אישור כפול)"]
tcp_handshake["לחיצת היד המשולשת של TCP"]
windows_tcp_timestamp_setting["הגדרת חותמות הזמן של TCP ב-Windows"]
packet_loss -->|"עלול לגרום ל"| tcp_retransmission
tcp_retransmission -.->|"מחייב"| tcp_rto
tcp_rto -->|"משתמש ב"| tcp_rtt
tcp_retransmission -->|"עלול לגרום ל"| intermittent_communication_stall
intermittent_communication_stall -->|"נבדק באמצעות"| wireshark
tcp_retransmission -->|"נבדק באמצעות"| wireshark
packet_loss -->|"נבדק באמצעות"| wireshark
tcp_timestamps_option -->|"משתמש ב"| rttm
tcp_timestamps_option -->|"משתמש ב"| paws
karn_algorithm -->|"מצמצם"| retransmission_rtt_ambiguity
tcp_timestamps_option -->|"מצמצם"| retransmission_rtt_ambiguity
tcp_timestamps_option -.->|"מצמצם"| intermittent_communication_stall
fast_retransmit -.->|"מונע"| tcp_rto
fast_retransmit -->|"מחייב"| duplicate_ack
packet_loss -->|"עלול לגרום ל"| duplicate_ack
tcp_timestamps_option -->|"מחייב"| tcp_handshake
tcp_timestamps_option -.->|"מוגדר באמצעות"| windows_tcp_timestamp_setting
windows_tcp_timestamp_setting -->|"נבדק באמצעות"| wireshark
tcp_rto -->|"משתמש ב"| karn_algorithm
בתרשים, קו מלא מציין קשר שמתקיים תמיד וקו מקווקו מציין קשר מותנה (תנאי ההתקיימות מפורטים בהסבר של כל קשר בעמוד המפורט). רשימת כל הקשרים (סך הכול 19, עם אסמכתה ורמת ודאות) והגדרות המושגים המרכזיים מרוכזות בעמוד המפורט של מפת הידע (ביפנית). נתונים: JSON-LD / Turtle
1. קודם כול, המסקנה (במשפט אחד)
- תקשורת TCP שנעצרת לעיתים נדירות לכמה שניות עשויה להיות לא עצירה של האפליקציה, אלא המתנה לשידור חוזר לאחר אובדן מנות
- אם בלכידת המנות רואים
Retransmissionופער זמן גדול, ומשך העצירה תואם את אופן ההמתנה של ה-RTO, זה חשוד מאוד - אפשרות חותמות הזמן של TCP קיימת למדידת RTT ול-PAWS, והיא גם מאפשרת להסיר את העמימות במדידת RTT בעת שידור חוזר
- במקרה הזה, הפעלת פונקציית חותמות הזמן מסדרת RFC1323 צמצמה את הזמן שבו הערכת ה-RTO נשארת ישנה ושמרנית מדי, וכך צומצמה העצירה בסדר גודל של שניות למינימום
- עם זאת, זו אינה קסם שמסלק את האובדן עצמו. יש לבחון בנפרד את השכבה הפיזית, ה-NIC, המתג, ציוד הביניים, הדרייברים ותכנון ה-buffer
בקיצור, אם הזהות האמיתית של “עצירה של כמה שניות מדי פעם” היא זמן המתנה בתוך ה-TCP, אז מאמץ שמושקע רק בניסיונות חוזרים (retry) באפליקציה מפספס את הליבה. מהיר יותר להסתכל קודם על ה-wire ולקבוע אם מדובר בהמתנה לשידור חוזר.
flowchart TB
accTitle: זרימת המסקנה של המאמר
accDescr: תרשים המראה שבתקשורת TCP שנעצרת לעיתים נדירות לכמה שניות יש להסתכל קודם על ה-wire ולקבוע אם מדובר בהמתנה לשידור חוזר, שאז לעיתים אפשר לצמצם את ההמתנה בעזרת timestamps, אבל חקירת מקור האובדן עצמו נדרשת בנפרד.
sym["תקשורת TCP שנעצרת מדי פעם"] --> wire["קודם כול, הסתכלות על wire"]
wire --> conf["קביעה אם זו המתנה לשידור חוזר"]
conf -.-> ts["timestamps עשויות לצמצם המתנה"]
conf -.-> loss["חקירת מקור האובדן נדרשת בנפרד"]
איור 1: לפני שמתאמצים על ניסיונות חוזרים באפליקציה, קודם קובעים ב-wire “איפה ממתינים”.
בהמשך יופיעו רצף של קיצורים מעולם ה-TCP. עבור מפתחי Windows שלא מתמחים ברשתות, הנה סיכום מראש. אם תשלטו רק בזה, לא תיתקעו בהמשך.
| מונח | שם מלא | משמעות |
|---|---|---|
| ACK | Acknowledgment | אישור קבלה. מנגנון שמודיע לצד השני “קיבלתי עד כאן” |
| RTT | Round-Trip Time | זמן הלוך-ושוב. הזמן משליחה ועד שחוזר ה-ACK |
| RTO | Retransmission Timeout | טיימר השידור החוזר. אם ה-ACK לא חוזר בתוך הזמן הזה, מתבצע שידור חוזר. הוא מחושב מהערכת ה-RTT |
| RTTM | Round-Trip Time Measurement | מדידת ה-RTT. אחת ממטרות פונקציית חותמות הזמן |
| PAWS | Protect Against Wrapped Sequences | הגנה מפני מצב שבו מספר הרצף עושה סיבוב שלם (wrap). המטרה השנייה של פונקציית חותמות הזמן |
| TSopt | TCP Timestamps Option | אחת האפשרויות שמצורפות לכותרת ה-TCP. סוג 8, אורך 10 בייטים, ונושאת שני ערכים |
| TSval | Timestamp Value | הערך שהצד השולח מכניס — הזמן לפי השעון שלו |
| TSecr | Timestamp Echo Reply | השדה שמחזיר בדיוק את ה-TSval שהתקבל. כך אפשר לדעת “לאיזו שליחה שייך האישור הזה” |
| SACK | Selective Acknowledgment | מנגנון שמאפשר לצד המקבל להודיע באופן פרטני “אילו טווחים התקבלו” |
| Dup ACK | Duplicate ACK | מצב שבו מתקבלים כמה ACK החוזרים על אותו מספר רצף. זה סימן לפער באמצע |
| fast retransmit | — | מנגנון שמבצע שידור חוזר בלי להמתין לתפוגת ה-RTO, ברגע שמצטבר מספר מסוים של Dup ACK. ברירת המחדל ב-Windows היא “לאחר קבלת שלושה ACK לאותו מספר רצף (הראשון ועוד שניים כפולים)” |
| האלגוריתם של Karn | — | הכלל שאומר שאסור לקחת מדגם RTT מקטע שעבר שידור חוזר, כי לא ידוע לאיזו שליחה שייך ה-ACK |
2. איך התסמין נראה
2.1. האפליקציה חיה, אבל התגובה נעצרת לכמה שניות
מה שמבלבל בהתחלה הוא שהאפליקציה כולה לא נראית תקועה.
- ה-UI לא מת לגמרי
- התהליך (process) לא קרס
- ה-CPU גם לא תקוע
- אבל רק התגובה לפקודות בקרת המצלמה נעלמת מדי פעם לכמה שניות
קשה להבחין בין תסמינים כאלה לבין קיפאון (deadlock) או לולאה אינסופית בתוך האפליקציה. יתרה מכך, בבקרת התקנים עצירה בודדת של כמה שניות מתקבלת מיד כרושם של עצירת קו הייצור. גם אם הממוצע נראה נקי, החוויה בשטח גרועה למדי.
2.2. בתדירות נמוכה, קשה לראות רק מהלוגים
מה שמטריד בסוג הזה של תקלה הוא שהתדירות נמוכה. ההתנהגות היא בערך פעם בשעה, פעם בחצי יום, או רק כשכמה תנאים מתלכדים יחד.
אם עוקבים אחר זה רק דרך הלוגים, בדרך כלל קורה כך:
- אצל האפליקציה, הלוג נעצר במצב “נשלח” ואז “לא חוזר”
- בצד המקבל, הלוג נראה כאילו “שום דבר לא הגיע”
- באותו פרק זמן קורים במקרה גם אירועים אחרים, והחשוד מתפזר
במצב כזה, ניסיון לשחזר את הקשר הסיבתי רק מלוגי האפליקציה נוטה להיתקע בבוץ. מהיר יותר לרדת שלב אחד עד שכבת התקשורת.
flowchart TB
accTitle: המבנה שבו הלוגים לבדם לא קובעים את החשוד
accDescr: תרשים המראה שלוג האפליקציה נעצר במצב שנשלח ולא חוזר, לוג הצד המקבל נראה כאילו לא הגיע דבר, ואירועים אחרים באותו פרק זמן מפזרים את החשוד, ולכן עדיף לרדת עד שכבת התקשורת ולא לנסות לשחזר את הסיבתיות רק מלוגי האפליקציה.
l1["לוג האפליקציה: נשלח ולא חוזר"] --> lost["החשוד מתפזר ונתקעים בבוץ"]
l2["לוג הצד המקבל: לא הגיע דבר"] --> lost
l3["אירוע אחר באותו פרק זמן"] -.-> lost
lost --> down["ירידה שלב אחד עד שכבת התקשורת"]
איור 2: עצירה בתדירות נמוכה שעוקבים אחריה רק בלוגים נתקעת בבוץ. מהיר יותר להסתכל דרך המנות.
3. מה קרה בפועל (בתרשימים)
3.1. מאובדן מנות להמתנה לשידור חוזר
התרחיש הפעם פשוט. מנה אבדה איפשהו בדרך, הצד השולח המתין ל-ACK, וכשזה לא הגיע, הוא המתין לתפוגת ה-RTO ואז ביצע שידור חוזר.
sequenceDiagram
accTitle: מעבר מאובדן מנה להמתנה לשידור חוזר
accDescr: תרשים רצף המראה שפקודת בקרה נשלחת מהמארח, המנה אובדת ברשת, המארח ממתין לתפוגת ה-RTO, מבצע שידור חוזר, והמנה המשודרת מחדש מגיעה למצלמה ומקבלת ACK שמסמן חידוש התקשורת.
participant Host as אפליקציית ה-Host
participant Net as הרשת
participant Cam as צד המצלמה
Host->>Net: פקודת בקרה (Seq=N)
Note over Net: כאן מתרחש האובדן
Note over Host: ה-ACK לא מגיע, ולכן ממתינים
Note over Host: השחזור של הבקשה הזו כולל המתנה ל-RTO
Host->>Net: שידור חוזר של פקודת הבקרה
Net->>Cam: המנה המשודרת מחדש מגיעה
Cam-->>Net: ACK
Net-->>Host: ACK
Note over Host: כאן התקשורת מתחדשת
איור 3: כשמנה אובדת, ה-ACK לא חוזר וממתינים לתפוגת ה-RTO לפני שידור חוזר. מבחינת האפליקציה, פרק הזמן הזה נראה כ”עצירה של כמה שניות”.
מבחינת האפליקציה זה נראה כ”עצירה של כמה שניות”, אבל מבחינת TCP זה פשוט “ה-ACK עדיין לא הגיע, ולכן ממתינים לתפוגת טיימר השידור החוזר”. זה לא מרשים, אבל עצירה מהסוג הזה שכיחה למדי.
תקשורת הבקרה במקרה הזה כללה בעיקר בקשות/תגובות (request/response) קטנות, ובכל חילופין לא נשלחה כמות גדולה של נתונים ללא ACK. לכן במקום שיצטברו מספיק Duplicate ACK כדי להפעיל fast retransmit, המבנה נטה לחשוף קודם המתנה ל-RTO.
flowchart TB
accTitle: הסיבה לכך שבתקשורת בקרה נחשפת בקלות המתנה ל-RTO
accDescr: תרשים המראה שבתקשורת בקרה המבוססת בעיקר על request/response קטנים יש מעט נתונים ללא ACK, לכן Duplicate ACK לא מצטברים מספיק, קשה להפעיל fast retransmit, ולכן נחשפת המתנה ל-RTO.
small["בעיקר request/response קטנים"] --> few["מעט נתונים ללא ACK"]
few --> nodup["Dup ACK לא מצטברים מספיק"]
nodup --> nofr["קשה להפעיל fast retransmit"]
nofr --> rto["נחשפת המתנה ל-RTO"]
איור 4: בשונה מתקשורת שזורמים בה נתונים רבים, אובדן בתקשורת בקרה נוטה להסתיים בהמתנה לתפוגת RTO.
3.2. העצירה בסדר גודל של שניות תאמה לצורת ה-RTO
ההמתנה לשידור חוזר ב-TCP שמרנית באופייה, גם אם יש הבדלים בין מימושים. לפי RFC 6298, ה-RTO ההתחלתי מבוסס על שנייה אחת: אם תוצאת החישוב קטנה מכך, מעגלים כלפי מעלה ל-1 שנייה, ועם כל תפוגה (timeout) מכפילים אותו.
flowchart LR
accTitle: מחזור ההכפלה של RTO עד לחידוש התקשורת
accDescr: תרשים המראה שאובדן מנה גורם להיעדר ACK, שמוביל להמתנה ל-RTO ואז לשידור חוזר; אם ה-ACK חוזר התקשורת מתחדשת, ואם לא, ה-RTO מוכפל והמחזור חוזר על עצמו.
A["אובדן מנה"] --> B["ה-ACK לא מגיע"]
B --> C["המתנה ל-RTO"]
C --> D["שידור חוזר"]
D --> E{"ה-ACK חוזר?"}
E -- "כן" --> F["התקשורת מתחדשת"]
E -- "לא" --> G["הכפלת ה-RTO"]
G --> C
איור 5: ה-RTO מוכפל בכל פעם שה-ACK לא חוזר. צורת ההמתנה של שנייה, שתי שניות, ארבע שניות נובעת מהמנגנון הזה.
לכן, גם ברגעים שבהם היינו רוצים שהעניין ייגמר תוך מאות מילישניות, בתנאים גרועים אפשר לראות דפוס המתנה כמו שנייה, שתי שניות, ארבע שניות. ה”עצירה הנדירה של כמה שניות” במקרה הזה תאמה את הצורה הזו בצורה די ישירה.
4. נקודות שנבדקו בחקירה
4.1. קודם כול, לשלול גורמי עצירה בתוך האפליקציה
בלי לקבוע מראש ש-TCP הוא האשם, קודם שללנו את הגורמים האופייניים בצד האפליקציה.
| מה נבדק | הסיבה לבדיקה | המסקנה במקרה הזה |
|---|---|---|
| ת’רד ה-UI / ת’רדי עבודה | בדיקת תקיעה (hang) או המתנה הדדית | לא היה הגורם העיקרי |
| ניצול CPU | בדיקת עיכוב עיבוד עקב עומס גבוה | גם בזמן העצירה ה-CPU לא היה תקוע |
| GC / לחץ זיכרון | בדיקת השהיה זמנית | צורת זמן ההשהיה לא תאמה |
| קריאות ל-SDK של המצלמה | בדיקת המתנה בתוך ה-SDK | לא תאם לעיכוב שנצפה ב-wire |
| לכידת מנות | בדיקת שידור חוזר בשכבת התקשורת | כאן נראה חוט הסיבה האמיתי |
החשוב כאן הוא לא לקבוע את החשוד רק לפי זמני לוג האפליקציה. באפליקציות בקרת התקנים, המתנה בשכבה עליונה לפעמים רק משקפת המתנה בשכבה נמוכה יותר.
flowchart TB
accTitle: סדר הבידוד ששולל קודם גורמים בתוך האפליקציה
accDescr: תרשים המראה שבמקום לקבוע מראש ש-TCP הוא האשם, קודם שוללים גורמי עצירה אופייניים בתוך האפליקציה כמו תהליכונים, CPU, GC ו-SDK של המצלמה, ורק אז בודקים שידור חוזר בשכבת התקשורת באמצעות לכידת מנות.
app["שלילת תהליכונים, CPU, GC ו-SDK תחילה"] --> cap["בדיקת שכבת התקשורת בלכידת מנות"]
cap --> found["חוט הסיבה של השידור החוזר מתגלה"]
app -.-> warn["לא לקבוע חשוד רק לפי זמני הלוג"]
איור 6: לא לקבוע מראש. קודם שוללים גורמים אופייניים בתוך האפליקציה, ורק אז יורדים אל ה-wire.
4.2. אימות שידור חוזר בלכידת מנות
כשלכדנו את המנות, ראינו TCP Retransmission בדיוק בפרק הזמן של העצירה, ומצאנו שממש לפני כן ה-ACK לא חזר.
אלה הנקודות שכדאי לבדוק:
- האם מופיע שידור חוזר לאותו
Seq - האם פער הזמן עד השידור החוזר תואם את משך העצירה
- האם זה נראה כהמתנה לתפוגת RTO ולא כ-
Dup ACKאוFast Retransmission - האם החיבור הבעייתי מופיע תמיד באותו
tcp.stream
כשהנקודות האלה מתיישרות, ההשערה ש”ה-TCP ממתין לשידור חוזר” — ולא ש”האפליקציה נעצרת” — מתחזקת מאוד.
flowchart TB
accTitle: נקודות הבדיקה שקובעות המתנה לשידור חוזר
accDescr: תרשים המראה ששלוש נקודות בדיקה — שידור חוזר לאותו Seq, פער זמן שתואם את משך העצירה, והופעה שנראית כהמתנה לתפוגת RTO ולא כ-fast retransmission — כשמתיישרות מחזקות את ההשערה שה-TCP ממתין לשידור חוזר ולא שהאפליקציה נעצרת.
c1["שידור חוזר לאותו Seq"] --> conc["ה-TCP ממתין לשידור חוזר"]
c2["פער זמן שתואם את משך העצירה"] --> conc
c3["נראה כהמתנה לתפוגת RTO"] --> conc
conc -.-> not["האפליקציה לא נעצרת"]
איור 7: אם שלוש הנקודות האלה מתיישרות, ההשערה עוברת מ”האפליקציה נעצרת” ל”ה-TCP ממתין לשידור חוזר”.
4.3. בדיקת אפשרויות ה-TCP שסוכמו
הדבר הבא שבדקנו היה ה-SYN / SYN-ACK בתחילת החיבור. חותמות הזמן מסוכמות (negotiated) בלחיצת היד המשולשת (3-way handshake) של חיבור ה-TCP, ואם ה-TSopt לא מופיע שם, הוא לא ישמש באותו חיבור.
sequenceDiagram
accTitle: סיכום TSopt בלחיצת היד המשולשת
accDescr: תרשים רצף המראה שהמארח שולח SYN עם TSopt אפשרי, המצלמה מחזירה SYN/ACK עם TSopt אפשרי, ורק אחרי שהסיכום הצליח ניתן להשתמש ב-TSopt בקטעים הבאים.
participant Host as המארח
participant Cam as צד המצלמה
Host->>Cam: SYN + TSopt?
Cam-->>Host: SYN/ACK + TSopt?
Host->>Cam: ACK
Note over Host,Cam: רק אחרי שהסיכום הזה מצליח, אפשר להשתמש ב-TSopt בקטעים הבאים
איור 8: חותמות הזמן מסוכמות בלחיצת היד המשולשת. אם אין TSopt ב-SYN / SYN-ACK, הן לא ישמשו באותו חיבור.
אם משנים רק את הגדרות מערכת ההפעלה בלי לבדוק את זה, קורה תקלה שקטה נוספת: “הפעלתי, אבל זה לא עובד”. העובדה שנראית ב-wire חזקה יותר מערך ההגדרה.
5. הסיבה לכך שחותמות הזמן של RFC1323 עוזרות
בפועל השם “חותמות הזמן של RFC1323” עדיין נפוץ, אבל הסיווג העדכני הוא RFC 7323. במאמר הזה אנחנו כותבים RFC1323 בהתאם למקובל, אך הכוונה היא לאפשרות חותמות הזמן של TCP.
5.1. חותמות הזמן נועדו ל-RTTM ול-PAWS
אפשרות ה-timestamps של TCP משמשת בעיקר לשתי מטרות:
- RTTM (מדידת זמן הלוך-ושוב)
- PAWS (הגנה מפני מחזור מספרי הרצף)
מה שעזר במקרה הזה הוא הצד של RTTM. הצד השני מחזיר את TSval של הקטע שנשלח בתוך TSecr של ה-ACK, וכך הצד השולח יכול למדוד את ה-RTT בפירוט ובדיוק רבים יותר.
flowchart TB
accTitle: שתי המטרות של אפשרות ה-timestamps
accDescr: תרשים המראה שאפשרות ה-timestamps של TCP משמשת לשתי מטרות, RTTM שהיא מדידת זמן הלוך-ושוב ו-PAWS שהיא הגנה מפני מחזור מספרי הרצף, ושבמקרה הזה מה שעזר היה הצד של RTTM.
tso["timestamps option"] --> rttm["RTTM (מדידת זמן הלוך-ושוב)"]
tso --> paws["PAWS (הגנה מפני מחזור מספרי רצף)"]
rttm --> hit["זה מה שעזר במקרה הזה"]
rttm -.-> how["מדידה בהחזרת TSval בתוך TSecr"]
איור 9: למטרת חותמות הזמן שני צדדים — RTTM ו-PAWS. במקרה הזה מה שעזר היה צד מדידת ה-RTT.
5.2. אפשר להסיר את העמימות במדידת RTT בעת שידור חוזר
כשמתרחש שידור חוזר, בלי חותמות זמן נוצרת עמימות: “האם ה-ACK הזה שייך לשליחה הראשונה או לשידור החוזר?” זו בדיוק הנקודה שהאלגוריתם של Karn מתייחס אליה.
לפי RFC 6298, אסור לקחת מדגם RTT מקטע שעבר שידור חוזר, מכיוון שלא ידוע לאיזו שליחה שייך ה-ACK. אבל כשקיימת אפשרות ה-timestamps, אפשר להסיר את העמימות הזו: הסתכלות על TSecr שמגיע בתוך ה-ACK מאפשרת לזהות איזה קטע, עם איזה TSval, הגיע.
sequenceDiagram
accTitle: זיהוי השליחה שאליה שייך ה-ACK באמצעות TSecr
accDescr: תרשים רצף המראה שקטע עם TSval=1000 אובד, השולח ממתין ל-ACK, מבצע שידור חוזר עם TSval=2000, ומקבל ACK עם TSecr=2000 שמאפשר לזהות בוודאות לאיזו שליחה הוא שייך.
participant Host as הצד השולח
participant Cam as הצד המקבל
Host->>Cam: Seq=N, TSval=1000
Note over Host,Cam: הקטע הזה אובד
Note over Host: ה-ACK לא מגיע, ולכן ממתינים
Host->>Cam: שידור חוזר עם Seq=N, TSval=2000
Cam-->>Host: ACK, TSecr=2000
Note over Host: אפשר לזהות לאיזו שליחה זו התגובה
איור 10: הסתכלות על TSecr מאפשרת לזהות אם ה-ACK הוא תגובה לשליחה הראשונה או לשידור החוזר.
זה הליבה של השיפור במקרה הזה.
5.3. הסיבה לכך שבמקרה הזה הצטמצם זמן ההמתנה
במקרה הזה אובדן מנות התרחש מדי פעם, ובכל פעם ההערכות של RTT/RTO נטו להיות שמרניות. הפעלת חותמות הזמן מקלה על עדכון הערכת ה-RTT גם ברגעים שכוללים שידור חוזר, וכך מצטמצם הזמן שבו הערכת ה-RTO ממשיכה להתנפח בלי עדכון.
זו נקודה שקל לדלג עליה בקפיצה, אז נפרק אותה בזהירות רבה יותר.
קודם כול, הגבול התחתון של ה-RTO עצמו לא משתנה בהתאם לקיום או היעדר חותמות זמן. RFC 6298 קובע שאם ה-RTO המחושב קטן משנייה, יש לעגל אותו כלפי מעלה לשנייה. יש מימושים עם גבול תחתון משלהם — ב-Windows זהו MinRtoMs שמופיע ב-Get-NetTCPSetting (בטווח של 20 עד 300 מילישניות, בקפיצות של 10 מילישניות). כלומר, זה לא ש”הגבול התחתון ירד כי הוספנו חותמות זמן”.
מה שבאמת עוזר קורה שלב לפני כן. RFC 6298 קובע שלושה דברים:
- בכל פעם שטיימר השידור החוזר פוקע, ה-RTO מוכפל (נסיגה מעריכית / exponential backoff)
- ה-RTO שהוכפל חוזר לערכו כשמתקבלת מדידת RTT חדשה
- אותה “מדידת RTT חדשה” מתקבלת רק כשנתונים שלא עברו שידור חוזר נשלחו וקיבלו ACK
יתרה מכך, לפי האלגוריתם של Karn, אסור לקחת מדגם RTT מקטע שעבר שידור חוזר. אבל כשמשתמשים באפשרות ה-timestamps, המגבלה הזו מוסרת, מכיוון שכפי שהוסבר בסעיף 5.2, הסתכלות על TSecr מאפשרת לזהות לאיזו שליחה שייך ה-ACK.
כשמסדרים את זה ברצף, החוט מתגלה. במערכת שבה אובדן מתרחש מדי פעם, בלי חותמות זמן קשה שהתנאים 2 ו-3 יתקיימו יחד, ולכן נשאר זמן ארוך שבו ה-RTO המוכפל לא חוזר לערכו על בסיס מדידה בפועל. אם באותו מצב מגיע אובדן נוסף, ההמתנה מתחילה לא משנייה אלא משתי שניות או ארבע שניות. כשיש חותמות זמן, אפשר למדוד מחדש גם בקטעים הכוללים שידור חוזר, כך שה”זמן שבו לא חוזרים לערך” מתקצר — וזה בדיוק המסלול שעבד במקרה הזה.
flowchart TB
accTitle: התנאים לחזרת ה-RTO המוכפל ואופן הפעולה של חותמות הזמן
accDescr: תרשים המראה שבכל תפוגה ה-RTO מוכפל וחוזר לערכו כשמתקבלת מדידת RTT חדשה, אך המדידה מתקבלת רק מ-ACK על נתונים שלא עברו שידור חוזר, ולכן כשחותמות הזמן מסירות את המגבלה הזו וניתן למדוד גם בקטעי שידור חוזר, מתקצר הזמן שבו ה-RTO המוכפל לא חוזר לערכו.
backoff["הכפלת ה-RTO בכל תפוגה"] --> ret["חזרה לערך עם מדידת RTT חדשה"]
ret -.-> limit["המדידה רק מ-ACK על נתונים שלא שוגרו מחדש"]
ts2["timestamps מאפשרות מדידה גם בשידור חוזר"] --> often["יותר הזדמנויות למדידה מחדש"]
often --> short["מתקצר הזמן שבו ה-RTO המוכפל לא חוזר"]
איור 11: הליבה של אופן הפעולה היא לא ירידה של הגבול התחתון, אלא חזרה מהירה יותר של ה-RTO המוכפל על סמך מדידה בפועל.
נכתוב את זה בכנות: במאמר הזה לא נאספו ערכי RTO בפועל אחרי השיפור. מה שידוע הוא שהעצירות בסדר גודל של שניות ירדו לרמה שלא מהווה בעיה בשטח. אם רוצים להראות את האפקט במספרים, הדרך הקצרה ביותר היא להשתמש במסנני התצוגה מפרק 7 ובעמודה Time delta from previous displayed packet כדי לרכז את התפלגות פערי הזמן עד לשידור חוזר, לפני ואחרי.
במילים אחרות, מה שנעשה כאן אינו קסם שמאיץ את ה-TCP, אלא צמצום הזמן שבו ה-TCP ממשיך “לחכות ולראות” יותר מהנדרש.
כמובן, גם RFC 7323 לא טוען ש”יותר מדגמי RTT פותרים הכול בצורה נקייה”. יש היבטים שבהם התרומה לאופטימיזציה של ה-RTO מוגבלת. אבל היכולת להסיר את העמימות בעת שידור חוזר היא נקודה שיכולה לעבוד טוב במערכות כמו זו שתוארה כאן.
יש גם נקודות לתשומת לב:
- זה תלוי בחלקו במימוש ה-TCP stack
- חותמות זמן בלבד לא מסלקות את אובדן המנות עצמו
- אם השכבה הפיזית או ציוד הביניים לקויים, הסיבה השורשית נמצאת במקום אחר
- כדאי לבדוק בנפרד גם SACK, דרייבר ה-NIC, הגדרות offload ובעיות בצד המתג
עם זאת, במערכות שבהן “האובדן לא אפס” אך “מה שכואב באמת זו ההמתנה בסדר גודל של שניות” — כמו במקרה הזה — זה יכול לעזור באופן משמעותי.
6. הפעולות שבוצעו בפועל
6.1. הפעלת חותמות הזמן
כפתרון, וידאנו ששני קצות החיבור יכולים לסכם את אפשרות ה-timestamps. במערכות Windows זה לפעמים מטופל כאפשרות RFC 1323, והוא מושפע מהגדרות מערכת ההפעלה והרשת.
נכתוב את השלבים המדויקים. קודם כול, בודקים מה המצב הנוכחי:
netsh interface tcp show global
בפלט מופיע פריט של חותמות זמן RFC 1323, ובודקים אם הוא מופעל. כדי להפעיל, בשורת פקודה עם הרשאות מנהל:
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 מבוטלות, 1 — window scaling בלבד, 2 — timestamps בלבד, 3 — שניהם מופעלים. כדי לא להתבלבל, כדאי לזכור שביט 0 מתאים ל-window scaling וביט 1 מתאים ל-timestamps.
יש שלוש נקודות לתשומת לב בעת ההגדרה:
- זה עובד רק על חיבורים חדשים. חותמות הזמן מסוכמות בלחיצת היד המשולשת, כך שזה לא משפיע על חיבורים שכבר קיימים. צריך לפתוח מחדש את החיבור בצד ההתקן
- זה לא יעבוד אם שני הצדדים לא תומכים. גם אם מפעילים רק בצד ה-host, אם המצלמה לא מחזירה TSopt ב-SYN/ACK, זה לא ישמש באותו חיבור
- ההגדרה גם משנה את אופי החיבור. חותמות הזמן מגדילות את כותרת ה-TCP, כך שכמות הנתונים שנכנסת לקטע אחד קטנה מעט
עם זאת, בפועל “TSopt מופיע בפועל במנת ה-SYN / SYN-ACK” חשוב יותר מ”מוצג כמופעל במסך ההגדרות”. זה באמת המצב.
flowchart TB
accTitle: שלוש נקודות לתשומת לב בהגדרת חותמות הזמן
accDescr: תרשים המראה ששלוש נקודות לתשומת לב בהגדרת חותמות הזמן הן שההגדרה עובדת רק על חיבורים חדשים כי היא מסוכמת בלחיצת היד המשולשת, ששני הצדדים חייבים לתמוך בה, ושהכותרת גדלה וכמות הנתונים בקטע קטנה מעט.
care["שלוש נקודות לתשומת לב"] --> n1["עובד רק מחיבורים חדשים"]
care --> n2["נדרשת תמיכה בשני הצדדים"]
care --> n3["הכותרת גדלה והנתונים קטנים מעט"]
n1 -.-> re["יש לפתוח מחדש את חיבור ההתקן"]
איור 12: ההגדרה לבדה לא מספיקה. צריך גם לפתוח מחדש את החיבור וגם לוודא תמיכה בצד השני.
6.2. בדיקת TSopt ב-SYN / SYN-ACK
אחרי ההפעלה בדקנו שלוש נקודות:
- האם יש TSopt ב-SYN של החיבור הבעייתי
- האם גם צד ה-SYN/ACK מחזיר TSopt
- האם TSopt ממשיך להופיע גם בקטעי הנתונים וב-ACK שבאים אחר כך
רק אחרי אימות הנקודות האלה אפשר לומר ש”חותמות הזמן באמת בשימוש בחיבור הזה”.
6.3. איפה לבדוק כשזה עדיין לא עוזר
גם אחרי הפעלת חותמות הזמן, במקרים הבאים השיפור עשוי להיות חלש:
- שיעור האובדן עצמו גבוה
- ציוד ביניים שובר, מפיל או משנה את אפשרויות ה-TCP
- יש בעיה אחרת סביב ה-NIC / הדרייבר / הגדרות ה-offload
- האפליקציה תולה את כל התהליך בקריאה סינכרונית בודדת, כך שהמתנה אחת נראית כעצירה כוללת
- בפועל הגורם העיקרי אינו TCP, אלא עצירת עיבוד בצד המצלמה או גודש בתור הפנימי של ההתקן
לכן, קל יותר להתקדם עם הטיפול לפי הסדר הבא:
- קודם כול, לוודא ב-wire שיש המתנה לשידור חוזר
- לבדוק אם התבצע סיכום של TSopt
- להפעיל timestamps ולבדוק את הפער בשיפור
- אם עדיין נשאר, לטפל בנפרד במקור האובדן ובתכנון האפליקציה
flowchart TB
accTitle: הסדר לביצוע הטיפול
accDescr: תרשים המראה שהסדר לביצוע הטיפול הוא קודם לבדוק ב-wire המתנה לשידור חוזר, לבדוק אם בוצע סיכום של TSopt, להפעיל timestamps ולבדוק את פער השיפור, ואם עדיין נשאר בעיה לטפל בנפרד במקור האובדן ובתכנון האפליקציה.
s1["בדיקת המתנה לשידור חוזר ב-wire"] --> s2["בדיקת סיכום TSopt"]
s2 --> s3["הפעלת timestamps ובדיקת השיפור"]
s3 --> s4["אם נשאר, טיפול נפרד במקור האובדן ובתכנון"]
איור 13: סדר של בדיקה, סיכום, הפעלה ובדיקת מה שנשאר מקל על בידוד הגורם כשההפעלה לא עוזרת.
7. נקודות בדיקה ב-Wireshark
הנה מסנני תצוגה שנוחים לשימוש בבידוד:
tcp.stream eq <תזרים היעד>
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ורואים ישירות כמה שניות העצירה נמשכה - בודקים אם
Retransmissionמופיע ברגע הבעייתי - בודקים אם TSopt סוכם ב-SYN / SYN-ACK בתחילת החיבור
- בודקים אם
TSecrחוזר ב-ACK
נכתוב גם איך זה נראה על המסך, במילים. אחרי שמתרגלים, אפשר לזהות את המקרה הזה במבט אחד.
| היכן מסתכלים | איך זה נראה |
|---|---|
| עמודת ה-Info ברשימת המנות | על מנות של שידור חוזר מופיע [TCP Retransmission] |
| צבע השורה | זה תואם לכלל צביעת ברירת המחדל של Wireshark “Bad TCP”, כך שהשורה מקבלת רקע שחור וטקסט אדום. אפשר לתפוס את זה גם במבט חטוף |
| חלונית הפרטים | בוחרים את השורה, פותחים את Transmission Control Protocol, ובתוכו את SEQ/ACK analysis — שם מופיע ציון שהמנה זוהתה כשידור חוזר |
| פער הזמן | הצגת Time delta from previous displayed packet כעמודה מראה כמה שניות עברו מהמנה המוצגת הקודמת. כאן רואים רצף של שנייה, שתי שניות |
| ה-Options של ה-SYN | בוחרים את שורת ה-SYN, פותחים את Options, ובודקים אם יש פריט Timestamps — כך יודעים אם יש TSopt |
הרצף האופייני נראה כך: תחילה שורה עם אותו Seq מופיעה שוב אחרי שנייה, ואז שוב אחרי שתי שניות נוספות, ומיד אחרי השורה האחרונה חוזר ה-ACK, ומשם מתחדשים חילופי הדברים הרגילים. אם “פער השניות הריק” הזה תואם את הזמן שבו התגובה נעצרה בלוג האפליקציה, כמעט אפשר לקבוע את החשוד.
כשמצליבים בין הלוג לבין המנות, יש לשים לב גם להפרש בין בסיס הזמן של האפליקציה לבין בסיס הזמן של הלכידה. אם יש הסטה כאן, קל להאשים אירוע לא קשור.
flowchart TB
accTitle: התהליך לקביעת החשוד ב-Wireshark
accDescr: תרשים המראה שמצמצמים ל-tcp.stream של החיבור היעד, מסתכלים על עמודת פער הזמן כדי לראות ישירות את משך העצירה, מוודאים שורות שידור חוזר לאותו Seq, ואם הפער תואם את זמן העצירה בלוג האפליקציה החשוד כמעט מוכרע.
filt["צמצום ל-tcp.stream של החיבור"] --> delta["הסתכלות על עמודת פער הזמן"]
delta --> re["וידוא שורות שידור חוזר לאותו Seq"]
re --> match{"תואם את זמן העצירה באפליקציה?"}
match -->|"כן"| fix["החשוד כמעט מוכרע"]
match -->|"לא"| other["לחשוד בהפרש זמן או בגורם אחר"]
איור 14: לצמצם, להסתכל על פער הזמן, ולהצליב. בשלושה צעדים אלה קובעים את זהות “פער השניות הריק”.
8. חלוקה גסה בין המצבים
| תסמין | הגורם החשוד הראשון | מה לבדוק תחילה |
|---|---|---|
| עצירה מדי פעם בסדר גודל של שניות | המתנה ל-RTO ב-TCP | לבדוק שידור חוזר ופער זמן במנות |
| עצירה כמעט באותו תזמון בכל פעם | המתנה בתוך האפליקציה, עיבוד בצד ההתקן, timeout קבוע | לבדוק תהליכונים, קריאות SDK ולוגי התקן |
| מחמיר רק בעומס גבוה | CPU, GC, גודש בתור | לבדוק CPU, הפרעות (interrupts), זיכרון ואורך תור |
| גרוע בבת אחת על פני חיבורים רבים | השכבה הפיזית, מתג, ציוד ביניים | לבדוק NIC, כבלים, סטטיסטיקת פורטים ולוגי ציוד ביניים |
| שינוי הגדרה לא שינה כלום | אפשרות ה-TCP לא סוכמה בפועל | לבדוק שוב את SYN / SYN-ACK |
השורה האחרונה קורית ממש הרבה. תחושת הסיפוק מכך ששיחקתם עם ההגדרות, והעובדה שהיא באמת בשימוש ב-wire — הם שני דברים שונים.
9. סיכום
הנקודות העיקריות הפעם:
- “עצירה מדי פעם לכמה שניות” יכולה להיות המתנה לשידור חוזר ב-TCP, ולא עצירה של האפליקציה
- אם משך העצירה תואם את אופן ההמתנה של ה-RTO ומופיע
Retransmission, זו השערה חזקה למדי - אפשרות ה-timestamps של TCP היא מנגנון של RTTM ו-PAWS, שגם מסירה את העמימות במדידת RTT בעת שידור חוזר
- במקרה הזה, הפעלת חותמות זמן מסדרת RFC1323 צמצמה את הזמן שבו ה-RTO נשאר שמרני מדי
דרכי פעולה שכדאי להימנע מהן:
- לקבוע את החשוד לעצירת התקשורת רק לפי לוגי האפליקציה
- להסתכל רק על הגדרות מערכת ההפעלה בלי לבדוק את המנות עצמן
- לחשוב שהפעלת חותמות זמן מסלקת גם את מקור האובדן
דרכי פעולה שעובדות בפועל:
- קודם כול, להסתכל על ה-wire
- לבדוק את הצורה של השידור החוזר וזמן ההמתנה
- לוודא סיכום של TSopt
- גם אחרי השיפור, לטפל בנפרד במקור האובדן ובתכנון האפליקציה
במילים אחרות, בסוג הזה של תקלות עדיף קודם “לזהות איפה ממתינים” ולא “להאיץ”. רק אם לא מפספסים את הנקודה הזו, החקירה מתקצרת משמעותית.
10. מקורות
- RFC 1323 - TCP Extensions for High Performance
- RFC 7323 - TCP Extensions for High Performance
- RFC 5681 - TCP Congestion Control
- RFC 6298 - Computing TCP’s Retransmission Timer
-
[Description of Windows TCP features - Windows Server Microsoft Learn](https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/description-tcp-features) - Netsh commands for Interface Transmission Control Protocol - Microsoft Learn
- Set-NetTCPSetting - Microsoft Learn
- Get-NetTCPSetting - Microsoft Learn
- Wireshark User’s Guide - Time Display Formats And Time References
- Wireshark User’s Guide - Packet Colorization
מאמרים קשורים
מאמרים עדכניים עם אותן תגיות, להעמקה בנושאים קרובים.
תשתית בדיקות למקרי קצה ב-Windows עם Application Verifier
מהו Application Verifier: מסודר כאן יחד עם בניית תשתית בדיקות למקרי קצה ב-Windows באמצעות Handles, Heaps, Low Resource Simulation ו-!h...
חקירת קריסה בהפעלה ממושכת של מצלמה תעשייתית — פרק דליפת ה-handle
איך בוחנים אפליקציית Windows שקורסת בפתאומיות אחרי הפעלה ממושכת: דרך מקרה של אפליקציית בקרת מצלמה תעשייתית, מסודר כאן איך למצוא דליפת han...
תכנון שמירת יומנים ו-dump בקריסת יישום Windows
המאמר מסדר איך לשלב יומן רגיל, סמן קריסה סופי, WER LocalDumps ותהליך ניטור, כדי שגם כשיישום Windows קורס מחריגה בלתי צפויה או מבאג בתוכני...
מבוא לאיסוף crash dump ב-Windows - WER, ProcDump, WinDbg
המאמר מסדר את אופן הבחירה והשימוש ב-WER LocalDumps, ProcDump, MiniDumpWriteDump ו-WinDbg, כולל נקודות תפעוליות, כדי לחקור קריסות באפליק...
מדריך להגדרות מתקדמות של כרטיס רשת ב-Windows - RSS/LSO/EEE/Wake on LAN
מסדרים מנקודת מבט מעשית את ההגדרות המתקדמות של כרטיסי רשת ב-Windows. Jumbo Packet, Speed & Duplex, RSS, RSC, LSO, Flow Control, EEE...
נושאים קשורים
העמודים האלה ממקמים את הנושא בהקשר רחב יותר של שירותים והחלטות.
נושאים טכניים ב-Windows
שער לנושאי פיתוח Windows, חקירת תקלות וניצול נכסים קיימים.
חקירת תקלות ובעיות בריצות ארוכות
תקלות לסירוגין, אבחון תקשורת, תקיעות בריצות ארוכות ובדיקת נתיבי כשל.
חקרי מקרה קשורים
חקרי המקרה האלה מציגים גישה דומה לניתוח, לתעדוף או לעיצוב מחדש.
כיצד בודדנו ניתוקי תקשורת של כמה שניות
חקר מקרה על ניתוק נדיר, שהופרד בין המתנת שידור חוזר לבין תנאי מערכת ההפעלה.
שירותים הקשורים לנושא הזה
המאמר קשור ישירות לשירותים הבאים.
חקירת תקלות ואיתור גורמים
מדובר בבידוד עצירת תקשורת שקשה לשחזר, בעזרת מנות ועדויות — נושא שקשור ישירות לחקירת תקלות וניתוח סיבות.
פיתוח יישומי Windows
כאפליקציית Windows הכוללת אינטגרציה עם התקנים, זה מוביל גם לייעוץ על בחינה מחדש של תכנון התקשורת והניטור מצד המימוש.
שאלות נפוצות
שאלות נפוצות בפניות בנושא המאמר.
- מהו TCP Retransmission (שידור חוזר ב-TCP)?
- מנגנון שבו TCP שולח מחדש את אותם הנתונים כשה-ACK (אישור קבלה) על מנה שנשלחה לא חוזר. אם מנה כלשהי אובדת בדרך, הצד השולח ממתין ל-ACK, ואם הוא לא מגיע, ממתינים לתפוגת טיימר השידור החוזר (RTO) ורק אז משדרים מחדש. מבחינת האפליקציה זה נראה כ"עצירה של כמה שניות", אבל מבחינת TCP זו פשוט המתנה לתפוגת הטיימר עד שה-ACK יגיע — סוג עצירה שקורה באופן שגרתי. בלכידת מנות אפשר לצפות בזה כ-TCP Retransmission.
- מה גורם ל-TCP Retransmission?
- הגורם הישיר הוא אובדן מנות: כשה-ACK לא חוזר, מתרחש שידור חוזר. את מקור האובדן צריך לבדוק בנפרד — השכבה הפיזית (כבלים ופורטים), ה-NIC והדרייבר או הגדרות ה-offload שלו, ובעיות במתג או בציוד ביניים. הפעלת TCP timestamps יכולה לצמצם את זמן ההמתנה אחרי שידור חוזר, אך אינה קסם שמסלק את האובדן עצמו, ולכן חקירת מקור האובדן נדרשת בנפרד. יש גם מקרים שבהם ציוד ביניים שובר או מפיל אפשרויות TCP, וכן מקרים שבהם הגורם העיקרי בפועל הוא עצירת עיבוד בצד ההתקן ולא TCP כלל.
- למה שידור חוזר ב-TCP עוצר תקשורת לכמה שניות?
- מכיוון שטיימר השידור החוזר (RTO) של TCP ממתין בצורה שמרנית. לפי RFC 6298, ה-RTO ההתחלתי מבוסס על שנייה אחת, ואם תוצאת החישוב קטנה מכך היא מעוגלת כלפי מעלה לשנייה, ומוכפלת בכל תפוגה. לכן בתנאים גרועים אפשר לראות המתנה כמו שנייה, שתי שניות, ארבע שניות. בתקשורת בקרה המבוססת בעיקר על request/response קטנים, לפני שמצטברים מספיק Duplicate ACK כדי להפעיל fast retransmit, נוטה להיחשף קודם המתנה ל-RTO, שמופיעה כעצירה נדירה של כמה שניות. הפעלת אפשרות ה-TCP timestamps יכולה, במקרים מסוימים, להסיר את העמימות במדידת RTT בעת שידור חוזר ולצמצם את הזמן שבו הערכת ה-RTO נשארת שמרנית מדי.
- איך בודקים TCP Retransmission ב-Wireshark?
- אפשר להשתמש במסנני התצוגה tcp.analysis.retransmission, tcp.analysis.fast_retransmission ו-tcp.analysis.lost_segment. מצמצמים ל-tcp.stream של החיבור היעד, מציגים את Time delta from previous displayed packet כדי לראות ישירות את משך העצירה, ובודקים אם Retransmission מופיע ברגע הבעייתי ואם פער הזמן עד השידור החוזר תואם את משך העצירה. את השאלה אם משתמשים ב-TCP timestamps בודקים לפי סיכום TSopt ב-SYN / SYN-ACK בתחילת החיבור. העובדה שה-TSopt נמצא בפועל במנות עצמן חשובה יותר מכך שההגדרה מוצגת כמופעלת במסך ההגדרות.