Esempio n. 1
0
    def getAndGeneratePTRZonesRootServer(cls, node):
        """ returns a list of all reverse zones a root dns server serves """

        # find dns root servers
        # (server_name, server_addr)
        rootservers = []
        service_helpers.nodewalker(node, node, rootservers,
                cls.nodewalker_find_root_dns_callback)
        rootservers = [('%s.' % server_name, server_addr) \
                for server_name, server_addr in rootservers]
        # find dns as authoritative servers
        # (server_name, server_addr, zone)
        as_auth_servers = []
        service_helpers.nodewalker(node, node, as_auth_servers,
                cls.nodewalker_root_dns_find_all_auth_servers_callback)
        as_auth_servers = [('%s.%s' % (server_name, zone), server_addr, zone) \
                for server_name, server_addr, zone in as_auth_servers]

        zonenames = []

        SOAHeader = cls.generateSOAHeader(cls, rootservers, '.')
        print(('[DEBUG] SOAHeader:\n%s' % SOAHeader))

        for ipversion in node.getIPversions():
            # collect loopback address space
            loopback_net = Loopback.getLoopbackNet(ipversion)
            print(('[DEBUG] loopback_net IPv%d: %s' % (ipversion, loopback_net)))

            # collect interface address space
            interface_net = Interface.getInterfaceNet(ipversion)
            print(('[DEBUG] interface_net IPv%d: %s' % (ipversion, interface_net)))

            # get all deployed ASN's
            asns = list(NetIDNodeMap.mapping[node.session.sessionid].keys())
            print(('[DEBUG] deployed ASN\'s: %s' % asns))
            for net in loopback_net, interface_net:
                zonename = cls.getPTRZoneNameFromPrefix(cls, net)
                net_prefixlen = net.prefixlen
                print(('[DEBUG] zonename: %s' % zonename))

                ORIGINHeader = '$ORIGIN %s\n' % zonename
                print(('[DEBUG] ORIGINHeader: %s' % ORIGINHeader))

                zoneentries = []
                for asn in asns:
                    # get AS address space
                    if net == loopback_net:
                        asn_net = Loopback.getLoopbackNet_per_net(\
                                node.session.sessionid, asn, ipversion)
                    elif net == interface_net:
                        asn_net = Interface.getInterfaceNet_per_net(\
                                node.session.sessionid, asn, ipversion)

                    # find authoritative AS dns servers
                    # zone == "AS%s.virtual." % str(netid)
                    for server_name, server_addr, zone in as_auth_servers:
                        server_asn = zone.lstrip('AS')
                        server_asn = int(server_asn[:server_asn.find('.')])

                        # not the correct asn
                        if not asn == server_asn:
                            continue

                        # not our IP version
                        if ipversion == 4 and not isIPv4Address(server_addr):
                            continue
                        if ipversion == 6 and not isIPv6Address(server_addr):
                            continue

                        print(('[DEBUG] server_name: %s, server_addr: %s, zone: %s' %
                                (server_name, server_addr, zone)))

                        if ipversion == 4:
                            # get host list of this AS
                            # TODO: iterating over all nodes for each AS for interface and
                            # loopback address space is expensive. and we are only talking
                            # about IPv4 at the moment. is there a better way of doing this?
                            hosts = []
                            # TODO: tmp. setting another netid of a node is a dirty hack
                            tmpnetid = node.netid
                            node.netid = server_asn
                            service_helpers.nodewalker(node, node, hosts,
                                    cls.nodewalker_asroot_dns_find_hosts_in_as_callback)
                            node.netid = tmpnetid
                            for hostname, asn_addr, zone in hosts:
                                if not isIPv4Address(asn_addr):
                                    continue

                                asn_addr = IPv4Addr(asn_addr)

                                print(('[DEBUG] asn_addr(%s) in asn_net(%s)' %
                                        (str(asn_addr), str(asn_net))))

                                if asn_addr < asn_net.minaddr() or \
                                        asn_addr > asn_net.maxaddr():
                                    continue

                                # set prefix length of the supernet
                                asn_addr.set_prefixlen(net_prefixlen)
                                asn_ptr_name = cls.getPTR_CNAME_FromAddr(cls, asn_addr)

                                #print(('[DEBUG] deployed ASN network (IPv%d): %s' %
                                #        (ipversion, str(asn_net))))
                                print(('[DEBUG] ASN PTR addr (IPv%d): %s' %
                                        (ipversion, str(asn_addr))))

                                print(('[DEBUG] adding: "%s IN NS %s"' %
                                        (asn_ptr_name, server_name)))
                                zoneentries.append(('%s IN NS %s' %
                                        (asn_ptr_name, server_name)))
                        elif ipversion == 6:
                            asn_ptr_name = cls.getPTRZoneNameFromPrefix(cls, asn_net)
                            print(('[DEBUG] adding: "%s IN NS %s"' %
                                    (asn_ptr_name, server_name)))
                            zoneentries.append(('%s IN NS %s' %
                                    (asn_ptr_name, server_name)))

                print(('[DEBUG] subnet name servers: %s' % (zoneentries)))

                zonecontents = '%s\n%s\n%s\n' % (ORIGINHeader, SOAHeader,
                        '\n'.join(zoneentries))
                cls.writeZoneFile(cls, node, zonename, zonecontents)
                print(('[DEBUG] adding ptrzone to zonenames: %s' % zonename))
                zonenames.append(zonename)

        return zonenames