forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test4' (head cd6f8d7166795ee12ac0b24b7e0e26fb2e404151)
to branch 'i2p.i2p.zzz.dhtsnark' (head 1dfd7ad10e6b9ec23db5722a5a024a96659c57a3)
This commit is contained in:
@@ -14,11 +14,13 @@ import java.util.StringTokenizer;
|
|||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.I2PException;
|
import net.i2p.I2PException;
|
||||||
import net.i2p.client.I2PSession;
|
import net.i2p.client.I2PSession;
|
||||||
|
import net.i2p.client.I2PSessionException;
|
||||||
import net.i2p.client.streaming.I2PServerSocket;
|
import net.i2p.client.streaming.I2PServerSocket;
|
||||||
import net.i2p.client.streaming.I2PSocket;
|
import net.i2p.client.streaming.I2PSocket;
|
||||||
import net.i2p.client.streaming.I2PSocketEepGet;
|
import net.i2p.client.streaming.I2PSocketEepGet;
|
||||||
import net.i2p.client.streaming.I2PSocketManager;
|
import net.i2p.client.streaming.I2PSocketManager;
|
||||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||||
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
@@ -341,21 +343,44 @@ public class I2PSnarkUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int BASE32_HASH_LENGTH = 52; // 1 + Hash.HASH_LENGTH * 8 / 5
|
||||||
|
|
||||||
/** Base64 Hash or Hash.i2p or name.i2p using naming service */
|
/** Base64 Hash or Hash.i2p or name.i2p using naming service */
|
||||||
Destination getDestination(String ip) {
|
Destination getDestination(String ip) {
|
||||||
if (ip == null) return null;
|
if (ip == null) return null;
|
||||||
if (ip.endsWith(".i2p")) {
|
if (ip.endsWith(".i2p")) {
|
||||||
if (ip.length() < 520) { // key + ".i2p"
|
if (ip.length() < 520) { // key + ".i2p"
|
||||||
Destination dest = _context.namingService().lookup(ip);
|
if (_manager != null && ip.length() == BASE32_HASH_LENGTH + 8 && ip.endsWith(".b32.i2p")) {
|
||||||
if (dest != null)
|
// Use existing I2PSession for b32 lookups if we have it
|
||||||
return dest;
|
// This is much more efficient than using the naming service
|
||||||
|
I2PSession sess = _manager.getSession();
|
||||||
|
if (sess != null) {
|
||||||
|
byte[] b = Base32.decode(ip.substring(0, BASE32_HASH_LENGTH));
|
||||||
|
if (b != null) {
|
||||||
|
Hash h = new Hash(b);
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Using existing session for lookup of " + ip);
|
||||||
|
try {
|
||||||
|
return sess.lookupDest(h);
|
||||||
|
} catch (I2PSessionException ise) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Using naming service for lookup of " + ip);
|
||||||
|
return _context.namingService().lookup(ip);
|
||||||
}
|
}
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Creating Destination for " + ip);
|
||||||
try {
|
try {
|
||||||
return new Destination(ip.substring(0, ip.length()-4)); // sans .i2p
|
return new Destination(ip.substring(0, ip.length()-4)); // sans .i2p
|
||||||
} catch (DataFormatException dfe) {
|
} catch (DataFormatException dfe) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
_log.info("Creating Destination for " + ip);
|
||||||
try {
|
try {
|
||||||
return new Destination(ip);
|
return new Destination(ip);
|
||||||
} catch (DataFormatException dfe) {
|
} catch (DataFormatException dfe) {
|
||||||
|
@@ -2,8 +2,6 @@ package net.i2p.router.web;
|
|||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -13,7 +11,7 @@ import java.util.TreeSet;
|
|||||||
|
|
||||||
import net.i2p.router.client.ClientManagerFacadeImpl;
|
import net.i2p.router.client.ClientManagerFacadeImpl;
|
||||||
import net.i2p.router.startup.ClientAppConfig;
|
import net.i2p.router.startup.ClientAppConfig;
|
||||||
import net.i2p.router.transport.Addresses;
|
import net.i2p.util.Addresses;
|
||||||
|
|
||||||
public class ConfigClientsHelper extends HelperBase {
|
public class ConfigClientsHelper extends HelperBase {
|
||||||
private String _edit;
|
private String _edit;
|
||||||
@@ -67,22 +65,8 @@ public class ConfigClientsHelper extends HelperBase {
|
|||||||
|
|
||||||
/** @since 0.8.3 */
|
/** @since 0.8.3 */
|
||||||
public String[] intfcAddresses() {
|
public String[] intfcAddresses() {
|
||||||
String[] addrs = Addresses.getAllAddresses();
|
ArrayList<String> al = new ArrayList(Addresses.getAllAddresses());
|
||||||
List<String> aList = new ArrayList();
|
return al.toArray(new String[al.size()]);
|
||||||
aList.addAll(Arrays.asList(addrs));
|
|
||||||
boolean ipv6 = false;
|
|
||||||
for (String a : aList) {
|
|
||||||
if (a.indexOf(':') >= 0) {
|
|
||||||
ipv6 = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!aList.contains("0.0.0.0"))
|
|
||||||
aList.add("0.0.0.0");
|
|
||||||
if (ipv6 && !aList.contains("0:0:0:0:0:0:0:0"))
|
|
||||||
aList.add("0:0:0:0:0:0:0:0"); // we could do "::" but all the other ones are probably in long form
|
|
||||||
Collections.sort(aList);
|
|
||||||
return aList.toArray(addrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 0.8.3 */
|
/** @since 0.8.3 */
|
||||||
|
@@ -1,14 +1,16 @@
|
|||||||
package net.i2p.router.web;
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.RouterAddress;
|
import net.i2p.data.RouterAddress;
|
||||||
import net.i2p.router.CommSystemFacade;
|
import net.i2p.router.CommSystemFacade;
|
||||||
import net.i2p.router.Router;
|
import net.i2p.router.Router;
|
||||||
import net.i2p.router.transport.Addresses;
|
|
||||||
import net.i2p.router.transport.TransportManager;
|
import net.i2p.router.transport.TransportManager;
|
||||||
import net.i2p.router.transport.udp.UDPAddress;
|
import net.i2p.router.transport.udp.UDPAddress;
|
||||||
import net.i2p.router.transport.udp.UDPTransport;
|
import net.i2p.router.transport.udp.UDPTransport;
|
||||||
import net.i2p.time.Timestamper;
|
import net.i2p.time.Timestamper;
|
||||||
|
import net.i2p.util.Addresses;
|
||||||
|
|
||||||
public class ConfigNetHelper extends HelperBase {
|
public class ConfigNetHelper extends HelperBase {
|
||||||
public ConfigNetHelper() {}
|
public ConfigNetHelper() {}
|
||||||
@@ -147,7 +149,8 @@ public class ConfigNetHelper extends HelperBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String[] getAddresses() {
|
public String[] getAddresses() {
|
||||||
return Addresses.getAddresses();
|
ArrayList<String> al = new ArrayList(Addresses.getAddresses());
|
||||||
|
return al.toArray(new String[al.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getInboundRate() {
|
public String getInboundRate() {
|
||||||
|
@@ -10,6 +10,9 @@ import net.i2p.data.i2cp.I2CPMessage;
|
|||||||
import net.i2p.data.i2cp.DestReplyMessage;
|
import net.i2p.data.i2cp.DestReplyMessage;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.data.Hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle I2CP dest replies from the router
|
* Handle I2CP dest replies from the router
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +25,12 @@ class DestReplyMessageHandler extends HandlerImpl {
|
|||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Handle message " + message);
|
_log.debug("Handle message " + message);
|
||||||
DestReplyMessage msg = (DestReplyMessage) message;
|
DestReplyMessage msg = (DestReplyMessage) message;
|
||||||
((I2PSimpleSession)session).destReceived(msg.getDestination());
|
Destination d = msg.getDestination();
|
||||||
|
if (d != null)
|
||||||
|
session.destReceived(d);
|
||||||
|
Hash h = msg.getHash();
|
||||||
|
if (h != null)
|
||||||
|
session.destLookupFailed(h);
|
||||||
|
// else let it time out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,6 +10,8 @@ package net.i2p.client;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.data.i2cp.BandwidthLimitsMessage;
|
||||||
|
import net.i2p.data.i2cp.DestReplyMessage;
|
||||||
import net.i2p.data.i2cp.DisconnectMessage;
|
import net.i2p.data.i2cp.DisconnectMessage;
|
||||||
import net.i2p.data.i2cp.MessagePayloadMessage;
|
import net.i2p.data.i2cp.MessagePayloadMessage;
|
||||||
import net.i2p.data.i2cp.MessageStatusMessage;
|
import net.i2p.data.i2cp.MessageStatusMessage;
|
||||||
@@ -36,6 +38,8 @@ class I2PClientMessageHandlerMap {
|
|||||||
highest = Math.max(highest, MessagePayloadMessage.MESSAGE_TYPE);
|
highest = Math.max(highest, MessagePayloadMessage.MESSAGE_TYPE);
|
||||||
highest = Math.max(highest, MessageStatusMessage.MESSAGE_TYPE);
|
highest = Math.max(highest, MessageStatusMessage.MESSAGE_TYPE);
|
||||||
highest = Math.max(highest, SetDateMessage.MESSAGE_TYPE);
|
highest = Math.max(highest, SetDateMessage.MESSAGE_TYPE);
|
||||||
|
highest = Math.max(highest, DestReplyMessage.MESSAGE_TYPE);
|
||||||
|
highest = Math.max(highest, BandwidthLimitsMessage.MESSAGE_TYPE);
|
||||||
|
|
||||||
_handlers = new I2CPMessageHandler[highest+1];
|
_handlers = new I2CPMessageHandler[highest+1];
|
||||||
_handlers[DisconnectMessage.MESSAGE_TYPE] = new DisconnectMessageHandler(context);
|
_handlers[DisconnectMessage.MESSAGE_TYPE] = new DisconnectMessageHandler(context);
|
||||||
@@ -44,6 +48,8 @@ class I2PClientMessageHandlerMap {
|
|||||||
_handlers[MessagePayloadMessage.MESSAGE_TYPE] = new MessagePayloadMessageHandler(context);
|
_handlers[MessagePayloadMessage.MESSAGE_TYPE] = new MessagePayloadMessageHandler(context);
|
||||||
_handlers[MessageStatusMessage.MESSAGE_TYPE] = new MessageStatusMessageHandler(context);
|
_handlers[MessageStatusMessage.MESSAGE_TYPE] = new MessageStatusMessageHandler(context);
|
||||||
_handlers[SetDateMessage.MESSAGE_TYPE] = new SetDateMessageHandler(context);
|
_handlers[SetDateMessage.MESSAGE_TYPE] = new SetDateMessageHandler(context);
|
||||||
|
_handlers[DestReplyMessage.MESSAGE_TYPE] = new DestReplyMessageHandler(context);
|
||||||
|
_handlers[BandwidthLimitsMessage.MESSAGE_TYPE] = new BWLimitsMessageHandler(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public I2CPMessageHandler getHandler(int messageTypeId) {
|
public I2CPMessageHandler getHandler(int messageTypeId) {
|
||||||
|
@@ -138,13 +138,21 @@ public interface I2PSession {
|
|||||||
public SigningPrivateKey getPrivateKey();
|
public SigningPrivateKey getPrivateKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup up a Hash
|
* Lookup a Destination by Hash.
|
||||||
*
|
* Blocking. Waits a max of 10 seconds by default.
|
||||||
*/
|
*/
|
||||||
public Destination lookupDest(Hash h) throws I2PSessionException;
|
public Destination lookupDest(Hash h) throws I2PSessionException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current bandwidth limits
|
* Blocking.
|
||||||
|
* @param maxWait ms
|
||||||
|
* @since 0.8.3
|
||||||
|
* @return null on failure
|
||||||
|
*/
|
||||||
|
public Destination lookupDest(Hash h, long maxWait) throws I2PSessionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current bandwidth limits. Blocking.
|
||||||
*/
|
*/
|
||||||
public int[] bandwidthLimits() throws I2PSessionException;
|
public int[] bandwidthLimits() throws I2PSessionException;
|
||||||
|
|
||||||
|
@@ -15,7 +15,6 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -23,6 +22,8 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
@@ -33,6 +34,8 @@ import net.i2p.data.PrivateKey;
|
|||||||
import net.i2p.data.SessionKey;
|
import net.i2p.data.SessionKey;
|
||||||
import net.i2p.data.SessionTag;
|
import net.i2p.data.SessionTag;
|
||||||
import net.i2p.data.SigningPrivateKey;
|
import net.i2p.data.SigningPrivateKey;
|
||||||
|
import net.i2p.data.i2cp.DestLookupMessage;
|
||||||
|
import net.i2p.data.i2cp.GetBandwidthLimitsMessage;
|
||||||
import net.i2p.data.i2cp.GetDateMessage;
|
import net.i2p.data.i2cp.GetDateMessage;
|
||||||
import net.i2p.data.i2cp.I2CPMessage;
|
import net.i2p.data.i2cp.I2CPMessage;
|
||||||
import net.i2p.data.i2cp.I2CPMessageException;
|
import net.i2p.data.i2cp.I2CPMessageException;
|
||||||
@@ -95,6 +98,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
protected I2CPMessageProducer _producer;
|
protected I2CPMessageProducer _producer;
|
||||||
/** map of Long --> MessagePayloadMessage */
|
/** map of Long --> MessagePayloadMessage */
|
||||||
protected Map<Long, MessagePayloadMessage> _availableMessages;
|
protected Map<Long, MessagePayloadMessage> _availableMessages;
|
||||||
|
|
||||||
|
/** hashes of lookups we are waiting for */
|
||||||
|
protected final LinkedBlockingQueue<LookupWaiter> _pendingLookups = new LinkedBlockingQueue();
|
||||||
|
protected final Object _bwReceivedLock = new Object();
|
||||||
|
protected int[] _bwLimits;
|
||||||
|
|
||||||
protected I2PClientMessageHandlerMap _handlerMap;
|
protected I2PClientMessageHandlerMap _handlerMap;
|
||||||
|
|
||||||
@@ -786,12 +794,104 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Destination lookupDest(Hash h) throws I2PSessionException {
|
/** called by the message handler */
|
||||||
return null;
|
void destReceived(Destination d) {
|
||||||
|
Hash h = d.calculateHash();
|
||||||
|
for (LookupWaiter w : _pendingLookups) {
|
||||||
|
if (w.hash.equals(h)) {
|
||||||
|
w.destination = d;
|
||||||
|
synchronized (w) {
|
||||||
|
w.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** called by the message handler */
|
||||||
|
void destLookupFailed(Hash h) {
|
||||||
|
for (LookupWaiter w : _pendingLookups) {
|
||||||
|
if (w.hash.equals(h)) {
|
||||||
|
synchronized (w) {
|
||||||
|
w.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** called by the message handler */
|
||||||
|
void bwReceived(int[] i) {
|
||||||
|
_bwLimits = i;
|
||||||
|
synchronized (_bwReceivedLock) {
|
||||||
|
_bwReceivedLock.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple object to wait for lookup replies
|
||||||
|
* @since 0.8.3
|
||||||
|
*/
|
||||||
|
private static class LookupWaiter {
|
||||||
|
/** the request */
|
||||||
|
public final Hash hash;
|
||||||
|
/** the reply */
|
||||||
|
public Destination destination;
|
||||||
|
|
||||||
|
public LookupWaiter(Hash h) {
|
||||||
|
this.hash = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking. Waits a max of 10 seconds by default.
|
||||||
|
* See lookupDest with maxWait parameter to change.
|
||||||
|
* Implemented in 0.8.3 in I2PSessionImpl;
|
||||||
|
* previously was available only in I2PSimpleSession.
|
||||||
|
* Multiple outstanding lookups are now allowed.
|
||||||
|
* @return null on failure
|
||||||
|
*/
|
||||||
|
public Destination lookupDest(Hash h) throws I2PSessionException {
|
||||||
|
return lookupDest(h, 10*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking.
|
||||||
|
* @param maxWait ms
|
||||||
|
* @since 0.8.3
|
||||||
|
* @return null on failure
|
||||||
|
*/
|
||||||
|
public Destination lookupDest(Hash h, long maxWait) throws I2PSessionException {
|
||||||
|
if (_closed)
|
||||||
|
return null;
|
||||||
|
LookupWaiter waiter = new LookupWaiter(h);
|
||||||
|
_pendingLookups.offer(waiter);
|
||||||
|
sendMessage(new DestLookupMessage(h));
|
||||||
|
try {
|
||||||
|
synchronized (waiter) {
|
||||||
|
waiter.wait(maxWait);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ie) {}
|
||||||
|
_pendingLookups.remove(waiter);
|
||||||
|
return waiter.destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Blocking. Waits a max of 5 seconds.
|
||||||
|
* But shouldn't take long.
|
||||||
|
* Implemented in 0.8.3 in I2PSessionImpl;
|
||||||
|
* previously was available only in I2PSimpleSession.
|
||||||
|
* Multiple outstanding lookups are now allowed.
|
||||||
|
* @return null on failure
|
||||||
|
*/
|
||||||
public int[] bandwidthLimits() throws I2PSessionException {
|
public int[] bandwidthLimits() throws I2PSessionException {
|
||||||
return null;
|
if (_closed)
|
||||||
|
return null;
|
||||||
|
sendMessage(new GetBandwidthLimitsMessage());
|
||||||
|
try {
|
||||||
|
synchronized (_bwReceivedLock) {
|
||||||
|
_bwReceivedLock.wait(5*1000);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ie) {}
|
||||||
|
return _bwLimits;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateActivity() {
|
protected void updateActivity() {
|
||||||
|
@@ -33,12 +33,6 @@ import net.i2p.util.I2PAppThread;
|
|||||||
* @author zzz
|
* @author zzz
|
||||||
*/
|
*/
|
||||||
class I2PSimpleSession extends I2PSessionImpl2 {
|
class I2PSimpleSession extends I2PSessionImpl2 {
|
||||||
private boolean _destReceived;
|
|
||||||
private /* FIXME final FIXME */ Object _destReceivedLock;
|
|
||||||
private Destination _destination;
|
|
||||||
private boolean _bwReceived;
|
|
||||||
private /* FIXME final FIXME */ Object _bwReceivedLock;
|
|
||||||
private int[] _bwLimits;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new session for doing naming and bandwidth queries only. Do not create a destination.
|
* Create a new session for doing naming and bandwidth queries only. Do not create a destination.
|
||||||
@@ -104,57 +98,6 @@ class I2PSimpleSession extends I2PSessionImpl2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** called by the message handler */
|
|
||||||
void destReceived(Destination d) {
|
|
||||||
_destReceived = true;
|
|
||||||
_destination = d;
|
|
||||||
synchronized (_destReceivedLock) {
|
|
||||||
_destReceivedLock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bwReceived(int[] i) {
|
|
||||||
_bwReceived = true;
|
|
||||||
_bwLimits = i;
|
|
||||||
synchronized (_bwReceivedLock) {
|
|
||||||
_bwReceivedLock.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Destination lookupDest(Hash h) throws I2PSessionException {
|
|
||||||
if (_closed)
|
|
||||||
return null;
|
|
||||||
_destReceivedLock = new Object();
|
|
||||||
sendMessage(new DestLookupMessage(h));
|
|
||||||
for (int i = 0; i < 10 && !_destReceived; i++) {
|
|
||||||
try {
|
|
||||||
synchronized (_destReceivedLock) {
|
|
||||||
_destReceivedLock.wait(1000);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ie) {}
|
|
||||||
}
|
|
||||||
_destReceived = false;
|
|
||||||
return _destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int[] bandwidthLimits() throws I2PSessionException {
|
|
||||||
if (_closed)
|
|
||||||
return null;
|
|
||||||
_bwReceivedLock = new Object();
|
|
||||||
sendMessage(new GetBandwidthLimitsMessage());
|
|
||||||
for (int i = 0; i < 5 && !_bwReceived; i++) {
|
|
||||||
try {
|
|
||||||
synchronized (_bwReceivedLock) {
|
|
||||||
_bwReceivedLock.wait(1000);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException ie) {}
|
|
||||||
}
|
|
||||||
_bwReceived = false;
|
|
||||||
return _bwLimits;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only map message handlers that we will use
|
* Only map message handlers that we will use
|
||||||
*/
|
*/
|
||||||
|
@@ -22,6 +22,13 @@ import net.i2p.data.Hash;
|
|||||||
*
|
*
|
||||||
* All calls are blocking and return null on failure.
|
* All calls are blocking and return null on failure.
|
||||||
* Timeout is set to 10 seconds in I2PSimpleSession.
|
* Timeout is set to 10 seconds in I2PSimpleSession.
|
||||||
|
*
|
||||||
|
* As of 0.8.3, standard I2PSessions support lookups,
|
||||||
|
* including multiple lookups in parallel, and overriding
|
||||||
|
* the default timeout.
|
||||||
|
* Using an existing I2PSession is much more efficient and
|
||||||
|
* flexible than using this class.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
class LookupDest {
|
class LookupDest {
|
||||||
|
|
||||||
|
@@ -13,14 +13,18 @@ import java.io.InputStream;
|
|||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
|
import net.i2p.data.Hash;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response to DestLookupMessage
|
* Response to DestLookupMessage.
|
||||||
*
|
* As of 0.8.3, the response may include the hash from the request, indicating
|
||||||
|
* a failure for a specific request.
|
||||||
|
* Payload may be empty (failure), a Hash (failure), or a Destination.
|
||||||
*/
|
*/
|
||||||
public class DestReplyMessage extends I2CPMessageImpl {
|
public class DestReplyMessage extends I2CPMessageImpl {
|
||||||
public final static int MESSAGE_TYPE = 35;
|
public final static int MESSAGE_TYPE = 35;
|
||||||
private Destination _dest;
|
private Destination _dest;
|
||||||
|
private Hash _hash;
|
||||||
|
|
||||||
public DestReplyMessage() {
|
public DestReplyMessage() {
|
||||||
super();
|
super();
|
||||||
@@ -30,23 +34,52 @@ public class DestReplyMessage extends I2CPMessageImpl {
|
|||||||
_dest = d;
|
_dest = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param h non-null with non-null data
|
||||||
|
* @since 0.8.3
|
||||||
|
*/
|
||||||
|
public DestReplyMessage(Hash h) {
|
||||||
|
_hash = h;
|
||||||
|
}
|
||||||
|
|
||||||
public Destination getDestination() {
|
public Destination getDestination() {
|
||||||
return _dest;
|
return _dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.8.3
|
||||||
|
*/
|
||||||
|
public Hash getHash() {
|
||||||
|
return _hash;
|
||||||
|
}
|
||||||
|
|
||||||
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
|
protected void doReadMessage(InputStream in, int size) throws I2CPMessageException, IOException {
|
||||||
try {
|
if (size == 0) {
|
||||||
Destination d = new Destination();
|
_dest = null;
|
||||||
d.readBytes(in);
|
_hash = null;
|
||||||
_dest = d;
|
} else {
|
||||||
} catch (DataFormatException dfe) {
|
try {
|
||||||
_dest = null; // null dest allowed
|
if (size == Hash.HASH_LENGTH) {
|
||||||
|
Hash h = new Hash();
|
||||||
|
h.readBytes(in);
|
||||||
|
_hash = h;
|
||||||
|
} else {
|
||||||
|
Destination d = new Destination();
|
||||||
|
d.readBytes(in);
|
||||||
|
_dest = d;
|
||||||
|
}
|
||||||
|
} catch (DataFormatException dfe) {
|
||||||
|
_dest = null;
|
||||||
|
_hash = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
|
protected byte[] doWriteMessage() throws I2CPMessageException, IOException {
|
||||||
if (_dest == null)
|
if (_dest == null && _hash == null)
|
||||||
return new byte[0]; // null response allowed
|
return new byte[0]; // null response allowed
|
||||||
|
if (_dest == null && _hash != null)
|
||||||
|
return _hash.getData();
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream(_dest.size());
|
ByteArrayOutputStream os = new ByteArrayOutputStream(_dest.size());
|
||||||
try {
|
try {
|
||||||
_dest.writeBytes(os);
|
_dest.writeBytes(os);
|
||||||
@@ -65,7 +98,8 @@ public class DestReplyMessage extends I2CPMessageImpl {
|
|||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if ((object != null) && (object instanceof DestReplyMessage)) {
|
if ((object != null) && (object instanceof DestReplyMessage)) {
|
||||||
DestReplyMessage msg = (DestReplyMessage) object;
|
DestReplyMessage msg = (DestReplyMessage) object;
|
||||||
return DataHelper.eq(getDestination(), msg.getDestination());
|
return DataHelper.eq(getDestination(), msg.getDestination()) &&
|
||||||
|
DataHelper.eq(getHash(), msg.getHash());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -75,6 +109,7 @@ public class DestReplyMessage extends I2CPMessageImpl {
|
|||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
buf.append("[DestReplyMessage: ");
|
buf.append("[DestReplyMessage: ");
|
||||||
buf.append("\n\tDestination: ").append(_dest);
|
buf.append("\n\tDestination: ").append(_dest);
|
||||||
|
buf.append("\n\tHash: ").append(_hash);
|
||||||
buf.append("]");
|
buf.append("]");
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
125
core/java/src/net/i2p/util/Addresses.java
Normal file
125
core/java/src/net/i2p/util/Addresses.java
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
package net.i2p.util;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* public domain
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local addresses
|
||||||
|
*
|
||||||
|
* @since 0.8.3 moved to core
|
||||||
|
* @author zzz
|
||||||
|
*/
|
||||||
|
public abstract class Addresses {
|
||||||
|
|
||||||
|
/** @return the first non-local address it finds, or null */
|
||||||
|
public static String getAnyAddress() {
|
||||||
|
SortedSet<String> a = getAddresses();
|
||||||
|
if (!a.isEmpty())
|
||||||
|
return a.first();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a sorted set of all addresses, excluding
|
||||||
|
* IPv6, local, broadcast, multicast, etc.
|
||||||
|
*/
|
||||||
|
public static SortedSet<String> getAddresses() {
|
||||||
|
return getAddresses(false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a sorted set of all addresses, excluding
|
||||||
|
* only link local and multicast
|
||||||
|
* @since 0.8.3
|
||||||
|
*/
|
||||||
|
public static SortedSet<String> getAllAddresses() {
|
||||||
|
return getAddresses(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a sorted array of all addresses
|
||||||
|
* @param whether to exclude IPV6 and local
|
||||||
|
* @return an array of all addresses
|
||||||
|
* @since 0.8.3
|
||||||
|
*/
|
||||||
|
public static SortedSet<String> getAddresses(boolean includeLocal, boolean includeIPv6) {
|
||||||
|
SortedSet<String> rv = new TreeSet();
|
||||||
|
try {
|
||||||
|
InetAddress localhost = InetAddress.getLocalHost();
|
||||||
|
InetAddress[] allMyIps = InetAddress.getAllByName(localhost.getCanonicalHostName());
|
||||||
|
if (allMyIps != null) {
|
||||||
|
for (int i = 0; i < allMyIps.length; i++) {
|
||||||
|
if (shouldInclude(allMyIps[i], includeLocal, includeIPv6))
|
||||||
|
rv.add(allMyIps[i].getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UnknownHostException e) {}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for(Enumeration<NetworkInterface> ifcs = NetworkInterface.getNetworkInterfaces(); ifcs.hasMoreElements();) {
|
||||||
|
NetworkInterface ifc = ifcs.nextElement();
|
||||||
|
for(Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements();) {
|
||||||
|
InetAddress addr = addrs.nextElement();
|
||||||
|
if (shouldInclude(addr, includeLocal, includeIPv6))
|
||||||
|
rv.add(addr.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SocketException e) {}
|
||||||
|
|
||||||
|
if (includeLocal)
|
||||||
|
rv.add("0.0.0.0");
|
||||||
|
if (includeLocal && includeIPv6) {
|
||||||
|
boolean ipv6 = false;
|
||||||
|
for (String a : rv) {
|
||||||
|
if (a.indexOf(':') >= 0) {
|
||||||
|
ipv6 = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ipv6)
|
||||||
|
rv.add("0:0:0:0:0:0:0:0"); // we could do "::" but all the other ones are probably in long form
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean shouldInclude(InetAddress ia, boolean includeLocal, boolean includeIPv6) {
|
||||||
|
return
|
||||||
|
(!ia.isLinkLocalAddress()) &&
|
||||||
|
(!ia.isMulticastAddress()) &&
|
||||||
|
(includeLocal ||
|
||||||
|
((!ia.isAnyLocalAddress()) &&
|
||||||
|
(!ia.isLoopbackAddress()) &&
|
||||||
|
(!ia.isSiteLocalAddress()))) &&
|
||||||
|
// Hamachi 5/8 allocated to RIPE (30 November 2010)
|
||||||
|
// Removed from TransportImpl.isPubliclyRoutable()
|
||||||
|
// Check moved to here, for now, but will eventually need to
|
||||||
|
// remove it from here also.
|
||||||
|
(includeLocal ||
|
||||||
|
(!ia.getHostAddress().startsWith("5."))) &&
|
||||||
|
(includeIPv6 ||
|
||||||
|
(ia instanceof Inet4Address));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.err.println("External Addresses:");
|
||||||
|
Set<String> a = getAddresses(false, false);
|
||||||
|
for (String s : a)
|
||||||
|
System.err.println(s);
|
||||||
|
System.err.println("All addresses:");
|
||||||
|
a = getAddresses(true, true);
|
||||||
|
for (String s : a)
|
||||||
|
System.err.println(s);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,121 +0,0 @@
|
|||||||
package net.i2p.router.transport;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* public domain
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Inet4Address;
|
|
||||||
import java.net.NetworkInterface;
|
|
||||||
import java.net.SocketException;
|
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the local addresses
|
|
||||||
*
|
|
||||||
* @author zzz
|
|
||||||
*/
|
|
||||||
public class Addresses {
|
|
||||||
|
|
||||||
/** @return the first non-local address it finds, or null */
|
|
||||||
public static String getAnyAddress() {
|
|
||||||
String[] a = getAddresses();
|
|
||||||
if (a.length > 0)
|
|
||||||
return a[0];
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a sorted array of all addresses, excluding
|
|
||||||
* IPv6, local, broadcast, multicast, etc.
|
|
||||||
*/
|
|
||||||
public static String[] getAddresses() {
|
|
||||||
return getAddresses(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a sorted array of all addresses, excluding
|
|
||||||
* only link local and multicast
|
|
||||||
* @since 0.8.3
|
|
||||||
*/
|
|
||||||
public static String[] getAllAddresses() {
|
|
||||||
return getAddresses(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a sorted array of all addresses
|
|
||||||
* @param whether to exclude IPV6 and local
|
|
||||||
* @return an array of all addresses
|
|
||||||
* @since 0.8.3
|
|
||||||
*/
|
|
||||||
public static String[] getAddresses(boolean all) {
|
|
||||||
Set<String> rv = new HashSet(4);
|
|
||||||
try {
|
|
||||||
InetAddress localhost = InetAddress.getLocalHost();
|
|
||||||
InetAddress[] allMyIps = InetAddress.getAllByName(localhost.getCanonicalHostName());
|
|
||||||
if (allMyIps != null) {
|
|
||||||
for (int i = 0; i < allMyIps.length; i++) {
|
|
||||||
if (all)
|
|
||||||
addAll(rv, allMyIps[i]);
|
|
||||||
else
|
|
||||||
add(rv, allMyIps[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (UnknownHostException e) {}
|
|
||||||
|
|
||||||
try {
|
|
||||||
for(Enumeration<NetworkInterface> ifcs = NetworkInterface.getNetworkInterfaces(); ifcs.hasMoreElements();) {
|
|
||||||
NetworkInterface ifc = ifcs.nextElement();
|
|
||||||
for(Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements();) {
|
|
||||||
InetAddress addr = addrs.nextElement();
|
|
||||||
if (all)
|
|
||||||
addAll(rv, addr);
|
|
||||||
else
|
|
||||||
add(rv, addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (SocketException e) {}
|
|
||||||
|
|
||||||
String[] rva = rv.toArray(new String[rv.size()]);
|
|
||||||
Arrays.sort(rva);
|
|
||||||
return rva;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void add(Set<String> set, InetAddress ia) {
|
|
||||||
if (ia.isAnyLocalAddress() ||
|
|
||||||
ia.isLinkLocalAddress() ||
|
|
||||||
ia.isLoopbackAddress() ||
|
|
||||||
ia.isMulticastAddress() ||
|
|
||||||
ia.isSiteLocalAddress() ||
|
|
||||||
// Hamachi 5/8 allocated to RIPE (30 November 2010)
|
|
||||||
// Removed from TransportImpl.isPubliclyRoutable()
|
|
||||||
// Check moved to here, for now, but will eventually need to
|
|
||||||
// remove it from here also.
|
|
||||||
ia.getHostAddress().startsWith("5.") ||
|
|
||||||
!(ia instanceof Inet4Address)) {
|
|
||||||
// System.err.println("Skipping: " + ia.getHostAddress());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
String ip = ia.getHostAddress();
|
|
||||||
set.add(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void addAll(Set<String> set, InetAddress ia) {
|
|
||||||
if (ia.isLinkLocalAddress() ||
|
|
||||||
ia.isMulticastAddress())
|
|
||||||
return;
|
|
||||||
String ip = ia.getHostAddress();
|
|
||||||
set.add(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
String[] a = getAddresses(true);
|
|
||||||
for (String s : a)
|
|
||||||
System.err.println("Address: " + s);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -32,6 +32,7 @@ import net.i2p.router.OutNetMessage;
|
|||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
import net.i2p.router.transport.ntcp.NTCPTransport;
|
import net.i2p.router.transport.ntcp.NTCPTransport;
|
||||||
import net.i2p.router.transport.udp.UDPTransport;
|
import net.i2p.router.transport.udp.UDPTransport;
|
||||||
|
import net.i2p.util.Addresses;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.Translate;
|
import net.i2p.util.Translate;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user