package mireka.smtp.client; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import javax.annotation.concurrent.Immutable; import org.xbill.DNS.Name; /** * MtaAddress contains all informations which are necessary to contact that MTA * and identify it in DSN reports, logs. */ @Immutable public class MtaAddress { /** * The host name as an RFC-5321 domain name or address-literal. It comes * from the content of a DNS MX record or an email address with a literal * address part, or a smart host or back-end server name. For example: * <ul> * <li>mail.example.com * <li>[192.0.2.0] * <li>[IPv6:::1] * </ul> */ public final String dnsName; /** * IP address of MTA. It is possible that a domain name in an MX records * have multiple A records, therefore a single domain name may refer to * multiple MTA servers, and only this address differentiates between them. */ public final InetAddress address; public final int port; /** * @param smtpFormattedHost * The host name as an RFC-5321 domain name or address-literal. * It comes from the content of a DNS MX record or an email * address with a literal address part, or a smart host or * back-end server name. For example: * <ul> * <li>mail.example.com * <li>[192.0.2.0] * <li>[IPv6:::1] * </ul> * @param address * IP address of the MTA * @param port * port of the remote MTA */ public MtaAddress(String smtpFormattedHost, InetAddress address, int port) { this.dnsName = smtpFormattedHost; this.address = address; this.port = port; } /** * Constructs a new MtaAddress with the default port, which is 25. This is * the equivalent of calling {@link #MtaAddress(String, InetAddress, int)} * with port 25. */ public MtaAddress(String dnsName, InetAddress address) { this(dnsName, address, 25); } /** * Constructs a new MtaAddress with the default port, which is 25. This is * the equivalent of calling {@link #MtaAddress(String, InetAddress, int)} * with port 25, and with a dnsName converted from the supplied DnsJava Name * object by removing the last dot. The trailing dot marks an absolute * domain name in DNS - but that syntax is invalid in SMTP. */ public MtaAddress(Name dnsName, InetAddress address) { this(name2string(dnsName), address); } private static String name2string(Name name) { String s = name.toString(); if (s.charAt(s.length() - 1) == '.') s = s.substring(0, s.length() - 1); return s; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((address == null) ? 0 : address.hashCode()); result = prime * result + ((dnsName == null) ? 0 : dnsName.hashCode()); result = prime * result + port; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MtaAddress other = (MtaAddress) obj; if (address == null) { if (other.address != null) return false; } else if (!address.equals(other.address)) return false; if (dnsName == null) { if (other.dnsName != null) return false; } else if (!dnsName.equals(other.dnsName)) return false; if (port != other.port) return false; return true; } /** * Prints the address in a compact form for informational purposes. */ @Override public String toString() { StringBuilder buffer = new StringBuilder(64); buffer.append(dnsName); if (address != null) { buffer.append(" ("); if (address instanceof Inet4Address) buffer.append(address.getHostAddress()); else if (address instanceof Inet6Address) buffer.append('[').append(address.getHostAddress()).append(']'); else throw new RuntimeException("Assertion failed"); buffer.append(':').append(port).append(')'); } return buffer.toString(); } }