def test_v4(self):
     self.assertEqual("127.0.0.1:123",
                      str(AddressFormatter(("127.0.0.1", 123))))
     self.assertEqual("127.0.0.1:123",
                      str(AddressFormatter(("127.0.0.1", 123), None)))
     self.assertEqual("192.0.2.1:1", str(AddressFormatter(
         ("192.0.2.1", 1))))
Exemple #2
0
    def _send_notify_message_udp(self, zone_notify_info, addrinfo):
        msg, qid = self._create_notify_message(
            Name(zone_notify_info.zone_name),
            RRClass(zone_notify_info.zone_class))
        render = MessageRenderer()
        render.set_length_limit(512)
        msg.to_wire(render)
        zone_notify_info.notify_msg_id = qid
        try:
            sock = zone_notify_info.create_socket(addrinfo[0])
            sock.sendto(render.get_data(), 0, addrinfo)
            # count notifying by IPv4 or IPv6 for statistics
            if self._counters is not None:
                if zone_notify_info.get_socket().family == socket.AF_INET:
                    self._counters.inc('zones', zone_notify_info.zone_class,
                                       zone_notify_info.zone_name,
                                       'notifyoutv4')
                elif zone_notify_info.get_socket().family == socket.AF_INET6:
                    self._counters.inc('zones', zone_notify_info.zone_class,
                                       zone_notify_info.zone_name,
                                       'notifyoutv6')
            logger.info(NOTIFY_OUT_SENDING_NOTIFY, AddressFormatter(addrinfo))
        except (socket.error, addr.InvalidAddress) as err:
            logger.error(NOTIFY_OUT_SOCKET_ERROR, AddressFormatter(addrinfo),
                         err)
            return False
        except addr.InvalidAddress as iae:
            logger.error(NOTIFY_OUT_INVALID_ADDRESS,
                         AddressFormatter(addrinfo), iae)
            return False

        return True
 def test_force_family_bad(self):
     """
     These results are 'bad' as in they don't return the value as
     specified by our guidelines, since the internal check is skipped if
     the family is given
     """
     self.assertEqual(
         "[127.0.0.1]:123",
         str(AddressFormatter(("127.0.0.1", 123), socket.AF_INET6)))
     self.assertEqual("::1:123",
                      str(AddressFormatter(("::1", 123), socket.AF_INET)))
Exemple #4
0
    def _zone_notify_handler(self, zone_notify_info, event_type):
        """Notify handler for one zone.

        For the event type of _EVENT_READ, this method reads a new notify
        response message from the corresponding socket.  If it succeeds
        and the response is the expected one, it will send another notify
        to the next slave for the zone (if any) or the next zone (if any)
        waiting for its turn of sending notifies.

        In the case of _EVENT_TIMEOUT, or if the read fails or the response
        is not an expected one in the case of _EVENT_READ, this method will
        resend the notify request to the same slave up to _MAX_NOTIFY_TRY_NUM
        times.  If it reaches the max, it will swith to the next slave or
        the next zone like the successful case above.

        The first notify message is always triggered by the event
        "_EVENT_TIMEOUT" since when one zone prepares to notify its slaves,
        its notify_timeout is set to now, which is used to trigger sending
        notify message when dispatcher() scanning zones.

        Parameters:
        zone_notify_info(ZoneNotifyInfo): the notify context for the event
        event_type(int): either _EVENT_READ or _EVENT_TIMEOUT constant

        """
        tgt = zone_notify_info.get_current_notify_target()
        if event_type == _EVENT_READ:
            # Note: _get_notify_reply() should also check the response's
            # source address (see #2924).  When it's done the following code
            # should also be adjusted a bit.
            reply = self._get_notify_reply(zone_notify_info.get_socket(), tgt)
            if reply is not None:
                if (self._handle_notify_reply(zone_notify_info, reply,
                                              tgt) == _REPLY_OK):
                    self._notify_next_target(zone_notify_info)

        else:
            assert event_type == _EVENT_TIMEOUT
            if zone_notify_info.notify_try_num > 0:
                logger.info(NOTIFY_OUT_TIMEOUT, AddressFormatter(tgt))

        tgt = zone_notify_info.get_current_notify_target()
        if tgt:
            zone_notify_info.notify_try_num += 1
            if zone_notify_info.notify_try_num > _MAX_NOTIFY_TRY_NUM:
                logger.warn(NOTIFY_OUT_RETRY_EXCEEDED, AddressFormatter(tgt),
                            _MAX_NOTIFY_TRY_NUM)
                self._notify_next_target(zone_notify_info)
            else:
                # set exponential backoff according to rfc1996 section 3.6
                retry_timeout = (_NOTIFY_TIMEOUT *
                                 pow(2, zone_notify_info.notify_try_num))
                zone_notify_info.notify_timeout = time.time() + retry_timeout
                self._send_notify_message_udp(zone_notify_info, tgt)
Exemple #5
0
    def _get_notify_reply(self, sock, tgt_addr):
        try:
            msg, addr = sock.recvfrom(512)
        except socket.error as err:
            logger.error(NOTIFY_OUT_SOCKET_RECV_ERROR,
                         AddressFormatter(tgt_addr), err)
            return None

        return msg
Exemple #6
0
    def _handle_notify_reply(self, zone_notify_info, msg_data, from_addr):
        """Parse the notify reply message.

        rcode will not be checked here; if we get the response
        from the slave, it means the slave got the notify.

        """
        msg = Message(Message.PARSE)
        try:
            msg.from_wire(msg_data)
            if not msg.get_header_flag(Message.HEADERFLAG_QR):
                logger.warn(NOTIFY_OUT_REPLY_QR_NOT_SET,
                            AddressFormatter(from_addr))
                return _BAD_QR

            if msg.get_qid() != zone_notify_info.notify_msg_id:
                logger.warn(NOTIFY_OUT_REPLY_BAD_QID,
                            AddressFormatter(from_addr), msg.get_qid(),
                            zone_notify_info.notify_msg_id)
                return _BAD_QUERY_ID

            question = msg.get_question()[0]
            if question.get_name() != Name(zone_notify_info.zone_name):
                logger.warn(NOTIFY_OUT_REPLY_BAD_QUERY_NAME,
                            AddressFormatter(from_addr),
                            question.get_name().to_text(),
                            Name(zone_notify_info.zone_name).to_text())
                return _BAD_QUERY_NAME

            if msg.get_opcode() != Opcode.NOTIFY:
                logger.warn(NOTIFY_OUT_REPLY_BAD_OPCODE,
                            AddressFormatter(from_addr),
                            msg.get_opcode().to_text())
                return _BAD_OPCODE
        except Exception as err:
            # We don't care what exception, just report it?
            logger.error(NOTIFY_OUT_REPLY_UNCAUGHT_EXCEPTION, err)
            return _BAD_REPLY_PACKET

        logger.debug(logger.DBGLVL_TRACE_BASIC, NOTIFY_OUT_REPLY_RECEIVED,
                     zone_notify_info.zone_name, zone_notify_info.zone_class,
                     AddressFormatter(from_addr), msg.get_rcode())

        return _REPLY_OK
 def test_bad_values(self):
     self.assertRaises(ValueError, str, AddressFormatter("string"))
     self.assertRaises(ValueError, str, AddressFormatter(None))
     self.assertRaises(ValueError, str, AddressFormatter(1))
     self.assertRaises(ValueError, str, AddressFormatter(("::1", 123), 1))
     self.assertRaises(ValueError, str, AddressFormatter(("::1", 123), 1))
 def test_force_family_good(self):
     self.assertEqual(
         "127.0.0.1:123",
         str(AddressFormatter(("127.0.0.1", 123), socket.AF_INET)))
     self.assertEqual("[::1]:123",
                      str(AddressFormatter(("::1", 123), socket.AF_INET6)))
 def test_v6(self):
     self.assertEqual("[::1]:123", str(AddressFormatter(("::1", 123))))
     self.assertEqual("[::1]:123", str(AddressFormatter(("::1", 123),
                                                        None)))
     self.assertEqual("[2001:db8::]:1",
                      str(AddressFormatter(("2001:db8::", 1))))