Android Open Source - ubihelper Dns Client






From Project

Back to project page ubihelper.

License

The source code is released under:

GNU General Public License

If you think the Android project ubihelper listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * Copyright (c) 2012 The University of Nottingham
 * //from w  ww  . j a  v  a 2  s.c o  m
 * This file is part of ubihelper
 *
 *  ubihelper is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  ubihelper is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with ubihelper. If not, see <http://www.gnu.org/licenses/>.
 *  
 *  @author Chris Greenhalgh (cmg@cs.nott.ac.uk), The University of Nottingham
 */

package uk.ac.horizon.ubihelper.dns;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
//import java.net.SocketException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.logging.Logger;

/**
 * @author cmg
 *
 */
public class DnsClient extends Thread {
  //static final String TAG = "ubihelper-dnssvr";
  static Logger logger =  Logger.getLogger(DnsServer.class.getName());

  private MulticastSocket socket;
  private boolean closed = false;
  private boolean done = false;
  private String error = null;
  private LinkedList<DnsProtocol.RR> answers = new LinkedList<DnsProtocol.RR>();
  private DnsProtocol.Query query;
  private long startTime;
  private boolean multiple = false;
  private NetworkInterface networkInterface;
  private InetAddress destAddress;
  private int destPort = DnsServer.MDNS_PORT;
  private OnChange onChange = null;
  // Note: for testing, false; for real use, true!
  private boolean disableLoopback = false;
  
  public static interface OnChange {
    void onAnswer(DnsProtocol.RR rr);
    void onComplete(String error);
  }
  
  public DnsClient(DnsProtocol.Query query, boolean multiple) {
    this.query = query;
    this.multiple = multiple;
    setDestination(DnsServer.MDNS_ADDRESS);
  }
  public synchronized DnsProtocol.Query getQuery() {
    return query;
  }
  public synchronized void setOnChange(OnChange onChange) {
    this.onChange = onChange;
  }
  public synchronized void setDestination(String dest) {
    try {
      destAddress = InetAddress.getByName(dest);
    } catch (UnknownHostException e) {
      logger.warning("Unknown destination: "+dest);
    }    
  }
  public synchronized void setDestination(InetAddress dest) {
    destAddress = dest;
  }
  public synchronized InetAddress getDestination() {
    return destAddress;
  }
  public synchronized void setNetworkInterface(NetworkInterface ni) {
    networkInterface = ni;
  }
  public synchronized long getAge() {
    return System.currentTimeMillis()-startTime;
  }
  public synchronized void close() {
    closed = true;
    closeInternal();
  }
  
  private synchronized void closeInternal() {
    if (socket!=null) {
      try {
        socket.close();
      }
      catch (Exception e) {
        /* ignore */
      }
      socket = null;
    }
  }
  
  public synchronized String getError() {
    return error;    
  }
  
  public synchronized LinkedList<DnsProtocol.RR> getAnswers() {
    LinkedList<DnsProtocol.RR> rval = new LinkedList<DnsProtocol.RR>();
    rval.addAll(answers);
    return rval;
  }
  
  public synchronized boolean getDone() {
    return done || closed || error!=null;
  }
  
  public void run() {
    synchronized (this) {
      startTime = System.currentTimeMillis();
      try {
        socket = new MulticastSocket(); // source port 5353?!
        socket.setLoopbackMode(disableLoopback );
        socket.setTimeToLive(255);
        //socket.setSoTimeout(TIMEOUT_MS);
        if (networkInterface!=null) {
          logger.info("Bind client socket to "+networkInterface.getDisplayName());
          socket.setNetworkInterface(networkInterface);
        }
        logger.info("TTL = "+socket.getTimeToLive());
      }
      catch (Exception e) {
        errorInternal("Creating socket: "+e.getMessage());
        return;
      }
    }
    DnsProtocol qp = new DnsProtocol();
    try {
      qp.queries = new DnsProtocol.Query[1];
      qp.queries[0] = query;
      qp.answers = new DnsProtocol.RR[0];
      qp.marshall();
    }
    catch (Exception e) {
      errorInternal("Marshalling query: "+e.getMessage());
      e.printStackTrace();
      return;
    }
    final int ATTEMPTS = 3;
    final int INTERVAL_MS = 3000;
    done:
    for (int a=0; a<ATTEMPTS && !closed && error==null && !done; a++) {
      long endTime = startTime+(a+1)*INTERVAL_MS;
      try {
        DatagramPacket dp = new DatagramPacket(qp.bytes, qp.len, destAddress, destPort);
        logger.info("Sending query to "+destAddress.getHostAddress()+":"+destPort);
        socket.send(dp);
      }
      catch (Exception e) {
        logger.warning("Error sending request: "+e.getMessage());
      }
      while (!closed && error==null) {
        long remaining = endTime-System.currentTimeMillis();
        if (remaining<=0)
          break;
        DatagramPacket rdp = new DatagramPacket(new byte[512], 512);
        try {
          socket.setSoTimeout((int)remaining);
          socket.receive(rdp);
        } catch (Exception e) {
          logger.warning("Error receiving packet: "+e.toString()); //getMessage());
        }
        try {
          DnsProtocol rp = new DnsProtocol();
          rp.bytes = rdp.getData();
          rp.len = rdp.getLength();
          rp.unmarshall();
          for (int i=0; i<rp.answers.length; i++) {
            DnsProtocol.RR r = rp.answers[i];
            if (query.name.equals(r.name) && query.rclass==r.rclass && query.type==r.type) {
              synchronized (this) {
                boolean known = false;
                for (int ai=0; !known && ai<answers.size(); ai++) {
                  DnsProtocol.RR ar = answers.get(ai);
                  if (ar.rdata.length==r.rdata.length) {
                    boolean same = true;
                    for (int bi=0; same && bi<ar.rdata.length; bi++)
                      if (ar.rdata[bi]!=r.rdata[bi])
                        same = false;
                    if (same)
                      known = true;
                  }
                }
                if (!known) {
                  r.src = rdp.getAddress();
                  answers.add(r);
                  logger.info("Found answer "+r+" from "+rdp.getAddress());
                  if (onChange!=null) {
                    try {
                      onChange.onAnswer(r);
                    }
                    catch (Exception e) {
                      logger.warning("Error on onChange.onAnswer: "+e.getMessage());
                      /* ignore */
                    }
                  }
                  if (!multiple)
                    break done;
                }
                else {
                  logger.info("Found known answer (query "+(a+1)+")");
                }
              }
            }
          }
        } catch (Exception e) {
          logger.warning("Error processing received packet: "+e.toString()); //getMessage());
        }
      }      
    }
    synchronized (this) {
      done = true;
      closeInternal();      
    }
    if (onChange!=null) {
      try {
        onChange.onComplete(error);
      }
      catch (Exception e) {
        logger.warning("Error on onChange.onComplete: "+e.getMessage());
        /* ignore */
      }
    }
  }

  private synchronized void errorInternal(String msg) {
    logger.warning(msg);
    error = msg;
    closeInternal();
  }

  public static NetworkInterface getFirstActiveInterface() {
    try {
      Enumeration<NetworkInterface> nets;
      nets = NetworkInterface.getNetworkInterfaces();
      for (NetworkInterface netint : Collections.list(nets)) {
        Enumeration<InetAddress> inetAddresses = netint.getInetAddresses();
        for (InetAddress inetAddress : Collections.list(inetAddresses)) {
          if (inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress() || inetAddress.getHostAddress().contains(":"))
            ;
          else {
            return netint;
          }
        }
      }
    } catch (Exception e) {
      logger.warning("Problem getting active network interfaces: "+e.getMessage());
      
    }
    return null;
  }
  /** test */
  public static void main(String args[]) {
    test(args, false);
    test(args, true);
  }
  private static void test(String args[], boolean multiple) {
    DnsProtocol.Query q = new DnsProtocol.Query();
    q.name = args.length==0 ? "some.name.local" : args[0];
    q.rclass = DnsProtocol.CLASS_IN;
    q.type = DnsProtocol.TYPE_A;
    if (args.length>=2) {
      if ("PTR".equals(args[1]))
        q.type = DnsProtocol.TYPE_PTR;
      else if ("SRV".equals(args[1]))
        q.type = DnsProtocol.TYPE_SRV;
      else
        logger.warning("Unknown type "+args[1]);
    }
    logger.info("Query for "+q.name+" ("+(multiple ? "multiple" : "single")+")");
    DnsClient c = new DnsClient(q, multiple);
    if (args.length>=3)
      c.setDestination(args[2]);
    NetworkInterface netinf = getFirstActiveInterface();
    if (netinf!=null)
      c.setNetworkInterface(netinf);
    c.start();
    try {
      c.join();
      logger.info("Client finished");
      logger.info("Client error: "+c.getError());
      LinkedList<DnsProtocol.RR> rrs = c.getAnswers();
      for (DnsProtocol.RR rr : rrs) {
        if (rr.type==DnsProtocol.TYPE_A && rr.rdata.length==4)
          logger.info("Found answer: "+(rr.rdata[0]&0xff)+"."+(rr.rdata[1]&0xff)+"."+(rr.rdata[2]&0xff)+"."+(rr.rdata[3]&0xff));
        else if (rr.type==DnsProtocol.TYPE_PTR) {
          String ns[] = DnsProtocol.ptrFromData(rr.rdata);
          logger.info("Found answer (ptr): "+Arrays.toString(ns));
        } else if (rr.type==DnsProtocol.TYPE_SRV) {
          DnsProtocol.SrvData srv = DnsProtocol.srvFromData(rr.rdata);
          logger.info("Found answer (srv): "+srv);
        } else
          logger.info("Found answer with "+rr.rdata.length+" bytes");
      }
    }
    catch (Exception e) {
      logger.warning("waiting for client: "+e.getMessage());
    }
  }
}




Java Source Code List

org.json.JSONArray.java
org.json.JSONException.java
org.json.JSONObject.java
org.json.JSONString.java
org.json.JSONStringer.java
org.json.JSONTokener.java
org.json.JSONWriter.java
uk.ac.horizon.ubihelper.channel.ChannelFactory.java
uk.ac.horizon.ubihelper.channel.ChannelListener.java
uk.ac.horizon.ubihelper.channel.ChannelManager.java
uk.ac.horizon.ubihelper.channel.ChannelValueEvent.java
uk.ac.horizon.ubihelper.channel.NamedChannel.java
uk.ac.horizon.ubihelper.channel.PullSubscription.java
uk.ac.horizon.ubihelper.channel.SharedVariableChannel.java
uk.ac.horizon.ubihelper.channel.Subscription.java
uk.ac.horizon.ubihelper.dns.DnsClient.java
uk.ac.horizon.ubihelper.dns.DnsProtocol.java
uk.ac.horizon.ubihelper.dns.DnsServer.java
uk.ac.horizon.ubihelper.dns.DnsUtils.java
uk.ac.horizon.ubihelper.httpserver.HttpClientHandler.java
uk.ac.horizon.ubihelper.httpserver.HttpContinuation.java
uk.ac.horizon.ubihelper.httpserver.HttpError.java
uk.ac.horizon.ubihelper.httpserver.HttpListener.java
uk.ac.horizon.ubihelper.j2se.Base64.java
uk.ac.horizon.ubihelper.j2se.Server.java
uk.ac.horizon.ubihelper.net.Fragment.java
uk.ac.horizon.ubihelper.net.Marshaller.java
uk.ac.horizon.ubihelper.net.Message.java
uk.ac.horizon.ubihelper.net.OnPeerConnectionListener.java
uk.ac.horizon.ubihelper.net.PeerConnectionScheduler.java
uk.ac.horizon.ubihelper.net.PeerConnection.java
uk.ac.horizon.ubihelper.protocol.ClientInfo.java
uk.ac.horizon.ubihelper.protocol.ClientState.java
uk.ac.horizon.ubihelper.protocol.MessageUtils.java
uk.ac.horizon.ubihelper.protocol.PeerInfo.java
uk.ac.horizon.ubihelper.protocol.ProtocolManager.java
uk.ac.horizon.ubihelper.service.BroadcastIntentSubscription.java
uk.ac.horizon.ubihelper.service.EnabledPeersChannel.java
uk.ac.horizon.ubihelper.service.LogManager.java
uk.ac.horizon.ubihelper.service.LogSubscription.java
uk.ac.horizon.ubihelper.service.PeerManager.java
uk.ac.horizon.ubihelper.service.PeersOpenHelper.java
uk.ac.horizon.ubihelper.service.Service.java
uk.ac.horizon.ubihelper.service.WifiDiscoveryManager.java
uk.ac.horizon.ubihelper.service.channel.BluetoothDiscoveryChannel.java
uk.ac.horizon.ubihelper.service.channel.CellLocationChannel.java
uk.ac.horizon.ubihelper.service.channel.CellStrengthChannel.java
uk.ac.horizon.ubihelper.service.channel.GpsStatusChannel.java
uk.ac.horizon.ubihelper.service.channel.LocationChannel.java
uk.ac.horizon.ubihelper.service.channel.MicChannel.java
uk.ac.horizon.ubihelper.service.channel.PollingChannel.java
uk.ac.horizon.ubihelper.service.channel.SensorChannel.java
uk.ac.horizon.ubihelper.service.channel.TimeChannel.java
uk.ac.horizon.ubihelper.service.channel.WifiScannerChannel.java
uk.ac.horizon.ubihelper.ui.AboutActivity.java
uk.ac.horizon.ubihelper.ui.ChannelListActivity.java
uk.ac.horizon.ubihelper.ui.ChannelPeerListActivity.java
uk.ac.horizon.ubihelper.ui.ChannelValueActivity.java
uk.ac.horizon.ubihelper.ui.ChannelViewActivity.java
uk.ac.horizon.ubihelper.ui.LoggingChannelListActivity.java
uk.ac.horizon.ubihelper.ui.LoggingPreferences.java
uk.ac.horizon.ubihelper.ui.MainPreferences.java
uk.ac.horizon.ubihelper.ui.ManagePeersActivity.java
uk.ac.horizon.ubihelper.ui.PeerInfoActivity.java
uk.ac.horizon.ubihelper.ui.PeerManualAddActivity.java
uk.ac.horizon.ubihelper.ui.PeerRequestActivity.java
uk.ac.horizon.ubihelper.ui.PeerRequestInfoActivity.java
uk.ac.horizon.ubihelper.ui.SearchPeersActivity.java
uk.ac.horizon.ubihelper.ui.TestActivity.java
uk.ac.horizon.ubihelper.ui.WifiStatusActivity.java
uk.ac.horizon.ubihelper.websocket.ClientWebsocket.java
uk.ac.horizon.ubihelper.websocket.ReadyState.java
uk.ac.horizon.ubihelper.websocket.SocketChannelWebsocket.java
uk.ac.horizon.ubihelper.websocket.WebsocketListener.java
uk.ac.horizon.ubihelper.websocket.Websocket.java