Example #1
0
    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'))
Example #3
0
 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,
Example #4
0
 def test_bad_option_length(self):
     with self.assertRaisesRegex(ValueError, 'must have length 0'):
         RapidCommitOption.parse(bytes.fromhex('000e0001'))
Example #5
0
 def setUp(self):
     self.option_bytes = bytes.fromhex('000e0000')
     self.option_object = RapidCommitOption()
     self.parse_option()