package net.windwards.dnsfrontend.backend;
import net.windwards.dnsfrontend.api.Configuration;
import net.windwards.dnsfrontend.api.Protocol;
import net.windwards.dnsfrontend.dialog.ProtocolCodingException;
import org.xbill.DNS.AAAARecord;
import org.xbill.DNS.ARecord;
import org.xbill.DNS.Address;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Name;
import org.xbill.DNS.Record;
import org.xbill.DNS.TextParseException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
public class BinaryBackendProtocol implements Protocol {
public static final int IPV4_UPDATE = 1;
public static final int IPV6_UPDATE = 2;
@Override
public byte[] encode(Record record, Configuration configuration) throws ProtocolCodingException {
return new byte[0]; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Record decode(byte[] message, Configuration configuration)
throws ProtocolCodingException {
Record rec = null;
ByteBuffer buf = ByteBuffer.wrap(message);
byte type = buf.get();
InetAddress addr;
try {
switch (type) {
case IPV4_UPDATE:
addr = getIPv4Address(buf);
break;
case IPV6_UPDATE:
addr = getIPv6Address(buf);
break;
default:
throw new ProtocolCodingException("Unkown operation: " + type);
}
} catch (UnknownHostException e) {
throw new ProtocolCodingException(e);
}
String host = getSizedString(buf);
String moniker = getSizedString(buf);
Name qualified;
try {
qualified = configuration.qualifiedDomainName(host, moniker);
} catch (TextParseException e) {
throw new ProtocolCodingException(e);
}
long ttl = configuration.getTtl(moniker);
switch (type) {
case IPV4_UPDATE:
rec = new ARecord(qualified, DClass.IN, ttl, addr);
break;
case IPV6_UPDATE:
rec = new AAAARecord(qualified, DClass.IN, ttl, addr);
break;
}
return rec;
}
private static InetAddress getIPv6Address(ByteBuffer buf) throws UnknownHostException {
InetAddress addr;
StringBuilder addrString = new StringBuilder();
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addrString.append(":");
addrString.append(Integer.toHexString(buf.getShort() & 0xffff));
addr = Address.getByAddress(addrString.toString());
return addr;
}
private static InetAddress getIPv4Address(ByteBuffer buf) throws UnknownHostException {
InetAddress addr;
StringBuilder addrString = new StringBuilder();
addrString.append(buf.get() & 0xff);
addrString.append(".");
addrString.append(buf.get() & 0xff);
addrString.append(".");
addrString.append(buf.get() & 0xff);
addrString.append(".");
addrString.append(buf.get() & 0xff);
addr = Address.getByAddress(addrString.toString());
return addr;
}
private static String getSizedString(ByteBuffer buf) {
byte[] tmp = new byte[64];
byte hostlen = buf.get();
buf.get(tmp, 0, hostlen);
return new String(tmp, 0, hostlen);
}
}