Repository: scionproto/scion
Issue: OF expiry after infrastructure running for a long time

If i leave the infrastructure running overnight, i tend to find my logs full of this in the morning:

```
er2-26er2-23.WARNING: Expired OF: Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 1, egress if: 0, mac: 372a23
er2-26er2-23.WARNING: 2016-02-22 09:00:04.502556+00:00 [ERROR] (MainThread) Dropping packet due to expired OF.
er2-26er2-23.WARNING: Header:
er2-26er2-23.WARNING: SCIONL4Packet(563B):
er2-26er2-23.WARNING:   CH ver: 0, src type: IPV4, dst type: SVC, total len: 563B, IOF idx: 0, HOF idx: 1, next hdr: 17, hdr len: 56B
er2-26er2-23.WARNING:   SCIONAddrHdr(16B): Src:<(2-26 (IPV4) 127.0.1.7)> Dst:<(2-21 (SVC) 2)>
er2-26er2-23.WARNING:   <Core-Path>
er2-26er2-23.WARNING:     <Up-Segment>
er2-26er2-23.WARNING:       [Info OF info(8B): CORE, up: True, TS: 2016-02-19 16:55:44+00:00, ISD: 2, hops: 3]
er2-26er2-23.WARNING:       Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 1, egress if: 0, mac: 372a23
er2-26er2-23.WARNING:       Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 2, egress if: 5, mac: e9833f
er2-26er2-23.WARNING:       Hop OF info(8B): XOVR_POINT, exp_time: 63, ingress if: 0, egress if: 3, mac: 5157c8
er2-26er2-23.WARNING:     </Up-Segment>
er2-26er2-23.WARNING:   </Core-Path>
er2-26er2-23.WARNING:   UDP hdr (8B): sport: 30040 dport: 30040 length: 507B checksum: e33b
er2-26er2-23.WARNING:   Payload(499B): 0302048056c ...
er2-26er2-23.WARNING: Expired OF: Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 1, egress if: 0, mac: 372a23
er1-17er1-14.WARNING: 2016-02-22 09:00:08.270639+00:00 [ERROR] (MainThread) Dropping packet due to expired OF.
er1-17er1-14.WARNING: Header:
er1-17er1-14.WARNING: SCIONL4Packet(563B):
er1-17er1-14.WARNING:   CH ver: 0, src type: IPV4, dst type: IPV4, total len: 563B, IOF idx: 0, HOF idx: 1, next hdr: 17, hdr len: 56B
er1-17er1-14.WARNING:   SCIONAddrHdr(16B): Src:<(1-17 (IPV4) 127.0.0.62)> Dst:<(1-17 (IPV4) 127.0.0.61)>
er1-17er1-14.WARNING:   <Core-Path>
er1-17er1-14.WARNING:     <Up-Segment>
er1-17er1-14.WARNING:       [Info OF info(8B): CORE, up: True, TS: 2016-02-19 16:55:00+00:00, ISD: 1, hops: 3]
er1-17er1-14.WARNING:       Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 1, egress if: 0, mac: 64da12
er1-17er1-14.WARNING:       Hop OF info(8B): NORMAL_OF, exp_time: 63, ingress if: 1, egress if: 4, mac: 2eef62
er1-17er1-14.WARNING:       Hop OF info(8B): XOVR_POINT, exp_time: 63, ingress if: 0, egress if: 4, mac: a604c5
er1-17er1-14.WARNING:     </Up-Segment>
er1-17er1-14.WARNING:   </Core-Path>
er1-17er1-14.WARNING:   UDP hdr (8B): sport: 30040 dport: 30040 length: 507B checksum: 7cfd
er1-17er1-14.WARNING:   Payload(499B): 0302048056c748e4 ...
```


Changed files:
infrastructure/sibra_server/steady.py, infrastructure/sibra_server/link.py

diff --git a/infrastructure/sibra_server/link.py b/infrastructure/sibra_server/link.py
index baab5db28..bd92d2a7a 100644
--- a/infrastructure/sibra_server/link.py
+++ b/infrastructure/sibra_server/link.py
@@ -73,6 +73,11 @@ class Link(object):
                 logging.info("Adding segment for interface %s: %s",
                              self.id, pcb.short_desc())
             self.segments[hops] = pcb
+            self._update_seg_steadies(pcb)
+
+    def _update_seg_steadies(self, pcb):
+        for steady in self.steadies.values():
+            steady.update_seg(pcb)
 
     def steady_add(self):
         """
diff --git a/infrastructure/sibra_server/steady.py b/infrastructure/sibra_server/steady.py
index b0f4920fb..d7602708f 100644
--- a/infrastructure/sibra_server/steady.py
+++ b/infrastructure/sibra_server/steady.py
@@ -28,6 +28,7 @@ from lib.defines import (
     SIBRA_MAX_STEADY_TICKS,
     SIBRA_TICK,
 )
+from infrastructure.sibra_server.util import seg_to_hops
 from lib.errors import SCIONBaseError
 from lib.packet.path import EmptyPath
 from lib.packet.path_mgmt import PathRecordsReg
@@ -41,8 +42,8 @@ from lib.sibra.payload import SIBRAPayload
 from lib.sibra.pcb_ext.info import SibraSegInfo
 from lib.sibra.pcb_ext.sof import SibraSegSOF
 from lib.sibra.util import current_tick, tick_to_time
-from lib.util import SCIONTime, hex_str
 from lib.types import PathSegmentType as PST
+from lib.util import SCIONTime, hex_str
 
 RESV_LEN = SIBRA_MAX_STEADY_TICKS - 1
 STATE_SETUP = 0
@@ -109,6 +110,14 @@ class SteadyPath(object):
         pkt = self._create_sibra_pkt(ext)
         self.sendq.put(pkt)
 
+    def update_seg(self, new_seg):
+        with self._lock:
+            old_hops = seg_to_hops(self.seg)
+            new_hops = seg_to_hops(new_seg)
+            if old_hops != new_hops:
+                return
+            self.seg = new_seg
+
     def process_reply(self, pkt, ext):
         with self._lock:
             self._process_reply(pkt, ext)
@@ -253,7 +262,7 @@ class SteadyPath(object):
         udp_hdr = SCIONUDPHeader.from_values(
             self.addr, SCION_UDP_PORT, dest, SCION_UDP_PORT, pld)
         return SCIONL4Packet.from_values(
-            cmn_hdr, addr_hdr, self.seg.get_path(True), [], udp_hdr, pld)
+            cmn_hdr, addr_hdr, path, [], udp_hdr, pld)
 
     def __str__(self):
         with self._lock: