Files
i2p.i2p/apps/i2pcontrol/java/net/i2p/i2pcontrol/servlets/jsonrpc2handlers/RouterInfoHandler.java
zzz d4caafb592 Bundle I2PControl 0.12, as a console webapp
Includes mods to use org.json.simple package.
See licenses/LICENSE-Apache2.0.txt
Includes jBCrypt:
Copyright (c) 2006 Damien Miller <djm@mindrot.org>
See licenses/LICENSE-jBCrypt.txt
Includes jsonrpc2 libs:
See licenses/LICENSE-Apache2.0.txt
http://software.dzhuvinov.com/json-rpc-2.0-server.html
Jars from maven central:
jsonrpc2-base-1.38.1-sources.jar  22-Oct-2017
jsonrpc2-server-1.11-sources.jar  16-Mar-2015
2018-11-25 13:26:43 +00:00

214 lines
9.0 KiB
Java

package net.i2p.i2pcontrol.servlets.jsonrpc2handlers;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Error;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Request;
import com.thetransactioncompany.jsonrpc2.JSONRPC2Response;
import com.thetransactioncompany.jsonrpc2.server.MessageContext;
import com.thetransactioncompany.jsonrpc2.server.RequestHandler;
import net.i2p.I2PAppContext;
import net.i2p.data.router.RouterAddress;
import net.i2p.router.CommSystemFacade;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.RouterVersion;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.transport.TransportUtil;
import net.i2p.router.transport.ntcp.NTCPTransport;
import java.util.HashMap;
import java.util.Map;
/*
* Copyright 2011 hottuna (dev@robertfoss.se)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
public class RouterInfoHandler implements RequestHandler {
private final JSONRPC2Helper _helper;
private final RouterContext _context;
public RouterInfoHandler(RouterContext ctx, JSONRPC2Helper helper) {
_helper = helper;
_context = ctx;
}
// Reports the method names of the handled requests
public String[] handledRequests() {
return new String[] { "RouterInfo" };
}
// Processes the requests
public JSONRPC2Response process(JSONRPC2Request req, MessageContext ctx) {
if (req.getMethod().equals("RouterInfo")) {
return process(req);
} else {
// Method name not supported
return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND,
req.getID());
}
}
@SuppressWarnings("unchecked")
private JSONRPC2Response process(JSONRPC2Request req) {
JSONRPC2Error err = _helper.validateParams(null, req);
if (err != null)
return new JSONRPC2Response(err, req.getID());
if (_context == null) {
return new JSONRPC2Response(new JSONRPC2Error(
JSONRPC2Error.INTERNAL_ERROR.getCode(),
"RouterContext was not initialized. Query failed"),
req.getID());
}
Map<String, Object> inParams = req.getNamedParams();
Map outParams = new HashMap();
if (inParams.containsKey("i2p.router.version")) {
try {
Class rvClass = Class.forName("net.i2p.router.RouterVersion");
java.lang.reflect.Field field = rvClass.getDeclaredField("FULL_VERSION");
String fullVersion = (String) field.get(new RouterVersion());
outParams.put("i2p.router.version", fullVersion);
} catch (Exception e) {} // Ignore
}
if (inParams.containsKey("i2p.router.uptime")) {
Router router = _context.router();
if (router == null) {
outParams.put("i2p.router.uptime", 0);
} else {
outParams.put("i2p.router.uptime", router.getUptime());
}
}
if (inParams.containsKey("i2p.router.status")) {
outParams.put("i2p.router.status", _context.throttle().getTunnelStatus());
}
if (inParams.containsKey("i2p.router.net.status")) {
outParams.put("i2p.router.net.status", getNetworkStatus().ordinal());
}
if (inParams.containsKey("i2p.router.net.bw.inbound.1s")) {
outParams.put("i2p.router.net.bw.inbound.1s", _context.bandwidthLimiter().getReceiveBps());
}
if (inParams.containsKey("i2p.router.net.bw.outbound.1s")) {
outParams.put("i2p.router.net.bw.outbound.1s", _context.bandwidthLimiter().getSendBps());
}
if (inParams.containsKey("i2p.router.net.bw.inbound.15s")) {
outParams.put("i2p.router.net.bw.inbound.15s", _context.bandwidthLimiter().getReceiveBps15s());
}
if (inParams.containsKey("i2p.router.net.bw.outbound.15s")) {
outParams.put("i2p.router.net.bw.outbound.15s", _context.bandwidthLimiter().getSendBps15s());
}
if (inParams.containsKey("i2p.router.net.tunnels.participating")) {
outParams.put("i2p.router.net.tunnels.participating", _context.tunnelManager().getParticipatingCount());
}
if (inParams.containsKey("i2p.router.netdb.knownpeers")) {
// Why max(-1, 0) is used I don't know, it is the implementation used in the router console.
outParams.put("i2p.router.netdb.knownpeers", Math.max(_context.netDb().getKnownRouters() - 1, 0));
}
if (inParams.containsKey("i2p.router.netdb.activepeers")) {
outParams.put("i2p.router.netdb.activepeers", _context.commSystem().countActivePeers());
}
if (inParams.containsKey("i2p.router.netdb.fastpeers")) {
outParams.put("i2p.router.netdb.fastpeers", _context.profileOrganizer().countFastPeers());
}
if (inParams.containsKey("i2p.router.netdb.highcapacitypeers")) {
outParams.put("i2p.router.netdb.highcapacitypeers", _context.profileOrganizer().countHighCapacityPeers());
}
if (inParams.containsKey("i2p.router.netdb.isreseeding")) {
outParams.put("i2p.router.netdb.isreseeding", Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue());
}
return new JSONRPC2Response(outParams, req.getID());
}
private static enum NETWORK_STATUS {
OK,
TESTING,
FIREWALLED,
HIDDEN,
WARN_FIREWALLED_AND_FAST,
WARN_FIREWALLED_AND_FLOODFILL,
WARN_FIREWALLED_WITH_INBOUND_TCP,
WARN_FIREWALLED_WITH_UDP_DISABLED,
ERROR_I2CP,
ERROR_CLOCK_SKEW,
ERROR_PRIVATE_TCP_ADDRESS,
ERROR_SYMMETRIC_NAT,
ERROR_UDP_PORT_IN_USE,
ERROR_NO_ACTIVE_PEERS_CHECK_CONNECTION_AND_FIREWALL,
ERROR_UDP_DISABLED_AND_TCP_UNSET,
};
// Ripped out of SummaryHelper.java
private NETWORK_STATUS getNetworkStatus() {
if (_context.router().getUptime() > 60 * 1000
&& (!_context.router().gracefulShutdownInProgress())
&& !_context.clientManager().isAlive())
return (NETWORK_STATUS.ERROR_I2CP);
long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
// Display the actual skew, not the offset
if (Math.abs(skew) > 60 * 1000)
return NETWORK_STATUS.ERROR_CLOCK_SKEW;
if (_context.router().isHidden())
return (NETWORK_STATUS.HIDDEN);
int status = _context.commSystem().getStatus().getCode();
switch (status) {
case CommSystemFacade.STATUS_OK:
RouterAddress ra = _context.router().getRouterInfo().getTargetAddress("NTCP");
if (ra == null || TransportUtil.isPubliclyRoutable(ra.getIP(), true))
return NETWORK_STATUS.OK;
return NETWORK_STATUS.ERROR_PRIVATE_TCP_ADDRESS;
case CommSystemFacade.STATUS_DIFFERENT:
return NETWORK_STATUS.ERROR_SYMMETRIC_NAT;
case CommSystemFacade.STATUS_REJECT_UNSOLICITED:
if (_context.router().getRouterInfo().getTargetAddress("NTCP") != null)
return NETWORK_STATUS.WARN_FIREWALLED_WITH_INBOUND_TCP;
if (((FloodfillNetworkDatabaseFacade) _context.netDb()).floodfillEnabled())
return NETWORK_STATUS.WARN_FIREWALLED_AND_FLOODFILL;
if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
return NETWORK_STATUS.WARN_FIREWALLED_AND_FAST;
return NETWORK_STATUS.FIREWALLED;
case CommSystemFacade.STATUS_HOSED:
return NETWORK_STATUS.ERROR_UDP_PORT_IN_USE;
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
default:
ra = _context.router().getRouterInfo().getTargetAddress("SSU");
if (ra == null && _context.router().getUptime() > 5 * 60 * 1000) {
if (_context.commSystem().countActivePeers() <= 0)
return NETWORK_STATUS.ERROR_NO_ACTIVE_PEERS_CHECK_CONNECTION_AND_FIREWALL;
else if (_context.getProperty(NTCPTransport.PROP_I2NP_NTCP_HOSTNAME) == null || _context.getProperty(NTCPTransport.PROP_I2NP_NTCP_PORT) == null)
return NETWORK_STATUS.ERROR_UDP_DISABLED_AND_TCP_UNSET;
else
return NETWORK_STATUS.WARN_FIREWALLED_WITH_UDP_DISABLED;
}
return NETWORK_STATUS.TESTING;
}
}
}