001/**
002 *
003 * Copyright 2014 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smack.util.dns.minidns;
018
019import java.util.LinkedList;
020import java.util.List;
021
022import org.jivesoftware.smack.util.dns.DNSResolver;
023import org.jivesoftware.smack.util.dns.SRVRecord;
024import org.jxmpp.util.cache.ExpirationCache;
025
026import de.measite.minidns.Client;
027import de.measite.minidns.DNSCache;
028import de.measite.minidns.DNSMessage;
029import de.measite.minidns.Question;
030import de.measite.minidns.Record;
031import de.measite.minidns.Record.CLASS;
032import de.measite.minidns.Record.TYPE;
033import de.measite.minidns.record.SRV;
034
035
036/**
037 * This implementation uses the <a href="https://github.com/rtreffer/minidns/">minidns</a> implementation for
038 * resolving DNS addresses.
039 */
040public class MiniDnsResolver implements DNSResolver {
041
042    private static final long ONE_DAY = 24*60*60*1000;
043    private static final MiniDnsResolver instance = new MiniDnsResolver();
044    private static final ExpirationCache<Question, DNSMessage> cache = new ExpirationCache<Question, DNSMessage>(10, ONE_DAY);
045    private final Client client; 
046
047    private MiniDnsResolver() {
048        client = new Client(new DNSCache() {
049
050            @Override
051            public DNSMessage get(Question question) {
052                return cache.get(question);
053            }
054
055            @Override
056            public void put(Question question, DNSMessage message) {
057                long expirationTime = ONE_DAY;
058                for (Record record : message.getAnswers()) {
059                    if (record.isAnswer(question)) {
060                        expirationTime = record.getTtl();
061                        break;
062                    }
063                }
064                cache.put(question, message, expirationTime);
065            }
066
067        });
068    }
069
070    public static DNSResolver getInstance() {
071        return instance;
072    }
073
074    @Override
075    public List<SRVRecord> lookupSRVRecords(String name) {
076        List<SRVRecord> res = new LinkedList<SRVRecord>();
077        DNSMessage message = client.query(name, TYPE.SRV, CLASS.IN);
078        for (Record record : message.getAnswers()) {
079            SRV srv = (SRV) record.getPayload();
080            res.add(new SRVRecord(srv.getName(), srv.getPort(), srv.getPriority(), srv.getWeight()));
081        }
082        return res;
083    }
084}