Changeset b41e714a


Ignore:
Timestamp:
Oct 13, 2010 4:07:33 PM (9 years ago)
Author:
z3d <z3d@…>
Branches:
master
Children:
8db45ff
Parents:
5a782cc (diff), 772c1d4 (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:

merge of '0738aeef8a1d4e9ca82dc5ba0077d83a57c47f81'

and '9625ea3e96d57df74bc62018bf64230a22c49ce0'

Files:
3 added
146 edited

Legend:

Unmodified
Added
Removed
  • apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java

    r5a782cc rb41e714a  
    2626import java.io.File;
    2727import java.io.FileInputStream;
    28 import java.io.FileWriter;
    2928import java.io.IOException;
    3029import java.io.InputStreamReader;
     30import java.io.OutputStreamWriter;
    3131import java.io.StringReader;
    3232import java.util.HashMap;
     
    3535import java.util.List;
    3636import java.util.Map;
     37
     38import net.i2p.util.SecureFileOutputStream;
    3739
    3840/**
     
    278280    public static void write(Map map, File file) throws IOException {
    279281        ConfigParser
    280                 .write(map, new BufferedWriter(new FileWriter(file, false)));
     282                .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
    281283    }
    282284
     
    317319            throws IOException {
    318320        ConfigParser.writeSubscriptions(list, new BufferedWriter(
    319                 new FileWriter(file, false)));
     321                new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
    320322    }
    321323
  • apps/addressbook/java/src/net/i2p/addressbook/Daemon.java

    r5a782cc rb41e714a  
    3030
    3131import net.i2p.I2PAppContext;
     32import net.i2p.util.SecureDirectory;
    3233
    3334/**
     
    132133        File homeFile;
    133134        if (args.length > 0) {
    134             homeFile = new File(args[0]);
     135            homeFile = new SecureDirectory(args[0]);
    135136            if (!homeFile.isAbsolute())
    136                 homeFile = new File(I2PAppContext.getGlobalContext().getRouterDir(), args[0]);
     137                homeFile = new SecureDirectory(I2PAppContext.getGlobalContext().getRouterDir(), args[0]);
    137138        } else {
    138             homeFile = new File(System.getProperty("user.dir"));
     139            homeFile = new SecureDirectory(System.getProperty("user.dir"));
    139140        }
    140141       
  • apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java

    r5a782cc rb41e714a  
    2727import net.i2p.util.FileUtil;
    2828import net.i2p.util.Log;
     29import net.i2p.util.SecureDirectory;
    2930import net.i2p.util.SimpleScheduler;
    3031import net.i2p.util.SimpleTimer;
     
    7879        // so it must be available even if not connected to I2CP.
    7980        // so much for multiple instances
    80         _tmpDir = new File(ctx.getTempDir(), "i2psnark");
     81        _tmpDir = new SecureDirectory(ctx.getTempDir(), "i2psnark");
    8182        FileUtil.rmdir(_tmpDir, false);
    8283        _tmpDir.mkdirs();
     
    197198    /** connect to the given destination */
    198199    I2PSocket connect(PeerID peer) throws IOException {
    199         Hash dest = peer.getAddress().calculateHash();
     200        Destination addr = peer.getAddress();
     201        if (addr == null)
     202            throw new IOException("Null address");
     203        Hash dest = addr.calculateHash();
    200204        if (_shitlist.contains(dest))
    201205            throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are shitlisted");
    202206        try {
    203             I2PSocket rv = _manager.connect(peer.getAddress());
     207            I2PSocket rv = _manager.connect(addr);
    204208            if (rv != null)
    205209                _shitlist.remove(dest);
     
    225229    public File get(String url, int retries) { return get(url, true, retries); }
    226230    public File get(String url, boolean rewrite, int retries) {
    227         _log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
     231        if (_log.shouldLog(Log.DEBUG))
     232            _log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
    228233        File out = null;
    229234        try {
     
    249254        EepGet get = new I2PSocketEepGet(_context, _manager, retries, out.getAbsolutePath(), fetchURL);
    250255        if (get.fetch()) {
    251             _log.debug("Fetch successful [" + url + "]: size=" + out.length());
     256            if (_log.shouldLog(Log.DEBUG))
     257                _log.debug("Fetch successful [" + url + "]: size=" + out.length());
    252258            return out;
    253259        } else {
    254             _log.warn("Fetch failed [" + url + "]");
     260            if (_log.shouldLog(Log.WARN))
     261                _log.warn("Fetch failed [" + url + "]");
    255262            out.delete();
    256263            return null;
  • apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java

    r5a782cc rb41e714a  
    110110  public MetaInfo(Map m) throws InvalidBEncodingException
    111111  {
    112     _log.debug("Creating a metaInfo: " + m, new Exception("source"));
     112    if (_log.shouldLog(Log.DEBUG))
     113        _log.debug("Creating a metaInfo: " + m, new Exception("source"));
    113114    BEValue val = (BEValue)m.get("announce");
    114115    if (val == null)
     
    447448            buf.append(val.toString());
    448449    }
    449     _log.debug(buf.toString());
     450    if (_log.shouldLog(Log.DEBUG))
     451        _log.debug(buf.toString());
    450452    byte[] infoBytes = BEncoder.bencode(info);
    451453    //_log.debug("info bencoded: [" + Base64.encode(infoBytes, true) + "]");
     
    454456        MessageDigest digest = MessageDigest.getInstance("SHA");
    455457        byte hash[] = digest.digest(infoBytes);
    456         _log.debug("info hash: [" + net.i2p.data.Base64.encode(hash) + "]");
     458        if (_log.shouldLog(Log.DEBUG))
     459            _log.debug("info hash: [" + net.i2p.data.Base64.encode(hash) + "]");
    457460        return hash;
    458461      }
  • apps/i2psnark/java/src/org/klomp/snark/Peer.java

    r5a782cc rb41e714a  
    9393    this.peerID = new PeerID(id, sock.getPeerDestination());
    9494    _id = ++__id;
    95     _log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating " + _id));
     95    if (_log.shouldLog(Log.DEBUG))
     96        _log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating " + _id));
    9697  }
    9798
     
    130131  public int hashCode()
    131132  {
    132     return peerID.hashCode() ^ (2 << _id);
     133    return peerID.hashCode() ^ (7777 * (int)_id);
    133134  }
    134135
     
    151152  /**
    152153   * Compares the PeerIDs.
     154   * @deprecated unused?
    153155   */
    154156  public int compareTo(Object o)
     
    182184      throw new IllegalStateException("Peer already started");
    183185
    184     _log.debug("Running connection to " + peerID.getAddress().calculateHash().toBase64(), new Exception("connecting"));   
     186    if (_log.shouldLog(Log.DEBUG))
     187        _log.debug("Running connection to " + peerID.getAddress().calculateHash().toBase64(), new Exception("connecting"));   
    185188    try
    186189      {
     
    189192          {
    190193            sock = util.connect(peerID);
    191             _log.debug("Connected to " + peerID + ": " + sock);
     194            if (_log.shouldLog(Log.DEBUG))
     195                _log.debug("Connected to " + peerID + ": " + sock);
    192196            if ((sock == null) || (sock.isClosed())) {
    193197                throw new IOException("Unable to reach " + peerID);
     
    208212            byte [] id = handshake(in, out); //handshake(bis, bos);
    209213            byte [] expected_id = peerID.getID();
    210             if (!Arrays.equals(expected_id, id))
    211               throw new IOException("Unexpected peerID '"
     214            if (expected_id == null) {
     215                peerID.setID(id);
     216            } else if (Arrays.equals(expected_id, id)) {
     217                if (_log.shouldLog(Log.DEBUG))
     218                    _log.debug("Handshake got matching IDs with " + toString());
     219            } else {
     220                throw new IOException("Unexpected peerID '"
    212221                                    + PeerID.idencode(id)
    213222                                    + "' expected '"
    214223                                    + PeerID.idencode(expected_id) + "'");
    215             _log.debug("Handshake got matching IDs with " + toString());
     224            }
    216225          } else {
    217             _log.debug("Already have din [" + sock + "] with " + toString());
     226            if (_log.shouldLog(Log.DEBUG))
     227                _log.debug("Already have din [" + sock + "] with " + toString());
    218228          }
    219229       
     
    230240        listener.connected(this);
    231241 
    232         _log.debug("Start running the reader with " + toString());
     242        if (_log.shouldLog(Log.DEBUG))
     243            _log.debug("Start running the reader with " + toString());
    233244        // Use this thread for running the incomming connection.
    234245        // The outgoing connection creates its own Thread.
     
    280291    dout.flush();
    281292   
    282     _log.debug("Wrote my shared hash and ID to " + toString());
     293    if (_log.shouldLog(Log.DEBUG))
     294        _log.debug("Wrote my shared hash and ID to " + toString());
    283295   
    284296    // Handshake read - header
     
    307319    // Handshake read - peer id
    308320    din.readFully(bs);
    309     _log.debug("Read the remote side's hash and peerID fully from " + toString());
     321    if (_log.shouldLog(Log.DEBUG))
     322        _log.debug("Read the remote side's hash and peerID fully from " + toString());
    310323    return bs;
    311324  }
  • apps/i2psnark/java/src/org/klomp/snark/PeerAcceptor.java

    r5a782cc rb41e714a  
    7777        try {
    7878          peerInfoHash = readHash(in);
    79           _log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
    80                     + ": " + Base64.encode(peerInfoHash));
     79          if (_log.shouldLog(Log.INFO))
     80              _log.info("infohash read from " + socket.getPeerDestination().calculateHash().toBase64()
     81                        + ": " + Base64.encode(peerInfoHash));
    8182        } catch (IOException ioe) {
    82             _log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
     83            if (_log.shouldLog(Log.INFO))
     84                _log.info("Unable to read the infohash from " + socket.getPeerDestination().calculateHash().toBase64());
    8385            throw ioe;
    8486        }
  • apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java

    r5a782cc rb41e714a  
    376376    if (need_more)
    377377      {
    378         _log.debug("Adding a peer " + peer.getPeerID().getAddress().calculateHash().toBase64() + " for " + metainfo.getName(), new Exception("add/run"));
     378        if (_log.shouldLog(Log.DEBUG))
     379            _log.debug("Adding a peer " + peer.getPeerID().toString() + " for " + metainfo.getName(), new Exception("add/run"));
    379380
    380381        // Run the peer with us as listener and the current bitfield.
  • apps/i2psnark/java/src/org/klomp/snark/PeerID.java

    r5a782cc rb41e714a  
    2525import java.util.Map;
    2626
     27import net.i2p.I2PAppContext;
     28import net.i2p.data.Base32;
    2729import net.i2p.data.Base64;
     30import net.i2p.data.DataHelper;
    2831import net.i2p.data.Destination;
    2932
     
    3235import org.klomp.snark.bencode.InvalidBEncodingException;
    3336
     37/**
     38 *  Store the address information about a peer.
     39 *  Prior to 0.8.1, an instantiation required a peer ID, and full Destination address.
     40 *  Starting with 0.8.1, to support compact tracker responses,
     41 *  a PeerID can be instantiated with a Destination Hash alone.
     42 *  The full destination lookup is deferred until getAddress() is called,
     43 *  and the PeerID is not required.
     44 *  Equality is now determined solely by the dest hash.
     45 */
    3446public class PeerID implements Comparable
    3547{
    36   private final byte[] id;
    37   private final Destination address;
     48  private byte[] id;
     49  private Destination address;
    3850  private final int port;
    39 
     51  private byte[] destHash;
     52  /** whether we have tried to get the dest from the hash - only do once */
     53  private boolean triedDestLookup;
    4054  private final int hash;
    4155
     
    4559    this.address = address;
    4660    this.port = 6881;
    47 
     61    this.destHash = address.calculateHash().getData();
    4862    hash = calculateHash();
    4963  }
     
    7892
    7993    port = 6881;
    80 
     94    this.destHash = address.calculateHash().getData();
    8195    hash = calculateHash();
    8296  }
    8397
     98  /**
     99   * Creates a PeerID from a destHash
     100   * @since 0.8.1
     101   */
     102  public PeerID(byte[] dest_hash) throws InvalidBEncodingException
     103  {
     104    // id and address remain null
     105    port = 6881;
     106    if (dest_hash.length != 32)
     107        throw new InvalidBEncodingException("bad hash length");
     108    destHash = dest_hash;
     109    hash = DataHelper.hashCode(dest_hash);
     110  }
     111
    84112  public byte[] getID()
    85113  {
     
    87115  }
    88116
    89   public Destination getAddress()
    90   {
     117  /** for connecting out to peer based on desthash @since 0.8.1 */
     118  public void setID(byte[] xid)
     119  {
     120    id = xid;
     121  }
     122
     123  /**
     124   *  Get the destination.
     125   *  If this PeerId was instantiated with a destHash,
     126   *  and we have not yet done so, lookup the full destination, which may take
     127   *  up to 10 seconds.
     128   *  @return Dest or null if unknown
     129   */
     130  public synchronized Destination getAddress()
     131  {
     132    if (address == null && destHash != null && !triedDestLookup) {
     133        String b32 = Base32.encode(destHash) + ".b32.i2p";
     134        address = I2PAppContext.getGlobalContext().namingService().lookup(b32);
     135        triedDestLookup = true;
     136    }
    91137    return address;
    92138  }
     
    97143  }
    98144
     145  /** @since 0.8.1 */
     146  public byte[] getDestHash()
     147  {
     148    return destHash;
     149  }
     150
    99151  private int calculateHash()
    100152  {
    101     int b = 0;
    102     for (int i = 0; i < id.length; i++)
    103       b ^= id[i];
    104     return (b ^ address.hashCode()) ^ port;
    105   }
    106 
    107   /**
    108    * The hash code of a PeerID is the exclusive or of all id bytes.
     153    return DataHelper.hashCode(destHash);
     154  }
     155
     156  /**
     157   * The hash code of a PeerID is the hashcode of the desthash
    109158   */
    110159    @Override
     
    116165  /**
    117166   * Returns true if and only if this peerID and the given peerID have
    118    * the same 20 bytes as ID.
     167   * the same destination hash
    119168   */
    120169  public boolean sameID(PeerID pid)
    121170  {
    122     boolean equal = true;
    123     for (int i = 0; equal && i < id.length; i++)
    124       equal = id[i] == pid.id[i];
    125     return equal;
    126   }
    127 
    128   /**
    129    * Two PeerIDs are equal when they have the same id, address and port.
     171    return DataHelper.eq(destHash, pid.getDestHash());
     172  }
     173
     174  /**
     175   * Two PeerIDs are equal when they have the same dest hash
    130176   */
    131177    @Override
     
    136182        PeerID pid = (PeerID)o;
    137183
    138         return port == pid.port
    139           && address.equals(pid.address)
    140           && sameID(pid);
     184        return sameID(pid);
    141185      }
    142186    else
     
    146190  /**
    147191   * Compares port, address and id.
     192   * @deprecated unused? and will NPE now that address can be null?
    148193   */
    149194  public int compareTo(Object o)
     
    177222  public String toString()
    178223  {
     224    if (id == null || address == null)
     225        return "unkn@" + Base64.encode(destHash).substring(0, 6);
    179226    int nonZero = 0;
    180227    for (int i = 0; i < id.length; i++) {
  • apps/i2psnark/java/src/org/klomp/snark/Snark.java

    r5a782cc rb41e714a  
    438438                ioee.printStackTrace();
    439439            }
    440             fatal("Could not create storage", ioe);
     440            fatal("Could not check or create storage", ioe);
    441441          }
    442442      }
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r5a782cc rb41e714a  
    2222import net.i2p.util.Log;
    2323import net.i2p.util.OrderedProperties;
     24import net.i2p.util.SecureDirectory;
    2425
    2526/**
     
    131132    public File getDataDir() {
    132133        String dir = _config.getProperty(PROP_DIR, "i2psnark");
    133         File f = new File(dir);
     134        File f = new SecureDirectory(dir);
    134135        if (!f.isAbsolute())
    135             f = new File(_context.getAppDir(), dir);
     136            f = new SecureDirectory(_context.getAppDir(), dir);
    136137        return f;
    137138    }
     
    202203        if (i2cpHost != null) {
    203204            _util.setI2CPConfig(i2cpHost, i2cpPort, i2cpOpts);
    204             _log.debug("Configuring with I2CP options " + i2cpOpts);
     205            if (_log.shouldLog(Log.DEBUG))
     206                _log.debug("Configuring with I2CP options " + i2cpOpts);
    205207        }
    206208        //I2PSnarkUtil.instance().setI2CPConfig("66.111.51.110", 7654, new Properties());
     
    332334                    _util.setI2CPConfig(i2cpHost, port, p);
    333335                    addMessage(_("I2CP and tunnel changes will take effect after stopping all torrents"));
    334                     _log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
    335                                + "] oldOpts [" + oldOpts + "]");
     336                    if (_log.shouldLog(Log.DEBUG))
     337                        _log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
     338                                   + "] oldOpts [" + oldOpts + "]");
    336339                } else {
    337340                    if (_util.connected()) {
     
    440443    }
    441444
     445    /** @throws RuntimeException via Snark.fatal() */
    442446    public void addTorrent(String filename) { addTorrent(filename, false); }
     447
     448    /** @throws RuntimeException via Snark.fatal() */
    443449    public void addTorrent(String filename, boolean dontAutoStart) {
    444450        if ((!dontAutoStart) && !_util.connected()) {
     
    712718            while (true) {
    713719                File dir = getDataDir();
    714                 _log.debug("Directory Monitor loop over " + dir.getAbsolutePath());
     720                if (_log.shouldLog(Log.DEBUG))
     721                    _log.debug("Directory Monitor loop over " + dir.getAbsolutePath());
    715722                try {
    716723                    monitorTorrents(dir);
     
    725732    /** two listeners */
    726733    public void torrentComplete(Snark snark) {
    727         File f = new File(snark.torrent);
     734        StringBuilder buf = new StringBuilder(256);
     735        buf.append("<a href=\"/i2psnark/").append(snark.storage.getBaseName());
     736        if (snark.meta.getFiles() != null)
     737            buf.append('/');
     738        buf.append("\">").append(snark.storage.getBaseName()).append("</a>");
    728739        long len = snark.meta.getTotalLength();
    729         addMessage(_("Download finished: \"{0}\"", f.getName()) + " (" + _("size: {0}B", DataHelper.formatSize2(len)) + ')');
     740        addMessage(_("Download finished: {0}", buf.toString()) + " (" + _("size: {0}B", DataHelper.formatSize2(len)) + ')');
    730741        updateStatus(snark);
    731742    }
     
    737748    private void monitorTorrents(File dir) {
    738749        String fileNames[] = dir.list(TorrentFilenameFilter.instance());
    739         List foundNames = new ArrayList(0);
     750        List<String> foundNames = new ArrayList(0);
    740751        if (fileNames != null) {
    741752            for (int i = 0; i < fileNames.length; i++) {
     
    748759        }
    749760       
    750         Set existingNames = listTorrentFiles();
     761        Set<String> existingNames = listTorrentFiles();
    751762        // lets find new ones first...
    752763        for (int i = 0; i < foundNames.size(); i++) {
     
    756767                if (shouldAutoStart() && !_util.connect())
    757768                    addMessage(_("Unable to connect to I2P!"));
    758                 addTorrent((String)foundNames.get(i), !shouldAutoStart());
     769                try {
     770                    // Snark.fatal() throws a RuntimeException
     771                    // don't let one bad torrent kill the whole loop
     772                    addTorrent(foundNames.get(i), !shouldAutoStart());
     773                } catch (Exception e) {
     774                    addMessage(_("Unable to add {0}", foundNames.get(i)) + ": " + e);
     775                }
    759776            }
    760777        }
     
    766783            } else {
    767784                // known, but removed.  drop it
    768                 stopTorrent(name, true);
     785                try {
     786                    // Snark.fatal() throws a RuntimeException
     787                    // don't let one bad torrent kill the whole loop
     788                    stopTorrent(name, true);
     789                } catch (Exception e) {
     790                    // don't bother with message
     791                }
    769792            }
    770793        }
  • apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java

    r5a782cc rb41e714a  
    358358      + "&downloaded=" + downloaded
    359359      + "&left=" + left
     360      + "&compact"
    360361      + ((! event.equals(NO_EVENT)) ? ("&event=" + event) : "");
    361362    if (left <= 0 || event.equals(STOPPED_EVENT) || !coordinator.needPeers())
  • apps/i2psnark/java/src/org/klomp/snark/TrackerInfo.java

    r5a782cc rb41e714a  
    2525import java.util.HashSet;
    2626import java.util.Collections;
    27 import java.util.Iterator;
    2827import java.util.List;
    2928import java.util.Map;
     
    3433import org.klomp.snark.bencode.InvalidBEncodingException;
    3534
     35/**
     36 *  The data structure for the tracker response.
     37 *  Handles both traditional and compact formats.
     38 *  Compact format 1 - a list of hashes - early format for testing
     39 *  Compact format 2 - One big string of concatenated hashes - official format
     40 */
    3641public class TrackerInfo
    3742{
    3843  private final String failure_reason;
    3944  private final int interval;
    40   private final Set peers;
     45  private final Set<Peer> peers;
    4146  private int complete;
    4247  private int incomplete;
     
    7479
    7580        BEValue bePeers = (BEValue)m.get("peers");
    76         if (bePeers == null)
     81        if (bePeers == null) {
    7782          peers = Collections.EMPTY_SET;
    78         else
    79           peers = getPeers(bePeers.getList(), my_id, metainfo);
     83        } else {
     84            Set<Peer> p;
     85            try {
     86              // One big string (the official compact format)
     87              p = getPeers(bePeers.getBytes(), my_id, metainfo);
     88            } catch (InvalidBEncodingException ibe) {
     89              // List of Dictionaries or List of Strings
     90              p = getPeers(bePeers.getList(), my_id, metainfo);
     91            }
     92            peers = p;
     93        }
    8094
    8195        BEValue bev = (BEValue)m.get("complete");
     
    95109  }
    96110
    97   public static Set getPeers(InputStream in, byte[] my_id, MetaInfo metainfo)
     111/******
     112  public static Set<Peer> getPeers(InputStream in, byte[] my_id, MetaInfo metainfo)
    98113    throws IOException
    99114  {
     
    101116  }
    102117
    103   public static Set getPeers(BDecoder be, byte[] my_id, MetaInfo metainfo)
     118  public static Set<Peer> getPeers(BDecoder be, byte[] my_id, MetaInfo metainfo)
    104119    throws IOException
    105120  {
    106121    return getPeers(be.bdecodeList().getList(), my_id, metainfo);
    107122  }
    108 
    109   public static Set getPeers(List l, byte[] my_id, MetaInfo metainfo)
    110     throws IOException
    111   {
    112     Set peers = new HashSet(l.size());
    113 
    114     Iterator it = l.iterator();
    115     while (it.hasNext())
    116       {
     123******/
     124
     125  /** List of Dictionaries or List of Strings */
     126  private static Set<Peer> getPeers(List<BEValue> l, byte[] my_id, MetaInfo metainfo)
     127    throws IOException
     128  {
     129    Set<Peer> peers = new HashSet(l.size());
     130
     131    for (BEValue bev : l) {
    117132        PeerID peerID;
    118133        try {
    119             peerID = new PeerID(((BEValue)it.next()).getMap());
     134            // Case 1 - non-compact - A list of dictionaries (maps)
     135            peerID = new PeerID(bev.getMap());
    120136        } catch (InvalidBEncodingException ibe) {
    121             // don't let one bad entry spoil the whole list
    122             //Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
     137            try {
     138                // Case 2 - compact - A list of 32-byte binary strings (hashes)
     139                // This was just for testing and is not the official format
     140                peerID = new PeerID(bev.getBytes());
     141            } catch (InvalidBEncodingException ibe2) {
     142                // don't let one bad entry spoil the whole list
     143                //Snark.debug("Discarding peer from list: " + ibe, Snark.ERROR);
     144                continue;
     145            }
     146        }
     147        peers.add(new Peer(peerID, my_id, metainfo));
     148      }
     149
     150    return peers;
     151  }
     152
     153  private static final int HASH_LENGTH = 32;
     154
     155  /**
     156   *  One big string of concatenated 32-byte hashes
     157   *  @since 0.8.1
     158   */
     159  private static Set<Peer> getPeers(byte[] l, byte[] my_id, MetaInfo metainfo)
     160    throws IOException
     161  {
     162    int count = l.length / HASH_LENGTH;
     163    Set<Peer> peers = new HashSet(count);
     164
     165    for (int i = 0; i < count; i++) {
     166        PeerID peerID;
     167        byte[] hash = new byte[HASH_LENGTH];
     168        System.arraycopy(l, i * HASH_LENGTH, hash, 0, HASH_LENGTH);
     169        try {
     170            peerID = new PeerID(hash);
     171        } catch (InvalidBEncodingException ibe) {
     172            // won't happen
    123173            continue;
    124174        }
     
    129179  }
    130180
    131   public Set getPeers()
     181  public Set<Peer> getPeers()
    132182  {
    133183    return peers;
  • apps/i2psnark/java/src/org/klomp/snark/bencode/BEValue.java

    r5a782cc rb41e714a  
    141141   * throw a InvalidBEncodingException.
    142142   */
    143   public List getList() throws InvalidBEncodingException
     143  public List<BEValue> getList() throws InvalidBEncodingException
    144144  {
    145145    try
     
    158158   * a Map, otherwise it will throw a InvalidBEncodingException.
    159159   */
    160   public Map getMap() throws InvalidBEncodingException
     160  public Map<BEValue, BEValue> getMap() throws InvalidBEncodingException
    161161  {
    162162    try
  • apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java

    r5a782cc rb41e714a  
    99import java.util.ArrayList;
    1010import java.util.Arrays;
     11import java.util.Collections;
    1112import java.util.Comparator;
    1213import java.util.Enumeration;
     
    822823
    823824        if(showPeers && isRunning && curPeers > 0) {
    824             List peers = snark.coordinator.peerList();
    825             Iterator it = peers.iterator();
    826             while (it.hasNext()) {
    827                 Peer peer = (Peer)it.next();
     825            List<Peer> peers = snark.coordinator.peerList();
     826            if (!showDebug)
     827                Collections.sort(peers, new PeerComparator());
     828            for (Peer peer : peers) {
    828829                if (!peer.isConnected())
    829830                    continue;
     
    909910    }
    910911   
     912    /**
     913     *  Sort by completeness (seeds first), then by ID
     914     *  @since 0.8.1
     915     */
     916    private static class PeerComparator implements Comparator<Peer> {
     917        public int compare(Peer l, Peer r) {
     918            int diff = r.completed() - l.completed();      // reverse
     919            if (diff != 0)
     920                return diff;
     921            return l.toString().substring(5, 9).compareTo(r.toString().substring(5, 9));
     922        }
     923    }
     924
    911925    private void writeAddForm(PrintWriter out, HttpServletRequest req) throws IOException {
    912926        String uri = req.getRequestURI();
  • apps/i2psnark/web.xml

    r5a782cc rb41e714a  
    2323        </session-timeout>
    2424    </session-config>
     25
     26
     27    <!-- mime types not in mime.properties in the jetty 5.1.15 source -->
     28
     29    <mime-mapping>
     30        <extension>mkv</extension>
     31        <mime-type>video/x-matroska</mime-type>
     32    </mime-mapping>
     33
     34    <mime-mapping>
     35        <extension>wmv</extension>
     36        <mime-type>video/x-ms-wmv</mime-type>
     37    </mime-mapping>
     38
     39    <mime-mapping>
     40        <extension>flv</extension>
     41        <mime-type>video/x-flv</mime-type>
     42    </mime-mapping>
     43
     44    <mime-mapping>
     45        <extension>mp4</extension>
     46        <mime-type>video/mp4</mime-type>
     47    </mime-mapping>
     48
     49    <mime-mapping>
     50        <extension>rar</extension>
     51        <mime-type>application/rar</mime-type>
     52    </mime-mapping>
     53
     54    <mime-mapping>
     55        <extension>7z</extension>
     56        <mime-type>application/x-7z-compressed</mime-type>
     57    </mime-mapping>
     58
     59    <mime-mapping>
     60        <extension>iso</extension>
     61        <mime-type>application/x-iso9660-image</mime-type>
     62    </mime-mapping>
     63
     64    <mime-mapping>
     65        <extension>ico</extension>
     66        <mime-type>image/x-icon</mime-type>
     67    </mime-mapping>
     68
     69    <mime-mapping>
     70        <extension>exe</extension>
     71        <mime-type>application/x-msdos-program</mime-type>
     72    </mime-mapping>
     73
     74    <mime-mapping>
     75        <extension>flac</extension>
     76        <mime-type>audio/flac</mime-type>
     77    </mime-mapping>
     78
     79    <mime-mapping>
     80        <extension>m4a</extension>
     81        <mime-type>audio/mpeg</mime-type>
     82    </mime-mapping>
     83
     84    <mime-mapping>
     85        <extension>wma</extension>
     86        <mime-type>audio/x-ms-wma</mime-type>
     87    </mime-mapping>
     88
    2589</web-app>
  • apps/i2ptunnel/java/build.xml

    r5a782cc rb41e714a  
    8282    <target name="war" depends="precompilejsp, bundle">
    8383        <war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
    84              basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp">
     84             basedir="../jsp/" excludes="web.xml, web-fragment.xml, web-out.xml, **/*.java, *.jsp">
    8585        </war>
    8686    </target>
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java

    r5a782cc rb41e714a  
    2525
    2626/**
     27 * This does the transparent gzip decompression on the client side.
     28 * Extended in I2PTunnelHTTPServer to do the compression on the server side.
     29 *
    2730 * Simple stream for delivering an HTTP response to
    2831 * the client, trivially filtered to make sure "Connection: close"
     
    3437 */
    3538class HTTPResponseOutputStream extends FilterOutputStream {
    36     private I2PAppContext _context;
    37     private Log _log;
    38     private ByteCache _cache;
     39    private final I2PAppContext _context;
     40    private final Log _log;
    3941    protected ByteArray _headerBuffer;
    4042    private boolean _headerWritten;
    41     private byte _buf1[];
     43    private final byte _buf1[];
    4244    protected boolean _gzip;
    4345    private long _dataWritten;
    4446    private InternalGZIPInputStream _in;
    4547    private static final int CACHE_SIZE = 8*1024;
     48    private static final ByteCache _cache = ByteCache.getInstance(8, CACHE_SIZE);
     49    // OOM DOS prevention
     50    private static final int MAX_HEADER_SIZE = 64*1024;
    4651   
    4752    public HTTPResponseOutputStream(OutputStream raw) {
    4853        super(raw);
    4954        _context = I2PAppContext.getGlobalContext();
    50         _context.statManager().createRateStat("i2ptunnel.httpCompressionRatio", "ratio of compressed size to decompressed size after transfer", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
    51         _context.statManager().createRateStat("i2ptunnel.httpCompressed", "compressed size transferred", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
    52         _context.statManager().createRateStat("i2ptunnel.httpExpanded", "size transferred after expansion", "I2PTunnel", new long[] { 60*1000, 30*60*1000 });
     55        _context.statManager().createRateStat("i2ptunnel.httpCompressionRatio", "ratio of compressed size to decompressed size after transfer", "I2PTunnel", new long[] { 60*60*1000 });
     56        _context.statManager().createRateStat("i2ptunnel.httpCompressed", "compressed size transferred", "I2PTunnel", new long[] { 60*60*1000 });
     57        _context.statManager().createRateStat("i2ptunnel.httpExpanded", "size transferred after expansion", "I2PTunnel", new long[] { 60*60*1000 });
    5358        _log = _context.logManager().getLog(getClass());
    54         _cache = ByteCache.getInstance(8, CACHE_SIZE);
    5559        _headerBuffer = _cache.acquire();
    56         _headerWritten = false;
    57         _gzip = false;
    58         _dataWritten = 0;
    5960        _buf1 = new byte[1];
    6061    }
     
    9798    }
    9899   
    99     /** grow (and free) the buffer as necessary */
    100     private void ensureCapacity() {
     100    /**
     101     *  grow (and free) the buffer as necessary
     102     *  @throws IOException if the headers are too big
     103     */
     104    private void ensureCapacity() throws IOException {
     105        if (_headerBuffer.getValid() >= MAX_HEADER_SIZE)
     106            throw new IOException("Max header size exceeded: " + MAX_HEADER_SIZE);
    101107        if (_headerBuffer.getValid() + 1 >= _headerBuffer.getData().length) {
    102108            int newSize = (int)(_headerBuffer.getData().length * 1.5);
     
    105111            newBuf.setValid(_headerBuffer.getValid());
    106112            newBuf.setOffset(0);
     113            // if we changed the ByteArray size, don't put it back in the cache
    107114            if (_headerBuffer.getData().length == CACHE_SIZE)
    108115                _cache.release(_headerBuffer);
     
    220227        PipedInputStream pi = new PipedInputStream();
    221228        PipedOutputStream po = new PipedOutputStream(pi);
    222         new I2PAppThread(new Pusher(pi, out), "HTTP decompresser").start();
     229        new I2PAppThread(new Pusher(pi, out), "HTTP decompressor").start();
    223230        out = po;
    224231    }
     
    232239        }
    233240        public void run() {
    234             OutputStream to = null;
    235241            _in = null;
    236             long start = System.currentTimeMillis();
    237242            long written = 0;
     243            ByteArray ba = null;
    238244            try {
    239245                _in = new InternalGZIPInputStream(_inRaw);
    240                 byte buf[] = new byte[8192];
     246                ba = _cache.acquire();
     247                byte buf[] = ba.getData();
    241248                int read = -1;
    242249                while ( (read = _in.read(buf)) != -1) {
     
    252259                if (_log.shouldLog(Log.WARN))
    253260                    _log.warn("Error decompressing: " + written + ", " + (_in != null ? _in.getTotalRead() + "/" + _in.getTotalExpanded() : ""), ioe);
     261            } catch (OutOfMemoryError oom) {
     262                _log.error("OOM in HTTP Decompressor", oom);
    254263            } finally {
    255264                if (_log.shouldLog(Log.WARN) && (_in != null))
     
    260269                                + ", finished=" + _in.getFinished()
    261270                               : ""));
     271                if (ba != null)
     272                    _cache.release(ba);
    262273                if (_out != null) try {
    263274                    _out.close();
    264275                } catch (IOException ioe) {}
    265276            }
    266             long end = System.currentTimeMillis();
     277
    267278            double compressed = (_in != null ? _in.getTotalRead() : 0);
    268279            double expanded = (_in != null ? _in.getTotalExpanded() : 0);
    269             double ratio = 0;
    270             if (expanded > 0)
    271                 ratio = compressed/expanded;
    272 
    273             _context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio), end-start);
    274             _context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed, end-start);
    275             _context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded, end-start);
    276         }
    277     }
    278 
     280            if (compressed > 0 && expanded > 0) {
     281                // only update the stats if we did something
     282                double ratio = compressed/expanded;
     283                _context.statManager().addRateData("i2ptunnel.httpCompressionRatio", (int)(100d*ratio), 0);
     284                _context.statManager().addRateData("i2ptunnel.httpCompressed", (long)compressed, 0);
     285                _context.statManager().addRateData("i2ptunnel.httpExpanded", (long)expanded, 0);
     286            }
     287        }
     288    }
     289
     290    /** just a wrapper to provide stats for debugging */
    279291    private static class InternalGZIPInputStream extends GZIPInputStream {
    280292        public InternalGZIPInputStream(InputStream in) throws IOException {
     
    295307            }
    296308        }
     309
     310        /**
     311         *  From Inflater javadoc:
     312         *  Returns the total number of bytes remaining in the input buffer. This can be used to find out
     313         *  what bytes still remain in the input buffer after decompression has finished.
     314         */
    297315        public long getRemaining() {
    298316            try {
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java

    r5a782cc rb41e714a  
    99import java.util.StringTokenizer;
    1010
    11 import net.i2p.I2PAppContext;
    1211import net.i2p.client.streaming.I2PSocket;
    1312import net.i2p.data.DataFormatException;
     
    111110        if (size == 1) // skip the rand in the most common case
    112111            return dests.get(0);
    113         int index = I2PAppContext.getGlobalContext().random().nextInt(size);
     112        int index = _context.random().nextInt(size);
    114113        return dests.get(index);
    115114    }
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelConnectClient.java

    r5a782cc rb41e714a  
    147147            if (size <= 0)
    148148                return null;
    149             int index = I2PAppContext.getGlobalContext().random().nextInt(size);
     149            int index = _context.random().nextInt(size);
    150150            return _proxyList.get(index);
    151151        }
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java

    r5a782cc rb41e714a  
    206206                return null;
    207207            }
    208             int index = I2PAppContext.getGlobalContext().random().nextInt(size);
     208            int index = _context.random().nextInt(size);
    209209            String proxy = (String)proxyList.get(index);
    210210            return proxy;
     
    627627                        line = null;
    628628                        continue; // completely strip the line
     629                    } else if (lowercaseLine.startsWith("authorization: ntlm ")) {
     630                        // Block Windows NTLM after 401
     631                        line = null;
     632                        continue;
     633                    } else if (lowercaseLine.startsWith("proxy-authorization: ntlm ")) {
     634                        // Block Windows NTLM after 407
     635                        line = null;
     636                        continue;
    629637                    }
    630638                }
     
    809817     */
    810818    private byte[] getErrorPage(String base, byte[] backup) {
    811         return getErrorPage(getTunnel().getContext(), base, backup);
     819        return getErrorPage(_context, base, backup);
    812820    }
    813821
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPServer.java

    r5a782cc rb41e714a  
    291291    }
    292292
     293    /** just a wrapper to provide stats for debugging */
    293294    private static class InternalGZIPOutputStream extends GZIPOutputStream {
    294295        public InternalGZIPOutputStream(OutputStream target) throws IOException {
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelIRCClient.java

    r5a782cc rb41e714a  
    1010import java.util.StringTokenizer;
    1111
    12 import net.i2p.I2PAppContext;
    1312import net.i2p.client.streaming.I2PSocket;
    1413import net.i2p.data.DataFormatException;
     
    125124        if (size == 1) // skip the rand in the most common case
    126125            return dests.get(0);
    127         int index = I2PAppContext.getGlobalContext().random().nextInt(size);
     126        int index = _context.random().nextInt(size);
    128127        return dests.get(index);
    129128    }
     
    183182                            outmsg=outmsg+"\r\n";   // rfc1459 sec. 2.3
    184183                            output.write(outmsg.getBytes("ISO-8859-1"));
     184                            // probably doesn't do much but can't hurt
     185                            output.flush();
    185186                        } else {
    186187                            if (_log.shouldLog(Log.WARN))
     
    258259                                outmsg=outmsg+"\r\n";   // rfc1459 sec. 2.3
    259260                                output.write(outmsg.getBytes("ISO-8859-1"));
     261                                // save 250 ms in streaming
     262                                output.flush();
    260263                            } else {
    261264                                if (_log.shouldLog(Log.WARN))
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelRunner.java

    r5a782cc rb41e714a  
    130130                    // But if we don't flush, then we have to wait for the connectDelay timer to fire
    131131                    // in i2p socket? To be researched and/or fixed.
    132                     //i2pout.flush();
     132                    //
     133                    // AS OF 0.8.1, MessageOutputStream.flush() is fixed to only wait for accept,
     134                    // not for "completion" (i.e. an ACK from the far end).
     135                    // So we now get a fast return from flush(), and can do it here to save 250 ms.
     136                    // To make sure we are under the initial window size and don't hang waiting for accept,
     137                    // only flush if it fits in one message.
     138                    if (initialI2PData.length <= 1730)   // ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE
     139                        i2pout.flush();
    133140                }
    134141            }
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java

    r5a782cc rb41e714a  
    1919import net.i2p.util.I2PAppThread;
    2020import net.i2p.util.Log;
     21import net.i2p.util.SecureFileOutputStream;
    2122
    2223/**
     
    9091        FileOutputStream fos = null;
    9192        try {
    92             fos = new FileOutputStream(keyFile);
     93            fos = new SecureFileOutputStream(keyFile);
    9394            Destination dest = client.createDestination(fos);
    9495            String destStr = dest.toBase64();
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelControllerGroup.java

    r5a782cc rb41e714a  
    2121import net.i2p.util.I2PAppThread;
    2222import net.i2p.util.Log;
     23import net.i2p.util.SecureFileOutputStream;
    2324
    2425/**
     
    256257        FileOutputStream fos = null;
    257258        try {
    258             fos = new FileOutputStream(cfgFile);
     259            fos = new SecureFileOutputStream(cfgFile);
    259260            fos.write(buf.toString().getBytes("UTF-8"));
    260261            if (_log.shouldLog(Log.INFO))
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java

    r5a782cc rb41e714a  
    1414import java.util.StringTokenizer;
    1515
     16import net.i2p.data.Base64;
     17import net.i2p.data.Destination;
     18import net.i2p.data.PrivateKeyFile;
     19import net.i2p.data.Signature;
     20import net.i2p.data.SigningPrivateKey;
    1621import net.i2p.i2ptunnel.TunnelController;
    1722import net.i2p.i2ptunnel.TunnelControllerGroup;
     
    6772            tunnel = _group.getControllers().size();
    6873        return "i2ptunnel" + tunnel + "-privKeys.dat";
     74    }
     75   
     76    public String getNameSignature(int tunnel) {
     77        String spoof = getSpoofedHost(tunnel);
     78        if (spoof.length() <= 0)
     79            return "";
     80        TunnelController tun = getController(tunnel);
     81        if (tun == null)
     82            return "";
     83        String keyFile = tun.getPrivKeyFile();
     84        if (keyFile != null && keyFile.trim().length() > 0) {
     85            PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
     86            try {
     87                Destination d = pkf.getDestination();
     88                if (d == null)
     89                    return "";
     90                SigningPrivateKey privKey = pkf.getSigningPrivKey();
     91                if (privKey == null)
     92                    return "";
     93                //System.err.println("Signing " + spoof + " with " + Base64.encode(privKey.getData()));
     94                Signature sig = _context.dsa().sign(spoof.getBytes("UTF-8"), privKey);
     95                return Base64.encode(sig.getData());
     96            } catch (Exception e) {}
     97        }
     98        return "";
    6999    }
    70100   
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java

    r5a782cc rb41e714a  
    1010
    1111import java.util.concurrent.ConcurrentHashMap;
     12import java.util.ArrayList;
    1213import java.util.Arrays;
    1314import java.util.HashSet;
     
    4243    private String _action;
    4344    private int _tunnel;
    44     private long _prevNonce;
    45     private long _prevNonce2;
    46     private long _curNonce;
    47     private long _nextNonce;
     45    //private long _prevNonce;
     46    //private long _prevNonce2;
     47    private String _curNonce;
     48    //private long _nextNonce;
    4849
    4950    private String _type;
     
    8687    //public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
    8788    public static final String PROP_TUNNEL_PASSPHRASE = "consolePassword";
    88     static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
    89     static final String PROP_NONCE_OLD = PROP_NONCE + '2';
     89    //static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
     90    //static final String PROP_NONCE_OLD = PROP_NONCE + '2';
     91    /** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */
     92    private static final int MAX_NONCES = 5;
     93    /** store nonces in a static FIFO instead of in System Properties @since 0.8.1 */
     94    private static final List<String> _nonces = new ArrayList(MAX_NONCES + 1);
     95
    9096    static final String CLIENT_NICKNAME = "shared clients";
    91    
    9297    public static final String PROP_THEME_NAME = "routerconsole.theme";
    9398    public static final String DEFAULT_THEME = "light";
     
    99104        _log = _context.logManager().getLog(IndexBean.class);
    100105        _group = TunnelControllerGroup.getInstance();
    101         _action = null;
    102106        _tunnel = -1;
    103         _curNonce = -1;
    104         _prevNonce = -1;
    105         _prevNonce2 = -1;
    106         try {
    107             String nonce2 = System.getProperty(PROP_NONCE_OLD);
    108             if (nonce2 != null)
    109                 _prevNonce2 = Long.parseLong(nonce2);
    110             String nonce = System.getProperty(PROP_NONCE);
    111             if (nonce != null) {
    112                 _prevNonce = Long.parseLong(nonce);
    113                 System.setProperty(PROP_NONCE_OLD, nonce);
    114             }
    115         } catch (NumberFormatException nfe) {}
    116         _nextNonce = _context.random().nextLong();
    117         System.setProperty(PROP_NONCE, Long.toString(_nextNonce));
     107        _curNonce = "-1";
     108        addNonce();
    118109        _booleanOptions = new ConcurrentHashSet(4);
    119110        _otherOptions = new ConcurrentHashMap(4);
    120111    }
    121112   
    122     public long getNextNonce() { return _nextNonce; }
     113    public static String getNextNonce() {
     114        synchronized (_nonces) {
     115            return _nonces.get(0);
     116        }
     117    }
     118
    123119    public void setNonce(String nonce) {
    124120        if ( (nonce == null) || (nonce.trim().length() <= 0) ) return;
    125         try {
    126             _curNonce = Long.parseLong(nonce);
    127         } catch (NumberFormatException nfe) {
    128             _curNonce = -1;
     121        _curNonce = nonce;
     122    }
     123
     124    /** add a random nonce to the head of the queue @since 0.8.1 */
     125    private void addNonce() {
     126        String nextNonce = Long.toString(_context.random().nextLong());
     127        synchronized (_nonces) {
     128            _nonces.add(0, nextNonce);
     129            int sz = _nonces.size();
     130            if (sz > MAX_NONCES)
     131                _nonces.remove(sz - 1);
     132        }
     133    }
     134
     135    /** do we know this nonce? @since 0.8.1 */
     136    private static boolean haveNonce(String nonce) {
     137        synchronized (_nonces) {
     138            return _nonces.contains(nonce);
    129139        }
    130140    }
     
    156166        if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
    157167            return "";
    158         if ( (_prevNonce != _curNonce) && (_prevNonce2 != _curNonce) && (!validPassphrase()) )
     168        if ( (!haveNonce(_curNonce)) && (!validPassphrase()) )
    159169            return "Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.";
    160170        if ("Stop all".equals(_action))
  • apps/i2ptunnel/jsp/editServer.jsp

    r5a782cc rb41e714a  
    197197         <% } %>
    198198            </div>
    199            
     199
     200            <% if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) {
     201          %><div id="sigField" class="rowItem">
     202                <label for="signature">
     203                    <%=intl._("Hostname Signature")%>
     204                </label>
     205                <input type="text" size="30" readonly="readonly" title="Use to prove that the website name is for this destination" value="<%=editBean.getNameSignature(curTunnel)%>" wrap="off" class="freetext" />               
     206            </div>
     207            <% } %>
     208
    200209            <div class="footer">
    201210            </div>
  • apps/ministreaming/java/src/net/i2p/client/streaming/I2PSocketManagerFactory.java

    r5a782cc rb41e714a  
    131131                opts.setProperty(name, System.getProperty(name));
    132132        }
    133         boolean oldLib = DEFAULT_MANAGER.equals(opts.getProperty(PROP_MANAGER, DEFAULT_MANAGER));
    134         if (oldLib && false) {
     133        //boolean oldLib = DEFAULT_MANAGER.equals(opts.getProperty(PROP_MANAGER, DEFAULT_MANAGER));
     134        //if (oldLib && false) {
    135135            // for the old streaming lib
    136             opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_GUARANTEED);
     136        //    opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_GUARANTEED);
    137137            //opts.setProperty("tunnels.depthInbound", "0");
    138         } else {
     138        //} else {
    139139            // for new streaming lib:
    140             opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
     140            //opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT);
     141            // as of 0.8.1 (I2CP default is BestEffort)
     142            if (!opts.containsKey(I2PClient.PROP_RELIABILITY))
     143                opts.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
    141144            //p.setProperty("tunnels.depthInbound", "0");
    142         }
     145        //}
    143146
    144147        if (i2cpHost != null)
  • apps/routerconsole/java/build.xml

    r5a782cc rb41e714a  
    114114        <!-- Don't include the css in the war, the main build.xml will copy it to docs/themes/console/ -->
    115115        <war destfile="build/routerconsole.war" webxml="../jsp/web-out.xml"
    116              basedir="../jsp/" excludes="web.xml, *.css, **/*.java, *.jsp, *.jsi, web-fragment.xml">
     116             basedir="../jsp/" excludes="web.xml, *.css, **/*.java, *.jsp, *.jsi, web-fragment.xml, web-out.xml">
    117117        </war>
    118118    </target>
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHandler.java

    r5a782cc rb41e714a  
    1818    private String _dateFormat;
    1919    private String _fileSize;
     20    private String _newLogClass;
     21    private String _newLogLevel = "WARN";
    2022   
    2123    @Override
     
    2729        }
    2830    }
    29    
     31
    3032    public void setShouldsave(String moo) { _shouldSave = true; }
    3133   
     
    4850        _fileSize = (size != null ? size.trim() : null);
    4951    }
     52
     53    /** @since 0.8.1 */
     54    public void setNewlogclass(String s) {
     55        if (s != null && s.length() > 0)
     56            _newLogClass = s;
     57    }
     58   
     59    /** @since 0.8.1 */
     60    public void setNewloglevel(String s) {
     61        if (s != null)
     62            _newLogLevel = s;
     63    }
    5064   
    5165    /**
     
    5771        boolean shouldSave = false;
    5872       
    59         if (_levels != null) {
     73        if (_levels != null || _newLogClass != null) {
    6074            try {
    6175                Properties props = new Properties();
    62                 props.load(new ByteArrayInputStream(_levels.getBytes()));
     76                if (_levels != null)
     77                    props.load(new ByteArrayInputStream(_levels.getBytes()));
     78                if (_newLogClass != null)
     79                    props.setProperty(_newLogClass, _newLogLevel);
    6380                _context.logManager().setLimits(props);
    6481                shouldSave = true;
    65                 addFormNotice("Log limits updated");
     82                addFormNotice(_("Log overrides updated"));
    6683            } catch (IOException ioe) {
     84                // shouldn't ever happen (BAIS shouldnt cause an IOE)
    6785                _context.logManager().getLog(ConfigLoggingHandler.class).error("Error reading from the props?", ioe);
    6886                addFormError("Error updating the log limits - levels not valid");
     
    84102        }
    85103       
    86         if (_dateFormat != null) {
     104        if (_dateFormat != null && !_dateFormat.equals(_context.logManager().getDateFormatPattern())) {
    87105            boolean valid = _context.logManager().setDateFormat(_dateFormat);
    88106            if (valid) {
     
    140158
    141159            if (saved)
    142                 addFormNotice("Log configuration saved and applied successfully");
     160                addFormNotice(_("Log configuration saved"));
    143161            else
    144162                addFormNotice("Error saving the configuration (applied but not saved) - please see the error logs");
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigLoggingHelper.java

    r5a782cc rb41e714a  
    11package net.i2p.router.web;
    22
     3import java.util.List;
    34import java.util.Iterator;
    45import java.util.Properties;
     6import java.util.Set;
    57import java.util.TreeSet;
    68
     9import net.i2p.data.DataHelper;
     10import net.i2p.util.Log;
    711
    812public class ConfigLoggingHelper extends HelperBase {
     
    2024    public String getMaxFileSize() {
    2125        int bytes = _context.logManager().getFileSize();
    22         if (bytes == 0) return "1m";
    23         if (bytes > 1024*1024*1024)
    24             return (bytes/(1024*1024*1024)) + "g";
    25         else if (bytes > 1024*1024)
    26             return (bytes/(1024*1024)) + "m";
    27         else
    28             return (bytes/(1024)) + "k";
     26        if (bytes <= 0) return "1.00 MB";
     27        return DataHelper.formatSize2(bytes) + 'B';
    2928    }
    3029    public String getLogLevelTable() {
    3130        StringBuilder buf = new StringBuilder(32*1024);
    3231        Properties limits = _context.logManager().getLimits();
    33         TreeSet sortedLogs = new TreeSet();
     32        TreeSet<String> sortedLogs = new TreeSet();
    3433        for (Iterator iter = limits.keySet().iterator(); iter.hasNext(); ) {
    3534            String prefix = (String)iter.next();
     
    4746        buf.append("<i>" + _("Or put entries in the logger.config file. Example: logger.record.net.i2p.router.tunnel=WARN") + "</i><br>");
    4847        buf.append("<i>" + _("Valid levels are DEBUG, INFO, WARN, ERROR, CRIT") + "</i>\n");
     48
     49      /****
     50        // this is too big and ugly
     51        if (limits.size() <= 0)
     52            return "";
     53        buf.append("<table>");
     54        for (String prefix : sortedLogs) {
     55            buf.append("<tr><td>").append(prefix).append("</td><td>");
     56            String level = limits.getProperty(prefix);
     57            buf.append(getLogLevelBox("level-" + prefix, level, true)).append("</td></tr>");
     58        }
     59        buf.append("</table>");
     60       ****/
     61
    4962        return buf.toString();
    5063    }
     
    5467    public String getDefaultLogLevelBox() {
    5568        String cur = _context.logManager().getDefaultLimit();
     69        return getLogLevelBox("defaultloglevel", cur, false);
     70    }
     71
     72    private String getLogLevelBox(String name, String cur, boolean showRemove) {
    5673        StringBuilder buf = new StringBuilder(128);
    57         buf.append("<select name=\"defaultloglevel\">\n");
     74        buf.append("<select name=\"").append(name).append("\">\n");
    5875       
    5976        for (int i = 0; i < levels.length; i++) {
    6077            String l = levels[i];
    61             buf.append("<option value=\"").append(l).append("\" ");
     78            buf.append("<option value=\"").append(l).append('\"');
    6279            if (l.equals(cur))
    63                 buf.append(" selected=\"true\" ");
     80                buf.append(" selected=\"true\"");
    6481            buf.append('>').append(_(l)).append("</option>\n");
    6582        }       
    6683       
     84        if (showRemove)
     85            buf.append("<option value=\"remove\">").append(_("Remove")).append("</option>");
    6786        buf.append("</select>\n");
    6887        return buf.toString();
    6988    }
     89
     90    /**
     91     *  All the classes the log manager knows about, except ones that
     92     *  already have overrides
     93     *  @since 0.8.1
     94     */
     95    public String getNewClassBox() {
     96        List<Log> logs = _context.logManager().getLogs();
     97        Set limits = _context.logManager().getLimits().keySet();
     98        TreeSet<String> sortedLogs = new TreeSet();
     99
     100        for (Log log : logs) {
     101            String name = log.getName();
     102            if (!limits.contains(name))
     103                sortedLogs.add(name);
     104
     105            // add higher classes of length 3 or more
     106            int dots = 0;
     107            int lastdot = -1;
     108            int nextdot = 0;
     109            while ((nextdot = name.indexOf('.', lastdot + 1)) > 0) {
     110                if (++dots >= 3) {
     111                    String subst = name.substring(0, nextdot);
     112                    if (!limits.contains(subst))
     113                        sortedLogs.add(subst);
     114                }
     115                lastdot = nextdot;
     116            }
     117        }
     118
     119        StringBuilder buf = new StringBuilder(65536);
     120        buf.append("<select name=\"newlogclass\">\n" +
     121                   "<option value=\"\" selected=\"true\">")
     122           .append(_("Select a class to add"))
     123           .append("</option>\n");
     124
     125        for (String l : sortedLogs) {
     126            buf.append("<option value=\"").append(l).append("\">")
     127               .append(l).append("</option>\n");
     128        }       
     129       
     130        buf.append("</select>\n");
     131        buf.append(getLogLevelBox("newloglevel", "WARN", false));
     132        return buf.toString();
     133    }
    70134}
  • apps/routerconsole/java/src/net/i2p/router/web/LogsHelper.java

    r5a782cc rb41e714a  
    4545    ******/
    4646
    47     private String formatMessages(List msgs) {
     47    /** formats in reverse order */
     48    private String formatMessages(List<String> msgs) {
     49        if (msgs.isEmpty())
     50            return "<p><i>" + _("No log messages") + "</i></p>";
    4851        boolean colorize = Boolean.valueOf(_context.getProperty("routerconsole.logs.color")).booleanValue();
    4952        StringBuilder buf = new StringBuilder(16*1024);
     
    5154        buf.append("<code>\n");
    5255        for (int i = msgs.size(); i > 0; i--) {
    53             String msg = (String)msgs.get(i - 1);
     56            String msg = msgs.get(i - 1);
    5457            buf.append("<li>");
    5558            if (colorize) {
  • apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java

    r5a782cc rb41e714a  
    2020import java.util.List;
    2121import java.util.Locale;
     22import java.util.Map;
     23import java.util.Properties;
    2224import java.util.Set;
    2325import java.util.TreeSet;
     
    3537import net.i2p.util.HexDump;                             // debug
    3638import net.i2p.util.ObjectCounter;
     39import net.i2p.util.OrderedProperties;
    3740import net.i2p.util.VersionComparator;
    3841
     
    372375            if (!((style.equals("SSU") && cost == 5) || (style.equals("NTCP") && cost == 10)))
    373376                buf.append('[').append(_("cost")).append('=').append("" + cost).append("] ");
    374             for (Iterator optIter = addr.getOptions().keySet().iterator(); optIter.hasNext(); ) {
    375                 String name = (String)optIter.next();
    376                 String val = addr.getOptions().getProperty(name);
     377            Properties p = new OrderedProperties();
     378            p.putAll(addr.getOptions());
     379            for (Map.Entry e : p.entrySet()) {
     380                String name = (String) e.getKey();
     381                String val = (String) e.getValue();
    377382                buf.append('[').append(_(DataHelper.stripHTML(name))).append('=').append(DataHelper.stripHTML(val)).append("] ");
    378383            }
  • apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java

    r5a782cc rb41e714a  
    564564     *  http://jimlife.wordpress.com/2007/12/19/java-adding-new-classpath-at-runtime/
    565565     */
    566     public static void addPath(URL u) throws Exception {
     566    private static void addPath(URL u) throws Exception {
    567567        URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    568568        Class urlClass = URLClassLoader.class;
  • apps/routerconsole/java/src/net/i2p/router/web/PluginUpdateHandler.java

    r5a782cc rb41e714a  
    1717import net.i2p.util.Log;
    1818import net.i2p.util.OrderedProperties;
     19import net.i2p.util.SecureDirectory;
    1920import net.i2p.util.SimpleScheduler;
    2021import net.i2p.util.SimpleTimer;
     
    151152            updateStatus("<b>" + _("Plugin downloaded") + "</b>");
    152153            File f = new File(_updateFile);
    153             File appDir = new File(_context.getConfigDir(), PLUGIN_DIR);
     154            File appDir = new SecureDirectory(_context.getConfigDir(), PLUGIN_DIR);
    154155            if ((!appDir.exists()) && (!appDir.mkdir())) {
    155156                f.delete();
     
    274275            }
    275276
    276             File destDir = new File(appDir, appName);
     277            File destDir = new SecureDirectory(appDir, appName);
    277278            if (destDir.exists()) {
    278279                if (Boolean.valueOf(props.getProperty("install-only")).booleanValue()) {
  • apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java

    r5a782cc rb41e714a  
    1515import net.i2p.util.FileUtil;
    1616import net.i2p.util.I2PAppThread;
     17import net.i2p.util.SecureDirectory;
    1718
    1819import org.mortbay.http.DigestAuthenticator;
     
    6364   
    6465    public void startConsole() {
    65         File workDir = new File(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
     66        File workDir = new SecureDirectory(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
    6667        boolean workDirRemoved = FileUtil.rmdir(workDir, false);
    6768        if (!workDirRemoved)
     
    116117            _server.setRootWebApp(ROUTERCONSOLE);
    117118            WebApplicationContext wac = _server.addWebApplication("/", _webAppsDir + ROUTERCONSOLE + ".war");
    118             File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
     119            File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + _listenPort);
    119120            tmpdir.mkdir();
    120121            wac.setTempDirectory(tmpdir);
     
    131132                        if (! "false".equals(enabled)) {
    132133                            String path = new File(dir, fileNames[i]).getCanonicalPath();
    133                             tmpdir = new File(workDir, appName + "-" + _listenPort);
     134                            tmpdir = new SecureDirectory(workDir, appName + "-" + _listenPort);
    134135                            WebAppStarter.addWebApp(I2PAppContext.getGlobalContext(), _server, appName, path, tmpdir);
    135136
  • apps/routerconsole/java/src/net/i2p/router/web/WebAppStarter.java

    r5a782cc rb41e714a  
    1111import net.i2p.I2PAppContext;
    1212import net.i2p.util.FileUtil;
     13import net.i2p.util.SecureDirectory;
    1314
    1415import org.mortbay.http.HttpContext;
     
    4243     */
    4344    static void startWebApp(I2PAppContext ctx, Server server, String appName, String warPath) throws Exception {
    44          File tmpdir = new File(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt());
     45         File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt());
    4546         WebApplicationContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
    4647         wac.start();
     
    7475        } else if (oldmod.longValue() < newmod) {
    7576            // copy war to temporary directory
    76             File warTmpDir = new File(ctx.getTempDir(), "war-copy-" + appName + ctx.random().nextInt());
     77            File warTmpDir = new SecureDirectory(ctx.getTempDir(), "war-copy-" + appName + ctx.random().nextInt());
    7778            warTmpDir.mkdir();
    7879            String tmpPath = (new File(warTmpDir, appName + ".war")).getAbsolutePath();
  • apps/routerconsole/jsp/configlogging.jsp

    r5a782cc rb41e714a  
    4747        </tr><tr><td class="mediumtags" align="right"><b><%=intl._("Log level overrides")%>:</b></td>
    4848          <td><jsp:getProperty name="logginghelper" property="logLevelTable" /></td>
     49        </tr><tr><td class="mediumtags" align="right"><b><%=intl._("New override")%>:</b></td>
     50          <td><jsp:getProperty name="logginghelper" property="newClassBox" /></td>
    4951        </tr><tr><td colspan="2"><hr></td>
    5052        </tr><tr class="tablefooter"><td colspan="2"> <div class="formaction">
  • apps/streaming/java/src/net/i2p/client/streaming/Connection.java

    r5a782cc rb41e714a  
    149149   
    150150    /**
     151     * This doesn't "send a choke". Rather, it blocks if the outbound window is full,
     152     * thus choking the sender that calls this.
     153     *
    151154     * Block until there is an open outbound packet slot or the write timeout
    152155     * expires. 
     156     * PacketLocal is the only caller, generally with -1.
    153157     *
    154      * @param timeoutMs PacketLocal is the only caller, often with -1??????
    155      * @return true if the packet should be sent
     158     * @param timeoutMs 0 or negative means wait forever, 5 minutes max
     159     * @return true if the packet should be sent, false for a fatal error
     160     *         will return false after 5 minutes even if timeoutMs is <= 0.
    156161     */
    157162    boolean packetSendChoke(long timeoutMs) {
    158163        // if (false) return true; // <--- what the fuck??
    159164        long start = _context.clock().now();
    160         long writeExpire = start + timeoutMs;
     165        long writeExpire = start + timeoutMs;  // only used if timeoutMs > 0
    161166        boolean started = false;
    162167        while (true) {
  • apps/streaming/java/src/net/i2p/client/streaming/ConnectionOptions.java

    r5a782cc rb41e714a  
    647647    }
    648648
     649/****
    649650    public static void main(String args[]) {
    650651        Properties p = new Properties();
     
    657658        System.out.println("opts: " + c);
    658659    }
     660****/
    659661}
  • apps/streaming/java/src/net/i2p/client/streaming/MessageInputStream.java

    r5a782cc rb41e714a  
    1212import net.i2p.I2PAppContext;
    1313import net.i2p.data.ByteArray;
    14 import net.i2p.util.ByteCache;
     14//import net.i2p.util.ByteCache;
    1515import net.i2p.util.Log;
    1616
     
    2121 */
    2222public class MessageInputStream extends InputStream {
    23     private I2PAppContext _context;
    24     private Log _log;
     23    private final I2PAppContext _context;
     24    private final Log _log;
    2525    /**
    2626     * List of ByteArray objects of data ready to be read,
     
    3030     *
    3131     */
    32     private List _readyDataBlocks;
     32    private final List<ByteArray> _readyDataBlocks;
    3333    private int _readyDataBlockIndex;
    3434    /** highest message ID used in the readyDataBlocks */
     
    4141     * received
    4242     */
    43     private Map _notYetReadyBlocks;
     43    private final Map<Long, ByteArray> _notYetReadyBlocks;
    4444    /**
    4545     * if we have received a flag saying there won't be later messages, EOF
     
    5252    private IOException _streamError;
    5353    private long _readTotal;
    54     private ByteCache _cache;
    55    
    56     private byte[] _oneByte = new byte[1];
     54    //private ByteCache _cache;
     55   
     56    private final byte[] _oneByte = new byte[1];
    5757   
    5858    private final Object _dataLock;
     
    6262        _log = ctx.logManager().getLog(MessageInputStream.class);
    6363        _readyDataBlocks = new ArrayList(4);
    64         _readyDataBlockIndex = 0;
    6564        _highestReadyBlockId = -1;
    6665        _highestBlockId = -1;
    6766        _readTimeout = -1;
    68         _readTotal = 0;
    6967        _notYetReadyBlocks = new HashMap(4);
    7068        _dataLock = new Object();
    71         _closeReceived = false;
    72         _locallyClosed = false;
    73         _cache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
     69        //_cache = ByteCache.getInstance(128, Packet.MAX_PAYLOAD_SIZE);
    7470    }
    7571   
     
    141137            blocks = new long[num];
    142138            int i = 0;
    143             for (Iterator iter = _notYetReadyBlocks.keySet().iterator(); iter.hasNext(); ) {
    144                 Long id = (Long)iter.next();
    145                 blocks[i] = id.longValue();
    146                 i++;
     139            for (Long id : _notYetReadyBlocks.keySet()) {
     140                blocks[i++] = id.longValue();
    147141            }
    148142        }
     
    179173                long available = 0;
    180174                for (int i = 0; i < _readyDataBlocks.size(); i++)
    181                     available += ((ByteArray)_readyDataBlocks.get(i)).getValid();
     175                    available += _readyDataBlocks.get(i).getValid();
    182176                available -= _readyDataBlockIndex;
    183177                buf.append(available);
     
    186180                buf.append(" not ready blocks: ");
    187181                long notAvailable = 0;
    188                 for (Iterator iter = _notYetReadyBlocks.keySet().iterator(); iter.hasNext(); ) {
    189                     Long id = (Long)iter.next();
    190                     ByteArray ba = (ByteArray)_notYetReadyBlocks.get(id);
     182                for (Long id : _notYetReadyBlocks.keySet()) {
     183                    ByteArray ba = _notYetReadyBlocks.get(id);
    191184                    buf.append(id).append(" ");
    192185                   
     
    238231                // now pull in any previously pending blocks
    239232                while (_notYetReadyBlocks.containsKey(new Long(cur))) {
    240                     ByteArray ba = (ByteArray)_notYetReadyBlocks.remove(new Long(cur));
     233                    ByteArray ba = _notYetReadyBlocks.remove(new Long(cur));
    241234                    if ( (ba != null) && (ba.getData() != null) && (ba.getValid() > 0) ) {
    242235                        _readyDataBlocks.add(ba);
     
    342335                } else {
    343336                    // either was already ready, or we wait()ed and it arrived
    344                     ByteArray cur = (ByteArray)_readyDataBlocks.get(0);
     337                    ByteArray cur = _readyDataBlocks.get(0);
    345338                    byte rv = cur.getData()[cur.getOffset()+_readyDataBlockIndex];
    346339                    _readyDataBlockIndex++;
     
    379372        synchronized (_dataLock) {
    380373            for (int i = 0; i < _readyDataBlocks.size(); i++) {
    381                 ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
     374                ByteArray cur = _readyDataBlocks.get(i);
    382375                if (i == 0)
    383376                    numBytes += cur.getValid() - _readyDataBlockIndex;
     
    403396            int numBytes = 0;
    404397            for (int i = 0; i < _readyDataBlocks.size(); i++) {
    405                 ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
     398                ByteArray cur = _readyDataBlocks.get(i);
    406399                if (i == 0)
    407400                    numBytes += cur.getValid() - _readyDataBlockIndex;
     
    409402                    numBytes += cur.getValid();
    410403            }
    411             for (Iterator iter = _notYetReadyBlocks.values().iterator(); iter.hasNext(); ) {
    412                 ByteArray cur = (ByteArray)iter.next();
     404            for (ByteArray cur : _notYetReadyBlocks.values()) {
    413405                numBytes += cur.getValid();
    414406            }
     
    422414            int numBytes = 0;
    423415            for (int i = 0; i < _readyDataBlocks.size(); i++) {
    424                 ByteArray cur = (ByteArray)_readyDataBlocks.get(i);
     416                ByteArray cur = _readyDataBlocks.get(i);
    425417                if (i == 0)
    426418                    numBytes += cur.getValid() - _readyDataBlockIndex;
     
    441433            // we don't need the data, but we do need to keep track of the messageIds
    442434            // received, so we can ACK accordingly
    443             for (Iterator iter = _notYetReadyBlocks.values().iterator(); iter.hasNext(); ) {
    444                 ByteArray ba = (ByteArray)iter.next();
     435            for (ByteArray ba : _notYetReadyBlocks.values()) {
    445436                ba.setData(null);
    446437                //_cache.release(ba);
  • apps/streaming/java/src/net/i2p/client/streaming/MessageOutputStream.java

    r5a782cc rb41e714a  
    4444    private int _sendBps;
    4545   
     46    /**
     47     *  Since this is less than i2ptunnel's i2p.streaming.connectDelay default of 1000,
     48     *  we only wait 250 at the start. Guess that's ok, 1000 is too long anyway.
     49     */
    4650    private static final int DEFAULT_PASSIVE_FLUSH_DELAY = 250;
    4751
     
    274278   
    275279    /**
    276      * Flush the data already queued up, blocking until it has been
    277      * delivered.
     280     * Flush the data already queued up, blocking only if the outbound
     281     * window is full.
     282     *
     283     * Prior to 0.8.1, this blocked until "delivered".
     284     * "Delivered" meant "received an ACK from the far end",
     285     * which is not the commom implementation of flush(), and really hurt the
     286     * performance of i2psnark, which flush()ed frequently.
     287     * Calling flush() would cause a complete window stall.
     288     *
     289     * As of 0.8.1, only wait for accept into the streaming output queue.
     290     * This will speed up snark significantly, and allow us to flush()
     291     * the initial data in I2PTunnelRunner, saving 250 ms.
    278292     *
    279293     * @throws IOException if the write fails
     
    284298      * Documented here, but doesn't belong in the javadoc.
    285299      */
     300        flush(true);
     301    }
     302
     303    /**
     304     *  @param wait_for_accept_only see discussion in close() code
     305     *  @@since 0.8.1
     306     */
     307    private void flush(boolean wait_for_accept_only) throws IOException {
    286308        long begin = _context.clock().now();
    287309        WriteStatus ws = null;
     
    298320                return;
    299321            }
    300             ws = _dataReceiver.writeData(_buf, 0, _valid);
    301             _written += _valid;
    302             _valid = 0;
    303             locked_updateBufferSize();
    304             _lastFlushed = _context.clock().now();
    305             _dataLock.notifyAll();
     322            // if valid == 0 return ??? - no, this could flush a CLOSE packet too.
     323
     324            // Yes, flush here, inside the data lock, and do all the waitForCompletion() stuff below
     325            // (disabled)
     326            if (!wait_for_accept_only) {
     327                ws = _dataReceiver.writeData(_buf, 0, _valid);
     328                _written += _valid;
     329                _valid = 0;
     330                locked_updateBufferSize();
     331                _lastFlushed = _context.clock().now();
     332                _dataLock.notifyAll();
     333            }
    306334        }
    307335       
     336        // Skip all the waitForCompletion() stuff below, which is insanity, as of 0.8.1
     337        // must do this outside the data lock
     338        if (wait_for_accept_only) {
     339            flushAvailable(_dataReceiver, true);
     340            return;
     341        }
     342
     343        // Wait a loooooong time, until we have the ACK
    308344        if (_log.shouldLog(Log.DEBUG))
    309345            _log.debug("before waiting " + _writeTimeout + "ms for completion of " + ws);
     
    329365    }
    330366   
     367    /**
     368     *  This does a flush, and BLOCKS until
     369     *  the CLOSE packet is acked.
     370     */
    331371    @Override
    332372    public void close() throws IOException {
     
    335375            return;
    336376        }
     377        // setting _closed before flush() will force flush() to send a CLOSE packet
    337378        _closed = true;
    338         flush();
     379
     380        // In 0.8.1 we rewrote flush() to only wait for accept into the window,
     381        // not "completion" (i.e. ack from the far end).
     382        // Unfortunately, that broke close(), at least in i2ptunnel HTTPClient.
     383        // Symptom was premature close, i.e. incomplete pages and images.
     384        // Possible cause - I2PTunnelRunner code? or the code here that follows flush()?
     385        // It seems like we shouldn't have to wait for the far-end ACK for a close packet,
     386        // should we? To be researched further.
     387        // false -> wait for completion, not just accept.
     388        flush(false);
    339389        _log.debug("Output stream closed after writing " + _written);
    340390        ByteArray ba = null;
     
    352402        }
    353403    }
    354     /** nonblocking close */
     404
     405    /**
     406     *  nonblocking close -
     407     *  Use outside of this package is deprecated, should be made package local
     408     */
    355409    public void closeInternal() {
    356410        _closed = true;
     
    413467            _log.info("flushAvailable() valid = " + _valid);
    414468        synchronized (_dataLock) {
     469            // if valid == 0 return ??? - no, this could flush a CLOSE packet too.
     470
    415471            // _buf may be null, but the data receiver can handle that just fine,
    416472            // deciding whether or not to send a packet
     
    458514    /** Define a way to detect the status of a write */
    459515    public interface WriteStatus {
    460         /** wait until the data written either fails or succeeds */
     516        /**
     517         * Wait until the data written either fails or succeeds.
     518         * Success means an ACK FROM THE FAR END.
     519         * @param maxWaitMs -1 = forever
     520         */
    461521        public void waitForCompletion(int maxWaitMs);
     522
    462523        /**
    463          * wait until the data written is accepted into the outbound pool,
     524         * Wait until the data written is accepted into the outbound pool,
     525         * (i.e. the outbound window is not full)
    464526         * which we throttle rather than accept arbitrary data and queue
    465          * @param maxWaitMs -1 = forever ?
     527         * @param maxWaitMs -1 = forever
    466528         */
    467529        public void waitForAccept(int maxWaitMs);
     530
    468531        /** the write was accepted.  aka did the socket not close? */
    469532        public boolean writeAccepted();
  • apps/streaming/java/src/net/i2p/client/streaming/PacketLocal.java

    r5a782cc rb41e714a  
    195195   
    196196    /**
    197      * @param maxWaitMs MessageOutputStream is the only caller, often with -1 ??????
     197     * Blocks until outbound window is not full. See Connection.packetSendChoke().
     198     * @param maxWaitMs MessageOutputStream is the only caller, generally with -1
    198199     */
    199200    public void waitForAccept(int maxWaitMs) {
     
    221222    }
    222223   
     224    /** block until the packet is acked from the far end */
    223225    public void waitForCompletion(int maxWaitMs) {
    224226        long expiration = _context.clock().now()+maxWaitMs;
  • apps/susidns/src/build.xml

    r5a782cc rb41e714a  
    7373                        <include name="css.css"/>
    7474                        <include name="index.html"/>
    75                         <include name="WEB-INF/web-out.xml"/>
    7675                        <include name="WEB-INF/classes/${project}.properties"/>
    7776                </fileset>
  • apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java

    r5a782cc rb41e714a  
    3939import net.i2p.data.DataHelper;
    4040import net.i2p.data.Destination;
     41import net.i2p.util.SecureFileOutputStream;
    4142
    4243public class AddressbookBean
     
    331332                String filename = properties.getProperty( getBook() + "_addressbook" );
    332333               
    333                 FileOutputStream fos = new FileOutputStream( ConfigBean.addressbookPrefix + filename  );
     334                FileOutputStream fos = new SecureFileOutputStream( ConfigBean.addressbookPrefix + filename  );
    334335                addressbook.store( fos, null );
    335336                try {
  • apps/susidns/src/java/src/i2p/susi/dns/ConfigBean.java

    r5a782cc rb41e714a  
    2828import java.io.File;
    2929import java.io.FileNotFoundException;
    30 import java.io.FileOutputStream;
    3130import java.io.FileReader;
    3231import java.io.IOException;
     
    3534
    3635import net.i2p.I2PAppContext;
     36import net.i2p.util.SecureFileOutputStream;
    3737
    3838public class ConfigBean implements Serializable {
     
    112112                File file = new File( configFileName );
    113113                try {
    114                         PrintWriter out = new PrintWriter( new FileOutputStream( file ) );
     114                        PrintWriter out = new PrintWriter( new SecureFileOutputStream( file ) );
    115115                        out.print( config );
    116116                        out.flush();
  • apps/susidns/src/java/src/i2p/susi/dns/SubscriptionsBean.java

    r5a782cc rb41e714a  
    2929import java.io.FileInputStream;
    3030import java.io.FileNotFoundException;
    31 import java.io.FileOutputStream;
    3231import java.io.FileReader;
    3332import java.io.IOException;
    3433import java.io.PrintWriter;
    3534import java.util.Properties;
     35
     36import net.i2p.util.SecureFileOutputStream;
    3637
    3738public class SubscriptionsBean
     
    114115                File file = new File( getFileName() );
    115116                try {
    116                         PrintWriter out = new PrintWriter( new FileOutputStream( file ) );
     117                        PrintWriter out = new PrintWriter( new SecureFileOutputStream( file ) );
    117118                        out.print( content );
    118119                        out.flush();
  • core/java/src/net/i2p/I2PAppContext.java

    r5a782cc rb41e714a  
    3232//import net.i2p.util.PooledRandomSource;
    3333import net.i2p.util.RandomSource;
     34import net.i2p.util.SecureDirectory;
    3435
    3536/**
     
    219220        s = getProperty("i2p.dir.config");
    220221        if (s != null) {
    221             _configDir = new File(s);
     222            _configDir = new SecureDirectory(s);
    222223            if (!_configDir.exists())
    223224                _configDir.mkdir();
     
    228229        s = getProperty("i2p.dir.router");
    229230        if (s != null) {
    230             _routerDir = new File(s);
     231            _routerDir = new SecureDirectory(s);
    231232            if (!_routerDir.exists())
    232233                _routerDir.mkdir();
     
    242243        s = getProperty("i2p.dir.log");
    243244        if (s != null) {
    244             _logDir = new File(s);
     245            _logDir = new SecureDirectory(s);
    245246            if (!_logDir.exists())
    246247                _logDir.mkdir();
     
    250251        s = getProperty("i2p.dir.app");
    251252        if (s != null) {
    252             _appDir = new File(s);
     253            _appDir = new SecureDirectory(s);
    253254            if (!_appDir.exists())
    254255                _appDir.mkdir();
     
    346347                // our random() probably isn't warmed up yet
    347348                String f = "i2p-" + Math.abs((new java.util.Random()).nextInt()) + ".tmp";
    348                 _tmpDir = new File(d, f);
     349                _tmpDir = new SecureDirectory(d, f);
    349350                if (_tmpDir.exists()) {
    350351                    // good or bad ?
     
    353354                } else {
    354355                    System.err.println("Could not create temp dir " + _tmpDir.getAbsolutePath());
    355                     _tmpDir = new File(_routerDir, "tmp");
     356                    _tmpDir = new SecureDirectory(_routerDir, "tmp");
    356357                    _tmpDir.mkdir();
    357358                }
  • core/java/src/net/i2p/client/HandlerImpl.java

    r5a782cc rb41e714a  
    1919 */
    2020abstract class HandlerImpl implements I2CPMessageHandler {
    21     protected Log _log;
    22     private int _type;
    23     protected I2PAppContext _context;
     21    protected final Log _log;
     22    private final int _type;
     23    protected final I2PAppContext _context;
    2424
    2525    public HandlerImpl(I2PAppContext context, int type) {
  • core/java/src/net/i2p/client/I2PClient.java

    r5a782cc rb41e714a  
    3535    /** Reliability value: guaranteed */
    3636    public final static String PROP_RELIABILITY_GUARANTEED = "Guaranteed";
     37    /** @since 0.8.1 */
     38    public final static String PROP_RELIABILITY_NONE = "none";
    3739
    3840    /** protocol flag that must be sent when opening the i2cp connection to the router */
  • core/java/src/net/i2p/client/I2PSessionImpl2.java

    r5a782cc rb41e714a  
    3434
    3535    /** set of MessageState objects, representing all of the messages in the process of being sent */
    36     private /* FIXME final FIXME */ Set _sendingStates;
     36    private /* FIXME final FIXME */ Set<MessageState> _sendingStates;
    3737    /** max # seconds to wait for confirmation of the message send */
    3838    private final static long SEND_TIMEOUT = 60 * 1000; // 60 seconds to send
     
    4040    private final static boolean SHOULD_COMPRESS = true;
    4141    private final static boolean SHOULD_DECOMPRESS = true;
     42    /** Don't expect any MSMs from the router for outbound traffic @since 0.8.1 */
     43    private boolean _noEffort;
    4244
    4345    /** for extension */
     
    5456        _log = ctx.logManager().getLog(I2PSessionImpl2.class);
    5557        _sendingStates = new HashSet(32);
     58        // default is BestEffort
     59        _noEffort = "none".equalsIgnoreCase(options.getProperty(I2PClient.PROP_RELIABILITY));
    5660
    5761        ctx.statManager().createRateStat("i2cp.sendBestEffortTotalTime", "how long to do the full sendBestEffort call?", "i2cp", new long[] { 10*60*1000 } );
     
    6165        //ctx.statManager().createRateStat("i2cp.sendBestEffortStage3", "fourth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
    6266        //ctx.statManager().createRateStat("i2cp.sendBestEffortStage4", "fifth part of sendBestEffort?", "i2cp", new long[] { 10*60*1000 } );
    63         _context.statManager().createRateStat("i2cp.receiveStatusTime.0", "How long it took to get status=0 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    64         _context.statManager().createRateStat("i2cp.receiveStatusTime.1", "How long it took to get status=1 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    65         _context.statManager().createRateStat("i2cp.receiveStatusTime.2", "How long it took to get status=2 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    66         _context.statManager().createRateStat("i2cp.receiveStatusTime.3", "How long it took to get status=3 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    67         _context.statManager().createRateStat("i2cp.receiveStatusTime.4", "How long it took to get status=4 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    68         _context.statManager().createRateStat("i2cp.receiveStatusTime.5", "How long it took to get status=5 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
    69         _context.statManager().createRateStat("i2cp.receiveStatusTime", "How long it took to get any status", "i2cp", new long[] { 60*1000, 10*60*1000 });
    70         _context.statManager().createRateStat("i2cp.tx.msgCompressed", "compressed size transferred", "i2cp", new long[] { 60*1000, 30*60*1000 });
    71         _context.statManager().createRateStat("i2cp.tx.msgExpanded", "size before compression", "i2cp", new long[] { 60*1000, 30*60*1000 });
     67        //_context.statManager().createRateStat("i2cp.receiveStatusTime.0", "How long it took to get status=0 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
     68        _context.statManager().createRateStat("i2cp.receiveStatusTime.1", "How long it took to get status=1 back", "i2cp", new long[] { 10*60*1000 });
     69        // best effort codes unused
     70        //_context.statManager().createRateStat("i2cp.receiveStatusTime.2", "How long it took to get status=2 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
     71        //_context.statManager().createRateStat("i2cp.receiveStatusTime.3", "How long it took to get status=3 back", "i2cp", new long[] { 60*1000, 10*60*1000 });
     72        _context.statManager().createRateStat("i2cp.receiveStatusTime.4", "How long it took to get status=4 back", "i2cp", new long[] { 10*60*1000 });
     73        _context.statManager().createRateStat("i2cp.receiveStatusTime.5", "How long it took to get status=5 back", "i2cp", new long[] { 10*60*1000 });
     74        _context.statManager().createRateStat("i2cp.receiveStatusTime", "How long it took to get any status", "i2cp", new long[] { 10*60*1000 });
     75        _context.statManager().createRateStat("i2cp.tx.msgCompressed", "compressed size transferred", "i2cp", new long[] { 30*60*1000 });
     76        _context.statManager().createRateStat("i2cp.tx.msgExpanded", "size before compression", "i2cp", new long[] { 30*60*1000 });
    7277    }
    7378
     
    187192        _context.statManager().addRateData("i2cp.tx.msgCompressed", compressed, 0);
    188193        _context.statManager().addRateData("i2cp.tx.msgExpanded", size, 0);
    189         return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
     194        if (_noEffort)
     195            return sendNoEffort(dest, payload, expires);
     196        else
     197            return sendBestEffort(dest, payload, keyUsed, tagsSent, expires);
    190198    }
    191199
     
    214222
    215223    /**
     224     * TODO - Don't need to save MessageState since actuallyWait is false...
     225     * But for now just use sendNoEffort() instead.
     226     *
    216227     * @param keyUsed unused - no end-to-end crypto
    217228     * @param tagsSent unused - no end-to-end crypto
     
    258269                               + (tag == null ? "no tag" : " a valid tag"));
    259270            }
    260        
     271
    261272            if (false) // rekey
    262273                newKey = _context.keyGenerator().generateSessionKey();
     
    372383    }
    373384   
     385    /**
     386     * Same as sendBestEffort(), except we do not expect any MessageStatusMessage responses -
     387     * not for accepted, or success, or failure.
     388     * So we don't create a MessageState and save it on the _sendingStates HashSet
     389     *
     390     * @return true always
     391     * @since 0.8.1
     392     */
     393    protected boolean sendNoEffort(Destination dest, byte payload[], long expires)
     394                    throws I2PSessionException {
     395        // nonce always 0
     396        _producer.sendMessage(this, dest, 0, payload, null, null, null, null, expires);
     397        return true;
     398    }
     399   
     400    /**
     401     *  Only call this with nonzero status, i.e. for outbound messages
     402     *  whose MessageState may be queued on _sendingStates.
     403     *
     404     *  Even when using sendBestEffort(), this is a waste, because the
     405     *  MessageState is removed from _sendingStates immediately and
     406     *  so the lookup here fails.
     407     *  And iterating through the HashSet instead of having a map
     408     *  is bad too.
     409     *
     410     *  This is now pretty much avoided since streaming now sets
     411     *  i2cp.messageReliability = none, which forces sendNoEffort() instead of sendBestEffort(),
     412     *  so the router won't send us any MSM's for outbound traffic.
     413     *
     414     *  @param status != 0
     415     */
    374416    @Override
    375417    public void receiveStatus(int msgId, long nonce, int status) {
     
    414456                    _context.statManager().addRateData("i2cp.receiveStatusTime.1", lifetime, 0);
    415457                    break;
    416                 case 2:
    417                     _context.statManager().addRateData("i2cp.receiveStatusTime.2", lifetime, 0);
    418                     break;
    419                 case 3:
    420                     _context.statManager().addRateData("i2cp.receiveStatusTime.3", lifetime, 0);
    421                     break;
     458                // best effort codes unused
     459                //case 2:
     460                //    _context.statManager().addRateData("i2cp.receiveStatusTime.2", lifetime, 0);
     461                //    break;
     462                //case 3:
     463                //    _context.statManager().addRateData("i2cp.receiveStatusTime.3", lifetime, 0);
     464                //    break;
    422465                case 4:
    423466                    _context.statManager().addRateData("i2cp.receiveStatusTime.4", lifetime, 0);
  • core/java/src/net/i2p/client/MessageState.java

    r5a782cc rb41e714a  
    3838        _nonce = nonce;
    3939        _prefix = prefix + "[" + _stateId + "]: ";
    40         _id = null;
    4140        _receivedStatus = new HashSet();
    42         _cancelled = false;
    43         _key = null;
    44         _newKey = null;
    45         _tags = null;
    46         _to = null;
    4741        _created = ctx.clock().now();
    4842        //ctx.statManager().createRateStat("i2cp.checkStatusTime", "how long it takes to go through the states", "i2cp", new long[] { 60*1000 });
  • core/java/src/net/i2p/client/SessionIdleTimer.java

    r5a782cc rb41e714a  
    1919 * @author zzz
    2020 */
    21 public class SessionIdleTimer implements SimpleTimer.TimedEvent {
     21class SessionIdleTimer implements SimpleTimer.TimedEvent {
    2222    public static final long MINIMUM_TIME = 5*60*1000;
    2323    private static final long DEFAULT_REDUCE_TIME = 20*60*1000;
    2424    private static final long DEFAULT_CLOSE_TIME = 30*60*1000;
    2525    private final static Log _log = new Log(SessionIdleTimer.class);
    26     private I2PAppContext _context;
    27     private I2PSessionImpl _session;
     26    private final I2PAppContext _context;
     27    private final I2PSessionImpl _session;
    2828    private boolean _reduceEnabled;
    2929    private int _reduceQuantity;
     
    3737     *  reduce, shutdown, or both must be true
    3838     */
    39     /* FIXME Exporting non-public type through public API FIXME */
    4039    public SessionIdleTimer(I2PAppContext context, I2PSessionImpl session, boolean reduce, boolean shutdown) {
    4140        _context = context;
  • core/java/src/net/i2p/client/naming/EepGetNamingService.java

    r5a782cc rb41e714a  
    6666
    6767        hostname = hostname.toLowerCase();
     68
     69        // If you want b32, chain with HostsTxtNamingService
     70        if (hostname.length() == 60 && hostname.endsWith(".b32.i2p"))
     71            return null;
    6872
    6973        // check the cache
  • core/java/src/net/i2p/client/naming/ExecNamingService.java

    r5a782cc rb41e714a  
    6767        hostname = hostname.toLowerCase();
    6868
     69        // If you want b32, chain with HostsTxtNamingService
     70        if (hostname.length() == 60 && hostname.endsWith(".b32.i2p"))
     71            return null;
     72
    6973        // check the cache
    7074        Destination d = getCache(hostname);
  • core/java/src/net/i2p/client/naming/LookupDest.java

    r5a782cc rb41e714a  
    2828    protected LookupDest(I2PAppContext context) {}
    2929
     30    /** @param key 52 chars (do not include the .b32.i2p suffix) */
    3031    static Destination lookupBase32Hash(I2PAppContext ctx, String key) {
    3132        byte[] h = Base32.decode(key);
     
    4546    ****/
    4647
     48    /** @param h 32 byte hash */
    4749    static Destination lookupHash(I2PAppContext ctx, byte[] h) {
    4850        Hash key = new Hash(h);
  • core/java/src/net/i2p/client/naming/NamingService.java

    r5a782cc rb41e714a  
    3333    private static final String DEFAULT_IMPL = "net.i2p.client.naming.HostsTxtNamingService";
    3434
    35     protected static final int CACHE_MAX_SIZE = 8;
     35    protected static final int CACHE_MAX_SIZE = 16;
    3636
    3737   
     
    108108     */
    109109    /** Don't know why a dest would ever change but keep this short anyway */
    110     protected static final long CACHE_MAX_AGE = 60*1000;
     110    protected static final long CACHE_MAX_AGE = 7*60*1000;
    111111
    112112    private class CacheEntry {
     
    175175        }
    176176    }
     177
     178    /** @since 0.8.1 */
     179    public void clearCache() {
     180        synchronized (_cache) {
     181            _cache.clear();
     182        }
     183    }
    177184}
  • core/java/src/net/i2p/crypto/CryptixAESKeyCache.java

    r5a782cc rb41e714a  
    11package net.i2p.crypto;
    22
    3 import java.util.ArrayList;
    4 import java.util.List;
     3import java.util.concurrent.LinkedBlockingQueue;
    54
    65/**
     
    1211 */
    1312public final class CryptixAESKeyCache {
    14     private final List _availableKeys;
     13    private final LinkedBlockingQueue<KeyCacheEntry> _availableKeys;
    1514   
    1615    private static final int KEYSIZE = 32; // 256bit AES
     
    2322   
    2423    public CryptixAESKeyCache() {
    25         _availableKeys = new ArrayList(MAX_KEYS);
     24        _availableKeys = new LinkedBlockingQueue(MAX_KEYS);
    2625    }
    2726   
     
    3130     */
    3231    public final KeyCacheEntry acquireKey() {
    33         synchronized (_availableKeys) {
    34             if (!_availableKeys.isEmpty())
    35                 return (KeyCacheEntry)_availableKeys.remove(0);
    36         }
     32        KeyCacheEntry rv = _availableKeys.poll();
     33        if (rv != null)
     34            return rv;
    3735        return createNew();
    3836    }
     
    4341     */
    4442    public final void releaseKey(KeyCacheEntry key) {
    45         synchronized (_availableKeys) {
    46             if (_availableKeys.size() < MAX_KEYS)
    47                 _availableKeys.add(key);
    48         }
     43        _availableKeys.offer(key);
    4944    }
    5045   
  • core/java/src/net/i2p/crypto/DHSessionKeyBuilder.java

    r5a782cc rb41e714a  
    6666    public final static String PROP_DH_PRECALC_MAX = "crypto.dh.precalc.max";
    6767    public final static String PROP_DH_PRECALC_DELAY = "crypto.dh.precalc.delay";
    68     public final static String DEFAULT_DH_PRECALC_MIN = "5";
    69     public final static String DEFAULT_DH_PRECALC_MAX = "50";
    70     public final static String DEFAULT_DH_PRECALC_DELAY = "10000";
     68    public final static int DEFAULT_DH_PRECALC_MIN = 5;
     69    public final static int DEFAULT_DH_PRECALC_MAX = 50;
     70    public final static int DEFAULT_DH_PRECALC_DELAY = 10000;
    7171
    7272    static {
     
    7474        ctx.statManager().createRateStat("crypto.dhGeneratePublicTime", "How long it takes to create x and X", "Encryption", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
    7575        ctx.statManager().createRateStat("crypto.dhCalculateSessionTime", "How long it takes to create the session key", "Encryption", new long[] { 60*1000, 5*60*1000, 60*60*1000 });       
    76         try {
    77             int val = Integer.parseInt(ctx.getProperty(PROP_DH_PRECALC_MIN, DEFAULT_DH_PRECALC_MIN));
    78             MIN_NUM_BUILDERS = val;
    79         } catch (Throwable t) {
    80             int val = Integer.parseInt(DEFAULT_DH_PRECALC_MIN);
    81             MIN_NUM_BUILDERS = val;
    82         }
    83         try {
    84             int val = Integer.parseInt(ctx.getProperty(PROP_DH_PRECALC_MAX, DEFAULT_DH_PRECALC_MAX));
    85             MAX_NUM_BUILDERS = val;
    86         } catch (Throwable t) {
    87             int val = Integer.parseInt(DEFAULT_DH_PRECALC_MAX);
    88             MAX_NUM_BUILDERS = val;
    89         }
    90         try {
    91             int val = Integer.parseInt(ctx.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY));
    92             CALC_DELAY = val;
    93         } catch (Throwable t) {
    94             int val = Integer.parseInt(DEFAULT_DH_PRECALC_DELAY);
    95             CALC_DELAY = val;
    96         }
     76        MIN_NUM_BUILDERS = ctx.getProperty(PROP_DH_PRECALC_MIN, DEFAULT_DH_PRECALC_MIN);
     77        MAX_NUM_BUILDERS = ctx.getProperty(PROP_DH_PRECALC_MAX, DEFAULT_DH_PRECALC_MAX);
     78        CALC_DELAY = ctx.getProperty(PROP_DH_PRECALC_DELAY, DEFAULT_DH_PRECALC_DELAY);
    9779
    9880        if (_log.shouldLog(Log.DEBUG))
  • core/java/src/net/i2p/crypto/DSAEngine.java

    r5a782cc rb41e714a  
    4242import net.i2p.util.NativeBigInteger;
    4343
     44/**
     45 *  Params and rv's changed from Hash to SHA1Hash for version 0.8.1
     46 *  There shouldn't be any external users of those variants.
     47 */
    4448public class DSAEngine {
    4549    private Log _log;
     
    6266        return verifySignature(signature, calculateHash(in), verifyingKey);
    6367    }
    64     public boolean verifySignature(Signature signature, Hash hash, SigningPublicKey verifyingKey) {
     68
     69    /** @param hash SHA-1 hash, NOT a SHA-256 hash */
     70    public boolean verifySignature(Signature signature, SHA1Hash hash, SigningPublicKey verifyingKey) {
    6571        long start = _context.clock().now();
    6672
     
    112118    public Signature sign(byte data[], int offset, int length, SigningPrivateKey signingKey) {
    113119        if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
    114         Hash h = calculateHash(data, offset, length);
     120        SHA1Hash h = calculateHash(data, offset, length);
    115121        return sign(h, signingKey);
    116122    }
     
    118124    public Signature sign(InputStream in, SigningPrivateKey signingKey) {
    119125        if ((signingKey == null) || (in == null) ) return null;
    120         Hash h = calculateHash(in);
     126        SHA1Hash h = calculateHash(in);
    121127        return sign(h, signingKey);
    122128    }
    123129
    124     public Signature sign(Hash hash, SigningPrivateKey signingKey) {
     130    /** @param hash SHA-1 hash, NOT a SHA-256 hash */
     131    public Signature sign(SHA1Hash hash, SigningPrivateKey signingKey) {
    125132        if ((signingKey == null) || (hash == null)) return null;
    126133        long start = _context.clock().now();
     
    187194    }
    188195   
    189     public Hash calculateHash(InputStream in) {
     196    /** @return hash SHA-1 hash, NOT a SHA-256 hash */
     197    public SHA1Hash calculateHash(InputStream in) {
    190198        SHA1 digest = new SHA1();
    191199        byte buf[] = new byte[64];
     
    200208            return null;
    201209        }
    202         return new Hash(digest.engineDigest());
    203     }
    204 
    205     public static Hash calculateHash(byte[] source, int offset, int len) {
     210        return new SHA1Hash(digest.engineDigest());
     211    }
     212
     213    /** @return hash SHA-1 hash, NOT a SHA-256 hash */
     214    public static SHA1Hash calculateHash(byte[] source, int offset, int len) {
    206215        SHA1 h = new SHA1();
    207216        h.engineUpdate(source, offset, len);
    208217        byte digested[] = h.digest();
    209         return new Hash(digested);
     218        return new SHA1Hash(digested);
    210219    }
    211220
  • core/java/src/net/i2p/crypto/HMAC256Generator.java

    r5a782cc rb41e714a  
    1616 * {@link org.bouncycastle.crypto.digests.MD5Digest}.
    1717 *
     18 * deprecated unused
    1819 */
    1920public class HMAC256Generator extends HMACGenerator {
     
    2223    @Override
    2324    protected I2PHMac acquire() {
    24         synchronized (_available) {
    25             if (!_available.isEmpty())
    26                 return (I2PHMac)_available.remove(0);
    27         }
     25        I2PHMac rv = _available.poll();
     26        if (rv != null)
     27            return rv;
    2828        // the HMAC is hardcoded to use SHA256 digest size
    2929        // for backwards compatability.  next time we have a backwards
     
    4444    }
    4545   
     46/******
    4647    public static void main(String args[]) {
    4748        I2PAppContext ctx = I2PAppContext.getGlobalContext();
     
    5253        System.out.println(Base64.encode(mac.getData()));
    5354    }
     55******/
    5456}
  • core/java/src/net/i2p/crypto/HMACGenerator.java

    r5a782cc rb41e714a  
    11package net.i2p.crypto;
    22
    3 import java.util.ArrayList;
    43import java.util.Arrays;
    5 import java.util.List;
     4import java.util.concurrent.LinkedBlockingQueue;
    65
    76import net.i2p.I2PAppContext;
     
    2322    private I2PAppContext _context;
    2423    /** set of available HMAC instances for calculate */
    25     protected final List _available;
     24    protected final LinkedBlockingQueue<I2PHMac> _available;
    2625    /** set of available byte[] buffers for verify */
    27     private final  List _availableTmp;
     26    private final LinkedBlockingQueue<byte[]> _availableTmp;
    2827   
    2928    public HMACGenerator(I2PAppContext context) {
    3029        _context = context;
    31         _available = new ArrayList(32);
    32         _availableTmp = new ArrayList(32);
     30        _available = new LinkedBlockingQueue(32);
     31        _availableTmp = new LinkedBlockingQueue(32);
    3332    }
    3433   
     
    8988   
    9089    protected I2PHMac acquire() {
    91         synchronized (_available) {
    92             if (!_available.isEmpty())
    93                 return (I2PHMac)_available.remove(0);
    94         }
     90        I2PHMac rv = _available.poll();
     91        if (rv != null)
     92            return rv;
    9593        // the HMAC is hardcoded to use SHA256 digest size
    9694        // for backwards compatability.  next time we have a backwards
     
    9896        return new I2PHMac(new MD5Digest(), 32);
    9997    }
    100     private void release(Mac mac) {
    101         synchronized (_available) {
    102             if (_available.size() < 64)
    103                 _available.add(mac);
    104         }
     98
     99    private void release(I2PHMac mac) {
     100        _available.offer(mac);
    105101    }
    106102
    107103    // temp buffers for verify(..)
    108104    private byte[] acquireTmp() {
    109         byte rv[] = null;
    110         synchronized (_availableTmp) {
    111             if (!_availableTmp.isEmpty())
    112                 rv = (byte[])_availableTmp.remove(0);
    113         }
     105        byte rv[] = _availableTmp.poll();
    114106        if (rv != null)
    115107            Arrays.fill(rv, (byte)0x0);
     
    118110        return rv;
    119111    }
     112
    120113    private void releaseTmp(byte tmp[]) {
    121         synchronized (_availableTmp) {
    122             if (_availableTmp.size() < 64)
    123                 _availableTmp.add((Object)tmp);
    124         }
     114        _availableTmp.offer(tmp);
    125115    }
    126116}
  • core/java/src/net/i2p/crypto/SHA1.java

    r5a782cc rb41e714a  
    6464     * This implementation returns a fixed-size digest.
    6565     */
    66     private static final int HASH_LENGTH = 20; // bytes == 160 bits
     66    static final int HASH_LENGTH = 20; // bytes == 160 bits
    6767 
    6868    /**
  • core/java/src/net/i2p/crypto/YKGenerator.java

    r5a782cc rb41e714a  
    1111
    1212import java.math.BigInteger;
    13 import java.util.ArrayList;
    14 import java.util.List;
     13import java.util.concurrent.LinkedBlockingQueue;
    1514
    1615import net.i2p.I2PAppContext;
     
    1918import net.i2p.util.Log;
    2019import net.i2p.util.NativeBigInteger;
    21 import net.i2p.util.RandomSource;
    2220
    2321/**
     
    2624 * This class precalcs a set of values on its own thread, using those transparently
    2725 * when a new instance is created.  By default, the minimum threshold for creating
    28  * new values for the pool is 5, and the max pool size is 10.  Whenever the pool has
     26 * new values for the pool is 20, and the max pool size is 50.  Whenever the pool has
    2927 * less than the minimum, it fills it up again to the max.  There is a delay after
    30  * each precalculation so that the CPU isn't hosed during startup (defaulting to 10 seconds). 
     28 * each precalculation so that the CPU isn't hosed during startup.
    3129 * These three parameters are controlled by java environmental variables and
    3230 * can be adjusted via:
     
    4038 */
    4139class YKGenerator {
    42     private final static Log _log = new Log(YKGenerator.class);
    43     private static int MIN_NUM_BUILDERS = -1;
    44     private static int MAX_NUM_BUILDERS = -1;
    45     private static int CALC_DELAY = -1;
    46     /* FIXME final type if you are to syncronize FIXME */
    47     private static volatile List _values = new ArrayList(50); // list of BigInteger[] values (y and k)
    48     private static Thread _precalcThread = null;
     40    //private final static Log _log = new Log(YKGenerator.class);
     41    private static final int MIN_NUM_BUILDERS;
     42    private static final int MAX_NUM_BUILDERS;
     43    private static final int CALC_DELAY;
     44    private static final LinkedBlockingQueue<BigInteger[]> _values = new LinkedBlockingQueue(50); // list of BigInteger[] values (y and k)
     45    private static final Thread _precalcThread;
     46    private static final I2PAppContext ctx;
    4947
    5048    public final static String PROP_YK_PRECALC_MIN = "crypto.yk.precalc.min";
    5149    public final static String PROP_YK_PRECALC_MAX = "crypto.yk.precalc.max";
    5250    public final static String PROP_YK_PRECALC_DELAY = "crypto.yk.precalc.delay";
    53     public final static String DEFAULT_YK_PRECALC_MIN = "10";
    54     public final static String DEFAULT_YK_PRECALC_MAX = "30";
    55     public final static String DEFAULT_YK_PRECALC_DELAY = "10000";
     51    public final static int DEFAULT_YK_PRECALC_MIN = 20;
     52    public final static int DEFAULT_YK_PRECALC_MAX = 50;
     53    public final static int DEFAULT_YK_PRECALC_DELAY = 200;
    5654
    5755    /** check every 30 seconds whether we have less than the minimum */
    58     private final static long CHECK_DELAY = 30 * 1000;
     56    private static long CHECK_DELAY = 30 * 1000;
    5957
    6058    static {
    61         I2PAppContext ctx = I2PAppContext.getGlobalContext();
    62         try {
    63             int val = Integer.parseInt(ctx.getProperty(PROP_YK_PRECALC_MIN, DEFAULT_YK_PRECALC_MIN));
    64             MIN_NUM_BUILDERS = val;
    65         } catch (Throwable t) {
    66             int val = Integer.parseInt(DEFAULT_YK_PRECALC_MIN);
    67             MIN_NUM_BUILDERS = val;
    68         }
    69         try {
    70             int val = Integer.parseInt(ctx.getProperty(PROP_YK_PRECALC_MAX, DEFAULT_YK_PRECALC_MAX));
    71             MAX_NUM_BUILDERS = val;
    72         } catch (Throwable t) {
    73             int val = Integer.parseInt(DEFAULT_YK_PRECALC_MAX);
    74             MAX_NUM_BUILDERS = val;
    75         }
    76         try {
    77             int val = Integer.parseInt(ctx.getProperty(PROP_YK_PRECALC_DELAY, DEFAULT_YK_PRECALC_DELAY));
    78             CALC_DELAY = val;
    79         } catch (Throwable t) {
    80             int val = Integer.parseInt(DEFAULT_YK_PRECALC_DELAY);
    81             CALC_DELAY = val;
    82         }
     59        ctx = I2PAppContext.getGlobalContext();
     60        MIN_NUM_BUILDERS = ctx.getProperty(PROP_YK_PRECALC_MIN, DEFAULT_YK_PRECALC_MIN);
     61        MAX_NUM_BUILDERS = ctx.getProperty(PROP_YK_PRECALC_MAX, DEFAULT_YK_PRECALC_MAX);
     62        CALC_DELAY = ctx.getProperty(PROP_YK_PRECALC_DELAY, DEFAULT_YK_PRECALC_DELAY);
    8363
    84         if (_log.shouldLog(Log.DEBUG))
    85             _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
    86                        + CALC_DELAY + ")");
     64        //if (_log.shouldLog(Log.DEBUG))
     65        //    _log.debug("ElGamal YK Precalc (minimum: " + MIN_NUM_BUILDERS + " max: " + MAX_NUM_BUILDERS + ", delay: "
     66        //               + CALC_DELAY + ")");
     67
     68        ctx.statManager().createRateStat("crypto.YKUsed", "Need a YK from the queue", "Encryption", new long[] { 60*60*1000 });
     69        ctx.statManager().createRateStat("crypto.YKEmpty", "YK queue empty", "Encryption", new long[] { 60*60*1000 });
    8770
    8871        _precalcThread = new I2PThread(new YKPrecalcRunner(MIN_NUM_BUILDERS, MAX_NUM_BUILDERS));
     
    9477
    9578    private static final int getSize() {
    96         synchronized (_values) {
    97             return _values.size();
    98         }
     79        return _values.size();
    9980    }
    10081
    101     private static final int addValues(BigInteger yk[]) {
    102         int sz = 0;
    103         synchronized (_values) {
    104             _values.add(yk);
    105             sz = _values.size();
    106         }
    107         return sz;
     82    /** @return true if successful, false if full */
     83    private static final boolean addValues(BigInteger yk[]) {
     84        return _values.offer(yk);
    10885    }
    10986
     87    /** @return rv[0] = Y; rv[1] = K */
    11088    public static BigInteger[] getNextYK() {
    111         if (true) {
    112             synchronized (_values) {
    113                 if (!_values.isEmpty()) {
    114                     if (_log.shouldLog(Log.DEBUG))
    115                         _log.debug("Sufficient precalculated YK values - fetch the existing");
    116                     return (BigInteger[]) _values.remove(0);
    117                 }
    118             }
    119         }
    120         if (_log.shouldLog(Log.INFO)) _log.info("Insufficient precalculated YK values - create a new one");
     89        ctx.statManager().addRateData("crypto.YKUsed", 1, 0);
     90        BigInteger[] rv = _values.poll();
     91        if (rv != null)
     92            return rv;
     93        ctx.statManager().addRateData("crypto.YKEmpty", 1, 0);
    12194        return generateYK();
    12295    }
     
    12497    private final static BigInteger _two = new NativeBigInteger(1, new byte[] { 0x02});
    12598
     99    /** @return rv[0] = Y; rv[1] = K */
    126100    private static final BigInteger[] generateYK() {
    127101        NativeBigInteger k = null;
    128102        BigInteger y = null;
    129         long t0 = 0;
    130         long t1 = 0;
     103        //long t0 = 0;
     104        //long t1 = 0;
    131105        while (k == null) {
    132             t0 = Clock.getInstance().now();
    133             k = new NativeBigInteger(KeyGenerator.PUBKEY_EXPONENT_SIZE, RandomSource.getInstance());
    134             t1 = Clock.getInstance().now();
     106            //t0 = Clock.getInstance().now();
     107            k = new NativeBigInteger(KeyGenerator.PUBKEY_EXPONENT_SIZE, ctx.random());
     108            //t1 = Clock.getInstance().now();
    135109            if (BigInteger.ZERO.compareTo(k) == 0) {
    136110                k = null;
     
    140114            if (kPlus2.compareTo(CryptoConstants.elgp) > 0) k = null;
    141115        }
    142         long t2 = Clock.getInstance().now();
     116        //long t2 = Clock.getInstance().now();
    143117        y = CryptoConstants.elgg.modPow(k, CryptoConstants.elgp);
    144118
     
    147121        yk[1] = k;
    148122
    149         long diff = t2 - t0;
    150         if (diff > 1000) {
    151             if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to generate YK value for ElGamal (" + diff + "ms)");
    152         }
     123        //long diff = t2 - t0;
     124        //if (diff > 1000) {
     125        //    if (_log.shouldLog(Log.WARN)) _log.warn("Took too long to generate YK value for ElGamal (" + diff + "ms)");
     126        //}
    153127
    154128        return yk;
     
    156130
    157131    public static void main(String args[]) {
    158         RandomSource.getInstance().nextBoolean(); // warm it up
    159         try {
    160             Thread.sleep(20 * 1000);
    161         } catch (InterruptedException ie) { // nop
    162         }
    163         _log.debug("\n\n\n\nBegin test\n");
     132        System.out.println("\n\n\n\nBegin test\n");
    164133        long negTime = 0;
    165134        for (int i = 0; i < 5; i++) {
     
    167136            getNextYK();
    168137            long endNeg = Clock.getInstance().now();
     138            negTime += endNeg - startNeg;
    169139        }
    170         _log.debug("YK fetch time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each");
    171         try {
    172             Thread.sleep(30 * 1000);
    173         } catch (InterruptedException ie) { // nop
    174         }
     140        System.out.println("YK fetch time for 5 runs: " + negTime + " @ " + negTime / 5l + "ms each");
    175141    }
    176142
     
    187153            while (true) {
    188154                int curSize = 0;
    189                 long start = Clock.getInstance().now();
     155                //long start = Clock.getInstance().now();
    190156                int startSize = getSize();
     157                // Adjust delay
     158                if (startSize <= (_minSize / 2) && CHECK_DELAY > 1000)
     159                    CHECK_DELAY -= 1000;
     160                else if (startSize > (_minSize * 2) && CHECK_DELAY < 60000)
     161                         CHECK_DELAY += 1000;
    191162                curSize = startSize;
    192                 while (curSize < _minSize) {
    193                     while (curSize < _maxSize) {
    194                         long begin = Clock.getInstance().now();
    195                         curSize = addValues(generateYK());
    196                         long end = Clock.getInstance().now();
    197                         if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalculated YK value in " + (end - begin) + "ms");
     163                if (curSize < _minSize) {
     164                    for (int i = curSize; i < _maxSize; i++) {
     165                        //long begin = Clock.getInstance().now();
     166                        if (!addValues(generateYK()))
     167                            break;
     168                        //long end = Clock.getInstance().now();
     169                        //if (_log.shouldLog(Log.DEBUG)) _log.debug("Precalculated YK value in " + (end - begin) + "ms");
    198170                        // for some relief...
    199171                        try {
     
    203175                    }
    204176                }
    205                 long end = Clock.getInstance().now();
    206                 int numCalc = curSize - startSize;
    207                 if (numCalc > 0) {
    208                     if (_log.shouldLog(Log.DEBUG))
    209                         _log.debug("Precalced " + numCalc + " to " + curSize + " in "
    210                                    + (end - start - CALC_DELAY * numCalc) + "ms (not counting "
    211                                    + (CALC_DELAY * numCalc) + "ms relief).  now sleeping");
    212                 }
     177                //long end = Clock.getInstance().now();
     178                //int numCalc = curSize - startSize;
     179                //if (numCalc > 0) {
     180                //    if (_log.shouldLog(Log.DEBUG))
     181                //        _log.debug("Precalced " + numCalc + " to " + curSize + " in "
     182                //                   + (end - start - CALC_DELAY * numCalc) + "ms (not counting "
     183                //                   + (CALC_DELAY * numCalc) + "ms relief).  now sleeping");
     184                //}
    213185                try {
    214186                    Thread.sleep(CHECK_DELAY);
  • core/java/src/net/i2p/data/DataHelper.java

    r5a782cc rb41e714a  
    1818import java.io.File;
    1919import java.io.FileInputStream;
    20 import java.io.FileOutputStream;
    2120import java.io.IOException;
    2221import java.io.InputStream;
     
    4342import net.i2p.util.ReusableGZIPInputStream;
    4443import net.i2p.util.ReusableGZIPOutputStream;
     44import net.i2p.util.SecureFileOutputStream;
    4545
    4646/**
     
    340340     * Writes the props to the file, unsorted (unless props is an OrderedProperties)
    341341     * Note that this does not escape the \r or \n that are unescaped in loadProps() above.
     342     * As of 0.8.1, file will be mode 600.
    342343     */
    343344    public static void storeProps(Properties props, File file) throws IOException {
    344345        PrintWriter out = null;
    345346        try {
    346             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")));
     347            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));
    347348            out.println("# NOTE: This I2P config file must use UTF-8 encoding");
    348349            for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
  • core/java/src/net/i2p/data/Hash.java

    r5a782cc rb41e714a  
    3232    }
    3333
     34    /** @throws IllegalArgumentException if data is not 32 bytes (null is ok) */
    3435    public Hash(byte data[]) {
    3536        setData(data);
     
    4041    }
    4142
     43    /** @throws IllegalArgumentException if data is not 32 bytes (null is ok) */
    4244    public void setData(byte[] data) {
     45        if (data != null && data.length != HASH_LENGTH)
     46            throw new IllegalArgumentException("Hash must be 32 bytes");
    4347        _data = data;
    4448        _stringified = null;
  • core/java/src/net/i2p/data/RouterAddress.java

    r5a782cc rb41e714a  
    1515import java.util.Date;
    1616import java.util.Iterator;
     17import java.util.Map;
    1718import java.util.Properties;
     19
     20import net.i2p.util.OrderedProperties;
    1821
    1922/**
     
    2932
    3033    public RouterAddress() {
    31         setCost(-1);
     34        _cost = -1;
    3235    }
    3336
     
    135138    }
    136139   
     140    /**
     141     *  This is used on peers.jsp so sort options so it looks better.
     142     *  We don't just use OrderedProperties for _options because DataHelper.writeProperties()
     143     *  sorts also.
     144     */
    137145    @Override
    138146    public String toString() {
    139         StringBuilder buf = new StringBuilder(64);
     147        StringBuilder buf = new StringBuilder(128);
    140148        buf.append("[RouterAddress: ");
    141         buf.append("\n\tTransportStyle: ").append(getTransportStyle());
    142         buf.append("\n\tCost: ").append(getCost());
    143         buf.append("\n\tExpiration: ").append(getExpiration());
    144         buf.append("\n\tOptions: #: ").append(getOptions().size());
    145         for (Iterator iter = getOptions().keySet().iterator(); iter.hasNext();) {
    146             String key = (String) iter.next();
    147             String val = getOptions().getProperty(key);
    148             buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
     149        buf.append("\n\tTransportStyle: ").append(_transportStyle);
     150        buf.append("\n\tCost: ").append(_cost);
     151        buf.append("\n\tExpiration: ").append(_expiration);
     152        if (_options != null) {
     153            buf.append("\n\tOptions: #: ").append(_options.size());
     154            Properties p = new OrderedProperties();
     155            p.putAll(_options);
     156            for (Map.Entry e : p.entrySet()) {
     157                String key = (String) e.getKey();
     158                String val = (String) e.getValue();
     159                buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
     160            }
    149161        }
    150162        buf.append("]");
  • core/java/src/net/i2p/data/i2cp/AbuseReason.java

    r5a782cc rb41e714a  
    5050    public boolean equals(Object object) {
    5151        if ((object == null) || !(object instanceof AbuseReason)) return false;
    52         return DataHelper.eq(getReason(), ((AbuseReason) object).getReason());
     52        return DataHelper.eq(_reason, ((AbuseReason) object).getReason());
    5353    }
    5454
    5555    @Override
    5656    public int hashCode() {
    57         return DataHelper.hashCode(getReason());
     57        return DataHelper.hashCode(_reason);
    5858    }
    5959
    6060    @Override
    6161    public String toString() {
    62         return "[AbuseReason: " + getReason() + "]";
     62        return "[AbuseReason: " + _reason + "]";
    6363    }
    6464}
  • core/java/src/net/i2p/data/i2cp/AbuseSeverity.java

    r5a782cc rb41e714a  
    2929
    3030    public AbuseSeverity() {
    31         setSeverity(-1);
     31        _severityId = -1;
    3232    }
    3333
     
    5757    @Override
    5858    public int hashCode() {
    59         return getSeverity();
     59        return _severityId;
    6060    }
    6161
    6262    @Override
    6363    public String toString() {
    64         return "[AbuseSeverity: " + getSeverity() + "]";
     64        return "[AbuseSeverity: " + _severityId + "]";
    6565    }
    6666}
  • core/java/src/net/i2p/data/i2cp/CreateSessionMessage.java

    r5a782cc rb41e714a  
    2828
    2929    public CreateSessionMessage(SessionConfig config) {
    30         setSessionConfig(config);
     30        _sessionConfig = config;
    3131    }
    3232
    3333    public CreateSessionMessage() {
    34         setSessionConfig(new SessionConfig());
     34        _sessionConfig = new SessionConfig();
    3535    }
    3636
     
    7676        if ((object != null) && (object instanceof CreateSessionMessage)) {
    7777            CreateSessionMessage msg = (CreateSessionMessage) object;
    78             return DataHelper.eq(getSessionConfig(), msg.getSessionConfig());
     78            return DataHelper.eq(_sessionConfig, msg.getSessionConfig());
    7979        }
    8080           
     
    8686        StringBuilder buf = new StringBuilder();
    8787        buf.append("[CreateSessionMessage: ");
    88         buf.append("\n\tConfig: ").append(getSessionConfig());
     88        buf.append("\n\tConfig: ").append(_sessionConfig);
    8989        buf.append("]");
    9090        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/DestroySessionMessage.java

    r5a782cc rb41e714a  
    7070        if ((object != null) && (object instanceof DestroySessionMessage)) {
    7171            DestroySessionMessage msg = (DestroySessionMessage) object;
    72             return DataHelper.eq(getSessionId(), msg.getSessionId());
     72            return DataHelper.eq(_sessionId, msg.getSessionId());
    7373        }
    7474           
     
    8787        StringBuilder buf = new StringBuilder();
    8888        buf.append("[DestroySessionMessage: ");
    89         buf.append("\n\tSessionId: ").append(getSessionId());
     89        buf.append("\n\tSessionId: ").append(_sessionId);
    9090        buf.append("]");
    9191        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/I2CPMessageHandler.java

    r5a782cc rb41e714a  
    4242            if (length < 0) throw new I2CPMessageException("Invalid message length specified");
    4343            int type = (int) DataHelper.readLong(in, 1);
    44             I2CPMessage msg = createMessage(in, length, type);
     44            I2CPMessage msg = createMessage(type);
    4545            msg.readMessage(in, length, type);
    4646            return msg;
     
    5454     *
    5555     */
    56     private static I2CPMessage createMessage(InputStream in, int length, int type) throws IOException,
    57                                                                                   I2CPMessageException {
     56    private static I2CPMessage createMessage(int type) throws IOException,
     57                                                       I2CPMessageException {
    5858        switch (type) {
    5959        case CreateLeaseSetMessage.MESSAGE_TYPE:
     
    102102    }
    103103
     104/***
    104105    public static void main(String args[]) {
    105106        try {
     
    110111        }
    111112    }
     113***/
    112114}
  • core/java/src/net/i2p/data/i2cp/MessageId.java

    r5a782cc rb41e714a  
    2828
    2929    public MessageId() {
    30         setMessageId(-1);
     30        _messageId = -1;
    3131    }
    3232    public MessageId(long id) {
    33         setMessageId(id);
     33        _messageId = id;
    3434    }
    3535
     
    5959    @Override
    6060    public int hashCode() {
    61         return (int)getMessageId();
     61        return (int)_messageId;
    6262    }
    6363
    6464    @Override
    6565    public String toString() {
    66         return "[MessageId: " + getMessageId() + "]";
     66        return "[MessageId: " + _messageId + "]";
    6767    }
    6868}
  • core/java/src/net/i2p/data/i2cp/MessagePayloadMessage.java

    r5a782cc rb41e714a  
    3030
    3131    public MessagePayloadMessage() {
    32         setSessionId(-1);
    33         setMessageId(-1);
     32        _sessionId = -1;
     33        _messageId = -1;
    3434    }
    3535
     
    114114            return _sessionId == msg.getSessionId()
    115115                   && _messageId == msg.getMessageId()
    116                    && DataHelper.eq(getPayload(), msg.getPayload());
     116                   && DataHelper.eq(_payload, msg.getPayload());
    117117        }
    118118           
     
    124124        StringBuilder buf = new StringBuilder();
    125125        buf.append("[MessagePayloadMessage: ");
    126         buf.append("\n\tSessionId: ").append(getSessionId());
    127         buf.append("\n\tMessageId: ").append(getMessageId());
    128         buf.append("\n\tPayload: ").append(getPayload());
     126        buf.append("\n\tSessionId: ").append(_sessionId);
     127        buf.append("\n\tMessageId: ").append(_messageId);
     128        buf.append("\n\tPayload: ").append(_payload);
    129129        buf.append("]");
    130130        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/MessageStatusMessage.java

    r5a782cc rb41e714a  
    3333    public final static int STATUS_AVAILABLE = 0;
    3434    public final static int STATUS_SEND_ACCEPTED = 1;
     35    /** unused */
    3536    public final static int STATUS_SEND_BEST_EFFORT_SUCCESS = 2;
     37    /** unused */
    3638    public final static int STATUS_SEND_BEST_EFFORT_FAILURE = 3;
    3739    public final static int STATUS_SEND_GUARANTEED_SUCCESS = 4;
     
    3941
    4042    public MessageStatusMessage() {
    41         setSessionId(-1);
    42         setStatus(-1);
    43         setMessageId(-1);
    44         setSize(-1);
    45         setNonce(-1);
     43        _sessionId = -1;
     44        _status = -1;
     45        _messageId = -1;
     46        _size = -1;
     47        _nonce = -1;
    4648    }
    4749
     
    170172        StringBuilder buf = new StringBuilder();
    171173        buf.append("[MessageStatusMessage: ");
    172         buf.append("\n\tSessionId: ").append(getSessionId());
    173         buf.append("\n\tNonce: ").append(getNonce());
    174         buf.append("\n\tMessageId: ").append(getMessageId());
    175         buf.append("\n\tStatus: ").append(getStatusString(getStatus()));
    176         buf.append("\n\tSize: ").append(getSize());
     174        buf.append("\n\tSessionId: ").append(_sessionId);
     175        buf.append("\n\tNonce: ").append(_nonce);
     176        buf.append("\n\tMessageId: ").append(_messageId);
     177        buf.append("\n\tStatus: ").append(getStatusString(_status));
     178        buf.append("\n\tSize: ").append(_size);
    177179        buf.append("]");
    178180        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/ReceiveMessageBeginMessage.java

    r5a782cc rb41e714a  
    2929
    3030    public ReceiveMessageBeginMessage() {
    31         setSessionId(-1);
    32         setMessageId(-1);
     31        _sessionId = -1;
     32        _messageId = -1;
    3333    }
    3434
     
    104104        StringBuilder buf = new StringBuilder();
    105105        buf.append("[ReceiveMessageBeginMessage: ");
    106         buf.append("\n\tSessionId: ").append(getSessionId());
    107         buf.append("\n\tMessageId: ").append(getMessageId());
     106        buf.append("\n\tSessionId: ").append(_sessionId);
     107        buf.append("\n\tMessageId: ").append(_messageId);
    108108        buf.append("]");
    109109        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/ReceiveMessageEndMessage.java

    r5a782cc rb41e714a  
    2828
    2929    public ReceiveMessageEndMessage() {
    30         setSessionId(-1);
    31         setMessageId(-1);
     30        _sessionId = -1;
     31        _messageId = -1;
    3232    }
    3333
     
    8888        StringBuilder buf = new StringBuilder();
    8989        buf.append("[ReceiveMessageEndMessage: ");
    90         buf.append("\n\tSessionId: ").append(getSessionId());
    91         buf.append("\n\tMessageId: ").append(getMessageId());
     90        buf.append("\n\tSessionId: ").append(_sessionId);
     91        buf.append("\n\tMessageId: ").append(_messageId);
    9292        buf.append("]");
    9393        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/ReconfigureSessionMessage.java

    r5a782cc rb41e714a  
    8282        if ((object != null) && (object instanceof ReconfigureSessionMessage)) {
    8383            ReconfigureSessionMessage msg = (ReconfigureSessionMessage) object;
    84             return DataHelper.eq(getSessionId(), msg.getSessionId())
    85                    && DataHelper.eq(getSessionConfig(), msg.getSessionConfig());
     84            return DataHelper.eq(_sessionId, msg.getSessionId())
     85                   && DataHelper.eq(_sessionConfig, msg.getSessionConfig());
    8686        }
    8787           
     
    9393        StringBuilder buf = new StringBuilder();
    9494        buf.append("[ReconfigureSessionMessage: ");
    95         buf.append("\n\tSessionId: ").append(getSessionId());
    96         buf.append("\n\tSessionConfig: ").append(getSessionConfig());
     95        buf.append("\n\tSessionId: ").append(_sessionId);
     96        buf.append("\n\tSessionConfig: ").append(_sessionConfig);
    9797        buf.append("]");
    9898        return buf.toString();
  • core/java/src/net/i2p/data/i2cp/RequestLeaseSetMessage.java

    r5a782cc rb41e714a  
    3131    public final static int MESSAGE_TYPE = 21;
    3232    private SessionId _sessionId;
    33     private List _endpoints;
     33    private List<TunnelEndpoint> _endpoints;
    3434    private Date _end;
    3535
     
    5252    public Hash getRouter(int endpoint) {
    5353        if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null;
    54         return ((TunnelEndpoint) _endpoints.get(endpoint)).getRouter();
     54        return _endpoints.get(endpoint).getRouter();
    5555    }
    5656
    5757    public TunnelId getTunnelId(int endpoint) {
    5858        if ((endpoint < 0) || (_endpoints.size() < endpoint)) return null;
    59         return ((TunnelEndpoint) _endpoints.get(endpoint)).getTunnelId();
     59        return _endpoints.get(endpoint).getTunnelId();
    6060    }
    6161
     
    160160
    161161        public TunnelEndpoint() {
    162             _router = null;
    163             _tunnelId = null;
    164162        }
    165163
  • core/java/src/net/i2p/data/i2cp/SessionConfig.java

    r5a782cc rb41e714a  
    169169        ByteArrayOutputStream out = new ByteArrayOutputStream();
    170170        try {
    171             _log.debug("PubKey size for destination: " + _destination.getPublicKey().getData().length);
    172             _log.debug("SigningKey size for destination: " + _destination.getSigningPublicKey().getData().length);
     171            //_log.debug("PubKey size for destination: " + _destination.getPublicKey().getData().length);
     172            //_log.debug("SigningKey size for destination: " + _destination.getSigningPublicKey().getData().length);
    173173            _destination.writeBytes(out);
    174174            DataHelper.writeProperties(out, _options, true);  // UTF-8
  • core/java/src/net/i2p/data/i2cp/SessionId.java

    r5a782cc rb41e714a  
    2727
    2828    public SessionId() {
    29         setSessionId(-1);
     29        _sessionId = -1;
    3030    }
    3131
     
    5050    public boolean equals(Object obj) {
    5151        if ((obj == null) || !(obj instanceof SessionId)) return false;
    52         return getSessionId() == ((SessionId) obj).getSessionId();
     52        return _sessionId == ((SessionId) obj).getSessionId();
    5353    }
    5454
    5555    @Override
    5656    public int hashCode() {
    57         return getSessionId();
     57        return _sessionId;
    5858    }
    5959
    6060    @Override
    6161    public String toString() {
    62         return "[SessionId: " + getSessionId() + "]";
     62        return "[SessionId: " + _sessionId + "]";
    6363    }
    6464}
  • core/java/src/net/i2p/data/i2cp/SetDateMessage.java

    r5a782cc rb41e714a  
    2929    public SetDateMessage() {
    3030        super();
    31         setDate(new Date(Clock.getInstance().now()));
     31        _date = new Date(Clock.getInstance().now());
    3232    }
    3333
     
    7171        if ((object != null) && (object instanceof SetDateMessage)) {
    7272            SetDateMessage msg = (SetDateMessage) object;
    73             return DataHelper.eq(getDate(), msg.getDate());
     73            return DataHelper.eq(_date, msg.getDate());
    7474        }
    7575           
     
    8181        StringBuilder buf = new StringBuilder();
    8282        buf.append("[SetDateMessage");
    83         buf.append("\n\tDate: ").append(getDate());
     83        buf.append("\n\tDate: ").append(_date);
    8484        buf.append("]");
    8585        return buf.toString();
  • core/java/src/net/i2p/util/EepGet.java

    r5a782cc rb41e714a  
    5656    protected long _bytesRemaining;
    5757    protected int _currentAttempt;
    58     private String _etag;
    59     private String _lastModified;
     58    protected String _etag;
     59    protected String _lastModified;
    6060    protected boolean _encodingChunked;
    6161    protected boolean _notModified;
    62     private String _contentType;
     62    protected String _contentType;
    6363    protected boolean _transferFailed;
    6464    protected boolean _headersRead;
     
    538538                throw new IOException("Too many redirects: to " + _redirectLocation);
    539539            if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     540
     541            // reset some important variables, we don't want to save the values from the redirect
     542            _bytesRemaining = -1;
     543            _redirectLocation = null;
     544            _etag = null;
     545            _lastModified = null;
     546            _contentType = null;
     547            _encodingChunked = false;
     548
    540549            sendRequest(timeout);
    541550            doFetch(timeout);
  • core/java/src/net/i2p/util/EepHead.java

    r5a782cc rb41e714a  
    117117            timeout.setInactivityTimeout(60*1000);
    118118       
     119        // Should we even follow redirects for HEAD?
    119120        if (_redirectLocation != null) {
    120121            //try {
     
    144145                throw new IOException("Too many redirects: to " + _redirectLocation);
    145146            if (_log.shouldLog(Log.INFO)) _log.info("Redirecting to " + _redirectLocation);
     147
     148            // reset some important variables, we don't want to save the values from the redirect
     149            _bytesRemaining = -1;
     150            _redirectLocation = null;
     151            _etag = null;
     152            _lastModified = null;
     153            _contentType = null;
     154            _encodingChunked = false;
     155
    146156            sendRequest(timeout);
    147157            doFetch(timeout);
  • core/java/src/net/i2p/util/LogConsoleBuffer.java

    r5a782cc rb41e714a  
    1212public class LogConsoleBuffer {
    1313    private I2PAppContext _context;
    14     private final List _buffer;
    15     private final List _critBuffer;
     14    private final List<String> _buffer;
     15    private final List<String> _critBuffer;
    1616
    1717    public LogConsoleBuffer(I2PAppContext context) {
     
    4444     *
    4545     */
    46     public List getMostRecentMessages() {
     46    public List<String> getMostRecentMessages() {
    4747        synchronized (_buffer) {
    4848            return new ArrayList(_buffer);
     
    5555     *
    5656     */
    57     public List getMostRecentCriticalMessages() {
     57    public List<String> getMostRecentCriticalMessages() {
    5858        synchronized (_critBuffer) {
    5959            return new ArrayList(_critBuffer);
  • core/java/src/net/i2p/util/LogManager.java

    r5a782cc rb41e714a  
    157157    }
    158158
    159     /** @deprecated unused */
     159    /** now used by ConfigLogingHelper */
    160160    public List<Log> getLogs() {
    161161        return new ArrayList(_logs.values());
     
    416416    /**
    417417     * Determine how many bytes are in the given formatted string (5m, 60g, 100k, etc)
    418      *
    419      */
    420     public int getFileSize(String size) {
    421         int sz = -1;
    422         try {
    423             String v = size;
    424             char mod = size.toUpperCase().charAt(size.length() - 1);
    425             if (!Character.isDigit(mod)) v = size.substring(0, size.length() - 1);
    426             int val = Integer.parseInt(v);
     418     * Size may be k, m, or g; a trailing b is ignored. Upper-case is allowed.
     419     * Spaces between the number and letter is are allowed.
     420     * The number may be in floating point.
     421     * 4096 min, 2 GB max (returns int)
     422     */
     423    public static int getFileSize(String size) {
     424        try {
     425            String v = size.trim().toUpperCase();
     426            if (v.length() < 2)
     427                return -1;
     428            if (v.endsWith("B"))
     429                v = v.substring(0, v.length() - 1);
     430            char mod = v.charAt(v.length() - 1);
     431            if (!Character.isDigit(mod)) v = v.substring(0, v.length() - 1);
     432            double val = Double.parseDouble(v);
    427433            switch (mod) {
    428434                case 'K':
     
    439445                    break;
    440446            }
    441             return val;
     447            if (val < 4096 || val > Integer.MAX_VALUE)
     448                return -1;
     449            return (int) val;
    442450        } catch (Throwable t) {
    443451            System.err.println("Error parsing config for filesize: [" + size + "]");
    444             t.printStackTrace();
    445452            return -1;
    446453        }
  • core/java/src/net/i2p/util/LogWriter.java

    r5a782cc rb41e714a  
    1212import java.io.BufferedWriter;
    1313import java.io.File;
    14 import java.io.FileOutputStream;
    1514import java.io.IOException;
    1615import java.io.OutputStream;
     
    159158        if (parent != null) {
    160159            if (!parent.exists()) {
    161                 boolean ok = parent.mkdirs();
     160                File sd = new SecureDirectory(parent.getAbsolutePath());
     161                boolean ok = sd.mkdirs();
    162162                if (!ok) {
    163163                    System.err.println("Unable to create the parent directory: " + parent.getAbsolutePath());
     
    172172        closeFile();
    173173        try {
    174             _currentOut = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), "UTF-8"));
     174            _currentOut = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(f), "UTF-8"));
    175175        } catch (IOException ioe) {
    176176            System.err.println("Error rotating into [" + f.getAbsolutePath() + "]" + ioe);
  • core/java/src/net/i2p/util/RandomSource.java

    r5a782cc rb41e714a  
    146146        FileOutputStream fos = null;
    147147        try {
    148             fos = new FileOutputStream(f);
     148            fos = new SecureFileOutputStream(f);
    149149            fos.write(buf);
    150150        } catch (IOException ioe) {
  • installer/resources/i2ptunnel.config

    r5a782cc rb41e714a  
    2626# irc
    2727tunnel.1.name=IRC Proxy
    28 tunnel.1.description=IRC proxy to access the anonymous IRC network
     28tunnel.1.description=IRC proxy to access anonymous IRC servers
    2929tunnel.1.type=ircclient
    3030tunnel.1.sharedClient=false
  • installer/resources/start-i2p.txt

    r5a782cc rb41e714a  
    22
    33$INSTALL_PATH/i2prouter start
     4
     5
     6On non-x86, run:
     7
     8$INSTALL_PATH/runplain.sh
  • router/java/src/net/i2p/data/i2np/BuildRequestRecord.java

    r5a782cc rb41e714a  
    1010
    1111/**
    12  * Hold the tunnel request record, managing its encryption and decryption.
     12 * Hold the tunnel request record, managing its ElGamal encryption and decryption.
     13 * Iterative AES encryption/decryption is done elsewhere.
     14 *
    1315 * Cleartext:
    1416 * <pre>
     
    2729 * </pre>
    2830 *
     31 * Encrypted:
     32 * <pre>
     33 *   bytes    0-15: First 16 bytes of router hash
     34 *   bytes  16-527: ElGamal encrypted block (discarding zero bytes at elg[0] and elg[257])
     35 * </pre>
     36 *
    2937 */
    3038public class BuildRequestRecord {
     
    153161    /**
    154162     * Encrypt the record to the specified peer.  The result is formatted as: <pre>
    155      *   bytes 0-15: SHA-256-128 of the current hop's identity (the toPeer parameter)
     163     *   bytes 0-15: truncated SHA-256 of the current hop's identity (the toPeer parameter)
    156164     * bytes 15-527: ElGamal-2048 encrypted block
    157165     * </pre>
  • router/java/src/net/i2p/router/KeyManager.java

    r5a782cc rb41e714a  
    2828import net.i2p.util.Clock;
    2929import net.i2p.util.Log;
     30import net.i2p.util.SecureDirectory;
     31import net.i2p.util.SecureFileOutputStream;
    3032
    3133/**
     
    143145        public void runJob() {
    144146            String keyDir = getContext().getProperty(PROP_KEYDIR, DEFAULT_KEYDIR);
    145             File dir = new File(getContext().getRouterDir(), keyDir);
     147            File dir = new SecureDirectory(getContext().getRouterDir(), keyDir);
    146148            if (!dir.exists())
    147149                dir.mkdirs();
     
    220222            try {
    221223                if (exists) {
    222                     out = new FileOutputStream(keyFile);
     224                    out = new SecureFileOutputStream(keyFile);
    223225                    structure.writeBytes(out);
    224226                    return structure;
  • router/java/src/net/i2p/router/Router.java

    r5a782cc rb41e714a  
    4747import net.i2p.util.I2PThread;
    4848import net.i2p.util.Log;
     49import net.i2p.util.SecureFileOutputStream;
    4950import net.i2p.util.SimpleScheduler;
    5051import net.i2p.util.SimpleTimer;
     
    306307   
    307308    public long getWhenStarted() { return _started; }
     309
    308310    /** wall clock uptime */
    309311    public long getUptime() {
     
    10541056     * Note that the escaping of \r or \n was probably a mistake and should be taken out.
    10551057     *
     1058     * FIXME Synchronize!!
    10561059     */
    10571060    public boolean saveConfig() {
    10581061        FileOutputStream fos = null;
    10591062        try {
    1060             fos = new FileOutputStream(_configFilename);
     1063            fos = new SecureFileOutputStream(_configFilename);
    10611064            StringBuilder buf = new StringBuilder(8*1024);
    10621065            buf.append("# NOTE: This I2P config file must use UTF-8 encoding\n");
     
    15421545        FileOutputStream fos = null;
    15431546        try {
    1544             fos = new FileOutputStream(infoFile);
     1547            fos = new SecureFileOutputStream(infoFile);
    15451548            info.writeBytes(fos);
    15461549        } catch (DataFormatException dfe) {
  • router/java/src/net/i2p/router/RouterLaunch.java

    r5a782cc rb41e714a  
    22
    33import java.io.File;
    4 import java.io.FileOutputStream;
    54import java.io.IOException;
    65import java.io.PrintStream;
     6
     7import net.i2p.util.SecureFileOutputStream;
    78
    89/**
     
    3435        System.setProperty(PROP_WRAPPER_LOG, logfile.getAbsolutePath());
    3536        try {
    36             System.setOut(new PrintStream(new FileOutputStream(logfile, true)));
     37            System.setOut(new PrintStream(new SecureFileOutputStream(logfile, true)));
    3738        } catch (IOException ioe) {
    3839            ioe.printStackTrace();
  • router/java/src/net/i2p/router/client/ClientConnectionRunner.java

    r5a782cc rb41e714a  
    1818import java.util.Set;
    1919
     20import net.i2p.client.I2PClient;
    2021import net.i2p.crypto.SessionKeyManager;
    2122import net.i2p.crypto.TransientSessionKeyManager;
     
    7778     * delivered to the client (so that we can be sure only to update when necessary)
    7879     */
    79     private final List _alreadyProcessed;
     80    private final List<MessageId> _alreadyProcessed;
    8081    private ClientWriterRunner _writer;
    8182    private Hash _destHashCache;
    8283    /** are we, uh, dead */
    8384    private boolean _dead;
     85    /** For outbound traffic. true if i2cp.messageReliability = "none"; @since 0.8.1 */
     86    private boolean _dontSendMSM;
    8487   
    8588    /**
     
    9295        _manager = manager;
    9396        _socket = socket;
    94         _config = null;
    9597        _messages = new ConcurrentHashMap();
    9698        _alreadyProcessed = new ArrayList();
    9799        _acceptedPending = new ConcurrentHashSet();
    98         _dead = false;
    99100    }
    100101   
     
    190191            _log.debug("SessionEstablished called for destination " + _destHashCache.toBase64());
    191192        _config = config;
     193        // This is the only option that is interpreted here, not at the tunnel manager
     194        if (config.getOptions() != null)
     195            _dontSendMSM = "none".equalsIgnoreCase(config.getOptions().getProperty(I2PClient.PROP_RELIABILITY));
    192196        // per-destination session key manager to prevent rather easy correlation
    193197        if (_sessionKeyManager == null)
     
    198202    }
    199203   
     204    /**
     205     * Send a notification to the client that their message (id specified) was
     206     * delivered (or failed delivery)
     207     * Note that this sends the Guaranteed status codes, even though we only support best effort.
     208     * Doesn't do anything if i2cp.messageReliability = "none"
     209     */
    200210    void updateMessageDeliveryStatus(MessageId id, boolean delivered) {
    201         if (_dead) return;
     211        if (_dead || _dontSendMSM)
     212            return;
    202213        _context.jobQueue().addJob(new MessageDeliveryStatusUpdate(id, delivered));
    203214    }
     215
    204216    /**
    205217     * called after a new leaseSet is granted by the client, the NetworkDb has been
     
    255267        if (message instanceof SendMessageExpiresMessage)
    256268            expiration = ((SendMessageExpiresMessage) message).getExpiration().getTime();
    257         _acceptedPending.add(id);
     269        if (!_dontSendMSM)
     270            _acceptedPending.add(id);
    258271
    259272        if (_log.shouldLog(Log.DEBUG))
     
    277290     * Send a notification to the client that their message (id specified) was accepted
    278291     * for delivery (but not necessarily delivered)
    279      *
     292     * Doesn't do anything if i2cp.messageReliability = "none"
    280293     */
    281294    void ackSendMessage(MessageId id, long nonce) {
     295        if (_dontSendMSM)
     296            return;
    282297        SessionId sid = _sessionId;
    283298        if (sid == null) return;
     
    518533
    519534        public String getName() { return "Update Delivery Status"; }
     535
     536        /**
     537         * Note that this sends the Guaranteed status codes, even though we only support best effort.
     538         */
    520539        public void runJob() {
    521540            if (_dead) return;
     
    524543            msg.setMessageId(_messageId.getMessageId());
    525544            msg.setSessionId(_sessionId.getSessionId());
     545            // has to be >= 0, it is initialized to -1
    526546            msg.setNonce(2);
    527547            msg.setSize(0);
  • router/java/src/net/i2p/router/client/ClientListenerRunner.java

    r5a782cc rb41e714a  
    4242        _manager = manager;
    4343        _port = port;
    44         _running = false;
    45         _listening = false;
    4644       
    4745        String val = context.getProperty(BIND_ALL_INTERFACES);
  • router/java/src/net/i2p/router/client/ClientManagerFacadeImpl.java

    r5a782cc rb41e714a  
    4444    public ClientManagerFacadeImpl(RouterContext context) {
    4545        _context = context;
    46         _manager = null;
    4746        _log.debug("Client manager facade created");
    4847    }
  • router/java/src/net/i2p/router/client/LeaseRequestState.java

    r5a782cc rb41e714a  
    3434        _expiration = expiration;
    3535        _requestedLeaseSet = requested;
    36         _successful = false;
    3736    }
    3837   
  • router/java/src/net/i2p/router/client/MessageReceivedJob.java

    r5a782cc rb41e714a  
    4848    /**
    4949     * Deliver notification to the client that the given message is available.
    50      * This is synchronous and returns true if the notification was sent safely,
    51      * otherwise it returns false
    52      *
    5350     */
    5451    public void messageAvailable(MessageId id, long size) {
     
    6057        msg.setSessionId(_runner.getSessionId().getSessionId());
    6158        msg.setSize(size);
     59        // has to be >= 0, it is initialized to -1
    6260        msg.setNonce(1);
    6361        msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE);
  • router/java/src/net/i2p/router/client/RequestLeaseSetJob.java

    r5a782cc rb41e714a  
    4545        _onFail = onFail;
    4646        _requestState = state;
    47         ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
    48         ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
    49         ctx.statManager().createRateStat("client.requestLeaseSetDropped", "How frequently the router requests a new leaseSet but the client drops?", "ClientMessages", new long[] { 10*60*1000, 60*60*1000, 24*60*60*1000 });
     47        ctx.statManager().createRateStat("client.requestLeaseSetSuccess", "How frequently the router requests successfully a new leaseSet?", "ClientMessages", new long[] { 60*60*1000 });
     48        ctx.statManager().createRateStat("client.requestLeaseSetTimeout", "How frequently the router requests a new leaseSet but gets no reply?", "ClientMessages", new long[] { 60*60*1000 });
     49        ctx.statManager().createRateStat("client.requestLeaseSetDropped", "How frequently the router requests a new leaseSet but the client drops?", "ClientMessages", new long[] { 60*60*1000 });
    5050    }
    5151   
  • router/java/src/net/i2p/router/message/GarlicConfig.java

    r5a782cc rb41e714a  
    3838   
    3939    public GarlicConfig() {
    40         _recipient = null;
    41         _recipientPublicKey = null;
    42         _cert = null;
    4340        _id = -1;
    4441        _expiration = -1;
    4542        _cloveConfigs = new ArrayList();
    46         _instructions = null;
    47         _requestAck = false;
    48         _replyThroughRouter = null;
    49         _replyInstructions = null;
    50         _replyBlockCertificate = null;
    5143        _replyBlockMessageId = -1;
    5244        _replyBlockExpiration = -1;
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    r5a782cc rb41e714a  
    195195    public void shutdown() {
    196196        _initialized = false;
    197         _kb = null;
     197        // don't null out _kb, it can cause NPEs in concurrent operations
     198        //_kb = null;
    198199        if (_ds != null)
    199200            _ds.stop();
    200         _ds = null;
     201        // don't null out _ds, it can cause NPEs in concurrent operations
     202        //_ds = null;
    201203        _exploreKeys.clear(); // hope this doesn't cause an explosion, it shouldn't.
    202204        // _exploreKeys = null;
     
    751753            if (routerInfo.getAddresses().isEmpty())
    752754                return "Peer " + key.toBase64() + " published > 90m ago with no addresses";
     755            // This should cover the introducers case below too
     756            // And even better, catches the case where the router is unreachable but knows no introducers
     757            if (routerInfo.getCapabilities().indexOf(Router.CAPABILITY_UNREACHABLE) >= 0)
     758                return "Peer " + key.toBase64() + " published > 90m ago and thinks it is unreachable";
    753759            RouterAddress ra = routerInfo.getTargetAddress("SSU");
    754760            if (ra != null) {
  • router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java

    r5a782cc rb41e714a  
    3030import net.i2p.util.I2PThread;
    3131import net.i2p.util.Log;
     32import net.i2p.util.SecureDirectory;
     33import net.i2p.util.SecureFileOutputStream;
    3234
    3335/**
     
    289291            if (dbFile.lastModified() < dataPublishDate) {
    290292                // our filesystem is out of date, lets replace it
    291                 fos = new FileOutputStream(dbFile);
     293                fos = new SecureFileOutputStream(dbFile);
    292294                try {
    293295                    data.writeBytes(fos);
     
    441443   
    442444    private File getDbDir() throws IOException {
    443         File f = new File(_context.getRouterDir(), _dbDir);
     445        File f = new SecureDirectory(_context.getRouterDir(), _dbDir);
    444446        if (!f.exists()) {
    445447            boolean created = f.mkdirs();
  • router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java

    r5a782cc rb41e714a  
    1818import net.i2p.util.I2PAppThread;
    1919import net.i2p.util.Log;
     20import net.i2p.util.SecureDirectory;
     21import net.i2p.util.SecureFileOutputStream;
    2022import net.i2p.util.SSLEepGet;
    2123import net.i2p.util.Translate;
     
    261263        private void writeSeed(String name, byte data[]) throws Exception {
    262264            String dirName = "netDb"; // _context.getProperty("router.networkDatabase.dbDir", "netDb");
    263             File netDbDir = new File(_context.getRouterDir(), dirName);
     265            File netDbDir = new SecureDirectory(_context.getRouterDir(), dirName);
    264266            if (!netDbDir.exists()) {
    265267                boolean ok = netDbDir.mkdirs();
    266268            }
    267             FileOutputStream fos = new FileOutputStream(new File(netDbDir, "routerInfo-" + name + ".dat"));
     269            FileOutputStream fos = new SecureFileOutputStream(new File(netDbDir, "routerInfo-" + name + ".dat"));
    268270            fos.write(data);
    269271            fos.close();
  • router/java/src/net/i2p/router/peermanager/ProfilePersistenceHelper.java

    r5a782cc rb41e714a  
    44import java.io.File;
    55import java.io.FileInputStream;
    6 import java.io.FileOutputStream;
    76import java.io.FilenameFilter;
    87import java.io.IOException;
     
    2019import net.i2p.router.RouterContext;
    2120import net.i2p.util.Log;
     21import net.i2p.util.SecureDirectory;
     22import net.i2p.util.SecureFileOutputStream;
    2223
    2324class ProfilePersistenceHelper {
     
    6263        OutputStream fos = null;
    6364        try {
    64             fos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(f)));
     65            fos = new BufferedOutputStream(new GZIPOutputStream(new SecureFileOutputStream(f)));
    6566            writeProfile(profile, fos);
    6667        } catch (IOException ioe) {
     
    311312        if (_profileDir == null) {
    312313            String dir = _context.getProperty(PROP_PEER_PROFILE_DIR, DEFAULT_PEER_PROFILE_DIR);
    313             _profileDir = new File(_context.getRouterDir(), dir);
     314            _profileDir = new SecureDirectory(_context.getRouterDir(), dir);
    314315        }
    315316        return _profileDir;
  • router/java/src/net/i2p/router/startup/ClientAppConfig.java

    r5a782cc rb41e714a  
    1212import net.i2p.data.DataHelper;
    1313import net.i2p.router.RouterContext;
     14import net.i2p.util.SecureFileOutputStream;
    1415
    1516
     
    192193        FileOutputStream fos = null;
    193194        try {
    194             fos = new FileOutputStream(cfgFile);
     195            fos = new SecureFileOutputStream(cfgFile);
    195196            StringBuilder buf = new StringBuilder(2048);
    196197            for(int i = 0; i < apps.size(); i++) {
  • router/java/src/net/i2p/router/startup/CreateRouterInfoJob.java

    r5a782cc rb41e714a  
    2828import net.i2p.router.RouterContext;
    2929import net.i2p.util.Log;
     30import net.i2p.util.SecureFileOutputStream;
    3031
    3132public class CreateRouterInfoJob extends JobImpl {
     
    8182            String infoFilename = getContext().getProperty(Router.PROP_INFO_FILENAME, Router.PROP_INFO_FILENAME_DEFAULT);
    8283            File ifile = new File(getContext().getRouterDir(), infoFilename);
    83             fos1 = new FileOutputStream(ifile);
     84            fos1 = new SecureFileOutputStream(ifile);
    8485            info.writeBytes(fos1);
    8586           
    8687            String keyFilename = getContext().getProperty(Router.PROP_KEYS_FILENAME, Router.PROP_KEYS_FILENAME_DEFAULT);
    8788            File kfile = new File(getContext().getRouterDir(), keyFilename);
    88             fos2 = new FileOutputStream(kfile);
     89            fos2 = new SecureFileOutputStream(kfile);
    8990            privkey.writeBytes(fos2);
    9091            signingPrivKey.writeBytes(fos2);
  • router/java/src/net/i2p/router/startup/RebuildRouterInfoJob.java

    r5a782cc rb41e714a  
    2727import net.i2p.router.RouterContext;
    2828import net.i2p.util.Log;
     29import net.i2p.util.SecureFileOutputStream;
    2930
    3031/**
     
    136137            FileOutputStream fos = null;
    137138            try {
    138                 fos = new FileOutputStream(infoFile);
     139                fos = new SecureFileOutputStream(infoFile);
    139140                info.writeBytes(fos);
    140141            } catch (DataFormatException dfe) {
  • router/java/src/net/i2p/router/startup/WorkingDir.java

    r5a782cc rb41e714a  
    1212
    1313import net.i2p.data.DataHelper;
     14import net.i2p.util.SecureDirectory;
     15import net.i2p.util.SecureFileOutputStream;
    1416
    1517/**
     
    6567        File dirf = null;
    6668        if (dir != null) {
    67             dirf = new File(dir);
     69            dirf = new SecureDirectory(dir);
    6870        } else {
    6971            String home = System.getProperty("user.home");
     
    7274                if (appdata != null)
    7375                    home = appdata;
    74                 dirf = new File(home, WORKING_DIR_DEFAULT_WINDOWS);
     76                dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_WINDOWS);
    7577            } else {
    7678                if (DAEMON_USER.equals(System.getProperty("user.name")))
    77                     dirf = new File(home, WORKING_DIR_DEFAULT_DAEMON);
     79                    dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT_DAEMON);
    7880                else
    79                     dirf = new File(home, WORKING_DIR_DEFAULT);
     81                    dirf = new SecureDirectory(home, WORKING_DIR_DEFAULT);
    8082            }
    8183        }
     
    144146        success &= migrateJettyXml(oldDirf, dirf);
    145147        success &= migrateClientsConfig(oldDirf, dirf);
    146         success &= copy(new File(oldDirf, "docs/news.xml"), new File(dirf, "docs"));
     148        success &= copy(new File(oldDirf, "docs/news.xml"), new SecureDirectory(dirf, "docs"));
    147149
    148150        // Report success or failure
     
    198200        try {
    199201            in = new FileInputStream(oldFile);
    200             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF-8")));
     202            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(newFile), "UTF-8")));
    201203            out.println("# Modified by I2P User dir migration script");
    202204            String s = null;
     
    241243        try {
    242244            in = new FileInputStream(oldFile);
    243             out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile), "UTF-8")));
     245            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(newFile), "UTF-8")));
    244246            String s = null;
    245247            while ((s = DataHelper.readLine(in)) != null) {
     
    271273     * @return true for success OR if src does not exist
    272274     */
    273     public static final boolean copy(File src, File targetDir) {
     275    private static boolean copy(File src, File targetDir) {
    274276        if (!src.exists())
    275277            return true;
     
    281283            System.err.println("Created " + targetDir.getPath());
    282284        }
    283         File targetFile = new File(targetDir, src.getName());
     285        // SecureDirectory is a File so this works for non-directories too
     286        File targetFile = new SecureDirectory(targetDir, src.getName());
    284287        if (!src.isDirectory())
    285288            return copyFile(src, targetFile);
     
    306309    /**
    307310     * @param src not a directory, must exist
    308      * @param dst not a directory, will be overwritten if existing
     311     * @param dst not a directory, will be overwritten if existing, will be mode 600
    309312     * @return true if it was copied successfully
    310313     */
    311     public static boolean copyFile(File src, File dst) {
     314    private static boolean copyFile(File src, File dst) {
    312315        if (!src.exists()) return false;
    313316        boolean rv = true;
     
    318321        try {
    319322            in = new FileInputStream(src);
    320             out = new FileOutputStream(dst);
     323            out = new SecureFileOutputStream(dst);
    321324           
    322325            int read = 0;
  • router/java/src/net/i2p/router/transport/GeoIP.java

    r5a782cc rb41e714a  
    9999            if (_lock.getAndSet(true))
    100100                return;
    101             // clear the negative cache every few runs, to prevent it from getting too big
    102             if (((++_lookupRunCount) % CLEAR) == 0)
    103                 _notFound.clear();
    104             Long[] search = _pendingSearch.toArray(new Long[_pendingSearch.size()]);
    105             if (search.length <= 0)
    106                 return;
    107             _pendingSearch.clear();
    108             Arrays.sort(search);
    109             String[] countries = readGeoIPFile(search);
    110 
    111             for (int i = 0; i < countries.length; i++) {
    112                 if (countries[i] != null)
    113                     _IPToCountry.put(search[i], countries[i]);
    114                 else
    115                     _notFound.add(search[i]);
     101            try {
     102                // clear the negative cache every few runs, to prevent it from getting too big
     103                if (((++_lookupRunCount) % CLEAR) == 0)
     104                    _notFound.clear();
     105                Long[] search = _pendingSearch.toArray(new Long[_pendingSearch.size()]);
     106                if (search.length <= 0)
     107                    return;
     108                _pendingSearch.clear();
     109                Arrays.sort(search);
     110                String[] countries = readGeoIPFile(search);
     111   
     112                for (int i = 0; i < countries.length; i++) {
     113                    if (countries[i] != null)
     114                        _IPToCountry.put(search[i], countries[i]);
     115                    else
     116                        _notFound.add(search[i]);
     117                }
     118            } finally {
     119                _lock.set(false);
    116120            }
    117             _lock.set(false);
    118121        }
    119122    }
  • router/java/src/net/i2p/router/transport/TransportManager.java

    r5a782cc rb41e714a  
    2222import java.util.TreeMap;
    2323import java.util.Vector;
     24import java.util.concurrent.ConcurrentHashMap;
    2425
    2526import net.i2p.data.Hash;
     
    3738public class TransportManager implements TransportEventListener {
    3839    private Log _log;
    39     private List<Transport> _transports;
     40    /**
     41     * Converted from List to prevent concurrent modification exceptions.
     42     * If we want more than one transport with the same style we will have to change this.
     43     */
     44    private Map<String, Transport> _transports;
    4045    private RouterContext _context;
    4146    private UPnPManager _upnpManager;
     
    5762        _context.statManager().createRateStat("transport.bidFailNoTransports", "Could not attempt to bid on message, as none of the transports could attempt it", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
    5863        _context.statManager().createRateStat("transport.bidFailAllTransports", "Could not attempt to bid on message, as all of the transports had failed", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
    59         _transports = new ArrayList();
     64        _transports = new ConcurrentHashMap(2);
    6065        if (Boolean.valueOf(_context.getProperty(PROP_ENABLE_UPNP, "true")).booleanValue())
    6166            _upnpManager = new UPnPManager(context, this);
     
    6469    public void addTransport(Transport transport) {
    6570        if (transport == null) return;
    66         _transports.add(transport);
     71        _transports.put(transport.getStyle(), transport);
    6772        transport.setListener(this);
    6873    }
     
    7075    public void removeTransport(Transport transport) {
    7176        if (transport == null) return;
    72         _transports.remove(transport);
     77        _transports.remove(transport.getStyle());
    7378        transport.setListener(null);
    7479    }
     
    141146        configTransports();
    142147        _log.debug("Starting up the transport manager");
    143         for (int i = 0; i < _transports.size(); i++) {
    144             Transport t = _transports.get(i);
     148        for (Transport t : _transports.values()) {
    145149            RouterAddress addr = t.startListening();
    146150            if (_log.shouldLog(Log.DEBUG))
    147                 _log.debug("Transport " + i + " (" + t.getStyle() + ") started");
     151                _log.debug("Transport " + t.getStyle() + " started");
    148152        }
    149153        // kick UPnP - Do this to get the ports opened even before UDP registers an address
     
    162166        if (_upnpManager != null)
    163167            _upnpManager.stop();
    164         for (int i = 0; i < _transports.size(); i++) {
    165             _transports.get(i).stopListening();
     168        for (Transport t : _transports.values()) {
     169            t.stopListening();
    166170        }
    167171        _transports.clear();
     
    169173   
    170174    public Transport getTransport(String style) {
    171         for (int i = 0; i < _transports.size(); i++) {
    172             Transport t = _transports.get(i);
    173             if(style.equals(t.getStyle()))
    174                 return t;
    175         }
    176         return null;
     175        return _transports.get(style);
    177176    }
    178177   
     
    190189    public int countActivePeers() {
    191190        int peers = 0;
    192         for (int i = 0; i < _transports.size(); i++) {
    193             peers += _transports.get(i).countActivePeers();
     191        for (Transport t : _transports.values()) {
     192            peers += t.countActivePeers();
    194193        }
    195194        return peers;
     
    198197    public int countActiveSendPeers() {
    199198        int peers = 0;
    200         for (int i = 0; i < _transports.size(); i++) {
    201             peers += _transports.get(i).countActiveSendPeers();
     199        for (Transport t : _transports.values()) {
     200            peers += t.countActiveSendPeers();
    202201        }
    203202        return peers;
     
    211210      */
    212211    public boolean haveOutboundCapacity(int pct) {
    213         for (int i = 0; i < _transports.size(); i++) {
    214             if (_transports.get(i).haveCapacity(pct))
     212        for (Transport t : _transports.values()) {
     213            if (t.haveCapacity(pct))
    215214                return true;
    216215        }
     
    226225        if (_transports.isEmpty())
    227226            return false;
    228         for (int i = 0; i < _transports.size(); i++) {
    229             if (!_transports.get(i).haveCapacity(HIGH_CAPACITY_PCT))
     227        for (Transport t : _transports.values()) {
     228            if (!t.haveCapacity(HIGH_CAPACITY_PCT))
    230229                return false;
    231230        }
     
    240239      */
    241240    public boolean haveInboundCapacity(int pct) {
    242         for (int i = 0; i < _transports.size(); i++) {
    243