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)); } }