forked from I2P_Developers/i2p.i2p
Compare commits
21 Commits
i2p-2.5.2-
...
i2p-2.5.2-
Author | SHA1 | Date | |
---|---|---|---|
bd1f4c9f6a | |||
ddfe816d80 | |||
d765f85515 | |||
f8394ac82a | |||
e4aab76045 | |||
a2dc80e089 | |||
b573fe461f | |||
d4f580ee39 | |||
88fbf0f82a | |||
14db2f3642 | |||
c15b29cd4d | |||
a0f92b2e28 | |||
5c8ddbe26a | |||
07cf02e969 | |||
a2dd0a756d | |||
aedcd02506 | |||
2f0ed24356 | |||
4659a922b8 | |||
774fd4c2ca | |||
02141473ad | |||
d7fbc79533 |
64
.github/workflows/mirror-release.yml
vendored
Normal file
64
.github/workflows/mirror-release.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
name: mirror
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'i2p-*.*.*'
|
||||
|
||||
jobs:
|
||||
dl:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
changelog.txt
|
||||
- name: download release artifacts
|
||||
run: |
|
||||
sudo apt-get install wget ca-certificates gpg sed curl
|
||||
while true; do wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pinstall_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')_windows.exe && break; done
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/I2P-Easy-Install-Bundle-$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')-signed.exe
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/I2P-Easy-Install-Bundle-$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').exe
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pinstall_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').jar
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pinstall_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').jar.sig
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pinstall_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')_windows.exe
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pinstall_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')_windows.exe.sig
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2psource_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').tar.bz2
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2psource_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').tar.bz2.sig
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pupdate-$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').su3
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pupdate-$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').su3.torrent
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pupdate.su3
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pupdate_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').zip
|
||||
wget -v https://files.i2p-projekt.de/$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')/i2pupdate_$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||').zip.sig'
|
||||
echo "$(git describe --abbrev=0 | sed 's|i2p-||g' |sed 's|-.*||')" > CHANGES.md
|
||||
echo "===========" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
curl https://raw.githubusercontent.com/i2p/i2p.newsxml/master/data/entries.html | sed -n '/<article/,/<\/article/p' | sed -n '1,/<\/article>/p' | sed -n '/<\/details>/,$p' | sed '1d' | sed 's/<\/\{0,1\}p>//g' | sed 's|<\/article>||g' >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
head -n 25 changelog.txt >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "## Checksums" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
sha256sum * >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
file * >> CHANGES.md
|
||||
echo '```' >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
echo "" >> CHANGES.md
|
||||
cat CHANGES.md
|
||||
- name: Upload artifacts
|
||||
uses: ncipollo/release-action@v1
|
||||
with:
|
||||
artifacts: "*"
|
||||
skipIfReleaseExists: true
|
||||
bodyFile: "CHANGES.md"
|
@ -856,7 +856,7 @@ public class MetaInfo
|
||||
String announce = null;
|
||||
List<String> url_list = null;
|
||||
String comment = null;
|
||||
Getopt g = new Getopt("Storage", args, "a:c:m:w:");
|
||||
Getopt g = new Getopt("MetaInfo", args, "a:c:m:w:");
|
||||
try {
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
|
@ -140,15 +140,40 @@ class PartialPiece implements Comparable<PartialPiece> {
|
||||
* @since 0.9.62
|
||||
*/
|
||||
public synchronized boolean isComplete() {
|
||||
return bitfield.complete();
|
||||
return bitfield.complete();
|
||||
}
|
||||
|
||||
/**
|
||||
* How many consecutive bytes are good - as set by read().
|
||||
* There may be more good bytes after "holes".
|
||||
* Have any chunks been downloaded?
|
||||
*
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public synchronized boolean hasData() {
|
||||
return bitfield.count() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has this chunk been downloaded?
|
||||
*
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public synchronized boolean hasChunk(int chunk) {
|
||||
return bitfield.get(chunk);
|
||||
}
|
||||
|
||||
/**
|
||||
* How many bytes are good - as set by read().
|
||||
* As of 0.9.63, accurately counts good bytes after "holes".
|
||||
*/
|
||||
public synchronized int getDownloaded() {
|
||||
return this.off;
|
||||
if (bitfield.complete())
|
||||
return pclen;
|
||||
int sz = bitfield.count();
|
||||
int rv = sz * PeerState.PARTSIZE;
|
||||
int rem = pclen % PeerState.PARTSIZE;
|
||||
if (rem != 0 && bitfield.get(sz - 1))
|
||||
rv -= PeerState.PARTSIZE - rem;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -348,8 +373,10 @@ class PartialPiece implements Comparable<PartialPiece> {
|
||||
public void release() {
|
||||
if (bs == null) {
|
||||
synchronized (this) {
|
||||
if (raf != null)
|
||||
if (raf != null) {
|
||||
locked_release();
|
||||
raf = null;
|
||||
}
|
||||
}
|
||||
//if (raf != null)
|
||||
// I2PAppContext.getGlobalContext().logManager().getLog(PartialPiece.class).warn("Released " + tempfile);
|
||||
@ -378,7 +405,7 @@ class PartialPiece implements Comparable<PartialPiece> {
|
||||
int d = this.piece.compareTo(opp.piece);
|
||||
if (d != 0)
|
||||
return d;
|
||||
return opp.off - this.off; // reverse
|
||||
return opp.getDownloaded() - getDownloaded(); // reverse
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -401,7 +428,7 @@ class PartialPiece implements Comparable<PartialPiece> {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Partial(" + piece.getId() + ',' + off + ',' + pclen + ')';
|
||||
return "Partial(" + piece.getId() + ',' + off + ',' + getDownloaded() + ',' + pclen + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,6 +96,8 @@ public class Peer implements Comparable<Peer>, BandwidthListener
|
||||
private final boolean _isIncoming;
|
||||
private int _totalCommentsSent;
|
||||
private int _maxPipeline = PeerState.MIN_PIPELINE;
|
||||
private long connected;
|
||||
private long pexLastSent;
|
||||
|
||||
/**
|
||||
* Outgoing connection.
|
||||
@ -307,6 +309,7 @@ public class Peer implements Comparable<Peer>, BandwidthListener
|
||||
// We are up and running!
|
||||
state = s;
|
||||
magnetState = mState;
|
||||
connected = util.getContext().clock().now();
|
||||
listener.connected(this);
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -888,4 +891,28 @@ public class Peer implements Comparable<Peer>, BandwidthListener
|
||||
public boolean isWebPeer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* when did handshake complete?
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public long getWhenConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* when did we last send pex peers?
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public long getPexLastSent() {
|
||||
return pexLastSent;
|
||||
}
|
||||
|
||||
/**
|
||||
* when did we last send pex peers?
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public void setPexLastSent(long now) {
|
||||
pexLastSent = now;
|
||||
}
|
||||
}
|
||||
|
@ -1370,14 +1370,14 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
synchronized(wantedPieces) {
|
||||
for (Request req : partials) {
|
||||
PartialPiece pp = req.getPartialPiece();
|
||||
if (req.off > 0) {
|
||||
if (pp.hasData()) {
|
||||
// PartialPiece.equals() only compares piece number, which is what we want
|
||||
int idx = partialPieces.indexOf(pp);
|
||||
if (idx < 0) {
|
||||
partialPieces.add(pp);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Saving orphaned partial piece (new) " + pp);
|
||||
} else if (idx >= 0 && pp.getDownloaded() > partialPieces.get(idx).getDownloaded()) {
|
||||
} else if (pp.getDownloaded() > partialPieces.get(idx).getDownloaded()) {
|
||||
// replace what's there now
|
||||
partialPieces.get(idx).release();
|
||||
partialPieces.set(idx, pp);
|
||||
@ -1434,7 +1434,9 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
for(Piece piece : wantedPieces) {
|
||||
if (piece.getId() == savedPiece) {
|
||||
if (peer.isCompleted() && piece.getPeerCount() > 1 &&
|
||||
wantedPieces.size() > 2*END_GAME_THRESHOLD) {
|
||||
wantedPieces.size() > 2*END_GAME_THRESHOLD &&
|
||||
partialPieces.size() < 4 &&
|
||||
_random.nextInt(4) != 0) {
|
||||
// Try to preserve rarest-first
|
||||
// by not requesting a partial piece that at least two non-seeders also have
|
||||
// from a seeder
|
||||
@ -1462,7 +1464,7 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
iter.remove();
|
||||
piece.setRequested(peer, true);
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
_log.info("Restoring orphaned partial piece " + pp +
|
||||
_log.info("Restoring orphaned partial piece " + pp + " to " + peer +
|
||||
" Partial list size now: " + partialPieces.size());
|
||||
}
|
||||
return pp;
|
||||
@ -1574,7 +1576,9 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
}
|
||||
}
|
||||
} else if (id == ExtensionHandler.ID_HANDSHAKE) {
|
||||
sendPeers(peer);
|
||||
// We may not have the bitfield yet, but if we do, don't send PEX to seeds
|
||||
if (!peer.isCompleted())
|
||||
sendPeers(peer);
|
||||
sendDHT(peer);
|
||||
if (_util.utCommentsEnabled())
|
||||
sendCommentReq(peer);
|
||||
@ -1583,8 +1587,8 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
|
||||
/**
|
||||
* Send a PEX message to the peer, if he supports PEX.
|
||||
* This just sends everybody we are connected to, we don't
|
||||
* track new vs. old peers yet.
|
||||
* This sends everybody we have connected to since the
|
||||
* last time we sent PEX to him.
|
||||
* @since 0.8.4
|
||||
*/
|
||||
void sendPeers(Peer peer) {
|
||||
@ -1598,14 +1602,25 @@ class PeerCoordinator implements PeerListener, BandwidthListener
|
||||
return;
|
||||
try {
|
||||
if (bev.getMap().get(ExtensionHandler.TYPE_PEX) != null) {
|
||||
List<Peer> pList = peerList();
|
||||
pList.remove(peer);
|
||||
for (Iterator<Peer> iter = pList.iterator(); iter.hasNext(); ) {
|
||||
if (iter.next().isWebPeer())
|
||||
iter.remove();
|
||||
List<Peer> pList = new ArrayList<Peer>();
|
||||
long t = peer.getPexLastSent();
|
||||
for (Peer p : peers) {
|
||||
if (p.equals(peer))
|
||||
continue;
|
||||
if (p.isWebPeer())
|
||||
continue;
|
||||
if (p.getWhenConnected() > t)
|
||||
pList.add(p);
|
||||
}
|
||||
if (!pList.isEmpty())
|
||||
if (!pList.isEmpty()) {
|
||||
ExtensionHandler.sendPEX(peer, pList);
|
||||
peer.setPexLastSent(_util.getContext().clock().now());
|
||||
//if (_log.shouldDebug())
|
||||
// _log.debug("Pex: sent " + pList.size() + " new peers to " + peer);
|
||||
//} else {
|
||||
//if (_log.shouldDebug())
|
||||
// _log.debug("Pex: no new peers to send to " + peer);
|
||||
}
|
||||
}
|
||||
} catch (InvalidBEncodingException ibee) {}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class PeerState implements DataLoader
|
||||
// Outstanding request
|
||||
private final List<Request> outstandingRequests = new ArrayList<Request>();
|
||||
/** the tail (NOT the head) of the request queue */
|
||||
private Request lastRequest = null;
|
||||
private Request lastRequest;
|
||||
private int currentMaxPipeline;
|
||||
|
||||
// FIXME if piece size < PARTSIZE, pipeline could be bigger
|
||||
@ -425,7 +425,8 @@ class PeerState implements DataLoader
|
||||
|
||||
// Last chunk needed for this piece?
|
||||
PartialPiece pp = req.getPartialPiece();
|
||||
if (pp.isComplete())
|
||||
boolean complete = pp.isComplete();
|
||||
if (complete)
|
||||
{
|
||||
// warning - may block here for a while
|
||||
if (listener.gotPiece(peer, pp))
|
||||
@ -449,6 +450,25 @@ class PeerState implements DataLoader
|
||||
synchronized(this) {
|
||||
pendingRequest = null;
|
||||
}
|
||||
|
||||
// getOutstandingRequest() was called by PeerConnectionIn at the start of the chunk;
|
||||
// if the bandwidth limiter throttled us to zero requests then, try again now
|
||||
if (outstandingRequests.isEmpty()) {
|
||||
addRequest();
|
||||
if (!complete) {
|
||||
synchronized(this) {
|
||||
if (outstandingRequests.isEmpty()) {
|
||||
// we MUST return the partial piece to PeerCoordinator,
|
||||
// or else we will lose it and leak the data
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Throttled, returned to coord. w/ data " + req);
|
||||
List<Request> pcs = Collections.singletonList(req);
|
||||
listener.savePartialPieces(this.peer, pcs);
|
||||
lastRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -577,15 +597,8 @@ class PeerState implements DataLoader
|
||||
List<Request> rv = new ArrayList<Request>(pcs.size());
|
||||
for (Integer p : pcs) {
|
||||
Request req = getLowestOutstandingRequest(p.intValue());
|
||||
if (req != null) {
|
||||
PartialPiece pp = req.getPartialPiece();
|
||||
synchronized(pp) {
|
||||
int dl = pp.getDownloaded();
|
||||
if (req.off != dl)
|
||||
req = new Request(pp, dl);
|
||||
}
|
||||
if (req != null)
|
||||
rv.add(req);
|
||||
}
|
||||
}
|
||||
outstandingRequests.clear();
|
||||
pendingRequest = null;
|
||||
@ -709,12 +722,6 @@ class PeerState implements DataLoader
|
||||
|
||||
/**
|
||||
* BEP 6
|
||||
* If the peer rejects lower chunks but not higher ones, thus creating holes,
|
||||
* we won't figure it out and the piece will fail, since we don't currently
|
||||
* keep a chunk bitmap in PartialPiece.
|
||||
* As long as the peer rejects all the chunks, or rejects only the last chunks,
|
||||
* no holes are created and we will be fine. The reject messages may be in any order,
|
||||
* just don't make a hole when it's over.
|
||||
*
|
||||
* @since 0.9.21
|
||||
*/
|
||||
@ -738,19 +745,10 @@ class PeerState implements DataLoader
|
||||
}
|
||||
}
|
||||
if (deletedRequest != null && !haveMoreRequests) {
|
||||
// We must return the piece to the coordinator
|
||||
// Create a new fake request so we can set the offset correctly
|
||||
PartialPiece pp = deletedRequest.getPartialPiece();
|
||||
int downloaded = pp.getDownloaded();
|
||||
Request req;
|
||||
if (deletedRequest.off == downloaded)
|
||||
req = deletedRequest;
|
||||
else
|
||||
req = new Request(pp, downloaded, 1);
|
||||
List<Request> pcs = Collections.singletonList(req);
|
||||
List<Request> pcs = Collections.singletonList(deletedRequest);
|
||||
listener.savePartialPieces(this.peer, pcs);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Returned to coord. w/ offset " + pp.getDownloaded() + " due to reject(" + piece + ',' + begin + ',' + length + ") from " + peer);
|
||||
_log.warn("Returned to coord. w/ data " + deletedRequest.getPartialPiece().getDownloaded() + " due to reject(" + piece + ',' + begin + ',' + length + ") from " + peer);
|
||||
}
|
||||
if (lastRequest != null && lastRequest.getPiece() == piece &&
|
||||
lastRequest.off == begin && lastRequest.len == length)
|
||||
@ -876,7 +874,7 @@ class PeerState implements DataLoader
|
||||
*
|
||||
* This is called from several places:
|
||||
*<pre>
|
||||
* By getOustandingRequest() when the first part of a chunk comes in
|
||||
* By getOutstandingRequest() when the first part of a chunk comes in
|
||||
* By havePiece() when somebody got a new piece completed
|
||||
* By chokeMessage() when we receive an unchoke
|
||||
* By setInteresting() when we are now interested
|
||||
@ -952,22 +950,32 @@ class PeerState implements DataLoader
|
||||
isLastChunk = lastRequest.off + lastRequest.len == pieceLength;
|
||||
|
||||
// Last part of a piece?
|
||||
if (isLastChunk)
|
||||
more_pieces = requestNextPiece();
|
||||
else
|
||||
{
|
||||
PartialPiece nextPiece = lastRequest.getPartialPiece();
|
||||
int nextBegin = lastRequest.off + PARTSIZE;
|
||||
int maxLength = pieceLength - nextBegin;
|
||||
int nextLength = maxLength > PARTSIZE ? PARTSIZE
|
||||
if (isLastChunk) {
|
||||
more_pieces = requestNextPiece();
|
||||
} else {
|
||||
PartialPiece nextPiece = lastRequest.getPartialPiece();
|
||||
int nextBegin = lastRequest.off + PARTSIZE;
|
||||
while (true) {
|
||||
// don't rerequest chunks we already have
|
||||
if (!nextPiece.hasChunk(nextBegin / PARTSIZE)) {
|
||||
int maxLength = pieceLength - nextBegin;
|
||||
int nextLength = maxLength > PARTSIZE ? PARTSIZE
|
||||
: maxLength;
|
||||
Request req
|
||||
= new Request(nextPiece,nextBegin, nextLength);
|
||||
outstandingRequests.add(req);
|
||||
if (!choked)
|
||||
out.sendRequest(req);
|
||||
lastRequest = req;
|
||||
}
|
||||
Request req = new Request(nextPiece,nextBegin, nextLength);
|
||||
outstandingRequests.add(req);
|
||||
if (!choked)
|
||||
out.sendRequest(req);
|
||||
lastRequest = req;
|
||||
break;
|
||||
} else {
|
||||
nextBegin += PARTSIZE;
|
||||
if (nextBegin >= pieceLength) {
|
||||
more_pieces = requestNextPiece();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -371,7 +371,7 @@ class WebPeer extends Peer implements EepGet.StatusListener {
|
||||
PartialPiece pp = last.getPartialPiece();
|
||||
synchronized(pp) {
|
||||
// Last chunk needed for this piece?
|
||||
if (pp.getLength() == pp.getDownloaded()) {
|
||||
if (pp.isComplete()) {
|
||||
if (listener.gotPiece(this, pp)) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Got " + piece + ": " + this);
|
||||
@ -650,15 +650,8 @@ class WebPeer extends Peer implements EepGet.StatusListener {
|
||||
List<Request> rv = new ArrayList<Request>(pcs.size());
|
||||
for (Integer p : pcs) {
|
||||
Request req = getLowestOutstandingRequest(p.intValue());
|
||||
if (req != null) {
|
||||
PartialPiece pp = req.getPartialPiece();
|
||||
synchronized(pp) {
|
||||
int dl = pp.getDownloaded();
|
||||
if (req.off != dl)
|
||||
req = new Request(pp, dl);
|
||||
}
|
||||
if (req != null)
|
||||
rv.add(req);
|
||||
}
|
||||
}
|
||||
outstandingRequests.clear();
|
||||
return rv;
|
||||
|
@ -98,7 +98,7 @@ button::-moz-focus-inner, input::-moz-focus-inner {
|
||||
width: auto;
|
||||
width: calc(100% - 22px);
|
||||
text-align: center;
|
||||
background: linear-gradient(to bottom, #fafaff 50%, #eef 51%, #eef 100%);
|
||||
background: linear-gradient(to bottom, #fafaff 10%, #eef 70%, #eef 100%);
|
||||
}
|
||||
|
||||
.iframed .snarknavbar {
|
||||
@ -983,7 +983,7 @@ tr:hover .percentBarText {
|
||||
border-top: 0;
|
||||
border-radius: 0 0 3px 3px;
|
||||
background: url(/themes/console/light/images/header.png) repeat-x scroll center center;
|
||||
background: linear-gradient(to bottom, #fff 50%, #eef 51%) !important;
|
||||
background: linear-gradient(to bottom, #fff 10%, #eef 70%) !important;
|
||||
font-variant: small-caps !important;
|
||||
box-shadow: 0 1px 2px #ccf, inset 0 0 0 1px #fff, inset 0 0 0 1px #fff;
|
||||
display: inline-block;
|
||||
@ -1000,7 +1000,7 @@ tr:hover .percentBarText {
|
||||
}
|
||||
|
||||
.snarkConfigTitle:hover, .toggleview:hover, .snarkConfigTitle:active, .toggleview:active, input.toggle_input:focus + .toggleview {
|
||||
background: linear-gradient(to bottom, #fcfaf7 50%, #ffe8bf 50%, #efd9b3 100%) !important;
|
||||
background: linear-gradient(to bottom, #fcfaf7 10%, #ffe8bf 70%, #efd9b3 100%) !important;
|
||||
}
|
||||
|
||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||
|
@ -177,7 +177,7 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited {
|
||||
|
||||
.snarkNav:link:first-child, .snarkNav:last-child[href="/i2psnark/"] {
|
||||
background: #310 url(images/button_snark.png) 11px center no-repeat;
|
||||
background: url(images/button_snark.png) 11px center no-repeat, linear-gradient(to bottom, #a68058 1%, #7a6045 27%, #5e4730 50%, #2e1700 51%, #1f0f00 100%);
|
||||
background: url(images/button_snark.png) 11px center no-repeat, linear-gradient(to bottom, #a68058 1%, #7a6045 10%, #5e4730 40%, #2e1700 90%, #1f0f00 100%);
|
||||
background-size: 18px auto, 100% 100%;
|
||||
padding-left: 28px !important;
|
||||
}
|
||||
@ -1286,7 +1286,7 @@ th.headerpriority br, .snarkTorrents thead th br {
|
||||
}
|
||||
|
||||
.snarkConfigTitle:hover, .snarkConfigTitle:focus, label.toggleview:hover, label.toggleview:focus, .toggle_input:focus + label {
|
||||
background: linear-gradient(to bottom, #5f475d 0%, #4f3b4f 50%, #1f001f 50%, #1f001f 100%) !important;
|
||||
background: linear-gradient(to bottom, #5f475d 0%, #4f3b4f 20%, #1f001f 100%) !important;
|
||||
box-shadow: inset 0 0 1px #3f173f;
|
||||
color: #d2baff !important;
|
||||
transition: ease all 0.1s;
|
||||
@ -1305,7 +1305,7 @@ th.headerpriority br, .snarkTorrents thead th br {
|
||||
border: 1px solid #101;
|
||||
border-top: none;
|
||||
background: #101 url(images/snarknav.png) repeat-x scroll center center;
|
||||
background: linear-gradient(to bottom, #4a3d49 0%, #3d303d 50%, #0d000d 50%, #0d000d 100%) !important;
|
||||
background: linear-gradient(to bottom, #4a3d49 0%, #3d303d 20%, #0d000d 100%) !important;
|
||||
box-shadow: inset 0 0 1px 0 #313, 0 0 0 1px rgba(16, 0, 16, 0.4);
|
||||
transition: ease all 0.1s;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ th a:active, th a:visited:active, td a:active, td a:visited:active {
|
||||
box-shadow: inset 0 0 0 1px #fff5ef, 0 0 1px 0 #4f3d36;
|
||||
box-shadow: inset 0 0 0 1px #fff5ef, 0 0 0 1px rgba(111, 96, 90, 0.3), 0 0 1px 1px rgba(79, 61, 54, 0.5);
|
||||
background: #efefef;
|
||||
background: linear-gradient(to bottom, #efefef 50%, #cfc7c2 53%);
|
||||
background: linear-gradient(to bottom, #efefef 15%, #cfc7c2 85%);
|
||||
text-align: center;
|
||||
transition: ease width 0.5s 0.5s;
|
||||
}
|
||||
@ -202,7 +202,7 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited {
|
||||
|
||||
.nav_main:link {
|
||||
background: #fff7ef url(images/button_snark.png) 11px center no-repeat !important;
|
||||
background: url(images/button_snark.png) 11px center no-repeat, linear-gradient(to bottom, #fff7ef 47%, rgba(207, 193, 181, 0.6) 50%), repeating-linear-gradient(45deg, #75604e 1px, #a09286 1px, #bfafa2 2px) !important;
|
||||
background: url(images/button_snark.png) 11px center no-repeat, linear-gradient(to bottom, #fff7ef 20%, rgba(207, 193, 181, 0.6) 80%), repeating-linear-gradient(45deg, #75604e 1px, #a09286 1px, #bfafa2 2px) !important;
|
||||
background-size: 18px auto, 100% 100%, 100% 100% !important;
|
||||
}
|
||||
|
||||
@ -219,7 +219,7 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited {
|
||||
|
||||
.nav_main:hover, .nav_main:focus {
|
||||
background: #ffeadf url(images/button_snark_hover.png) 11px center no-repeat !important;
|
||||
background: url(images/button_snark_hover.png) 11px center no-repeat, linear-gradient(to bottom, #ffeadf 47%, #cfb6a8 50%) !important;
|
||||
background: url(images/button_snark_hover.png) 11px center no-repeat, linear-gradient(to bottom, #ffeadf 20%, #cfb6a8 80%) !important;
|
||||
background-size: 18px auto, 100% 100%, 100% 100% !important;
|
||||
}
|
||||
|
||||
@ -235,7 +235,7 @@ _:-ms-lang(x), .snarkNav:link, .snarkNav:visited {
|
||||
|
||||
.nav_main:active {
|
||||
background: #dfb899 url(images/button_snark_active.png) 11px center no-repeat !important;
|
||||
background: url(images/button_snark_active.png) 11px center no-repeat, linear-gradient(to bottom, #dfb899 47%, #af9178 50%) !important;
|
||||
background: url(images/button_snark_active.png) 11px center no-repeat, linear-gradient(to bottom, #dfb899 20%, #af9178 80%) !important;
|
||||
background-size: 18px auto, 100% 100%, 100% 100% !important;
|
||||
}
|
||||
|
||||
@ -1287,7 +1287,7 @@ input[type="submit"], .trackerconfig input[type="submit"], input[name="savepri"]
|
||||
border: 1px solid #111;
|
||||
border-top: 0;
|
||||
background: #fff7ef;
|
||||
background: linear-gradient(to bottom, #fff7ef 50%, rgba(207, 193, 181, 0.6) 50%), repeating-linear-gradient(135deg, #75604e 1px, #a09286 1px, #bfafa2 2px);
|
||||
background: linear-gradient(to bottom, #fff7ef 20%, rgba(207, 193, 181, 0.6) 80%), repeating-linear-gradient(135deg, #75604e 1px, #a09286 1px, #bfafa2 2px);
|
||||
color: #444039 !important;
|
||||
box-shadow: 0 0 2px #4d453e, inset 0 0 0 1px #efe6e0;
|
||||
display: inline-block;
|
||||
|
@ -372,6 +372,7 @@
|
||||
<pathelement location="../../../core/java/build/i2p.jar" />
|
||||
<!-- required for multipart form handling in register.jsp -->
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jspc.jar" />
|
||||
</classpath>
|
||||
<arg value="-d" />
|
||||
<arg value="../jsp/WEB-INF/classes" />
|
||||
|
@ -234,7 +234,10 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
try {
|
||||
_filter = FilterFactory.createFilter(context, filterDefinition);
|
||||
} catch (IOException | InvalidDefinitionException bad) {
|
||||
throw new IllegalArgumentException("Bad filter definition file: " + bad.getMessage(), bad);
|
||||
String msg = "Bad filter definition file: " + filterDefinition + " - filtering disabled: " + bad.getMessage();
|
||||
_log.error(msg, bad);
|
||||
l.log(msg);
|
||||
_filter = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class I2Ping extends I2PTunnelClientBase {
|
||||
int remotePort = 0;
|
||||
boolean error = false;
|
||||
String[] argv = DataHelper.split(cmd, " ");
|
||||
Getopt g = new Getopt("ping", argv, "t:m:n:chl:f:p:");
|
||||
Getopt g = new Getopt("i2ping", argv, "t:m:n:chl:f:p:");
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
switch (c) {
|
||||
|
@ -236,7 +236,7 @@ class AccessFilter implements StatefulConnectionFilter {
|
||||
syncer.schedule(SYNC_INTERVAL);
|
||||
} catch (IOException bad) {
|
||||
Log log = context.logManager().getLog(AccessFilter.class);
|
||||
log.log(Log.CRIT, "syncing access list failed", bad);
|
||||
log.error("syncing access list failed", bad);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -8,7 +8,9 @@ import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* An element of filter definition that reads hashes of remote destinations
|
||||
@ -55,7 +57,16 @@ class FileFilterDefinitionElement extends FilterDefinitionElement {
|
||||
reader = new BufferedReader(new FileReader(file));
|
||||
String b32;
|
||||
while((b32 = reader.readLine()) != null) {
|
||||
Hash hash = fromBase32(b32);
|
||||
if (b32.length() == 0)
|
||||
continue;
|
||||
Hash hash;
|
||||
try {
|
||||
hash = fromBase32(b32);
|
||||
} catch (InvalidDefinitionException bad32) {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(FileFilterDefinitionElement.class);
|
||||
log.error("Invalid access list entry \"" + b32 + "\" in " + file, bad32);
|
||||
continue;
|
||||
}
|
||||
if (map.containsKey(hash))
|
||||
continue;
|
||||
DestTracker newTracker = new DestTracker(hash, threshold);
|
||||
@ -64,8 +75,6 @@ class FileFilterDefinitionElement extends FilterDefinitionElement {
|
||||
lastLoaded.put(hash, newTracker);
|
||||
}
|
||||
}
|
||||
} catch (InvalidDefinitionException bad32) {
|
||||
throw new IOException("invalid access list entry", bad32);
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try { reader.close(); } catch (IOException ignored) {}
|
||||
|
@ -451,7 +451,7 @@
|
||||
<!-- set if unset -->
|
||||
<property name="workspace.changes.tr" value="" />
|
||||
<copy todir="build/obj" file="resources/log4j.properties" />
|
||||
<jar destfile="./jettylib/jetty-i2p.jar" basedir="./build/obj" includes="**/*.class log4j.properties" >
|
||||
<jar destfile="./jettylib/jetty-i2p.jar" basedir="./build/obj" includes="**/*.class log4j.properties" excludes="**/JspC.class">
|
||||
<manifest>
|
||||
<attribute name="Implementation-Version" value="${full.version}" />
|
||||
<attribute name="Built-By" value="${build.built-by}" />
|
||||
@ -464,6 +464,9 @@
|
||||
<attribute name="X-Compile-Target-JDK" value="${javac.version}" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<!-- separate jar for JspC wrapper used only in build, not included in jetty-i2p.jar -->
|
||||
<jar destfile="./jettylib/jspc.jar" basedir="./build/obj" includes="**/JspC.class" >
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jarUpToDate">
|
||||
|
@ -32,6 +32,8 @@ import net.i2p.util.VersionComparator;
|
||||
* https://bz.apache.org/bugzilla/show_bug.cgi?id=62674
|
||||
*
|
||||
* We could set fork=false in build.xml, but then the paths are all wrong.
|
||||
*
|
||||
* Warning - used in build process only, not included in runtime jars, not for external use.
|
||||
* Only for use in build scripts, obviously not a public API.
|
||||
* See apps/routerconsole/java/build.xml for more information.
|
||||
*
|
||||
|
@ -392,6 +392,11 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
xaxisColor, stroke);
|
||||
worker.drawLine(im.xorigin, im.yorigin + 4, im.xorigin, im.yorigin - im.ysize - 4,
|
||||
yaxisColor, stroke);
|
||||
|
||||
// I2P skip arrowheads if transparent
|
||||
if (((Color)arrowColor).getAlpha() == 0)
|
||||
return;
|
||||
|
||||
//Do X axis arrow
|
||||
double[] Xarrow_x = {
|
||||
im.xorigin + im.xsize + 4,
|
||||
@ -404,10 +409,6 @@ public class RrdGraph implements RrdGraphConstants {
|
||||
};
|
||||
worker.fillPolygon(Xarrow_x, im.yorigin + 3.0, Xarrow_y, arrowColor);
|
||||
|
||||
// I2P skip arrowheads if transparent
|
||||
if (((Color)arrowColor).getAlpha() == 0)
|
||||
return;
|
||||
|
||||
//Do y axis arrow
|
||||
double[] Yarrow_x = {
|
||||
im.xorigin - 3,
|
||||
|
@ -492,6 +492,7 @@
|
||||
<pathelement location="../../jetty/jettylib/jetty-util.jar" />
|
||||
<pathelement location="${ant.home}/lib/ant.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
|
||||
<pathelement location="../../jetty/jettylib/jspc.jar" />
|
||||
<pathelement location="../../systray/java/build/obj" />
|
||||
<pathelement location="../../desktopgui/dist/desktopgui.jar" />
|
||||
<pathelement location="../../../installer/lib/wrapper/all/wrapper.jar" />
|
||||
|
@ -70,7 +70,15 @@ public class GraphHelper extends FormHandler {
|
||||
ConfigRestartBean.getRestartTimeRemaining() < (1000 * (_refreshDelaySeconds + 30)))
|
||||
return "";
|
||||
// shorten the refresh by 3 seconds so we beat the iframe
|
||||
return "<meta http-equiv=\"refresh\" content=\"" + (_refreshDelaySeconds - 3) + "\">";
|
||||
return "<noscript><meta http-equiv=\"refresh\" content=\"" + (_refreshDelaySeconds - 3) + ";url=/graphs\" /></noscript>";
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public int getRefresh() {
|
||||
// shorten the refresh by 3 seconds so we beat the iframe
|
||||
return _refreshDelaySeconds - 3;
|
||||
}
|
||||
|
||||
public void setPeriodCount(String str) {
|
||||
|
@ -46,7 +46,7 @@
|
||||
}
|
||||
response.setHeader("X-XSS-Protection", "1; mode=block");
|
||||
response.setHeader("X-Content-Type-Options", "nosniff");
|
||||
response.setHeader("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture(), fullscreen=(self), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), vibrate=(), vr=()");
|
||||
response.setHeader("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), fullscreen=(self), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), vibrate=(), vr=()");
|
||||
// https://www.w3.org/TR/referrer-policy/
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
||||
// As of Chrome 56, Firefox 50, Opera 43. "same-origin" not widely supported.
|
||||
|
@ -16,6 +16,12 @@
|
||||
boolean allowRefresh = intl.allowIFrame(request.getHeader("User-Agent"));
|
||||
if (allowRefresh) {
|
||||
out.print(graphHelper.getRefreshMeta());
|
||||
%>
|
||||
<script nonce="<%=cspNonce%>" type="text/javascript">
|
||||
var graphRefreshInterval = "<%=graphHelper.getRefresh()%>";
|
||||
</script>
|
||||
<script src="/js/graphs.js?<%=net.i2p.CoreVersion.VERSION%>" type="text/javascript"></script>
|
||||
<%
|
||||
}
|
||||
%>
|
||||
<%@include file="summaryajax.jsi" %>
|
||||
|
31
apps/routerconsole/jsp/js/graphs.js
Normal file
31
apps/routerconsole/jsp/js/graphs.js
Normal file
@ -0,0 +1,31 @@
|
||||
/* I2P+ graphs.js by dr|z3d */
|
||||
/* Ajax graph refresh and configuration toggle */
|
||||
/* Adapted from I2P+, licensed to I2P under our license */
|
||||
|
||||
var __graphs_counter = 0;
|
||||
|
||||
function initGraphs() {
|
||||
if (graphRefreshInterval > 0) {
|
||||
setTimeout(updateGraphs, graphRefreshInterval * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function updateGraphs() {
|
||||
const param = '&g=' + (++__graphs_counter);
|
||||
var images = document.getElementsByClassName("statimage");
|
||||
for (var i = 0; i < images.length; i++) {
|
||||
let image = images[i];
|
||||
// https://stackoverflow.com/questions/1077041/refresh-image-with-a-new-one-at-the-same-url
|
||||
let idx = image.src.indexOf('&g=');
|
||||
if (idx > 0) {
|
||||
image.src = image.src.substring(0, idx) + param;
|
||||
} else {
|
||||
image.src = image.src + param;
|
||||
}
|
||||
}
|
||||
setTimeout(updateGraphs, graphRefreshInterval * 1000);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
initGraphs();
|
||||
});
|
@ -31,6 +31,7 @@
|
||||
<pathelement location="${lib}/jasper-runtime.jar" />
|
||||
<pathelement location="${lib}/jetty-util.jar" />
|
||||
<pathelement location="${lib}/jetty-i2p.jar" />
|
||||
<pathelement location="${lib}/jspc.jar" />
|
||||
<pathelement location="${ant.home}/lib/ant.jar" />
|
||||
<pathelement location="../../../core/java/build/i2p.jar" />
|
||||
<pathelement location="../../addressbook/dist/addressbook.jar" />
|
||||
|
@ -17,9 +17,9 @@
|
||||
<servlet-name>SusiMail</servlet-name>
|
||||
<servlet-class>i2p.susi.webmail.WebMail</servlet-class>
|
||||
<multipart-config>
|
||||
<!-- 23 MB. See SMTPClient for discussion -->
|
||||
<max-file-size>24117248</max-file-size>
|
||||
<max-request-size>24117248</max-request-size>
|
||||
<!-- 7.27 MB. See SMTPClient for discussion -->
|
||||
<max-file-size>7629902</max-file-size>
|
||||
<max-request-size>7629902</max-request-size>
|
||||
<file-size-threshold>131072</file-size-threshold>
|
||||
</multipart-config>
|
||||
</servlet>
|
||||
|
@ -2278,7 +2278,7 @@ public class WebMail extends HttpServlet
|
||||
response.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self'; script-src 'self'; form-action 'self'; frame-ancestors 'self'; object-src 'none'; media-src 'none'; img-src 'self'");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
}
|
||||
response.setHeader("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture(), fullscreen=(self), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), vibrate=(), vr=()");
|
||||
response.setHeader("Permissions-Policy", "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), fullscreen=(self), geolocation=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), usb=(), vibrate=(), vr=()");
|
||||
response.setHeader("X-XSS-Protection", "1; mode=block");
|
||||
response.setHeader("X-Content-Type-Options", "nosniff");
|
||||
response.setHeader("Referrer-Policy", "no-referrer");
|
||||
|
@ -51,14 +51,14 @@ import net.i2p.util.Log;
|
||||
public class SMTPClient {
|
||||
|
||||
/**
|
||||
* 31.84 MB
|
||||
* smtp.postman.i2p as of 2017-12.
|
||||
* 10.00 MB
|
||||
* smtp.postman.i2p as of 2024-06-22.
|
||||
* @since 0.9.33
|
||||
*/
|
||||
public static final long DEFAULT_MAX_SIZE = 33388608;
|
||||
public static final long DEFAULT_MAX_SIZE = 10485760;
|
||||
|
||||
/**
|
||||
* About 23.25 MB.
|
||||
* 7629902 ~= 7.27 MB
|
||||
* Base64 encodes 57 chars to 76 + \r\n on a line
|
||||
* @since 0.9.33
|
||||
*/
|
||||
|
@ -391,7 +391,7 @@
|
||||
<target name="buildJetty" depends="buildCore" >
|
||||
<ant dir="apps/jetty" target="build" />
|
||||
<copy todir="build/" >
|
||||
<fileset dir="apps/jetty/jettylib" excludes="ant.jar" />
|
||||
<fileset dir="apps/jetty/jettylib" excludes="jspc.jar" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
|
@ -134,6 +134,14 @@ public class LeaseSet2 extends LeaseSet {
|
||||
return _options.getProperty(opt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return not a copy, do not modify, or null
|
||||
* @since 0.9.63
|
||||
*/
|
||||
public Properties getOptions() {
|
||||
return _options;
|
||||
}
|
||||
|
||||
/**
|
||||
* If more than one key, return the first supported one.
|
||||
* If none supported, return the first one.
|
||||
@ -237,8 +245,7 @@ public class LeaseSet2 extends LeaseSet {
|
||||
_options.clear();
|
||||
else
|
||||
_options = new OrderedProperties();
|
||||
if (options != null)
|
||||
_options.putAll(options);
|
||||
_options.putAll(options);
|
||||
}
|
||||
|
||||
public boolean isOffline() {
|
||||
|
@ -119,7 +119,7 @@ public class PrivateKeyFile {
|
||||
double days = 365;
|
||||
int mode = 0;
|
||||
boolean error = false;
|
||||
Getopt g = new Getopt("pkf", args, "t:nuxhse:c:a:o:d:r:p:b:y:z:w:");
|
||||
Getopt g = new Getopt("PrivateKeyFile", args, "t:nuxhse:c:a:o:d:r:p:b:y:z:w:v:V:");
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
switch (c) {
|
||||
|
@ -1,5 +1,14 @@
|
||||
2024-06-04 zzz
|
||||
* Console: Add js refresh on /graphs (Gitlab MR !199)
|
||||
* i2psnark:
|
||||
- Fix leaked requests, partial pieces, and temp files (Gitlab MR !203)
|
||||
- Make PEX more efficient
|
||||
* Reseed: Increase min version when creating bundles; CLI improvements
|
||||
* Router: Add synthetic stats for client and expl. build success rate
|
||||
|
||||
2024-06-01 zzz
|
||||
* I2CP: Store local destination in lookup cache (Gitlab #482)
|
||||
* Router: Don't update rates for full stats when not enabled
|
||||
* Transport: Remove SSU1 code from UDPTransport (Gitlab MR !197)
|
||||
|
||||
2024-05-29 zzz
|
||||
|
@ -46,7 +46,7 @@ import net.i2p.util.FileUtil;
|
||||
public class BundleRouterInfos {
|
||||
|
||||
/**
|
||||
* Usage: PersistentDataStore -i configDir -o toDir -c count
|
||||
* Usage: BundleRouterInfos -i configDir -o toDir -c count
|
||||
*
|
||||
* Copy a random selection of 'count' router infos from configDir/netDb
|
||||
* to 'toDir'. Skip your own router info, and old, hidden, unreachable, and
|
||||
@ -55,7 +55,7 @@ public class BundleRouterInfos {
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
Getopt g = new Getopt("PersistentDataStore", args, "i:o:c:");
|
||||
Getopt g = new Getopt("BundleRouterInfos", args, "i:o:c:");
|
||||
String in = System.getProperty("user.home") + "/.i2p";
|
||||
String out = "netDb";
|
||||
int count = 200;
|
||||
|
@ -20,7 +20,7 @@ public class RouterVersion {
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
/** for example: "beta", "alpha", "rc" */
|
||||
public final static String QUALIFIER = "";
|
||||
public final static long BUILD = 4;
|
||||
public final static long BUILD = 5;
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
public final static String FULL_VERSION = VERSION + "-" + BUILD + QUALIFIER + EXTRA;
|
||||
|
@ -820,7 +820,7 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide router limit by 1.75 for overhead.
|
||||
* Divide router limit by 1.5 for overhead.
|
||||
* This could someday give a different answer to each client.
|
||||
* But it's not enforced anywhere.
|
||||
*
|
||||
@ -833,7 +833,7 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
|
||||
int out = _context.bandwidthLimiter().getOutboundKBytesPerSecond();
|
||||
int inb = _context.bandwidthLimiter().getInboundBurstKBytesPerSecond();
|
||||
int outb = _context.bandwidthLimiter().getOutboundBurstKBytesPerSecond();
|
||||
BandwidthLimitsMessage msg = new BandwidthLimitsMessage(in * 4 / 7, out * 4 / 7, in, inb, out, outb, 1);
|
||||
BandwidthLimitsMessage msg = new BandwidthLimitsMessage(in * 2 / 3, out * 2 / 3, in, inb, out, outb, 1);
|
||||
try {
|
||||
_runner.doSend(msg);
|
||||
} catch (I2CPMessageException ime) {
|
||||
|
@ -762,7 +762,7 @@ abstract class StoreJob extends JobImpl {
|
||||
* Short ECIES tunnel build messages (1.5.0)
|
||||
* @since 0.9.28
|
||||
*/
|
||||
public static final String MIN_STORE_VERSION = "0.9.51";
|
||||
public static final String MIN_STORE_VERSION = "0.9.59";
|
||||
|
||||
/**
|
||||
* Is it new enough?
|
||||
@ -782,7 +782,7 @@ abstract class StoreJob extends JobImpl {
|
||||
}
|
||||
|
||||
/** @since 0.9.38 */
|
||||
public static final String MIN_STORE_LS2_VERSION = "0.9.51";
|
||||
public static final String MIN_STORE_LS2_VERSION = "0.9.59";
|
||||
|
||||
/**
|
||||
* Is it new enough?
|
||||
@ -797,7 +797,7 @@ abstract class StoreJob extends JobImpl {
|
||||
* Was supported in 38, but they're now sigtype 11 which wasn't added until 39
|
||||
* @since 0.9.39
|
||||
*/
|
||||
public static final String MIN_STORE_ENCLS2_VERSION = "0.9.51";
|
||||
public static final String MIN_STORE_ENCLS2_VERSION = "0.9.59";
|
||||
|
||||
/**
|
||||
* Is it new enough?
|
||||
|
@ -47,8 +47,8 @@ public class ReseedBundler {
|
||||
private final static String ROUTERINFO_PREFIX = "routerInfo-";
|
||||
private final static String ROUTERINFO_SUFFIX = ".dat";
|
||||
private static final int MINIMUM = 50;
|
||||
/** NTCP2 */
|
||||
private static final String MIN_VERSION = "0.9.36";
|
||||
/** Same as in TunnelPeerSelector */
|
||||
private static final String MIN_VERSION = "0.9.59";
|
||||
|
||||
public ReseedBundler(RouterContext ctx) {
|
||||
_context = ctx;
|
||||
@ -82,9 +82,12 @@ public class ReseedBundler {
|
||||
}
|
||||
if (ri.getPublished() < tooOld)
|
||||
continue;
|
||||
if (ri.getCapabilities().contains("U"))
|
||||
String caps = ri.getCapabilities();
|
||||
if (caps.contains("U"))
|
||||
continue;
|
||||
if (ri.getCapabilities().contains("K"))
|
||||
if (caps.contains("K"))
|
||||
continue;
|
||||
if (caps.contains("G"))
|
||||
continue;
|
||||
if (VersionComparator.comp(ri.getVersion(), MIN_VERSION) < 0)
|
||||
continue;
|
||||
|
@ -39,6 +39,7 @@ import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
import net.i2p.util.SystemVersion;
|
||||
import net.i2p.util.Translate;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
* Moved from ReseedHandler in routerconsole. See ReseedChecker for additional comments.
|
||||
@ -69,6 +70,8 @@ public class Reseeder {
|
||||
private static final int MIN_RESEED_SERVERS = 2;
|
||||
// network ID cross-check, proposal 147, as of 0.9.42
|
||||
private static final String NETID_PARAM = "?netid=";
|
||||
/** Same as in TunnelPeerSelector */
|
||||
private static final String MIN_VERSION = "0.9.59";
|
||||
|
||||
/**
|
||||
* NOTE - URLs that are in both the standard and SSL groups must use the same hostname,
|
||||
@ -1242,6 +1245,10 @@ public class Reseeder {
|
||||
SSLEepGet.SSLState sslState = null;
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
for (String url : urls) {
|
||||
if (!url.startsWith("https://"))
|
||||
url = "https://" + url;
|
||||
if (!url.endsWith("/"))
|
||||
url += "/";
|
||||
url += SU3_FILENAME + NETID_PARAM + '2';
|
||||
URI uri = new URI(url);
|
||||
String host = uri.getHost();
|
||||
@ -1273,9 +1280,10 @@ public class Reseeder {
|
||||
java.util.zip.ZipFile zipf = new java.util.zip.ZipFile(zip);
|
||||
java.util.Enumeration<? extends java.util.zip.ZipEntry> entries = zipf.entries();
|
||||
int ri = 0, old = 0;
|
||||
int oldver = 0, unreach = 0;
|
||||
while (entries.hasMoreElements()) {
|
||||
java.util.zip.ZipEntry entry = (java.util.zip.ZipEntry) entries.nextElement();
|
||||
net.i2p.data.router.RouterInfo r = new net.i2p.data.router.RouterInfo();
|
||||
RouterInfo r = new RouterInfo();
|
||||
InputStream in = zipf.getInputStream(entry);
|
||||
r.readBytes(in);
|
||||
in.close();
|
||||
@ -1283,6 +1291,10 @@ public class Reseeder {
|
||||
ri++;
|
||||
else
|
||||
old++;
|
||||
if (VersionComparator.comp(r.getVersion(), MIN_VERSION) < 0)
|
||||
oldver++;
|
||||
if (r.getCapabilities().indexOf('U') >= 0)
|
||||
unreach++;
|
||||
}
|
||||
zipf.close();
|
||||
if (old > 0) {
|
||||
@ -1300,6 +1312,7 @@ public class Reseeder {
|
||||
System.out.println("Test failed for " + host + ", returned only " + ri + " router infos");
|
||||
fail++;
|
||||
}
|
||||
System.out.println("Router infos included " + oldver + " with versions before " + MIN_VERSION + " and " + unreach + " unreachable");
|
||||
} else {
|
||||
System.out.println("Test failed for " + host + " return code: " + rc);
|
||||
su3.delete();
|
||||
|
@ -44,6 +44,8 @@ public class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
|
||||
sm.createRateStat("router.integratedPeers", "Known integrated (floodfill) peers", "NetworkDatabase", new long[] { 60*1000 });
|
||||
sm.createRateStat("router.knownPeers", "Known peers", "NetworkDatabase", new long[] { 60*1000 });
|
||||
sm.createRequiredRateStat("router.tunnelBacklog", _x("Size of tunnel acceptor backlog"), "Tunnels", new long[] { 60*60*1000 });
|
||||
sm.createRateStat("tunnel.buildClientSuccessRate", "Percent success", "Tunnels", new long[] { 60*1000 });
|
||||
sm.createRateStat("tunnel.buildExploratorySuccessRate", "Percent success", "Tunnels", new long[] { 60*1000 });
|
||||
_maxMemory = Runtime.getRuntime().maxMemory();
|
||||
String legend = "(Bytes)";
|
||||
if (_maxMemory < Long.MAX_VALUE)
|
||||
@ -57,20 +59,12 @@ public class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
|
||||
int active = _ctx.commSystem().countActivePeers();
|
||||
sm.addRateData("router.activePeers", active);
|
||||
|
||||
int activeSend = _ctx.commSystem().countActiveSendPeers();
|
||||
sm.addRateData("router.activeSendPeers", activeSend);
|
||||
|
||||
int fast = _ctx.profileOrganizer().countFastPeers();
|
||||
sm.addRateData("router.fastPeers", fast);
|
||||
|
||||
int highCap = _ctx.profileOrganizer().countHighCapacityPeers();
|
||||
sm.addRateData("router.highCapacityPeers", highCap);
|
||||
|
||||
int integrated = _ctx.peerManager().countPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
|
||||
sm.addRateData("router.integratedPeers", integrated);
|
||||
|
||||
sm.addRateData("router.knownPeers", _ctx.netDb().getKnownRouters());
|
||||
|
||||
sm.addRateData("bw.sendRate", (long)_ctx.bandwidthLimiter().getSendBps());
|
||||
sm.addRateData("bw.recvRate", (long)_ctx.bandwidthLimiter().getReceiveBps());
|
||||
|
||||
@ -103,6 +97,48 @@ public class CoalesceStatsEvent implements SimpleTimer.TimedEvent {
|
||||
sm.addRateData("bw.sendBps", (long)bps, 60*1000);
|
||||
}
|
||||
}
|
||||
|
||||
if (_ctx.getBooleanProperty("stat.full")) {
|
||||
int activeSend = _ctx.commSystem().countActiveSendPeers();
|
||||
sm.addRateData("router.activeSendPeers", activeSend);
|
||||
|
||||
int integrated = _ctx.peerManager().countPeersByCapability(FloodfillNetworkDatabaseFacade.CAPABILITY_FLOODFILL);
|
||||
sm.addRateData("router.integratedPeers", integrated);
|
||||
|
||||
sm.addRateData("router.knownPeers", _ctx.netDb().getKnownRouters());
|
||||
|
||||
RateStat s1 = sm.getRate("tunnel.buildExploratorySuccess");
|
||||
RateStat s2 = sm.getRate("tunnel.buildExploratoryExpire");
|
||||
RateStat s3 = sm.getRate("tunnel.buildExploratoryReject");
|
||||
if (s1 != null && s2 != null && s3 != null) {
|
||||
Rate r1 = s1.getRate(10*60*1000);
|
||||
Rate r2 = s2.getRate(10*60*1000);
|
||||
Rate r3 = s3.getRate(10*60*1000);
|
||||
if (r1 != null && r2 != null && r3 != null) {
|
||||
long s = r1.getCurrentEventCount() + r1.getLastEventCount();
|
||||
long t = s + r2.getCurrentEventCount() + r2.getLastEventCount() +
|
||||
r3.getCurrentEventCount() + r3.getLastEventCount();
|
||||
if (t > 0)
|
||||
sm.addRateData("tunnel.buildExploratorySuccessRate", 100 * s / t, 60*1000);
|
||||
}
|
||||
}
|
||||
|
||||
s1 = sm.getRate("tunnel.buildClientSuccess");
|
||||
s2 = sm.getRate("tunnel.buildClientExpire");
|
||||
s3 = sm.getRate("tunnel.buildClientReject");
|
||||
if (s1 != null && s2 != null && s3 != null) {
|
||||
Rate r1 = s1.getRate(10*60*1000);
|
||||
Rate r2 = s2.getRate(10*60*1000);
|
||||
Rate r3 = s3.getRate(10*60*1000);
|
||||
if (r1 != null && r2 != null && r3 != null) {
|
||||
long s = r1.getCurrentEventCount() + r1.getLastEventCount();
|
||||
long t = s + r2.getCurrentEventCount() + r2.getLastEventCount() +
|
||||
r3.getCurrentEventCount() + r3.getLastEventCount();
|
||||
if (t > 0)
|
||||
sm.addRateData("tunnel.buildClientSuccessRate", 100 * s / t, 60*1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,7 +352,7 @@ public abstract class TunnelPeerSelector extends ConnectChecker {
|
||||
}
|
||||
|
||||
/** SSU2 fixes (2.1.0), Congestion fixes (2.2.0) */
|
||||
private static final String MIN_VERSION = "0.9.58";
|
||||
private static final String MIN_VERSION = "0.9.59";
|
||||
|
||||
/**
|
||||
* Should the peer be excluded based on its published caps?
|
||||
|
@ -116,7 +116,7 @@ class LocalClientManager extends ClientManager {
|
||||
int dropX1000 = 0, jitter = 0, latency = 0;
|
||||
int port = ClientManagerFacadeImpl.DEFAULT_PORT;
|
||||
boolean error = false;
|
||||
Getopt g = new Getopt("router", args, "d:j:l:p:");
|
||||
Getopt g = new Getopt("LocalClientManager", args, "d:j:l:p:");
|
||||
try {
|
||||
int c;
|
||||
while ((c = g.getopt()) != -1) {
|
||||
|
Reference in New Issue
Block a user