/* This file is part of GNUnet. Copyright (C) 2012, 2013 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet 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 General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gnunet.transport; import org.gnunet.transport.messages.AddressIterateMessage; import org.gnunet.transport.messages.AddressIterateResponseMessage; import org.gnunet.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Get active addresses of peers. */ public class AddressQuery { private static final Logger logger = LoggerFactory .getLogger(AddressQuery.class); private final boolean oneShot; private final PeerIdentity peerIdentity; private final PeerAddressMonitorCallback monitorCallback; private final PeerAddressListCallback listCallback; /** * Client connecting to the transport service. */ private Client client; private final class AddressMonitorReceiver extends RunaboutMessageReceiver { public void visit(AddressIterateResponseMessage m) { if (m.content == null) { // uglyness in the api, when using one-shot the service // may send a second message indicating end of list. if (listCallback != null) { listCallback.onDone(); } else { client.reconnect(); sendInitMessage(); } return; } if (listCallback != null) { if (m.content.addrLen == 0 && m.content.pluginLen == 0) { logger.warn("empty peer address list item"); } else { HelloAddress helloAddress = new HelloAddress(); helloAddress.peer = m.content.peerIdentity; helloAddress.address = m.content.address; helloAddress.transportName = m.content.plugin; listCallback.onPeerAddress(helloAddress, m.content.state, AbsoluteTime.fromNetwork(m.content.stateTimeout)); } } else { if (m.content.addrLen == 0 && m.content.pluginLen == 0) { monitorCallback.onPeerDisconnect(m.content.peerIdentity); } else { HelloAddress helloAddress = new HelloAddress(); helloAddress.peer = m.content.peerIdentity; helloAddress.address = m.content.address; helloAddress.transportName = m.content.plugin; monitorCallback.onPeerAddress(helloAddress, m.content.state, AbsoluteTime.fromNetwork(m.content.stateTimeout)); } } } @Override public void handleError() { client.reconnect(); sendInitMessage(); } } /** * Monitor active addresses of the given peer, or of all peers if 'null' is * passed as peer identity. * * @param configuration configuration to use for connecting to * the transport service * @param peerIdentity peer identity to monitor addresses of, null * to monitor addresses of all connected peers * @param peerAddressCallback callback to call when receiving an address * for the specified peer */ public AddressQuery(Configuration configuration, PeerIdentity peerIdentity, PeerAddressMonitorCallback peerAddressCallback) { this.oneShot = false; this.peerIdentity = peerIdentity; this.monitorCallback = peerAddressCallback; this.listCallback = null; createAndInitClient(configuration); } /** * Monitor active addresses of the given peer, or of all peers if 'null' is * passed as peer identity. * * @param configuration configuration to use for connecting to * the transport service * @param peerIdentity peer identity to monitor addresses of, null * to monitor addresses of all connected peers * @param listCallback callback to call when receiving an address * for the specified peer */ public AddressQuery(Configuration configuration, PeerIdentity peerIdentity, PeerAddressListCallback listCallback) { this.oneShot = true; this.peerIdentity = peerIdentity; this.listCallback = listCallback; this.monitorCallback = null; createAndInitClient(configuration); } private void createAndInitClient(Configuration configuration) { client = new Client("transport", configuration); client.installReceiver(new AddressMonitorReceiver()); sendInitMessage(); } private void sendInitMessage() { AddressIterateMessage m = new AddressIterateMessage(); m.oneShot = oneShot; if (peerIdentity == null) { // set peer to all zeroes m.peer = new PeerIdentity(); } else { m.peer = peerIdentity; } client.send(m); } }