9.8 - נתיב חבילה ובקרת רשת - פתרון
פתרון מאפייני הממשק¶
פתרון ראשון - שם מתוך מאפיין¶
הפונקציה הבאה מקבלת רק את אזור המאפיינים שמתחיל אחרי שלושים ושניים הבתים הראשונים של רשומת ממשק. היא משתמשת בפונקציית העזר u16_at מההרצאה.
fn interface_name(attributes: &[u8]) -> io::Result<Option<String>> {
let mut offset = 0;
let mut name = None;
while offset < attributes.len() {
if attributes.len() - offset < 4 { return Err(invalid("short attribute header")); }
let length = u16_at(attributes, offset) as usize;
let kind = u16_at(attributes, offset + 2) & 0x3fff;
if length < 4 || length > attributes.len() - offset {
return Err(invalid("bad attribute length"));
}
if kind == libc::IFLA_IFNAME as u16 {
let value = &attributes[offset + 4..offset + length];
let end = value.iter().position(|&byte| byte == 0)
.ok_or_else(|| invalid("unterminated interface name"))?;
name = Some(String::from_utf8_lossy(&value[..end]).into_owned());
}
let aligned = (length + 3) & !3;
if aligned > attributes.len() - offset {
if length == attributes.len() - offset { break; }
return Err(invalid("missing attribute padding"));
}
offset += aligned;
}
Ok(name)
}
בענף של רשומת ממשק קוראים לפונקציה עם &item[32..] ושומרים זוג של מזהה ושם. יש להתאים את וקטור התוצאות ואת ההדפסה בסיום לזוג הזה. המסכה מסירה ביטי תכונה מחלק הסוג; היא אינה מתירה לפענח מאפיין מקונן כאילו היה מחרוזת כאשר הסוג אינו מתאים.
פתרון שני - בדיקות של גבולות¶
הבדיקות הבאות נמצאות באותו מודול עם פונקציית הפענוח. הן יוצרות כותרות בסדר הבתים המקומי של ממשק המעבדה.
fn attribute(length: u16, kind: u16, value: &[u8]) -> Vec<u8> {
let mut bytes = length.to_ne_bytes().to_vec();
bytes.extend_from_slice(&kind.to_ne_bytes());
bytes.extend_from_slice(value);
bytes
}
fn main() {
assert!(interface_name(&[0, 0]).is_err());
assert!(interface_name(&attribute(0, 3, b"")).is_err());
assert!(interface_name(&attribute(20, 3, b"x")).is_err());
assert_eq!(interface_name(&attribute(4, 999, b"")).unwrap(), None);
assert_eq!(interface_name(&attribute(8, libc::IFLA_IFNAME as u16, b"lo\0\0")).unwrap(),
Some("lo".to_owned()));
}
מאפיין לא מוכר בעל אורך תקין מדולג, כדי שתוספת מידע בגרסה חדשה לא תשבור את הכלי. מאפיין בעל אורך לא תקין נדחה, משום שאין דרך בטוחה לדעת היכן מתחיל המאפיין הבא. מחרוזת ללא סיום בתחום המאפיין אינה נשלחת לפונקציה שממשיכה לקרוא מעבר לגבול.
פתרון שלישי - תמונה שאיבדה תוקף¶
אחרי אובדן או קטיעה מסמנים את התמונה המקומית כלא מהימנה, מפסיקים לבצע החלטות שמחייבות תמונה מלאה ומבקשים תמונה חדשה. עדכונים שמגיעים בזמן הבנייה נשמרים או גורמים לרענון נוסף לפי מדיניות מוגדרת. תמונה מופרעת אינה מתפרסמת כתוצאה סופית.
שינוי נתיב הוא שינוי במדיניות העברת המנות. הסוקט הקיים יכול להישאר אותו אובייקט עם אותן כתובות קצה, בעוד שהנתיב של מנות עתידיות משתנה או נכשל. לכן כלי החקירה צריך לקשר בין זהות הסוקט, מועד שינוי הנתיב ותוצאות השליחה, ולא להמציא יצירה חדשה של חיבור שלא התרחשה.