DS-Lab / src / main / java / dslab / routing / DomainNameResolver.java
DomainNameResolver.java
Raw
package dslab.routing;

import dslab.nameserver.INameserverRemote;

import java.net.InetSocketAddress;
import java.rmi.RemoteException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

import static dslab.util.Utils.listElements;
import static java.lang.Integer.parseInt;

/**
 * This class tells you IP and port for a given domain name.
 */
public class DomainNameResolver {

    private static final Logger LOG = Logger.getLogger(DomainNameResolver.class.getSimpleName());
    private final INameserverRemote root;

    private final Map<Domain, InetSocketAddress> mailserverAddresses = new ConcurrentHashMap<>();

    public DomainNameResolver(INameserverRemote rootRemote) {
        this.root = rootRemote;
    }

    public void resolve(Domain domainArg) throws AddressResolutionException {

        if (!mailserverAddresses.containsKey(domainArg))
            try { //iterative resolution according to assignment section 2.2.3

                INameserverRemote nameserver = root;
                INameserverRemote childNameserver;

                var domain = domainArg;
                while (!domain.isLeaf()) {
                    childNameserver = nameserver.getNameserver(domain.getLast().toString());
                    if (childNameserver == null) {
                        var nameservers = nameserver.getSortedZones();
                        LOG.severe(domain + " is not a zone of " + nameserver + ". " +
                                "The following exist: " + (nameservers.isEmpty() ? "<empty>" :
                                                           listElements(nameservers)));
                        throw new AddressResolutionException(domain);
                    }
                    nameserver = childNameserver;
                    domain = domain.getInit();
                }

                var mailserverIpAndPort = nameserver.lookup(domain.toString());

                if (mailserverIpAndPort == null) {
                    var mailboxes = nameserver.getMailboxserverAddresses();
                    LOG.severe(domain + " is not a mailserver of " + nameserver + ". " +
                            "The following exist: " + (mailboxes.isEmpty() ? "<empty>" : listElements(mailboxes)));
                    throw new AddressResolutionException(domain);
                }

                var splitIpAndPort = mailserverIpAndPort.split(":");

                mailserverAddresses.put(
                        domainArg,
                        new InetSocketAddress(splitIpAndPort[0], parseInt(splitIpAndPort[1])));

            } catch (RemoteException e) {
                throw new AddressResolutionException(e.getMessage());
            }

        domainArg.setAddress(mailserverAddresses.get(domainArg));

    }
}