def post(self, bundle: TransactionBundle): """ Upgrade the response from a AdvertiseMessage to a ReplyMessage if appropriate :param bundle: The transaction bundle """ # Does this transaction even allow rapid commit? if not bundle.allow_rapid_commit: return # We only look for SolicitMessages that have a RapidCommitOption if not isinstance( bundle.request, SolicitMessage ) or not bundle.request.get_option_of_type(RapidCommitOption): return # And only if the current response is an AdvertiseMessage if not isinstance(bundle.response, AdvertiseMessage): return # Ok, this looks promising, do extra checks if requested if not self.rapid_commit_rejections: # Ok, we don't want to rapid-commit rejections. Check for them. if bundle.get_unhandled_options( (IANAOption, IATAOption, IAPDOption)): # Unhandled options. We are post-processing, so they are not going to be answered anymore return # Did we already refuse anything? ia_options = [ option for option in bundle.response.options if isinstance(option, (IANAOption, IATAOption)) ] for option in ia_options: status = option.get_option_of_type(StatusCodeOption) if status and status.status_code == STATUS_NO_ADDRS_AVAIL: # Refusal: don't do anything return iapd_options = [ option for option in bundle.response.options if isinstance(option, IAPDOption) ] for option in iapd_options: status = option.get_option_of_type(StatusCodeOption) if status and status.status_code == STATUS_NO_PREFIX_AVAIL: # Refusal: don't do anything return # It seems the request and response qualify: upgrade to ReplyMessage bundle.response = ReplyMessage(bundle.response.transaction_id, [RapidCommitOption()] + bundle.response.options)
def test_bad_option_length(self): with self.assertRaisesRegex(ValueError, 'must have length 0'): RapidCommitOption.parse(bytes.fromhex('000e0001'))
link_address=IPv6Address('2001:db8:ffff:1::1'), peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'), options=[ RelayMessageOption(relayed_message=RelayForwardMessage( hop_count=0, link_address=IPv6Address('::'), peer_address=IPv6Address('fe80::3631:c4ff:fe3c:b2f1'), options=[ RelayMessageOption(relayed_message=SolicitMessage( transaction_id=bytes.fromhex('f350d6'), options=[ ElapsedTimeOption(elapsed_time=0), ClientIdOption(duid=LinkLayerDUID( hardware_type=1, link_layer_address=bytes.fromhex('3431c43cb2f1'))), RapidCommitOption(), IANAOption(iaid=bytes.fromhex('c43cb2f1')), IAPDOption(iaid=bytes.fromhex('c43cb2f1'), options=[ IAPrefixOption( prefix=IPv6Network('::/0')), ]), ReconfigureAcceptOption(), OptionRequestOption(requested_options=[ OPTION_DNS_SERVERS, OPTION_NTP_SERVER, OPTION_SNTP_SERVERS, OPTION_IA_PD, OPTION_IA_NA, OPTION_VENDOR_OPTS, OPTION_SOL_MAX_RT,
def setUp(self): self.option_bytes = bytes.fromhex('000e0000') self.option_object = RapidCommitOption() self.parse_option()