@@ -400,7 +400,7 @@ def add_payload(self, payload, clear_cache=True):
400
400
401
401
# Invalidate cache when the packet has changed.
402
402
if clear_cache :
403
- self .clear_cache ()
403
+ self .clear_cache (upwards = True , downwards = False )
404
404
405
405
def remove_payload (self ):
406
406
# type: () -> None
@@ -409,7 +409,7 @@ def remove_payload(self):
409
409
self .overloaded_fields = {}
410
410
411
411
# Invalidate cache when the packet has changed.
412
- self .clear_cache ()
412
+ self .clear_cache (upwards = True , downwards = False )
413
413
414
414
def add_underlayer (self , underlayer ):
415
415
# type: (Packet) -> None
@@ -655,7 +655,7 @@ def setfieldval(self, attr, val):
655
655
any2i (self , val )
656
656
self .explicit = 0
657
657
# Invalidate cache when the packet has changed.
658
- self .clear_cache ()
658
+ self .clear_cache (upwards = True , downwards = False )
659
659
self .wirelen = None
660
660
elif attr == "payload" :
661
661
self .remove_payload ()
@@ -679,7 +679,7 @@ def delfieldval(self, attr):
679
679
del self .fields [attr ]
680
680
self .explicit = 0 # in case a default value must be explicit
681
681
# Invalidate cache when the packet has changed.
682
- self .clear_cache ()
682
+ self .clear_cache (upwards = True , downwards = False )
683
683
self .wirelen = None
684
684
elif attr in self .default_fields :
685
685
pass
@@ -810,33 +810,33 @@ def copy_field_value(self, fieldname, value):
810
810
# type: (str, Any) -> Any
811
811
return self .get_field (fieldname ).do_copy (value )
812
812
813
- def clear_cache (self ):
814
- # type: () -> None
813
+ def clear_cache (self , upwards = False , downwards = True ):
814
+ # type: (bool, bool ) -> None
815
815
"""
816
- Ensure cache invalidation for all:
817
-
818
- - parent packet if any,
819
- - underlayer if any.
816
+ Clear the raw packet cache for the current packet.
820
817
821
- .. note::
822
- Contrary to base former implementation, don't invalidate cache for:
818
+ ``upwards`` and ``downwards`` indicate how this call should recurse in the packet tree.
823
819
824
- - packet fields if any,
825
- - payload if any.
826
-
827
- .. todo::
828
- Shall we restore a default behaviour to avoid breaking the API:
829
- "Clear the raw packet cache for the field and all its subfields"?
820
+ :param upwards: Set to ``True`` to clear cache recursively over parent and underlayer packets. ``False`` by default.
821
+ :param downwards: Set to ``True`` (default) to clear cache recursively over subfields and payload.
830
822
"""
831
- def _clear_cache_ascending (pkt ): # type: (Packet) -> None
832
- pkt .raw_packet_cache = None
833
-
834
- if isinstance (pkt , Packet ) and pkt .parent :
835
- _clear_cache_ascending (pkt .parent )
836
- if pkt .underlayer :
837
- _clear_cache_ascending (pkt .underlayer )
838
-
839
- _clear_cache_ascending (self )
823
+ self .raw_packet_cache = None
824
+
825
+ if upwards :
826
+ if self .parent :
827
+ self .parent .clear_cache (upwards = True , downwards = False )
828
+ if self .underlayer :
829
+ self .underlayer .clear_cache (upwards = True , downwards = False )
830
+ if downwards :
831
+ for fname , fval in self .fields .items ():
832
+ fld = self .get_field (fname )
833
+ if fld .holds_packets :
834
+ if isinstance (fval , Packet ):
835
+ fval .clear_cache (upwards = False , downwards = True )
836
+ elif isinstance (fval , list ):
837
+ for fsubval in fval :
838
+ fsubval .clear_cache (upwards = False , downwards = True )
839
+ self .payload .clear_cache (upwards = False , downwards = True )
840
840
841
841
def self_build (self ):
842
842
# type: () -> bytes
0 commit comments