forked from I2P_Developers/i2p.i2p
Compare commits
2 Commits
i2p.i2p.2.
...
ip-restric
Author | SHA1 | Date | |
---|---|---|---|
d3af2af369 | |||
257c0aff42 |
@ -407,7 +407,7 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
||||||
selectFastPeers(howMany, exclude, matches, 0);
|
selectFastPeers(howMany, exclude, matches, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -421,17 +421,19 @@ public class ProfileOrganizer {
|
|||||||
* @param matches set to store the return value in
|
* @param matches set to store the return value in
|
||||||
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @param ipSet in/out param, use for multiple calls, may be null only if mask is 0
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
|
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
getReadLock();
|
getReadLock();
|
||||||
try {
|
try {
|
||||||
locked_selectPeers(_fastPeers, howMany, exclude, matches, mask);
|
locked_selectPeers(_fastPeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("selectFastPeers("+howMany+"), not enough fast (" + matches.size() + ") going on to highCap");
|
_log.info("selectFastPeers("+howMany+"), not enough fast (" + matches.size() + ") going on to highCap");
|
||||||
selectHighCapacityPeers(howMany, exclude, matches, mask);
|
selectHighCapacityPeers(howMany, exclude, matches, mask, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("selectFastPeers("+howMany+"), found enough fast (" + matches.size() + ")");
|
_log.debug("selectFastPeers("+howMany+"), found enough fast (" + matches.size() + ")");
|
||||||
@ -482,8 +484,12 @@ public class ProfileOrganizer {
|
|||||||
* 6: return only from group 2
|
* 6: return only from group 2
|
||||||
* 7: return only from group 3
|
* 7: return only from group 3
|
||||||
*</pre>
|
*</pre>
|
||||||
|
* @param mask 0-4
|
||||||
|
* @param ipSet in/out param, use for multiple calls, may be null only if mask is 0
|
||||||
|
* @since 0.9.53 added mask and ipSet params
|
||||||
*/
|
*/
|
||||||
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, SessionKey randomKey, Slice subTierMode) {
|
public void selectFastPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, SessionKey randomKey,
|
||||||
|
Slice subTierMode, int mask, MaskedIPSet ipSet) {
|
||||||
getReadLock();
|
getReadLock();
|
||||||
try {
|
try {
|
||||||
if (subTierMode != Slice.SLICE_ALL) {
|
if (subTierMode != Slice.SLICE_ALL) {
|
||||||
@ -492,14 +498,14 @@ public class ProfileOrganizer {
|
|||||||
subTierMode = Slice.SLICE_ALL;
|
subTierMode = Slice.SLICE_ALL;
|
||||||
}
|
}
|
||||||
if (subTierMode != Slice.SLICE_ALL)
|
if (subTierMode != Slice.SLICE_ALL)
|
||||||
locked_selectPeers(_fastPeers, howMany, exclude, matches, randomKey, subTierMode);
|
locked_selectPeers(_fastPeers, howMany, exclude, matches, randomKey, subTierMode, mask, ipSet);
|
||||||
else
|
else
|
||||||
locked_selectPeers(_fastPeers, howMany, exclude, matches, 2);
|
locked_selectPeers(_fastPeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("selectFastPeers("+howMany+"), not enough fast (" + matches.size() + ") going on to highCap");
|
_log.info("selectFastPeers("+howMany+"), not enough fast (" + matches.size() + ") going on to highCap");
|
||||||
selectHighCapacityPeers(howMany, exclude, matches, 2);
|
selectHighCapacityPeers(howMany, exclude, matches, mask, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("selectFastPeers("+howMany+"), found enough fast (" + matches.size() + ")");
|
_log.debug("selectFastPeers("+howMany+"), found enough fast (" + matches.size() + ")");
|
||||||
@ -512,14 +518,16 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void selectHighCapacityPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
public void selectHighCapacityPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
||||||
selectHighCapacityPeers(howMany, exclude, matches, 0);
|
selectHighCapacityPeers(howMany, exclude, matches, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @param ipSet in/out param, use for multiple calls, may be null only if mask is 0
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*/
|
*/
|
||||||
public void selectHighCapacityPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
|
public void selectHighCapacityPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
getReadLock();
|
getReadLock();
|
||||||
try {
|
try {
|
||||||
// we only use selectHighCapacityPeers when we are selecting for PURPOSE_TEST
|
// we only use selectHighCapacityPeers when we are selecting for PURPOSE_TEST
|
||||||
@ -531,12 +539,12 @@ public class ProfileOrganizer {
|
|||||||
else
|
else
|
||||||
exclude.addAll(_fastPeers.keySet());
|
exclude.addAll(_fastPeers.keySet());
|
||||||
*/
|
*/
|
||||||
locked_selectPeers(_highCapacityPeers, howMany, exclude, matches, mask);
|
locked_selectPeers(_highCapacityPeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("selectHighCap("+howMany+"), not enough highcap (" + matches.size() + ") going on to ANFP2");
|
_log.info("selectHighCap("+howMany+"), not enough highcap (" + matches.size() + ") going on to ANFP2");
|
||||||
selectActiveNotFailingPeers2(howMany, exclude, matches, mask);
|
selectActiveNotFailingPeers2(howMany, exclude, matches, mask, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("selectHighCap("+howMany+"), found enough highCap (" + matches.size() + ")");
|
_log.debug("selectHighCap("+howMany+"), found enough highCap (" + matches.size() + ")");
|
||||||
@ -551,7 +559,7 @@ public class ProfileOrganizer {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void selectWellIntegratedPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
public void selectWellIntegratedPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
||||||
selectWellIntegratedPeers(howMany, exclude, matches, 0);
|
selectWellIntegratedPeers(howMany, exclude, matches, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -559,18 +567,19 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
* @deprecated unused
|
* @deprecated unused
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void selectWellIntegratedPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
|
public void selectWellIntegratedPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
getReadLock();
|
getReadLock();
|
||||||
try {
|
try {
|
||||||
locked_selectPeers(_wellIntegratedPeers, howMany, exclude, matches, mask);
|
locked_selectPeers(_wellIntegratedPeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("selectWellIntegrated("+howMany+"), not enough integrated (" + matches.size() + ") going on to notFailing");
|
_log.info("selectWellIntegrated("+howMany+"), not enough integrated (" + matches.size() + ") going on to notFailing");
|
||||||
selectNotFailingPeers(howMany, exclude, matches, mask);
|
selectNotFailingPeers(howMany, exclude, matches, mask, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("selectWellIntegrated("+howMany+"), found enough well integrated (" + matches.size() + ")");
|
_log.debug("selectWellIntegrated("+howMany+"), found enough well integrated (" + matches.size() + ")");
|
||||||
@ -585,18 +594,20 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
||||||
selectNotFailingPeers(howMany, exclude, matches, false, 0);
|
selectNotFailingPeers(howMany, exclude, matches, false, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mask ignored, should call locked_selectPeers, to be fixed
|
* @param mask ignored, should call locked_selectPeers, to be fixed
|
||||||
|
* @param ipSet ignored, should call locked_selectPeers, to be fixed
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*/
|
*/
|
||||||
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
|
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
selectNotFailingPeers(howMany, exclude, matches, false, mask);
|
selectNotFailingPeers(howMany, exclude, matches, false, mask, ipSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing) {
|
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing) {
|
||||||
selectNotFailingPeers(howMany, exclude, matches, onlyNotFailing, 0);
|
selectNotFailingPeers(howMany, exclude, matches, onlyNotFailing, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -608,8 +619,11 @@ public class ProfileOrganizer {
|
|||||||
* @param matches set to store the matches in
|
* @param matches set to store the matches in
|
||||||
* @param onlyNotFailing if true, don't include any high capacity peers
|
* @param onlyNotFailing if true, don't include any high capacity peers
|
||||||
* @param mask ignored, should call locked_selectPeers, to be fixed
|
* @param mask ignored, should call locked_selectPeers, to be fixed
|
||||||
|
* @param ipSet ignored, should call locked_selectPeers, to be fixed
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*/
|
*/
|
||||||
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing, int mask) {
|
public void selectNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing,
|
||||||
|
int mask, MaskedIPSet ipSet) {
|
||||||
if (matches.size() < howMany)
|
if (matches.size() < howMany)
|
||||||
selectAllNotFailingPeers(howMany, exclude, matches, onlyNotFailing, mask);
|
selectAllNotFailingPeers(howMany, exclude, matches, onlyNotFailing, mask);
|
||||||
return;
|
return;
|
||||||
@ -627,9 +641,30 @@ public class ProfileOrganizer {
|
|||||||
* be used when there is a good number of connected peers.
|
* be used when there is a good number of connected peers.
|
||||||
*
|
*
|
||||||
* @param exclude non-null, WARNING - side effect, all not-connected peers are added
|
* @param exclude non-null, WARNING - side effect, all not-connected peers are added
|
||||||
* No mask parameter, to be fixed
|
|
||||||
*/
|
*/
|
||||||
public void selectActiveNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
public void selectActiveNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches) {
|
||||||
|
selectActiveNotFailingPeers(howMany, exclude, matches, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a set of Hashes for peers that are both not failing and we're actively
|
||||||
|
* talking with.
|
||||||
|
*
|
||||||
|
* We use commSystem().isEstablished(), not profile.getIsActive(), as the
|
||||||
|
* NTCP idle time is now shorter than the 5 minute getIsActive() threshold,
|
||||||
|
* and we're using this to try and limit connections.
|
||||||
|
*
|
||||||
|
* Caution, this does NOT cascade further to non-connected peers, so it should only
|
||||||
|
* be used when there is a good number of connected peers.
|
||||||
|
*
|
||||||
|
* @param exclude non-null, WARNING - side effect, all not-connected peers are added
|
||||||
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @param ipSet ignored, should call locked_selectPeers, to be fixed
|
||||||
|
* @param ipSet may be null only if mask is 0
|
||||||
|
* @since 0.9.53
|
||||||
|
*/
|
||||||
|
public void selectActiveNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
Set<Hash> connected = _context.commSystem().getEstablished();
|
Set<Hash> connected = _context.commSystem().getEstablished();
|
||||||
getReadLock();
|
getReadLock();
|
||||||
@ -638,7 +673,7 @@ public class ProfileOrganizer {
|
|||||||
if (!connected.contains(peer))
|
if (!connected.contains(peer))
|
||||||
exclude.add(peer);
|
exclude.add(peer);
|
||||||
}
|
}
|
||||||
locked_selectPeers(_notFailingPeers, howMany, exclude, matches, 0);
|
locked_selectPeers(_notFailingPeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,8 +690,10 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @param ipSet in/out param, use for multiple calls, may be null only if mask is 0
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*/
|
*/
|
||||||
private void selectActiveNotFailingPeers2(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask) {
|
private void selectActiveNotFailingPeers2(int howMany, Set<Hash> exclude, Set<Hash> matches, int mask, MaskedIPSet ipSet) {
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
Set<Hash> connected = _context.commSystem().getEstablished();
|
Set<Hash> connected = _context.commSystem().getEstablished();
|
||||||
Map<Hash, PeerProfile> activePeers = new HashMap<Hash, PeerProfile>(connected.size());
|
Map<Hash, PeerProfile> activePeers = new HashMap<Hash, PeerProfile>(connected.size());
|
||||||
@ -667,13 +704,13 @@ public class ProfileOrganizer {
|
|||||||
if (prof != null)
|
if (prof != null)
|
||||||
activePeers.put(peer, prof);
|
activePeers.put(peer, prof);
|
||||||
}
|
}
|
||||||
locked_selectPeers(activePeers, howMany, exclude, matches, mask);
|
locked_selectPeers(activePeers, howMany, exclude, matches, mask, ipSet);
|
||||||
} finally { releaseReadLock(); }
|
} finally { releaseReadLock(); }
|
||||||
}
|
}
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("selectANFP2("+howMany+"), not enough ANFP (" + matches.size() + ") going on to notFailing");
|
_log.info("selectANFP2("+howMany+"), not enough ANFP (" + matches.size() + ") going on to notFailing");
|
||||||
selectNotFailingPeers(howMany, exclude, matches, mask);
|
selectNotFailingPeers(howMany, exclude, matches, mask, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
_log.debug("selectANFP2("+howMany+"), found enough ANFP (" + matches.size() + ")");
|
_log.debug("selectANFP2("+howMany+"), found enough ANFP (" + matches.size() + ")");
|
||||||
@ -690,7 +727,6 @@ public class ProfileOrganizer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mask ignored, should call locked_selectPeers, to be fixed
|
* @param mask ignored, should call locked_selectPeers, to be fixed
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void selectAllNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing, int mask) {
|
private void selectAllNotFailingPeers(int howMany, Set<Hash> exclude, Set<Hash> matches, boolean onlyNotFailing, int mask) {
|
||||||
if (matches.size() < howMany) {
|
if (matches.size() < howMany) {
|
||||||
@ -1287,19 +1323,21 @@ public class ProfileOrganizer {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches) {
|
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches) {
|
||||||
locked_selectPeers(peers, howMany, toExclude, matches, 0);
|
locked_selectPeers(peers, howMany, toExclude, matches, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* As of 0.9.24, checks for a netdb family match as well, unless mask == 0.
|
* As of 0.9.24, checks for a netdb family match as well, unless mask == 0.
|
||||||
*
|
*
|
||||||
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
* @param mask 0-4 Number of bytes to match to determine if peers in the same IP range should
|
||||||
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
* not be in the same tunnel. 0 = disable check; 1 = /8; 2 = /16; 3 = /24; 4 = exact IP match
|
||||||
|
* @param ipSet may be null only if mask is 0
|
||||||
|
* @since 0.9.53 added ipSet param
|
||||||
*/
|
*/
|
||||||
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches, int mask) {
|
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude, Set<Hash> matches,
|
||||||
|
int mask, MaskedIPSet ipSet) {
|
||||||
List<Hash> all = new ArrayList<Hash>(peers.keySet());
|
List<Hash> all = new ArrayList<Hash>(peers.keySet());
|
||||||
MaskedIPSet IPSet = new MaskedIPSet(16);
|
|
||||||
// use RandomIterator to avoid shuffling the whole thing
|
// use RandomIterator to avoid shuffling the whole thing
|
||||||
for (Iterator<Hash> iter = new RandomIterator<Hash>(all); (matches.size() < howMany) && iter.hasNext(); ) {
|
for (Iterator<Hash> iter = new RandomIterator<Hash>(all); (matches.size() < howMany) && iter.hasNext(); ) {
|
||||||
Hash peer = iter.next();
|
Hash peer = iter.next();
|
||||||
@ -1311,7 +1349,7 @@ public class ProfileOrganizer {
|
|||||||
continue;
|
continue;
|
||||||
boolean ok = isSelectable(peer);
|
boolean ok = isSelectable(peer);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
ok = mask <= 0 || notRestricted(peer, IPSet, mask);
|
ok = mask <= 0 || notRestricted(peer, ipSet, mask);
|
||||||
if ((!ok) && _log.shouldLog(Log.WARN))
|
if ((!ok) && _log.shouldLog(Log.WARN))
|
||||||
_log.warn("IP restriction prevents " + peer + " from joining " + matches);
|
_log.warn("IP restriction prevents " + peer + " from joining " + matches);
|
||||||
}
|
}
|
||||||
@ -1350,9 +1388,13 @@ public class ProfileOrganizer {
|
|||||||
* 6: return only from group 2
|
* 6: return only from group 2
|
||||||
* 7: return only from group 3
|
* 7: return only from group 3
|
||||||
*</pre>
|
*</pre>
|
||||||
|
* @param mask is 1-4 (number of bytes to match)
|
||||||
|
* @param IPMatches all IPs so far, modified by this routine
|
||||||
|
* @since 0.9.53 added mask/ipSet params
|
||||||
*/
|
*/
|
||||||
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude,
|
private void locked_selectPeers(Map<Hash, PeerProfile> peers, int howMany, Set<Hash> toExclude,
|
||||||
Set<Hash> matches, SessionKey randomKey, Slice subTierMode) {
|
Set<Hash> matches, SessionKey randomKey, Slice subTierMode,
|
||||||
|
int mask, MaskedIPSet ipSet) {
|
||||||
List<Hash> all = new ArrayList<Hash>(peers.keySet());
|
List<Hash> all = new ArrayList<Hash>(peers.keySet());
|
||||||
byte[] rk = randomKey.getData();
|
byte[] rk = randomKey.getData();
|
||||||
// we use the first half of the random key here,
|
// we use the first half of the random key here,
|
||||||
@ -1373,6 +1415,11 @@ public class ProfileOrganizer {
|
|||||||
if ((subTier & subTierMode.mask) != subTierMode.val)
|
if ((subTier & subTierMode.mask) != subTierMode.val)
|
||||||
continue;
|
continue;
|
||||||
boolean ok = isSelectable(peer);
|
boolean ok = isSelectable(peer);
|
||||||
|
if (ok) {
|
||||||
|
ok = mask <= 0 || notRestricted(peer, ipSet, mask);
|
||||||
|
if ((!ok) && _log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("IP restriction prevents " + peer + " from joining " + matches);
|
||||||
|
}
|
||||||
if (ok)
|
if (ok)
|
||||||
matches.add(peer);
|
matches.add(peer);
|
||||||
else
|
else
|
||||||
|
@ -13,6 +13,7 @@ import net.i2p.router.TunnelInfo;
|
|||||||
import net.i2p.router.TunnelManagerFacade;
|
import net.i2p.router.TunnelManagerFacade;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import static net.i2p.router.peermanager.ProfileOrganizer.Slice.*;
|
import static net.i2p.router.peermanager.ProfileOrganizer.Slice.*;
|
||||||
|
import net.i2p.router.util.MaskedIPSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick peers randomly out of the fast pool, and put them into tunnels
|
* Pick peers randomly out of the fast pool, and put them into tunnels
|
||||||
@ -29,7 +30,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
* Returns ENDPOINT FIRST, GATEWAY LAST!!!!
|
* Returns ENDPOINT FIRST, GATEWAY LAST!!!!
|
||||||
* In: us .. closest .. middle .. IBGW
|
* In: us .. closest .. middle .. IBGW
|
||||||
* Out: OBGW .. middle .. closest .. us
|
* Out: OBGW .. middle .. closest .. us
|
||||||
*
|
*
|
||||||
* @return ordered list of Hash objects (one per peer) specifying what order
|
* @return ordered list of Hash objects (one per peer) specifying what order
|
||||||
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
||||||
* the local router in the list. If there are no tunnels or peers
|
* the local router in the list. If there are no tunnels or peers
|
||||||
@ -45,7 +46,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
|
|
||||||
List<Hash> rv;
|
List<Hash> rv;
|
||||||
boolean isInbound = settings.isInbound();
|
boolean isInbound = settings.isInbound();
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
// special cases
|
// special cases
|
||||||
boolean v6Only = isIPv6Only();
|
boolean v6Only = isIPv6Only();
|
||||||
@ -57,10 +58,12 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
!ctx.commSystem().haveInboundCapacity(95);
|
!ctx.commSystem().haveInboundCapacity(95);
|
||||||
boolean hiddenInbound = hidden && isInbound;
|
boolean hiddenInbound = hidden && isInbound;
|
||||||
boolean hiddenOutbound = hidden && !isInbound;
|
boolean hiddenOutbound = hidden && !isInbound;
|
||||||
|
int ipRestriction = (ctx.getBooleanProperty("i2np.allowLocal") || length <= 1) ? 0 : settings.getIPRestriction();
|
||||||
|
MaskedIPSet ipSet = ipRestriction > 0 ? new MaskedIPSet(16) : null;
|
||||||
|
|
||||||
if (shouldSelectExplicit(settings))
|
if (shouldSelectExplicit(settings))
|
||||||
return selectExplicit(settings, length);
|
return selectExplicit(settings, length);
|
||||||
|
|
||||||
Set<Hash> exclude = getExclude(isInbound, false);
|
Set<Hash> exclude = getExclude(isInbound, false);
|
||||||
Set<Hash> matches = new HashSet<Hash>(length);
|
Set<Hash> matches = new HashSet<Hash>(length);
|
||||||
if (length == 1) {
|
if (length == 1) {
|
||||||
@ -70,6 +73,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
if (moreExclude != null)
|
if (moreExclude != null)
|
||||||
exclude.addAll(moreExclude);
|
exclude.addAll(moreExclude);
|
||||||
}
|
}
|
||||||
|
// 1-hop, IP restrictions not required here
|
||||||
if (hiddenInbound) {
|
if (hiddenInbound) {
|
||||||
// SANFP adds all not-connected to exclude, so make a copy
|
// SANFP adds all not-connected to exclude, so make a copy
|
||||||
Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
|
Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
|
||||||
@ -77,7 +81,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
if (matches.isEmpty()) {
|
if (matches.isEmpty()) {
|
||||||
// ANFP does not fall back to non-connected
|
// ANFP does not fall back to non-connected
|
||||||
ctx.profileOrganizer().selectFastPeers(length, exclude, matches, 0);
|
ctx.profileOrganizer().selectFastPeers(length, exclude, matches);
|
||||||
}
|
}
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
rv = new ArrayList<Hash>(matches);
|
rv = new ArrayList<Hash>(matches);
|
||||||
@ -108,17 +112,17 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
lastHopExclude = exclude;
|
lastHopExclude = exclude;
|
||||||
}
|
}
|
||||||
if (hiddenInbound) {
|
if (hiddenInbound) {
|
||||||
// IB closest hop
|
// IB closest hop
|
||||||
if (log.shouldInfo())
|
if (log.shouldInfo())
|
||||||
log.info("CPS SANFP closest IB exclude " + lastHopExclude.size());
|
log.info("CPS SANFP closest IB exclude " + lastHopExclude.size());
|
||||||
// SANFP adds all not-connected to exclude, so make a copy
|
// SANFP adds all not-connected to exclude, so make a copy
|
||||||
Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
|
Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
|
||||||
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches);
|
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches, ipRestriction, ipSet);
|
||||||
if (matches.isEmpty()) {
|
if (matches.isEmpty()) {
|
||||||
if (log.shouldInfo())
|
if (log.shouldInfo())
|
||||||
log.info("CPS SFP closest IB exclude " + lastHopExclude.size());
|
log.info("CPS SFP closest IB exclude " + lastHopExclude.size());
|
||||||
// ANFP does not fall back to non-connected
|
// ANFP does not fall back to non-connected
|
||||||
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
|
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
} else if (hiddenOutbound) {
|
} else if (hiddenOutbound) {
|
||||||
// OBEP
|
// OBEP
|
||||||
@ -177,19 +181,19 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
log.info("CPS SANFP OBEP exclude " + lastHopExclude.size());
|
log.info("CPS SANFP OBEP exclude " + lastHopExclude.size());
|
||||||
// SANFP adds all not-connected to exclude, so make a copy
|
// SANFP adds all not-connected to exclude, so make a copy
|
||||||
Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
|
Set<Hash> SANFPExclude = new HashSet<Hash>(lastHopExclude);
|
||||||
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches);
|
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, matches, ipRestriction, ipSet);
|
||||||
if (matches.isEmpty()) {
|
if (matches.isEmpty()) {
|
||||||
// ANFP does not fall back to non-connected
|
// ANFP does not fall back to non-connected
|
||||||
if (log.shouldInfo())
|
if (log.shouldInfo())
|
||||||
log.info("CPS SFP OBEP exclude " + lastHopExclude.size());
|
log.info("CPS SFP OBEP exclude " + lastHopExclude.size());
|
||||||
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
|
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
|
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO exclude IPv6-only at OBEP? Caught in checkTunnel() below
|
// TODO exclude IPv6-only at OBEP? Caught in checkTunnel() below
|
||||||
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0);
|
ctx.profileOrganizer().selectFastPeers(1, lastHopExclude, matches, randomKey, length == 2 ? SLICE_0_1 : SLICE_0, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
@ -199,7 +203,7 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
if (length > 2) {
|
if (length > 2) {
|
||||||
// middle hop(s)
|
// middle hop(s)
|
||||||
// group 2 or 3
|
// group 2 or 3
|
||||||
ctx.profileOrganizer().selectFastPeers(length - 2, exclude, matches, randomKey, SLICE_2_3);
|
ctx.profileOrganizer().selectFastPeers(length - 2, exclude, matches, randomKey, SLICE_2_3, ipRestriction, ipSet);
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
if (matches.size() > 1) {
|
if (matches.size() > 1) {
|
||||||
// order the middle peers for tunnels >= 4 hops
|
// order the middle peers for tunnels >= 4 hops
|
||||||
@ -225,14 +229,14 @@ class ClientPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO exclude IPv6-only at IBGW? Caught in checkTunnel() below
|
// TODO exclude IPv6-only at IBGW? Caught in checkTunnel() below
|
||||||
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, randomKey, length == 2 ? SLICE_2_3 : SLICE_1);
|
ctx.profileOrganizer().selectFastPeers(1, exclude, matches, randomKey, length == 2 ? SLICE_2_3 : SLICE_1, ipRestriction, ipSet);
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
rv.addAll(matches);
|
rv.addAll(matches);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rv = new ArrayList<Hash>(1);
|
rv = new ArrayList<Hash>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (length != rv.size() && log.shouldWarn())
|
//if (length != rv.size() && log.shouldWarn())
|
||||||
// log.warn("CPS requested " + length + " got " + rv.size() + ": " + DataHelper.toString(rv));
|
// log.warn("CPS requested " + length + " got " + rv.size() + ": " + DataHelper.toString(rv));
|
||||||
//else if (log.shouldDebug())
|
//else if (log.shouldDebug())
|
||||||
|
@ -11,6 +11,7 @@ import net.i2p.router.RouterContext;
|
|||||||
import net.i2p.router.TunnelInfo;
|
import net.i2p.router.TunnelInfo;
|
||||||
import net.i2p.router.TunnelManagerFacade;
|
import net.i2p.router.TunnelManagerFacade;
|
||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
|
import net.i2p.router.util.MaskedIPSet;
|
||||||
import net.i2p.stat.Rate;
|
import net.i2p.stat.Rate;
|
||||||
import net.i2p.stat.RateStat;
|
import net.i2p.stat.RateStat;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
@ -31,7 +32,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
* Returns ENDPOINT FIRST, GATEWAY LAST!!!!
|
* Returns ENDPOINT FIRST, GATEWAY LAST!!!!
|
||||||
* In: us .. closest .. middle .. IBGW
|
* In: us .. closest .. middle .. IBGW
|
||||||
* Out: OBGW .. middle .. closest .. us
|
* Out: OBGW .. middle .. closest .. us
|
||||||
*
|
*
|
||||||
* @return ordered list of Hash objects (one per peer) specifying what order
|
* @return ordered list of Hash objects (one per peer) specifying what order
|
||||||
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
||||||
* the local router in the list. If there are no tunnels or peers
|
* the local router in the list. If there are no tunnels or peers
|
||||||
@ -40,19 +41,19 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
*/
|
*/
|
||||||
public List<Hash> selectPeers(TunnelPoolSettings settings) {
|
public List<Hash> selectPeers(TunnelPoolSettings settings) {
|
||||||
int length = getLength(settings);
|
int length = getLength(settings);
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
if (log.shouldLog(Log.DEBUG))
|
if (log.shouldLog(Log.DEBUG))
|
||||||
log.debug("Length requested is zero: " + settings);
|
log.debug("Length requested is zero: " + settings);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (false && shouldSelectExplicit(settings)) {
|
//if (false && shouldSelectExplicit(settings)) {
|
||||||
// List<Hash> rv = selectExplicit(settings, length);
|
// List<Hash> rv = selectExplicit(settings, length);
|
||||||
// if (l.shouldLog(Log.DEBUG))
|
// if (l.shouldLog(Log.DEBUG))
|
||||||
// l.debug("Explicit peers selected: " + rv);
|
// l.debug("Explicit peers selected: " + rv);
|
||||||
// return rv;
|
// return rv;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
boolean isInbound = settings.isInbound();
|
boolean isInbound = settings.isInbound();
|
||||||
Set<Hash> exclude = getExclude(isInbound, true);
|
Set<Hash> exclude = getExclude(isInbound, true);
|
||||||
exclude.add(ctx.routerHash());
|
exclude.add(ctx.routerHash());
|
||||||
@ -70,6 +71,8 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
boolean hiddenInbound = hidden && isInbound;
|
boolean hiddenInbound = hidden && isInbound;
|
||||||
boolean hiddenOutbound = hidden && !isInbound;
|
boolean hiddenOutbound = hidden && !isInbound;
|
||||||
boolean lowOutbound = nonzero && !isInbound && !ctx.commSystem().haveHighOutboundCapacity();
|
boolean lowOutbound = nonzero && !isInbound && !ctx.commSystem().haveHighOutboundCapacity();
|
||||||
|
int ipRestriction = (ctx.getBooleanProperty("i2np.allowLocal") || length <= 1) ? 0 : settings.getIPRestriction();
|
||||||
|
MaskedIPSet ipSet = ipRestriction > 0 ? new MaskedIPSet(16) : null;
|
||||||
|
|
||||||
|
|
||||||
// closest-hop restrictions
|
// closest-hop restrictions
|
||||||
@ -99,21 +102,21 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
log.info("EPS SANFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
log.info("EPS SANFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
||||||
// SANFP adds all not-connected to exclude, so make a copy
|
// SANFP adds all not-connected to exclude, so make a copy
|
||||||
Set<Hash> SANFPExclude = new HashSet<Hash>(closestExclude);
|
Set<Hash> SANFPExclude = new HashSet<Hash>(closestExclude);
|
||||||
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, closest);
|
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, closest, ipRestriction, ipSet);
|
||||||
if (closest.isEmpty()) {
|
if (closest.isEmpty()) {
|
||||||
// ANFP does not fall back to non-connected
|
// ANFP does not fall back to non-connected
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
log.info("EPS SFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
||||||
ctx.profileOrganizer().selectFastPeers(1, closestExclude, closest);
|
ctx.profileOrganizer().selectFastPeers(1, closestExclude, closest, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
} else if (exploreHighCap) {
|
} else if (exploreHighCap) {
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SHCP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
log.info("EPS SHCP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
||||||
ctx.profileOrganizer().selectHighCapacityPeers(1, closestExclude, closest);
|
ctx.profileOrganizer().selectHighCapacityPeers(1, closestExclude, closest, ipRestriction, ipSet);
|
||||||
} else {
|
} else {
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SNFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
log.info("EPS SNFP closest " + (isInbound ? "IB" : "OB") + " exclude " + closestExclude.size());
|
||||||
ctx.profileOrganizer().selectNotFailingPeers(1, closestExclude, closest, false);
|
ctx.profileOrganizer().selectNotFailingPeers(1, closestExclude, closest, false, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
if (!closest.isEmpty()) {
|
if (!closest.isEmpty()) {
|
||||||
closestHop = closest.iterator().next();
|
closestHop = closest.iterator().next();
|
||||||
@ -155,12 +158,12 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
log.info("EPS SANFP furthest OB exclude " + exclude.size());
|
log.info("EPS SANFP furthest OB exclude " + exclude.size());
|
||||||
// ANFP adds all not-connected to exclude, so make a copy
|
// ANFP adds all not-connected to exclude, so make a copy
|
||||||
Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
|
Set<Hash> SANFPExclude = new HashSet<Hash>(exclude);
|
||||||
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, furthest);
|
ctx.profileOrganizer().selectActiveNotFailingPeers(1, SANFPExclude, furthest, ipRestriction, ipSet);
|
||||||
if (furthest.isEmpty()) {
|
if (furthest.isEmpty()) {
|
||||||
// ANFP does not fall back to non-connected
|
// ANFP does not fall back to non-connected
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SFP furthest OB exclude " + exclude.size());
|
log.info("EPS SFP furthest OB exclude " + exclude.size());
|
||||||
ctx.profileOrganizer().selectFastPeers(1, exclude, furthest);
|
ctx.profileOrganizer().selectFastPeers(1, exclude, furthest, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
if (!furthest.isEmpty()) {
|
if (!furthest.isEmpty()) {
|
||||||
furthestHop = furthest.iterator().next();
|
furthestHop = furthest.iterator().next();
|
||||||
@ -179,13 +182,10 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
HashSet<Hash> matches = new HashSet<Hash>(length);
|
HashSet<Hash> matches = new HashSet<Hash>(length);
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
//
|
|
||||||
// We don't honor IP Restriction here, to be fixed
|
|
||||||
//
|
|
||||||
if (exploreHighCap) {
|
if (exploreHighCap) {
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SHCP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
|
log.info("EPS SHCP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
|
||||||
ctx.profileOrganizer().selectHighCapacityPeers(length, exclude, matches);
|
ctx.profileOrganizer().selectHighCapacityPeers(length, exclude, matches, ipRestriction, ipSet);
|
||||||
} else {
|
} else {
|
||||||
// As of 0.9.23, we include a max of 2 not failing peers,
|
// As of 0.9.23, we include a max of 2 not failing peers,
|
||||||
// to improve build success on 3-hop tunnels.
|
// to improve build success on 3-hop tunnels.
|
||||||
@ -194,7 +194,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
ctx.profileOrganizer().selectHighCapacityPeers(length - 2, exclude, matches);
|
ctx.profileOrganizer().selectHighCapacityPeers(length - 2, exclude, matches);
|
||||||
if (log.shouldLog(Log.INFO))
|
if (log.shouldLog(Log.INFO))
|
||||||
log.info("EPS SNFP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
|
log.info("EPS SNFP " + length + (isInbound ? " IB" : " OB") + " exclude " + exclude.size());
|
||||||
ctx.profileOrganizer().selectNotFailingPeers(length, exclude, matches, false);
|
ctx.profileOrganizer().selectNotFailingPeers(length, exclude, matches, false, ipRestriction, ipSet);
|
||||||
}
|
}
|
||||||
matches.remove(ctx.routerHash());
|
matches.remove(ctx.routerHash());
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int MIN_NONFAILING_PCT = 15;
|
private static final int MIN_NONFAILING_PCT = 15;
|
||||||
private static final int MIN_ACTIVE_PEERS_STARTUP = 6;
|
private static final int MIN_ACTIVE_PEERS_STARTUP = 6;
|
||||||
private static final int MIN_ACTIVE_PEERS = 12;
|
private static final int MIN_ACTIVE_PEERS = 12;
|
||||||
@ -290,7 +290,7 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
}
|
}
|
||||||
return (failPct >= ctx.random().nextInt(100));
|
return (failPct >= ctx.random().nextInt(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We should really use the difference between the exploratory fail rate
|
* We should really use the difference between the exploratory fail rate
|
||||||
* and the high capacity fail rate - but we don't have a stat for high cap,
|
* and the high capacity fail rate - but we don't have a stat for high cap,
|
||||||
@ -326,11 +326,11 @@ class ExploratoryPeerSelector extends TunnelPeerSelector {
|
|||||||
double pct = (double)(reject + timeout) / (accept + reject + timeout);
|
double pct = (double)(reject + timeout) / (accept + reject + timeout);
|
||||||
return (int)(100 * pct);
|
return (int)(100 * pct);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Use current + last to get more recent and smoother data */
|
/** Use current + last to get more recent and smoother data */
|
||||||
private int getEvents(String stat, long period) {
|
private int getEvents(String stat, long period) {
|
||||||
RateStat rs = ctx.statManager().getRate(stat);
|
RateStat rs = ctx.statManager().getRate(stat);
|
||||||
if (rs == null)
|
if (rs == null)
|
||||||
return 0;
|
return 0;
|
||||||
Rate r = rs.getRate(period);
|
Rate r = rs.getRate(period);
|
||||||
if (r == null)
|
if (r == null)
|
||||||
|
@ -32,7 +32,7 @@ import net.i2p.util.SystemVersion;
|
|||||||
import net.i2p.util.VersionComparator;
|
import net.i2p.util.VersionComparator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Coordinate the selection of peers to go into a tunnel for one particular
|
* Coordinate the selection of peers to go into a tunnel for one particular
|
||||||
* pool.
|
* pool.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -45,8 +45,8 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which peers should go into the next tunnel for the given settings?
|
* Which peers should go into the next tunnel for the given settings?
|
||||||
*
|
*
|
||||||
* @return ordered list of Hash objects (one per peer) specifying what order
|
* @return ordered list of Hash objects (one per peer) specifying what order
|
||||||
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
* they should appear in a tunnel (ENDPOINT FIRST). This includes
|
||||||
* the local router in the list. If there are no tunnels or peers
|
* the local router in the list. If there are no tunnels or peers
|
||||||
@ -54,7 +54,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
* return null.
|
* return null.
|
||||||
*/
|
*/
|
||||||
public abstract List<Hash> selectPeers(TunnelPoolSettings settings);
|
public abstract List<Hash> selectPeers(TunnelPoolSettings settings);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return randomized number of hops 0-7, not including ourselves
|
* @return randomized number of hops 0-7, not including ourselves
|
||||||
*/
|
*/
|
||||||
@ -81,7 +81,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
else if (length > 7) // as documented in tunnel.html
|
else if (length > 7) // as documented in tunnel.html
|
||||||
length = 7;
|
length = 7;
|
||||||
/*
|
/*
|
||||||
if ( (ctx.tunnelManager().getOutboundTunnelCount() <= 0) ||
|
if ( (ctx.tunnelManager().getOutboundTunnelCount() <= 0) ||
|
||||||
(ctx.tunnelManager().getFreeTunnelCount() <= 0) ) {
|
(ctx.tunnelManager().getFreeTunnelCount() <= 0) ) {
|
||||||
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
Log log = ctx.logManager().getLog(TunnelPeerSelector.class);
|
||||||
// no tunnels to build tunnels with
|
// no tunnels to build tunnels with
|
||||||
@ -98,7 +98,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
*/
|
*/
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging, also possibly for restricted routes?
|
* For debugging, also possibly for restricted routes?
|
||||||
* Needs analysis and testing
|
* Needs analysis and testing
|
||||||
@ -118,7 +118,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging, also possibly for restricted routes?
|
* For debugging, also possibly for restricted routes?
|
||||||
* Needs analysis and testing
|
* Needs analysis and testing
|
||||||
@ -128,10 +128,10 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
String peers = null;
|
String peers = null;
|
||||||
Properties opts = settings.getUnknownOptions();
|
Properties opts = settings.getUnknownOptions();
|
||||||
peers = opts.getProperty("explicitPeers");
|
peers = opts.getProperty("explicitPeers");
|
||||||
|
|
||||||
if (peers == null)
|
if (peers == null)
|
||||||
peers = ctx.getProperty("explicitPeers");
|
peers = ctx.getProperty("explicitPeers");
|
||||||
|
|
||||||
List<Hash> rv = new ArrayList<Hash>();
|
List<Hash> rv = new ArrayList<Hash>();
|
||||||
StringTokenizer tok = new StringTokenizer(peers, ",");
|
StringTokenizer tok = new StringTokenizer(peers, ",");
|
||||||
while (tok.hasMoreTokens()) {
|
while (tok.hasMoreTokens()) {
|
||||||
@ -139,7 +139,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
Hash peer = new Hash();
|
Hash peer = new Hash();
|
||||||
try {
|
try {
|
||||||
peer.fromBase64(peerStr);
|
peer.fromBase64(peerStr);
|
||||||
|
|
||||||
if (ctx.profileOrganizer().isSelectable(peer)) {
|
if (ctx.profileOrganizer().isSelectable(peer)) {
|
||||||
rv.add(peer);
|
rv.add(peer);
|
||||||
} else {
|
} else {
|
||||||
@ -150,14 +150,14 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
log.error("Explicit peer is improperly formatted (" + peerStr + ")", dfe);
|
log.error("Explicit peer is improperly formatted (" + peerStr + ")", dfe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sz = rv.size();
|
int sz = rv.size();
|
||||||
if (sz == 0) {
|
if (sz == 0) {
|
||||||
log.logAlways(Log.WARN, "No valid explicit peers found, building zero hop");
|
log.logAlways(Log.WARN, "No valid explicit peers found, building zero hop");
|
||||||
} else if (sz > 1) {
|
} else if (sz > 1) {
|
||||||
Collections.shuffle(rv, ctx.random());
|
Collections.shuffle(rv, ctx.random());
|
||||||
}
|
}
|
||||||
|
|
||||||
while (rv.size() > length) {
|
while (rv.size() > length) {
|
||||||
rv.remove(0);
|
rv.remove(0);
|
||||||
}
|
}
|
||||||
@ -166,11 +166,12 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
Set<Hash> exclude = getExclude(settings.isInbound(), settings.isExploratory());
|
Set<Hash> exclude = getExclude(settings.isInbound(), settings.isExploratory());
|
||||||
exclude.addAll(rv);
|
exclude.addAll(rv);
|
||||||
Set<Hash> matches = new HashSet<Hash>(more);
|
Set<Hash> matches = new HashSet<Hash>(more);
|
||||||
ctx.profileOrganizer().selectFastPeers(more, exclude, matches, 0);
|
// don't bother with IP restrictions here
|
||||||
|
ctx.profileOrganizer().selectFastPeers(more, exclude, matches);
|
||||||
rv.addAll(matches);
|
rv.addAll(matches);
|
||||||
Collections.shuffle(rv, ctx.random());
|
Collections.shuffle(rv, ctx.random());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.shouldLog(Log.INFO)) {
|
if (log.shouldLog(Log.INFO)) {
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
if (settings.getDestinationNickname() != null)
|
if (settings.getDestinationNickname() != null)
|
||||||
@ -187,16 +188,16 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
buf.append(", out of ").append(sz).append(" (not including self)");
|
buf.append(", out of ").append(sz).append(" (not including self)");
|
||||||
log.info(buf.toString());
|
log.info(buf.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.isInbound())
|
if (settings.isInbound())
|
||||||
rv.add(0, ctx.routerHash());
|
rv.add(0, ctx.routerHash());
|
||||||
else
|
else
|
||||||
rv.add(ctx.routerHash());
|
rv.add(ctx.routerHash());
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick peers that we want to avoid
|
* Pick peers that we want to avoid
|
||||||
*/
|
*/
|
||||||
public Set<Hash> getExclude(boolean isInbound, boolean isExploratory) {
|
public Set<Hash> getExclude(boolean isInbound, boolean isExploratory) {
|
||||||
@ -267,7 +268,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
peers.add(peer.getIdentity().calculateHash());
|
peers.add(peer.getIdentity().calculateHash());
|
||||||
// otherwise, it contains flags we aren't trying to focus on,
|
// otherwise, it contains flags we aren't trying to focus on,
|
||||||
// so don't exclude it based on published capacity
|
// so don't exclude it based on published capacity
|
||||||
|
|
||||||
if (filterUptime(ctx, isInbound, isExploratory)) {
|
if (filterUptime(ctx, isInbound, isExploratory)) {
|
||||||
Properties opts = peer.getOptions();
|
Properties opts = peer.getOptions();
|
||||||
if (opts != null) {
|
if (opts != null) {
|
||||||
@ -298,7 +299,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
peers.add(peer.getIdentity().calculateHash());
|
peers.add(peer.getIdentity().calculateHash());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
long infoAge = ctx.clock().now() - peer.getPublished();
|
long infoAge = ctx.clock().now() - peer.getPublished();
|
||||||
if (infoAge < 0) {
|
if (infoAge < 0) {
|
||||||
infoAge = 0;
|
infoAge = 0;
|
||||||
@ -387,8 +388,8 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
return false;
|
return false;
|
||||||
return canConnect(ANY_V4, ri);
|
return canConnect(ANY_V4, ri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pick peers that we want to avoid for the first OB hop or last IB hop.
|
* Pick peers that we want to avoid for the first OB hop or last IB hop.
|
||||||
* There's several cases of importance:
|
* There's several cases of importance:
|
||||||
* <ol><li>Inbound and we are hidden -
|
* <ol><li>Inbound and we are hidden -
|
||||||
@ -452,19 +453,19 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** warning, this is also called by ProfileOrganizer.isSelectable() */
|
/** warning, this is also called by ProfileOrganizer.isSelectable() */
|
||||||
public static boolean shouldExclude(RouterContext ctx, RouterInfo peer) {
|
public static boolean shouldExclude(RouterContext ctx, RouterInfo peer) {
|
||||||
return shouldExclude(peer, getExcludeCaps(ctx));
|
return shouldExclude(peer, getExcludeCaps(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return non-null, possibly empty
|
* @return non-null, possibly empty
|
||||||
*/
|
*/
|
||||||
private static String getExcludeCaps(RouterContext ctx) {
|
private static String getExcludeCaps(RouterContext ctx) {
|
||||||
return ctx.getProperty("router.excludePeerCaps", DEFAULT_EXCLUDE_CAPS);
|
return ctx.getProperty("router.excludePeerCaps", DEFAULT_EXCLUDE_CAPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** NTCP2 */
|
/** NTCP2 */
|
||||||
private static final String MIN_VERSION = "0.9.36";
|
private static final String MIN_VERSION = "0.9.36";
|
||||||
|
|
||||||
@ -555,18 +556,18 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
******/
|
******/
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.outboundExploratoryExcludeUnreachable";
|
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.outboundExploratoryExcludeUnreachable";
|
||||||
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = "router.outboundClientExcludeUnreachable";
|
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = "router.outboundClientExcludeUnreachable";
|
||||||
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.inboundExploratoryExcludeUnreachable";
|
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = "router.inboundExploratoryExcludeUnreachable";
|
||||||
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "router.inboundClientExcludeUnreachable";
|
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = "router.inboundClientExcludeUnreachable";
|
||||||
|
|
||||||
private static final boolean DEFAULT_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
|
private static final boolean DEFAULT_OUTBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
|
||||||
private static final boolean DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
|
private static final boolean DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
|
||||||
// see comments at getExclude() above
|
// see comments at getExclude() above
|
||||||
private static final boolean DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
|
private static final boolean DEFAULT_INBOUND_EXPLORATORY_EXCLUDE_UNREACHABLE = false;
|
||||||
private static final boolean DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
|
private static final boolean DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do we want to skip unreachable peers?
|
* do we want to skip unreachable peers?
|
||||||
* @return true if yes
|
* @return true if yes
|
||||||
@ -587,18 +588,18 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
if (ctx.router().isHidden())
|
if (ctx.router().isHidden())
|
||||||
return true;
|
return true;
|
||||||
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE);
|
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_INBOUND_CLIENT_EXCLUDE_UNREACHABLE);
|
||||||
} else {
|
} else {
|
||||||
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE);
|
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE, DEFAULT_OUTBOUND_CLIENT_EXCLUDE_UNREACHABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.outboundExploratoryExcludeSlow";
|
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.outboundExploratoryExcludeSlow";
|
||||||
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_SLOW = "router.outboundClientExcludeSlow";
|
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_SLOW = "router.outboundClientExcludeSlow";
|
||||||
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.inboundExploratoryExcludeSlow";
|
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_SLOW = "router.inboundExploratoryExcludeSlow";
|
||||||
private static final String PROP_INBOUND_CLIENT_EXCLUDE_SLOW = "router.inboundClientExcludeSlow";
|
private static final String PROP_INBOUND_CLIENT_EXCLUDE_SLOW = "router.inboundClientExcludeSlow";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do we want to skip peers that are slow?
|
* do we want to skip peers that are slow?
|
||||||
* @return true unless configured otherwise
|
* @return true unless configured otherwise
|
||||||
@ -612,18 +613,18 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
} else {
|
} else {
|
||||||
if (isInbound)
|
if (isInbound)
|
||||||
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_SLOW, true);
|
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_SLOW, true);
|
||||||
else
|
else
|
||||||
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_SLOW, true);
|
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_SLOW, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/****
|
/****
|
||||||
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.outboundExploratoryExcludeUptime";
|
private static final String PROP_OUTBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.outboundExploratoryExcludeUptime";
|
||||||
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_UPTIME = "router.outboundClientExcludeUptime";
|
private static final String PROP_OUTBOUND_CLIENT_EXCLUDE_UPTIME = "router.outboundClientExcludeUptime";
|
||||||
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.inboundExploratoryExcludeUptime";
|
private static final String PROP_INBOUND_EXPLORATORY_EXCLUDE_UPTIME = "router.inboundExploratoryExcludeUptime";
|
||||||
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UPTIME = "router.inboundClientExcludeUptime";
|
private static final String PROP_INBOUND_CLIENT_EXCLUDE_UPTIME = "router.inboundClientExcludeUptime";
|
||||||
****/
|
****/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do we want to skip peers who haven't been up for long?
|
* do we want to skip peers who haven't been up for long?
|
||||||
* @return true unless configured otherwise
|
* @return true unless configured otherwise
|
||||||
@ -638,7 +639,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
|||||||
} else {
|
} else {
|
||||||
if (isInbound)
|
if (isInbound)
|
||||||
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UPTIME, true);
|
return ctx.getProperty(PROP_INBOUND_CLIENT_EXCLUDE_UPTIME, true);
|
||||||
else
|
else
|
||||||
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UPTIME, true);
|
return ctx.getProperty(PROP_OUTBOUND_CLIENT_EXCLUDE_UPTIME, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user