use of i2p.bote.network.RelayPeer in project i2p.i2p-bote by i2p.
the class RelayPeerManager method run.
@Override
public void run() {
while (!Thread.interrupted()) {
try {
// ask all peers for their peer lists
Set<RelayPeer> peersToQuery = new HashSet<RelayPeer>(peers);
PacketBatch batch = new PacketBatch();
for (RelayPeer peer : peersToQuery) // don't reuse request packets because PacketBatch will not add the same one more than once
batch.putPacket(new PeerListRequest(), peer);
sendQueue.send(batch);
batch.awaitSendCompletion();
batch.awaitAllResponses(2, TimeUnit.MINUTES);
// build a Set of destinations
Set<Destination> responders = batch.getResponses().keySet();
// update reachability data
log.debug("Relay peer stats:");
for (RelayPeer peer : peersToQuery) {
// use peersToQuery (not peers) so new peers that have been added in the meantime are not wrongly considered unresponsive
boolean didRespond = responders.contains(peer);
peer.addReachabilitySample(didRespond);
if (log.shouldLog(Log.DEBUG)) {
StringBuilder logMessage = new StringBuilder(" ");
logMessage.append(Util.toBase32(peer));
logMessage.append(" ");
for (boolean responded : peer.getAllSamples()) logMessage.append(responded ? '*' : '.');
log.debug(logMessage.toString());
}
}
// make a Set with the new peers
Set<Destination> receivedPeers = new HashSet<Destination>();
BanList banList = BanList.getInstance();
for (DataPacket response : batch.getResponses().values()) {
if (!(response instanceof PeerList))
continue;
PeerList peerList = (PeerList) response;
for (Destination peer : peerList.getPeers()) if (!banList.isBanned(peer))
receivedPeers.add(peer);
}
log.debug("Received a total of " + receivedPeers.size() + " relay peers in " + batch.getResponses().size() + " packets.");
// replace low-reachability peers with new peers (a PeerList is supposed to contain only high-reachability peers)
synchronized (peers) {
// add all received peers, then remove low-reachability ones (all of which are existing peers)
for (Destination newPeer : receivedPeers) if (!localDestination.equals(newPeer))
peers.add(new RelayPeer(newPeer));
for (Iterator<RelayPeer> iterator = peers.iterator(); iterator.hasNext(); ) {
if (peers.size() <= MAX_PEERS)
break;
RelayPeer peer = iterator.next();
if (// don't remove the peer before it has had a chance to respond to a request
!peer.getAllSamples().isEmpty() && peer.getReachability() < MIN_REACHABILITY)
iterator.remove();
}
}
log.debug("Number of relay peers is now " + peers.size());
// if no good peers available, ask more often
if (getGoodPeers().isEmpty())
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_SHORT);
else
TimeUnit.MINUTES.sleep(UPDATE_INTERVAL_LONG);
} catch (InterruptedException e) {
break;
} catch (RuntimeException e) {
// catch unexpected exceptions to keep the thread running
log.error("Exception caught in RelayPeerManager loop", e);
}
}
writePeers(peerFile);
log.debug("RelayPeerManager thread exiting.");
}
use of i2p.bote.network.RelayPeer in project i2p.i2p-bote by i2p.
the class PeerInfoTag method createRelayChart.
private String createRelayChart(RelayPeer[] relayPeers) throws IOException {
RingPlot plot;
if (relayPeers.length == 0) {
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("", 100);
plot = new RingPlot(dataset);
plot.setSectionPaint("", Color.gray);
} else {
int good = 0;
int untested = 0;
for (RelayPeer relayPeer : relayPeers) {
int reachability = relayPeer.getReachability();
if (reachability == 0)
untested += 1;
else if (reachability > 80)
good += 1;
}
int bad = relayPeers.length - good - untested;
DefaultPieDataset dataset = new DefaultPieDataset();
if (good > 0)
dataset.setValue(_t("Good"), good);
if (bad > 0)
dataset.setValue(_t("Unreliable"), bad);
if (untested > 0)
dataset.setValue(_t("Untested"), untested);
plot = new RingPlot(dataset);
plot.setSectionPaint(_t("Good"), Color.green);
plot.setSectionPaint(_t("Unreliable"), Color.red);
plot.setSectionPaint(_t("Untested"), Color.orange);
}
plot.setLabelGenerator(null);
plot.setShadowGenerator(null);
JFreeChart chart = new JFreeChart(_t("Relay Peers:"), JFreeChart.DEFAULT_TITLE_FONT, plot, relayPeers.length == 0 ? false : true);
return ServletUtilities.saveChartAsPNG(chart, 400, 300, null);
}
use of i2p.bote.network.RelayPeer in project i2p.i2p-bote by i2p.
the class PeerInfoTag method doTag.
@Override
public void doTag() {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
try {
// Print DHT peer info
DhtPeerStats dhtStats = I2PBote.getInstance().getDhtStats(new WebappPeerStatsRenderer());
if (dhtStats == null)
return;
int numDhtPeers = dhtStats.getData().size();
// Get a sorted list of relay peers
RelayPeer[] relayPeers = I2PBote.getInstance().getRelayPeers().toArray(new RelayPeer[0]);
Arrays.sort(relayPeers, new Comparator<RelayPeer>() {
@Override
public int compare(RelayPeer peer1, RelayPeer peer2) {
return peer2.getReachability() - peer1.getReachability();
}
});
// Print charts
out.println("<div class=\"network-charts\">");
out.println("<div class=\"chart\">");
out.println("<img src=\"displayChart?filename=" + createDhtChart(dhtStats) + "\"/>");
out.println("<div class=\"chart-text\">" + numDhtPeers + "</div>");
out.println("</div>");
out.println("<div class=\"chart\">");
out.println("<img src=\"displayChart?filename=" + createRelayChart(relayPeers) + "\"/>");
out.println("<div class=\"chart-text\">" + relayPeers.length + "</div>");
out.println("</div>");
out.println("</div>");
out.println("<br>");
out.println("<span class=\"subheading\">" + _t("Kademlia Peers:") + " " + numDhtPeers + "</span>");
if (numDhtPeers > 0) {
out.println("<table");
// header
out.println("<tr>");
for (String columnHeader : dhtStats.getHeader()) out.println("<th>" + columnHeader + "</th>");
out.println("</tr>");
// data
for (DhtPeerStatsRow row : dhtStats.getData()) {
out.println("<tr>");
for (String cellData : row.toStrings()) out.println("<td class=\"ellipsis\">" + cellData + "</td>");
out.println("</tr>");
}
out.println("</table>");
}
out.println("<br/>");
// Print relay peer info
out.println("<span class=\"subheading\">" + _t("Relay Peers:") + " " + relayPeers.length + "</span>");
if (relayPeers.length > 0) {
out.println("<table");
out.println("<tr>");
out.println("<th>" + _t("Peer") + "</th>");
out.println("<th>" + _t("I2P Destination") + "</th>");
out.println("<th>" + _t("Reachability %") + "</th>");
out.println("</tr>");
int i = 1;
for (RelayPeer peer : relayPeers) {
out.println("<tr>");
out.println("<td>" + i + "</td>");
out.println("<td class=\"ellipsis\">" + Util.toBase32(peer) + "</td>");
int reachability = peer.getReachability();
out.println("<td>" + (reachability == 0 ? _t("Untested") : reachability) + "</td>");
out.println("</tr>");
i++;
}
out.println("</table>");
}
out.println("<br/>");
// List banned peers
Collection<BannedPeer> bannedPeers = I2PBote.getInstance().getBannedPeers();
out.println("<span class=\"subheading\">" + _t("Banned Peers:") + " " + bannedPeers.size() + "</span>");
if (bannedPeers.size() > 0) {
out.println("<table>");
out.println("<tr>");
out.println("<th>" + _t("Peer") + "</th>");
out.println("<th>" + _t("Destination Hash") + "</th>");
out.println("<th>" + _t("Ban Reason") + "</th>");
out.println("</tr>");
int peerIndex = 1;
for (BannedPeer peer : bannedPeers) {
out.println("<tr>");
out.println("<td>" + peerIndex++ + "</td>");
out.println("<td class=\"ellipsis\">" + Util.toBase32(peer.getDestination()) + "</td>");
out.println("<td>" + getBanReason(peer) + "</td>");
out.println("</tr>");
}
out.println("</table>");
}
} catch (IOException e) {
log.error("Can't write output to HTML page", e);
}
}
use of i2p.bote.network.RelayPeer in project i2p.i2p-bote by i2p.
the class NetworkInfoFragment method setupRelayPeers.
private void setupRelayPeers() {
Set<RelayPeer> relayPeers = I2PBote.getInstance().getRelayPeers();
mRelayPeers.setText("" + relayPeers.size());
if (relayPeers.size() == 0) {
Segment n = new Segment("", 100);
SegmentFormatter nf = new SegmentFormatter(getResources().getColor(android.R.color.darker_gray));
setupSegmentFormatter(nf);
mRelayPie.addSeries(n, nf);
} else {
int good = 0;
int untested = 0;
for (RelayPeer relayPeer : relayPeers) {
int reachability = relayPeer.getReachability();
if (reachability == 0)
untested += 1;
else if (reachability > 80)
good += 1;
}
int bad = relayPeers.size() - good - untested;
if (good > 0) {
Segment g = new Segment(getString(R.string.good), good);
SegmentFormatter gf = new SegmentFormatter(getResources().getColor(R.color.green));
setupSegmentFormatter(gf);
mRelayPie.addSeries(g, gf);
}
if (bad > 0) {
Segment b = new Segment(getString(R.string.unreliable), bad);
SegmentFormatter bf = new SegmentFormatter(getResources().getColor(R.color.red));
setupSegmentFormatter(bf);
mRelayPie.addSeries(b, bf);
}
if (untested > 0) {
Segment u = new Segment(getString(R.string.untested), untested);
SegmentFormatter uf = new SegmentFormatter(getResources().getColor(R.color.accent));
setupSegmentFormatter(uf);
mRelayPie.addSeries(u, uf);
}
}
mRelayPie.getBorderPaint().setColor(Color.TRANSPARENT);
mRelayPie.getBackgroundPaint().setColor(Color.TRANSPARENT);
}
use of i2p.bote.network.RelayPeer in project i2p.i2p-bote by i2p.
the class RelayPeerManager method writePeers.
private void writePeers(File file) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file.getAbsolutePath())));
writer.write("# Each line is in the format: <dest> [resp1] [resp2] ...");
writer.newLine();
writer.write("# dest = the I2P destination");
writer.newLine();
writer.write("# resp* = true or false, depending on whether the peer responded");
writer.newLine();
writer.write("# The fields are separated by a tab character.");
writer.newLine();
writer.write("# Lines starting with a # are ignored.");
writer.newLine();
writer.write("# Do not edit this file while I2P-Bote is running as it will be overwritten.");
writer.newLine();
for (RelayPeer peer : peers) {
writer.write(peer.toBase64());
for (boolean responded : peer.getAllSamples()) writer.write("\t" + responded);
writer.newLine();
}
} catch (IOException e) {
log.error("Can't write peers to file <" + file.getAbsolutePath() + ">", e);
} finally {
if (writer != null)
try {
writer.close();
} catch (IOException e) {
log.error("Can't close BufferedWriter for file <" + file.getAbsolutePath() + ">", e);
}
}
}
Aggregations