001/** 002 * 003 * Copyright 2014-2016 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.initializer.SmackInitializer; 023import org.jivesoftware.smack.util.DNSUtil; 024import org.jivesoftware.smack.util.dns.DNSResolver; 025import org.jivesoftware.smack.util.dns.SRVRecord; 026import org.jxmpp.util.cache.ExpirationCache; 027 028import de.measite.minidns.Client; 029import de.measite.minidns.DNSCache; 030import de.measite.minidns.DNSMessage; 031import de.measite.minidns.Question; 032import de.measite.minidns.Record; 033import de.measite.minidns.Record.CLASS; 034import de.measite.minidns.Record.TYPE; 035import de.measite.minidns.record.Data; 036import de.measite.minidns.record.SRV; 037 038 039/** 040 * This implementation uses the <a href="https://github.com/rtreffer/minidns/">minidns</a> implementation for 041 * resolving DNS addresses. 042 */ 043public class MiniDnsResolver implements SmackInitializer, DNSResolver { 044 045 private static final long ONE_DAY = 24*60*60*1000; 046 private static final MiniDnsResolver instance = new MiniDnsResolver(); 047 private static final ExpirationCache<Question, DNSMessage> cache = new ExpirationCache<Question, DNSMessage>(10, ONE_DAY); 048 private final Client client; 049 050 public MiniDnsResolver() { 051 client = new Client(new DNSCache() { 052 053 @Override 054 public DNSMessage get(Question question) { 055 return cache.get(question); 056 } 057 058 @Override 059 public void put(Question question, DNSMessage message) { 060 long expirationTime = ONE_DAY; 061 for (Record record : message.getAnswers()) { 062 if (record.isAnswer(question)) { 063 expirationTime = record.getTtl(); 064 break; 065 } 066 } 067 cache.put(question, message, expirationTime); 068 } 069 070 }); 071 } 072 073 public static DNSResolver getInstance() { 074 return instance; 075 } 076 077 @Override 078 public List<SRVRecord> lookupSRVRecords(String name) { 079 List<SRVRecord> res = new LinkedList<SRVRecord>(); 080 DNSMessage message = client.query(name, TYPE.SRV, CLASS.IN); 081 if (message == null) { 082 return res; 083 } 084 for (Record record : message.getAnswers()) { 085 Data data = record.getPayload(); 086 if (!(data instanceof SRV)) { 087 continue; 088 } 089 SRV srv = (SRV) data; 090 res.add(new SRVRecord(srv.getName(), srv.getPort(), srv.getPriority(), srv.getWeight())); 091 } 092 return res; 093 } 094 095 public static void setup() { 096 DNSUtil.setDNSResolver(getInstance()); 097 } 098 099 @Override 100 public List<Exception> initialize() { 101 setup(); 102 return null; 103 } 104 105}