Changeset 7b373743


Ignore:
Timestamp:
Mar 30, 2009 4:07:13 PM (11 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
58fc3a50
Parents:
0c98d18 (diff), e692e18d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

propagate from branch 'i2p.i2p.zzz.next' (head e89194f845a2a74dbf00f0f9e3c25a8f96ec36e4)

to branch 'i2p.i2p' (head 9cb2795f19efeae08b9ecffa5137fd944de120c7)

Files:
4 added
13 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/build.xml

    r0c98d18 r7b373743  
    1919            <classpath>
    2020                <pathelement location="../../../core/java/build/obj" />
    21                 <pathelement location="../../../router/java/build/obj" />
    2221                <pathelement location="../../ministreaming/java/build/obj" />
    2322                <pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
     
    3332            debug="true" deprecation="on" source="1.5" target="1.5"
    3433            destdir="./build/obj"
    35             classpath="../../../core/java/build/i2p.jar:../../../router/java/build/router.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" />
     34            classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" />
    3635    </target>
    3736    <target name="jar" depends="builddep, compile">
  • apps/i2psnark/java/src/org/klomp/snark/Snark.java

    r0c98d18 r7b373743  
    3737
    3838import net.i2p.I2PAppContext;
    39 import net.i2p.router.client.ClientManagerFacadeImpl;
    4039import net.i2p.client.streaming.I2PServerSocket;
    4140import net.i2p.data.Destination;
     
    262261               StorageListener slistener, boolean start, String rootDir) {
    263262    this(new I2PSnarkUtil(ctx), torrent, null, -1, slistener, null, null, null, null, false, rootDir);
    264     String host = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_HOST);
     263    String host = opts.getProperty("i2cp.hostname");
    265264    int port = 0;
    266     String s = opts.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_PORT);
     265    String s = opts.getProperty("i2cp.port");
    267266    if (s != null) {
    268267        try {
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r0c98d18 r7b373743  
    1919import net.i2p.data.Base64;
    2020import net.i2p.data.DataHelper;
    21 import net.i2p.router.RouterContext;
    2221import net.i2p.util.I2PAppThread;
    2322import net.i2p.util.Log;
     
    148147        if (!_config.containsKey(PROP_UPLOADERS_TOTAL))
    149148            _config.setProperty(PROP_UPLOADERS_TOTAL, "" + Snark.MAX_TOTAL_UPLOADERS);
    150         if (!_config.containsKey(PROP_UPBW_MAX)) {
    151             try {
    152                 if (_context instanceof RouterContext)
    153                     _config.setProperty(PROP_UPBW_MAX, "" + (((RouterContext)_context).bandwidthLimiter().getOutboundKBytesPerSecond() / 2));
    154                 else
    155                     _config.setProperty(PROP_UPBW_MAX, "" + DEFAULT_MAX_UP_BW);
    156             } catch (NoClassDefFoundError ncdfe) {
    157                 _config.setProperty(PROP_UPBW_MAX, "" + DEFAULT_MAX_UP_BW);
    158             }
    159         }
    160149        if (!_config.containsKey(PROP_DIR))
    161150            _config.setProperty(PROP_DIR, "i2psnark");
     
    163152            _config.setProperty(PROP_AUTO_START, DEFAULT_AUTO_START);
    164153        updateConfig();
     154    }
     155
     156    /** call from DirMonitor since loadConfig() is called before router I2CP is up */
     157    private void getBWLimit() {
     158        if (!_config.containsKey(PROP_UPBW_MAX)) {
     159            int[] limits = BWLimits.getBWLimits(_util.getI2CPHost(), _util.getI2CPPort());
     160            if (limits != null && limits[1] > 0)
     161                _util.setMaxUpBW(limits[1]);
     162        }
    165163    }
    166164   
     
    620618            }
    621619
     620            // here because we need to delay until I2CP is up
     621            // although the user will see the default until then
     622            getBWLimit();
    622623            while (true) {
    623624                File dir = getDataDir();
  • core/java/src/net/i2p/client/I2PSession.java

    r0c98d18 r7b373743  
    144144    public Destination lookupDest(Hash h) throws I2PSessionException;
    145145
     146    /**
     147     * Get the current bandwidth limits
     148     */
     149    public int[] bandwidthLimits() throws I2PSessionException;
     150
    146151    /** See I2PSessionMuxedImpl for details */
    147152    public void addSessionListener(I2PSessionListener lsnr, int proto, int port);
  • core/java/src/net/i2p/client/I2PSessionImpl.java

    r0c98d18 r7b373743  
    657657    }
    658658
     659    public int[] bandwidthLimits() throws I2PSessionException {
     660        return null;
     661    }
     662
    659663    protected void updateActivity() {
    660664        _lastActivity = _context.clock().now();
  • core/java/src/net/i2p/client/I2PSimpleSession.java

    r0c98d18 r7b373743  
    1818import net.i2p.data.Destination;
    1919import net.i2p.data.Hash;
     20import net.i2p.data.i2cp.BandwidthLimitsMessage;
    2021import net.i2p.data.i2cp.DestLookupMessage;
    2122import net.i2p.data.i2cp.DestReplyMessage;
     23import net.i2p.data.i2cp.GetBandwidthLimitsMessage;
    2224import net.i2p.data.i2cp.I2CPMessageReader;
    2325import net.i2p.util.I2PThread;
     
    2527
    2628/**
    27  * Create a new session for doing naming queries only. Do not create a Destination.
     29 * Create a new session for doing naming and bandwidth queries only. Do not create a Destination.
    2830 * Don't create a producer. Do not send/receive messages to other Destinations.
    2931 * Cannot handle multiple simultaneous queries atm.
    3032 * Could be expanded to ask the router other things.
     33 *
     34 * @author zzz
    3135 */
    3236class I2PSimpleSession extends I2PSessionImpl2 {
     
    3438    private Object _destReceivedLock;
    3539    private Destination _destination;
     40    private boolean _bwReceived;
     41    private Object _bwReceivedLock;
     42    private int[] _bwLimits;
    3643
    3744    /**
    38      * Create a new session for doing naming queries only. Do not create a destination.
     45     * Create a new session for doing naming and bandwidth queries only. Do not create a destination.
    3946     *
    4047     * @throws I2PSessionException if there is a problem
     
    95102    }
    96103
     104    void bwReceived(int[] i) {
     105        _bwReceived = true;
     106        _bwLimits = i;
     107        synchronized (_bwReceivedLock) {
     108            _bwReceivedLock.notifyAll();
     109        }
     110    }
     111
    97112    public Destination lookupDest(Hash h) throws I2PSessionException {
    98113        if (_closed)
     
    111126    }
    112127
     128    public int[] bandwidthLimits() throws I2PSessionException {
     129        if (_closed)
     130            return null;
     131        _bwReceivedLock = new Object();
     132        sendMessage(new GetBandwidthLimitsMessage());
     133        for (int i = 0; i < 5 && !_bwReceived; i++) {
     134            try {
     135                synchronized (_bwReceivedLock) {
     136                    _bwReceivedLock.wait(1000);
     137                }
     138            } catch (InterruptedException ie) {}
     139        }
     140        _bwReceived = false;
     141        return _bwLimits;
     142    }
     143
    113144    /**
    114145     * Only map message handlers that we will use
     
    116147    class SimpleMessageHandlerMap extends I2PClientMessageHandlerMap {
    117148        public SimpleMessageHandlerMap(I2PAppContext context) {
    118             int highest = DestReplyMessage.MESSAGE_TYPE;
     149            int highest = Math.max(DestReplyMessage.MESSAGE_TYPE, BandwidthLimitsMessage.MESSAGE_TYPE);
    119150            _handlers = new I2CPMessageHandler[highest+1];
    120151            _handlers[DestReplyMessage.MESSAGE_TYPE] = new DestReplyMessageHandler(context);
     152            _handlers[BandwidthLimitsMessage.MESSAGE_TYPE] = new BWLimitsMessageHandler(context);
    121153        }
    122154    }
  • core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java

    r0c98d18 r7b373743  
    9595        case DestReplyMessage.MESSAGE_TYPE:
    9696            return new DestReplyMessage();
     97        case GetBandwidthLimitsMessage.MESSAGE_TYPE:
     98            return new GetBandwidthLimitsMessage();
     99        case BandwidthLimitsMessage.MESSAGE_TYPE:
     100            return new BandwidthLimitsMessage();
    97101        default:
    98102            throw new I2CPMessageException("The type " + type + " is an unknown I2CP message");
  • router/java/src/net/i2p/router/DummyTunnelManagerFacade.java

    r0c98d18 r7b373743  
    1111import java.io.IOException;
    1212import java.io.Writer;
     13import java.util.Set;
    1314
    1415import net.i2p.data.Destination;
     
    4546    public void setOutboundSettings(Hash client, TunnelPoolSettings settings) {}
    4647    public int getInboundBuildQueueSize() { return 0; }
     48    public Set<Hash> selectPeersInTooManyTunnels() { return null; }
    4749   
    4850    public void renderStatusHTML(Writer out) throws IOException {}
  • router/java/src/net/i2p/router/TunnelManagerFacade.java

    r0c98d18 r7b373743  
    1111import java.io.IOException;
    1212import java.io.Writer;
     13import java.util.Set;
    1314
    1415import net.i2p.data.Destination;
     
    6364    public int getInboundBuildQueueSize();
    6465   
     66    /** @return Set of peers that should not be allowed to be in another tunnel */
     67    public Set<Hash> selectPeersInTooManyTunnels();
     68
    6569    /**
    6670     * the client connected (or updated their settings), so make sure we have
  • router/java/src/net/i2p/router/client/ClientMessageEventListener.java

    r0c98d18 r7b373743  
    1212
    1313import net.i2p.data.Payload;
     14import net.i2p.data.i2cp.BandwidthLimitsMessage;
    1415import net.i2p.data.i2cp.CreateLeaseSetMessage;
    1516import net.i2p.data.i2cp.CreateSessionMessage;
    1617import net.i2p.data.i2cp.DestLookupMessage;
    1718import net.i2p.data.i2cp.DestroySessionMessage;
     19import net.i2p.data.i2cp.GetBandwidthLimitsMessage;
    1820import net.i2p.data.i2cp.GetDateMessage;
    1921import net.i2p.data.i2cp.I2CPMessage;
     
    9496                handleReconfigureSession(reader, (ReconfigureSessionMessage)message);
    9597                break;
     98            case GetBandwidthLimitsMessage.MESSAGE_TYPE:
     99                handleGetBWLimits(reader, (GetBandwidthLimitsMessage)message);
     100                break;
    96101            default:
    97102                if (_log.shouldLog(Log.ERROR))
     
    275280    }
    276281
     282    /**
     283     * Divide router limit by 1.75 for overhead.
     284     * This could someday give a different answer to each client.
     285     * But it's not enforced anywhere.
     286     */
     287    private void handleGetBWLimits(I2CPMessageReader reader, GetBandwidthLimitsMessage message) {
     288        if (_log.shouldLog(Log.INFO))
     289            _log.info("Got BW Limits request");
     290        int in = _context.bandwidthLimiter().getInboundKBytesPerSecond() * 4 / 7;
     291        int out = _context.bandwidthLimiter().getOutboundKBytesPerSecond() * 4 / 7;
     292        BandwidthLimitsMessage msg = new BandwidthLimitsMessage(in, out);
     293        try {
     294            _runner.doSend(msg);
     295        } catch (I2CPMessageException ime) {
     296            _log.error("Error writing out the session status message", ime);
     297        }
     298    }
     299
    277300    // this *should* be mod 65536, but UnsignedInteger is still b0rked.  FIXME
    278301    private final static int MAX_SESSION_ID = 32767;
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPeerSelector.java

    r0c98d18 r7b373743  
    177177        Set peers = new HashSet(1);
    178178        peers.addAll(ctx.profileOrganizer().selectPeersRecentlyRejecting());
     179        peers.addAll(ctx.tunnelManager().selectPeersInTooManyTunnels());
    179180        // if (false && filterUnreachable(ctx, isInbound, isExploratory)) {
    180181        if (filterUnreachable(ctx, isInbound, isExploratory)) {
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java

    r0c98d18 r7b373743  
    2929    private Log _log;
    3030    private TunnelPoolSettings _settings;
    31     private ArrayList _tunnels;
     31    private ArrayList<TunnelInfo> _tunnels;
    3232    private TunnelPeerSelector _peerSelector;
    3333    private TunnelPoolManager _manager;
     
    228228     * @return list of TunnelInfo objects
    229229     */
    230     public List listTunnels() {
     230    public List<TunnelInfo> listTunnels() {
    231231        synchronized (_tunnels) {
    232232            return new ArrayList(_tunnels);
  • router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java

    r0c98d18 r7b373743  
    77import java.util.Comparator;
    88import java.util.HashMap;
     9import java.util.HashSet;
    910import java.util.Iterator;
    1011import java.util.List;
    1112import java.util.Map;
     13import java.util.Set;
     14import java.util.concurrent.ConcurrentHashMap;
    1215
    1316import net.i2p.data.DataHelper;
     
    507510        out.write("Inactive participating tunnels: " + inactive + "<br />\n");
    508511        out.write("Lifetime bandwidth usage: " + DataHelper.formatSize(processed*1024) + "B<br />\n");
     512        renderPeers(out);
    509513    }
    510514   
     
    580584    }
    581585   
     586    private void renderPeers(Writer out) throws IOException {
     587        // count up the peers in the local pools
     588        HashCounter lc = new HashCounter();
     589        int tunnelCount = countTunnelsPerPeer(lc);
     590
     591        // count up the peers in the participating tunnels
     592        HashCounter pc = new HashCounter();
     593        int partCount = countParticipatingPerPeer(pc);
     594
     595        Set<Hash> peers = new HashSet(lc.hashes());
     596        peers.addAll(pc.hashes());
     597        List<Hash> peerList = new ArrayList(peers);
     598        Collections.sort(peerList, new HashComparator());
     599
     600        out.write("<h2><a name=\"peers\">Tunnel Counts By Peer</a>:</h2>\n");
     601        out.write("<table border=\"1\"><tr><td><b>Peer</b></td><td><b>Expl. + Client</b></td><td><b>% of total</b></td><td><b>Part. from + to</b></td><td><b>% of total</b></td></tr>\n");
     602        for (Hash h : peerList) {
     603             out.write("<tr><td>");
     604             out.write(netDbLink(h));
     605             out.write("<td align=\"right\">" + lc.count(h));
     606             out.write("<td align=\"right\">");
     607             if (tunnelCount > 0)
     608                 out.write("" + (lc.count(h) * 100 / tunnelCount));
     609             else
     610                 out.write('0');
     611             out.write("<td align=\"right\">" + pc.count(h));
     612             out.write("<td align=\"right\">");
     613             if (partCount > 0)
     614                 out.write("" + (pc.count(h) * 100 / partCount));
     615             else
     616                 out.write('0');
     617             out.write('\n');
     618        }
     619        out.write("<tr><td>Tunnels<td align=\"right\">" + tunnelCount);
     620        out.write("<td>&nbsp;<td align=\"right\">" + partCount);
     621        out.write("<td>&nbsp;</table>\n");
     622    }
     623
     624    /** @return total number of non-fallback expl. + client tunnels */
     625    private int countTunnelsPerPeer(HashCounter lc) {
     626        List<TunnelPool> pools = new ArrayList();
     627        listPools(pools);
     628        int tunnelCount = 0;
     629        for (TunnelPool tp : pools) {
     630            for (TunnelInfo info : tp.listTunnels()) {
     631                if (info.getLength() > 1) {
     632                    tunnelCount++;
     633                    for (int j = 0; j < info.getLength(); j++) {
     634                        Hash peer = info.getPeer(j);
     635                        if (!_context.routerHash().equals(peer))
     636                            lc.increment(peer);
     637                    }
     638                }
     639            }
     640        }
     641        return tunnelCount;
     642    }
     643
     644    private static final int DEFAULT_MAX_PCT_TUNNELS = 33;
     645    /**
     646     *  For reliability reasons, don't allow a peer in more than x% of
     647     *  client and exploratory tunnels.
     648     *
     649     *  This also will prevent a single huge-capacity (or malicious) peer from
     650     *  taking all the tunnels in the network (although it would be nice to limit
     651     *  the % of total network tunnels to 10% or so, but that appears to be
     652     *  too low to set as a default here... much lower than 33% will push client
     653     *  tunnels out of the fast tier into high cap or beyond...)
     654     *
     655     *  Possible improvement - restrict based on count per IP, or IP block,
     656     *  to slightly increase costs of collusion
     657     *
     658     *  @return Set of peers that should not be allowed in another tunnel
     659     */
     660    public Set<Hash> selectPeersInTooManyTunnels() {
     661        HashCounter lc = new HashCounter();
     662        int tunnelCount = countTunnelsPerPeer(lc);
     663        Set<Hash> rv = new HashSet();
     664        if (tunnelCount >= 4 && _context.router().getUptime() > 10*60*1000) {
     665            int max = _context.getProperty("router.maxTunnelPercentage", DEFAULT_MAX_PCT_TUNNELS);
     666            for (Hash h : lc.hashes()) {
     667                 if (lc.count(h) > 0 && (lc.count(h) + 1) * 100 / (tunnelCount + 1) > max)
     668                     rv.add(h);
     669            }
     670        }
     671        return rv;
     672    }
     673
     674    /** @return total number of part. tunnels */
     675    private int countParticipatingPerPeer(HashCounter pc) {
     676        List<HopConfig> participating = _context.tunnelDispatcher().listParticipatingTunnels();
     677        for (HopConfig cfg : participating) {
     678            Hash from = cfg.getReceiveFrom();
     679            if (from != null)
     680                pc.increment(from);
     681            Hash to = cfg.getSendTo();
     682            if (to != null)
     683                pc.increment(to);
     684        }
     685        return participating.size();
     686    }
     687
     688    class HashComparator implements Comparator {
     689         public int compare(Object l, Object r) {
     690             return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
     691        }
     692    }
     693
     694    private static class HashCounter {
     695        private ConcurrentHashMap<Hash, Integer> _map;
     696        public HashCounter() {
     697            _map = new ConcurrentHashMap();
     698        }
     699        public void increment(Hash h) {
     700            Integer i = _map.putIfAbsent(h, Integer.valueOf(1));
     701            if (i != null)
     702                _map.put(h, Integer.valueOf(i.intValue() + 1));
     703        }
     704        public int count(Hash h) {
     705            Integer i = _map.get(h);
     706            if (i != null)
     707                return i.intValue();
     708            return 0;
     709        }
     710        public Set<Hash> hashes() {
     711            return _map.keySet();
     712        }
     713    }
     714
    582715    private String getCapacity(Hash peer) {
    583716        RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
Note: See TracChangeset for help on using the changeset viewer.