Changeset 3ec92c8


Ignore:
Timestamp:
Dec 16, 2005 3:00:48 AM (15 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
2a922098
Parents:
b37bb93
git-author:
jrandom <jrandom> (12/16/05 03:00:48)
git-committer:
zzz <zzz@…> (12/16/05 03:00:48)
Message:

2005-12-15 jrandom

  • Added a first pass to the I2PSnark web UI (see /i2psnark/)
Files:
2 added
14 edited

Legend:

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

    rb37bb93 r3ec92c8  
    22<project basedir="." default="all" name="i2psnark">
    33    <target name="all" depends="clean, build" />
    4     <target name="build" depends="builddep, jar" />
     4    <target name="build" depends="builddep, jar, war" />
    55    <target name="builddep">
     6        <ant dir="../../jetty/" target="build" />
    67        <ant dir="../../ministreaming/java/" target="build" />
    78        <!-- ministreaming will build core -->
     
    1415            debug="true" deprecation="on" source="1.3" target="1.3"
    1516            destdir="./build/obj"
    16             classpath="../../../core/java/build/i2p.jar:../../ministreaming/java/build/mstreaming.jar" />
     17            classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../ministreaming/java/build/mstreaming.jar" />
    1718    </target>
    1819    <target name="jar" depends="builddep, compile">
    19         <jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class">
     20        <jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/*Servlet.class">
    2021            <manifest>
    2122                <attribute name="Main-Class" value="org.klomp.snark.Snark" />
     
    2324            </manifest>
    2425        </jar>
     26    </target>   
     27    <target name="war" depends="jar">
     28        <war destfile="../i2psnark.war" webxml="../web.xml">
     29          <classes dir="./build/obj" includes="**/*" />
     30        </war>
    2531    </target>
    2632    <target name="clean">
    2733        <delete dir="./build" />
     34        <delete file="../i2psnark.war" />
    2835    </target>
    2936    <target name="cleandep" depends="clean">
  • apps/i2psnark/java/src/org/klomp/snark/ConnectionAcceptor.java

    rb37bb93 r3ec92c8  
    3333public class ConnectionAcceptor implements Runnable
    3434{
    35   private final I2PServerSocket serverSocket;
     35  private I2PServerSocket serverSocket;
    3636  private final PeerAcceptor peeracceptor;
    3737  private Thread thread;
    3838
    3939  private boolean stop;
     40  private boolean socketChanged;
    4041
    4142  public ConnectionAcceptor(I2PServerSocket serverSocket,
     
    4546    this.peeracceptor = peeracceptor;
    4647   
     48    socketChanged = false;
    4749    stop = false;
    48     thread = new Thread(this);
     50    thread = new Thread(this, "I2PSnark acceptor");
     51    thread.setDaemon(true);
    4952    thread.start();
    5053  }
     
    6669      t.interrupt();
    6770  }
     71 
     72  public void restart() {
     73      serverSocket = I2PSnarkUtil.instance().getServerSocket();
     74      socketChanged = true;
     75      Thread t = thread;
     76      if (t != null)
     77          t.interrupt();
     78  }
    6879
    6980  public int getPort()
     
    7687    while(!stop)
    7788      {
     89        if (socketChanged) {
     90            // ok, already updated
     91            socketChanged = false;
     92        }
     93        if (serverSocket == null) {
     94            Snark.debug("Server socket went away.. boo hiss", Snark.ERROR);
     95            stop = true;
     96            return;
     97        }
    7898        try
    7999          {
    80             final I2PSocket socket = serverSocket.accept();
    81             Thread t = new Thread("Connection-" + socket)
    82               {
    83                 public void run()
    84                 {
    85                   try
    86                     {
    87                       InputStream in = socket.getInputStream();
    88                       OutputStream out = socket.getOutputStream();
    89                       BufferedInputStream bis = new BufferedInputStream(in);
    90                       BufferedOutputStream bos = new BufferedOutputStream(out);
    91                      
    92                       // See what kind of connection it is.
    93                       /*
    94                       if (httpacceptor != null)
    95                         {
    96                           byte[] scratch = new byte[4];
    97                           bis.mark(4);
    98                           int len = bis.read(scratch);
    99                           if (len != 4)
    100                             throw new IOException("Need at least 4 bytes");
    101                           bis.reset();
    102                           if (scratch[0] == 19 && scratch[1] == 'B'
    103                               && scratch[2] == 'i' && scratch[3] == 't')
    104                             peeracceptor.connection(socket, bis, bos);
    105                           else if (scratch[0] == 'G' && scratch[1] == 'E'
    106                                    && scratch[2] == 'T' && scratch[3] == ' ')
    107                             httpacceptor.connection(socket, bis, bos);
    108                         }
    109                       else
    110                        */
    111                         peeracceptor.connection(socket, bis, bos);
    112                     }
    113                   catch (IOException ioe)
    114                     {
    115                       try
    116                         {
    117                           socket.close();
    118                         }
    119                       catch (IOException ignored) { }
    120                     }
     100            I2PSocket socket = serverSocket.accept();
     101            if (socket == null) {
     102                if (socketChanged) {
     103                    continue;
     104                } else {
     105                    Snark.debug("Null socket accepted, but socket wasn't changed?", Snark.ERROR);
    121106                }
    122               };
    123             t.start();
     107            } else {
     108                Thread t = new Thread(new Handler(socket), "Connection-" + socket);
     109                t.start();
     110            }
    124111          }
    125112        catch (I2PException ioe)
    126113          {
    127             Snark.debug("Error while accepting: " + ioe, Snark.ERROR);
    128             stop = true;
     114            if (!socketChanged) {
     115                Snark.debug("Error while accepting: " + ioe, Snark.ERROR);
     116                stop = true;
     117            }
    129118          }
    130119        catch (IOException ioe)
     
    141130    catch (I2PException ignored) { }
    142131  }
     132 
     133  private class Handler implements Runnable {
     134      private I2PSocket _socket;
     135      public Handler(I2PSocket socket) {
     136          _socket = socket;
     137      }
     138      public void run() {
     139          try {
     140              InputStream in = _socket.getInputStream();
     141              OutputStream out = _socket.getOutputStream();
     142              BufferedInputStream bis = new BufferedInputStream(in);
     143              BufferedOutputStream bos = new BufferedOutputStream(out);
     144
     145              peeracceptor.connection(_socket, bis, bos);
     146          } catch (IOException ioe) {
     147              try { _socket.close(); } catch (IOException ignored) { }
     148          }
     149      }
     150  }
    143151}
  • apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java

    rb37bb93 r3ec92c8  
    1414
    1515import java.io.*;
    16 import java.util.Properties;
     16import java.util.*;
    1717
    1818/**
     
    3030    private String _i2cpHost;
    3131    private int _i2cpPort;
    32     private Properties _opts;
     32    private Map _opts;
    3333    private I2PSocketManager _manager;
     34    private boolean _configured;
    3435   
    3536    private I2PSnarkUtil() {
    3637        _context = I2PAppContext.getGlobalContext();
    3738        _log = _context.logManager().getLog(Snark.class);
     39        _opts = new HashMap();
    3840        setProxy("127.0.0.1", 4444);
    3941        setI2CPConfig("127.0.0.1", 7654, null);
     42        _configured = false;
    4043    }
    4144   
     
    5558            _proxyPort = -1;
    5659        }
    57     }
    58    
    59     public void setI2CPConfig(String i2cpHost, int i2cpPort, Properties opts) {
     60        _configured = true;
     61    }
     62   
     63    public boolean configured() { return _configured; }
     64   
     65    public void setI2CPConfig(String i2cpHost, int i2cpPort, Map opts) {
    6066        _i2cpHost = i2cpHost;
    6167        _i2cpPort = i2cpPort;
    6268        if (opts != null)
    63             _opts = opts;
    64     }
     69            _opts.putAll(opts);
     70        _configured = true;
     71    }
     72   
     73    public String getI2CPHost() { return _i2cpHost; }
     74    public int getI2CPPort() { return _i2cpPort; }
     75    public Map getI2CPOptions() { return _opts; }
     76    public String getEepProxyHost() { return _proxyHost; }
     77    public int getEepProxyPort() { return _proxyPort; }
     78    public boolean getEepProxySet() { return _shouldProxy; }
    6579   
    6680    /**
    6781     * Connect to the router, if we aren't already
    6882     */
    69     boolean connect() {
     83    public boolean connect() {
    7084        if (_manager == null) {
    71             _manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, _opts);
     85            Properties opts = new Properties();
     86            if (_opts != null) {
     87                for (Iterator iter = _opts.keySet().iterator(); iter.hasNext(); ) {
     88                    String key = (String)iter.next();
     89                    opts.setProperty(key, _opts.get(key).toString());
     90                }
     91            }
     92            if (opts.getProperty("inbound.nickname") == null)
     93                opts.setProperty("inbound.nickname", "I2PSnark");
     94            _manager = I2PSocketManagerFactory.createManager(_i2cpHost, _i2cpPort, opts);
    7295        }
    7396        return (_manager != null);
     97    }
     98   
     99    public boolean connected() { return _manager != null; }
     100    /**
     101     * Destroy the destination itself
     102     */
     103    public void disconnect() {
     104        I2PSocketManager mgr = _manager;
     105        _manager = null;
     106        mgr.destroySocketManager();
    74107    }
    75108   
     
    86119     * fetch the given URL, returning the file it is stored in, or null on error
    87120     */
    88     File get(String url) {
     121    public File get(String url) { return get(url, true); }
     122    public File get(String url, boolean rewrite) {
    89123        _log.debug("Fetching [" + url + "] proxy=" + _proxyHost + ":" + _proxyPort + ": " + _shouldProxy);
    90124        File out = null;
     
    96130            return null;
    97131        }
    98         String fetchURL = rewriteAnnounce(url);
    99         _log.debug("Rewritten url [" + fetchURL + "]");
     132        String fetchURL = url;
     133        if (rewrite)
     134            fetchURL = rewriteAnnounce(url);
     135        //_log.debug("Rewritten url [" + fetchURL + "]");
    100136        EepGet get = new EepGet(_context, _shouldProxy, _proxyHost, _proxyPort, 1, out.getAbsolutePath(), fetchURL);
    101137        if (get.fetch()) {
     
    109145    }
    110146   
    111     I2PServerSocket getServerSocket() {
     147    public I2PServerSocket getServerSocket() {
    112148        return _manager.getServerSocket();
    113149    }
  • apps/i2psnark/java/src/org/klomp/snark/Peer.java

    rb37bb93 r3ec92c8  
    3838
    3939  private final byte[] my_id;
    40   private final MetaInfo metainfo;
     40  final MetaInfo metainfo;
    4141
    4242  // The data in/output streams set during the handshake and used by
  • apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java

    rb37bb93 r3ec92c8  
    7171                it.remove();
    7272                coordinator.removePeerFromPieces(peer);
     73                coordinator.peerCount = coordinator.peers.size();
    7374                continue;
    7475              }
     
    186187            // Put it at the back of the list
    187188            coordinator.peers.remove(worstDownloader);
     189            coordinator.peerCount = coordinator.peers.size();
    188190            removed.add(worstDownloader);
    189191          }
     
    194196        // Put peers back at the end of the list that we removed earlier.
    195197        coordinator.peers.addAll(removed);
     198        coordinator.peerCount = coordinator.peers.size();
    196199      }
    197200  }
  • apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java

    rb37bb93 r3ec92c8  
    2525import java.util.*;
    2626
     27import net.i2p.util.Log;
     28
    2729class PeerConnectionIn implements Runnable
    2830{
     31  private Log _log = new Log(PeerConnectionIn.class);
    2932  private final Peer peer;
    3033  private final DataInputStream din;
     
    7376              {
    7477                ps.keepAliveMessage();
     78                if (_log.shouldLog(Log.DEBUG))
     79                    _log.debug("Received keepalive from " + peer + " on " + peer.metainfo.getName());
    7580                continue;
    7681              }
     
    8388              case 0:
    8489                ps.chokeMessage(true);
     90                if (_log.shouldLog(Log.DEBUG))
     91                    _log.debug("Received choke from " + peer + " on " + peer.metainfo.getName());
    8592                break;
    8693              case 1:
    8794                ps.chokeMessage(false);
     95                if (_log.shouldLog(Log.DEBUG))
     96                    _log.debug("Received unchoke from " + peer + " on " + peer.metainfo.getName());
    8897                break;
    8998              case 2:
    9099                ps.interestedMessage(true);
     100                if (_log.shouldLog(Log.DEBUG))
     101                    _log.debug("Received interested from " + peer + " on " + peer.metainfo.getName());
    91102                break;
    92103              case 3:
    93104                ps.interestedMessage(false);
     105                if (_log.shouldLog(Log.DEBUG))
     106                    _log.debug("Received not interested from " + peer + " on " + peer.metainfo.getName());
    94107                break;
    95108              case 4:
    96109                piece = din.readInt();
    97110                ps.haveMessage(piece);
     111                if (_log.shouldLog(Log.DEBUG))
     112                    _log.debug("Received havePiece(" + piece + ") from " + peer + " on " + peer.metainfo.getName());
    98113                break;
    99114              case 5:
     
    101116                din.readFully(bitmap);
    102117                ps.bitfieldMessage(bitmap);
     118                if (_log.shouldLog(Log.DEBUG))
     119                    _log.debug("Received bitmap from " + peer + " on " + peer.metainfo.getName());
    103120                break;
    104121              case 6:
     
    107124                len = din.readInt();
    108125                ps.requestMessage(piece, begin, len);
     126                if (_log.shouldLog(Log.DEBUG))
     127                    _log.debug("Received request(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
    109128                break;
    110129              case 7:
     
    119138                    din.readFully(piece_bytes, begin, len);
    120139                    ps.pieceMessage(req);
     140                    if (_log.shouldLog(Log.DEBUG))
     141                        _log.debug("Received data(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
    121142                  }
    122143                else
     
    125146                    piece_bytes = new byte[len];
    126147                    din.readFully(piece_bytes);
     148                    if (_log.shouldLog(Log.DEBUG))
     149                        _log.debug("Received UNWANTED data(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
    127150                  }
    128151                break;
     
    132155                len = din.readInt();
    133156                ps.cancelMessage(piece, begin, len);
     157                if (_log.shouldLog(Log.DEBUG))
     158                    _log.debug("Received cancel(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
    134159                break;
    135160              default:
     
    137162                din.readFully(bs);
    138163                ps.unknownMessage(b, bs);
     164                if (_log.shouldLog(Log.DEBUG))
     165                    _log.debug("Received unknown message from " + peer + " on " + peer.metainfo.getName());
    139166              }
    140167          }
  • apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java

    rb37bb93 r3ec92c8  
    2525import java.util.*;
    2626
     27import net.i2p.util.Log;
     28
    2729class PeerConnectionOut implements Runnable
    2830{
     31  private Log _log = new Log(PeerConnectionOut.class);
    2932  private final Peer peer;
    3033  private final DataOutputStream dout;
     
    3538  // Contains Messages.
    3639  private List sendQueue = new ArrayList();
     40 
     41  private static long __id = 0;
     42  private long _id;
    3743
    3844  public PeerConnectionOut(Peer peer, DataOutputStream dout)
     
    4046    this.peer = peer;
    4147    this.dout = dout;
     48    _id = ++__id;
    4249
    4350    quit = false;
    44     thread = new Thread(this);
     51    thread = new Thread(this, "Snark sender " + _id);
    4552    thread.start();
    4653  }
     
    6572                      {
    6673                        // Make sure everything will reach the other side.
     74                        // i2p flushes passively, no need to force it
     75                        // ... maybe not though
    6776                        dout.flush();
    6877                       
     
    115124                if (Snark.debug >= Snark.ALL)
    116125                  Snark.debug("Send " + peer + ": " + m, Snark.ALL);
     126                if (_log.shouldLog(Log.DEBUG))
     127                    _log.debug("Send " + peer + ": " + m + " on " + peer.metainfo.getName());
    117128                m.sendMessage(dout);
    118129
  • apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java

    rb37bb93 r3ec92c8  
    5252  // synchronize on this when changing peers or downloaders
    5353  final List peers = new ArrayList();
     54  /** estimate of the peers, without requiring any synchronization */
     55  volatile int peerCount;
    5456
    5557  /** Timer to handle all periodical tasks. */
     
    6466
    6567  private final CoordinatorListener listener;
     68 
     69  public String trackerProblems = null;
     70  public int trackerSeenPeers = 0;
    6671
    6772  public PeerCoordinator(byte[] id, MetaInfo metainfo, Storage storage,
     
    98103  }
    99104
     105  public int getPeerCount() { return peerCount; }
    100106
    101107  public int getPeers()
     
    103109    synchronized(peers)
    104110      {
    105         return peers.size();
     111        int rv = peers.size();
     112        peerCount = rv;
     113        return rv;
    106114      }
    107115  }
     
    164172            removePeerFromPieces(peer);
    165173          }
     174        peerCount = peers.size();
    166175      }
    167176  }
     
    188197              Snark.debug("New connection to peer: " + peer, Snark.INFO);
    189198
     199            _log.info("New connection to peer " + peer + " for " + metainfo.getName());
    190200            // Add it to the beginning of the list.
    191201            // And try to optimistically make it a uploader.
    192202            peers.add(0, peer);
     203            peerCount = peers.size();
    193204            unchokePeer();
    194205
     
    224235    if (need_more)
    225236      {
    226         _log.debug("Addng a peer " + peer.getPeerID().getAddress().calculateHash().toBase64(), new Exception("add/run"));
     237        _log.debug("Adding a peer " + peer.getPeerID().getAddress().calculateHash().toBase64() + " for " + metainfo.getName(), new Exception("add/run"));
    227238
    228239        // Run the peer with us as listener and the current bitfield.
     
    282293        peers.remove(peer);
    283294        peers.add(peer);
     295        peerCount = peers.size();
    284296      }
    285297  }
     
    423435  public boolean gotPiece(Peer peer, int piece, byte[] bs)
    424436  {
    425     if (halted)
     437    if (halted) {
     438      _log.info("Got while-halted piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
    426439      return true; // We don't actually care anymore.
     440    }
    427441   
    428442    synchronized(wantedPieces)
     
    434448              Snark.debug(peer + " piece " + piece + " no longer needed",
    435449                          Snark.INFO);
     450
     451            _log.info("Got unwanted piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
    436452           
    437453            // No need to announce have piece to peers.
     
    446462                if (Snark.debug >= Snark.INFO)
    447463                  Snark.debug("Recv p" + piece + " " + peer, Snark.INFO);
     464                _log.info("Got valid piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
    448465              }
    449466            else
     
    454471                  Snark.debug("Got BAD piece " + piece + " from " + peer,
    455472                              Snark.NOTICE);
     473                _log.warn("Got BAD piece " + piece + "/" + metainfo.getPieces() + " from " + peer + " for " + metainfo.getName());
    456474                return false; // No need to announce BAD piece to peers.
    457475              }
     
    525543            removePeerFromPieces(peer);
    526544          }
     545        peerCount = peers.size();
    527546      }
    528547
  • apps/i2psnark/java/src/org/klomp/snark/Snark.java

    rb37bb93 r3ec92c8  
    210210  }
    211211
    212   String torrent;
    213   MetaInfo meta;
    214   Storage storage;
    215   PeerCoordinator coordinator;
    216   ConnectionAcceptor acceptor;
    217   TrackerClient trackerclient;
    218   String rootDataDir = ".";
     212  public String torrent;
     213  public MetaInfo meta;
     214  public Storage storage;
     215  public PeerCoordinator coordinator;
     216  public ConnectionAcceptor acceptor;
     217  public TrackerClient trackerclient;
     218  public String rootDataDir = ".";
     219  public CompleteListener completeListener;
     220  public boolean stopped;
    219221
    220222  Snark(String torrent, String ip, int user_port,
     
    234236    this.rootDataDir = rootDir;
    235237
     238    stopped = true;
    236239    activity = "Network setup";
    237240
     
    364367   */
    365368  public void startTorrent() {
     369    stopped = false;
    366370    boolean coordinatorChanged = false;
    367371    if (coordinator.halted()) {
     
    376380        coordinatorChanged = true;
    377381    }
    378     if (trackerclient.halted() || coordinatorChanged) {
     382    if (!trackerclient.started() && !coordinatorChanged) {
     383        trackerclient.start();
     384    } else if (trackerclient.halted() || coordinatorChanged) {
    379385        TrackerClient newClient = new TrackerClient(coordinator.getMetaInfo(), coordinator);
    380386        if (!trackerclient.halted())
    381387            trackerclient.halt();
    382388        trackerclient = newClient;
     389        trackerclient.start();
    383390    }
    384     trackerclient.start();
    385391  }
    386392  /**
     
    388394   */
    389395  public void stopTorrent() {
     396    stopped = true;
    390397    trackerclient.halt();
    391398    coordinator.halt();
     
    418425    String torrent = null;
    419426
     427    boolean configured = I2PSnarkUtil.instance().configured();
     428   
    420429    int i = 0;
    421430    while (i < args.length)
     
    464473            String proxyHost = args[i+1];
    465474            String proxyPort = args[i+2];
    466             I2PSnarkUtil.instance().setProxy(proxyHost, Integer.parseInt(proxyPort));
     475            if (!configured)
     476                I2PSnarkUtil.instance().setProxy(proxyHost, Integer.parseInt(proxyPort));
    467477            i += 3;
    468478          }
     
    485495                }
    486496            }
    487             I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, Integer.parseInt(i2cpPort), opts);
     497            if (!configured)
     498                I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, Integer.parseInt(i2cpPort), opts);
    488499            i += 3 + (opts != null ? 1 : 0);
    489500          }
     
    655666    //storage.close();
    656667    System.out.println("Completely received: " + torrent);
     668    if (completeListener != null)
     669        completeListener.torrentComplete(this);
    657670  }
    658671
     
    663676    System.exit(0);
    664677  }
     678 
     679  public interface CompleteListener {
     680    public void torrentComplete(Snark snark);
     681  }
    665682}
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    rb37bb93 r3ec92c8  
    1111 * Manage multiple snarks
    1212 */
    13 public class SnarkManager {
     13public class SnarkManager implements Snark.CompleteListener {
    1414    private static SnarkManager _instance = new SnarkManager();
    1515    public static SnarkManager instance() { return _instance; }
     
    3636        _messages = new ArrayList(16);
    3737        loadConfig("i2psnark.config");
     38        int minutes = getStartupDelayMinutes();
     39        _messages.add("Starting up torrents in " + minutes + (minutes == 1 ? " minute" : " minutes"));
    3840        I2PThread monitor = new I2PThread(new DirMonitor(), "Snark DirMonitor");
    3941        monitor.setDaemon(true);
     
    5153    }
    5254   
    53     private boolean shouldAutoStart() { return true; }
     55    /** newest last */
     56    public List getMessages() {
     57        synchronized (_messages) {
     58            return new ArrayList(_messages);
     59        }
     60    }
     61   
     62    public boolean shouldAutoStart() { return true; }
    5463    private int getStartupDelayMinutes() { return 1; }
    55     private File getDataDir() {
     64    public File getDataDir() {
    5665        String dir = _config.getProperty(PROP_DIR);
    5766        if ( (dir == null) || (dir.trim().length() <= 0) )
     
    9099        int i2cpPort = getInt(PROP_I2CP_PORT, 7654);
    91100        String opts = _config.getProperty(PROP_I2CP_OPTS);
    92         Properties i2cpOpts = new Properties();
     101        Map i2cpOpts = new HashMap();
    93102        if (opts != null) {
    94103            StringTokenizer tok = new StringTokenizer(opts, " ");
     
    96105                String pair = tok.nextToken();
    97106                int split = pair.indexOf('=');
    98                 if (split > 0) 
    99                     i2cpOpts.setProperty(pair.substring(0, split), pair.substring(split+1));
     107                if (split > 0)
     108                    i2cpOpts.put(pair.substring(0, split), pair.substring(split+1));
    100109            }
    101110        }
     
    123132    }
    124133   
     134    public void updateConfig(String dataDir, boolean autoStart, String seedPct, String eepHost,
     135                             String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts) {
     136        boolean changed = false;
     137        if (eepHost != null) {
     138            int port = I2PSnarkUtil.instance().getEepProxyPort();
     139            try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
     140            String host = I2PSnarkUtil.instance().getEepProxyHost();
     141            if ( (eepHost.trim().length() > 0) && (port > 0) &&
     142                 ((!host.equals(eepHost) || (port != I2PSnarkUtil.instance().getEepProxyPort()) )) ) {
     143                I2PSnarkUtil.instance().setProxy(eepHost, port);
     144                changed = true;
     145                _config.setProperty(PROP_EEP_HOST, eepHost);
     146                _config.setProperty(PROP_EEP_PORT, eepPort+"");
     147                addMessage("EepProxy location changed to " + eepHost + ":" + port);
     148            }
     149        }
     150        if (i2cpHost != null) {
     151            int oldI2CPPort = I2PSnarkUtil.instance().getI2CPPort();
     152            String oldI2CPHost = I2PSnarkUtil.instance().getI2CPHost();
     153            int port = oldI2CPPort;
     154            try { port = Integer.parseInt(i2cpPort); } catch (NumberFormatException nfe) {}
     155            String host = oldI2CPHost;
     156            Map opts = new HashMap();
     157            if (i2cpOpts == null) i2cpOpts = "";
     158            StringTokenizer tok = new StringTokenizer(i2cpOpts, " \t\n");
     159            while (tok.hasMoreTokens()) {
     160                String pair = tok.nextToken();
     161                int split = pair.indexOf('=');
     162                if (split > 0)
     163                    opts.put(pair.substring(0, split), pair.substring(split+1));
     164            }
     165            Map oldOpts = new HashMap();
     166            String oldI2CPOpts = _config.getProperty(PROP_I2CP_OPTS);
     167            if (oldI2CPOpts == null) oldI2CPOpts = "";
     168            tok = new StringTokenizer(oldI2CPOpts, " \t\n");
     169            while (tok.hasMoreTokens()) {
     170                String pair = tok.nextToken();
     171                int split = pair.indexOf('=');
     172                if (split > 0)
     173                    oldOpts.put(pair.substring(0, split), pair.substring(split+1));
     174            }
     175           
     176            if ( (i2cpHost.trim().length() > 0) && (port > 0) &&
     177                 ((!host.equals(i2cpHost) ||
     178                  (port != I2PSnarkUtil.instance().getI2CPPort()) ||
     179                  (!oldOpts.equals(opts)))) ) {
     180                boolean snarksActive = false;
     181                Set names = listTorrentFiles();
     182                for (Iterator iter = names.iterator(); iter.hasNext(); ) {
     183                    Snark snark = getTorrent((String)iter.next());
     184                    if ( (snark != null) && (!snark.stopped) ) {
     185                        snarksActive = true;
     186                        break;
     187                    }
     188                }
     189                if (snarksActive) {
     190                    addMessage("Cannot change the I2CP settings while torrents are active");
     191                    _log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
     192                               + "] oldOpts [" + oldOpts + "]");
     193                } else {
     194                    if (I2PSnarkUtil.instance().connected()) {
     195                        I2PSnarkUtil.instance().disconnect();
     196                        addMessage("Disconnecting old I2CP destination");
     197                    }
     198                    Properties p = new Properties();
     199                    p.putAll(opts);
     200                    addMessage("I2CP settings changed to " + i2cpHost + ":" + port + " (" + i2cpOpts.trim() + ")");
     201                    I2PSnarkUtil.instance().setI2CPConfig(i2cpHost, port, p);
     202                    boolean ok = I2PSnarkUtil.instance().connect();
     203                    if (!ok) {
     204                        addMessage("Unable to connect with the new settings, reverting to the old I2CP settings");
     205                        I2PSnarkUtil.instance().setI2CPConfig(oldI2CPHost, oldI2CPPort, oldOpts);
     206                        ok = I2PSnarkUtil.instance().connect();
     207                        if (!ok)
     208                            addMessage("Unable to reconnect with the old settings!");
     209                    } else {
     210                        addMessage("Reconnected on the new I2CP destination");
     211                        _config.setProperty(PROP_I2CP_HOST, i2cpHost.trim());
     212                        _config.setProperty(PROP_I2CP_PORT, "" + port);
     213                        _config.setProperty(PROP_I2CP_OPTS, i2cpOpts.trim());
     214                        changed = true;
     215                        // no PeerAcceptors/I2PServerSockets to deal with, since all snarks are inactive
     216                        for (Iterator iter = names.iterator(); iter.hasNext(); ) {
     217                            String name = (String)iter.next();
     218                            Snark snark = getTorrent(name);
     219                            if ( (snark != null) && (snark.acceptor != null) ) {
     220                                snark.acceptor.restart();
     221                                addMessage("I2CP listener restarted for " + snark.meta.getName());
     222                            }
     223                        }
     224                    }
     225                }
     226                changed = true;
     227            }
     228        }
     229        if (changed) {
     230            saveConfig();
     231        } else {
     232            addMessage("Configuration unchanged");
     233        }
     234    }
     235   
    125236    public void saveConfig() {
    126237        try {
     
    130241        }
    131242    }
     243   
     244    public Properties getConfig() { return _config; }
    132245   
    133246    /** set of filenames that we are dealing with */
     
    152265            if (torrent == null) {
    153266                torrent = new Snark(filename, null, -1, null, null, false, dataDir.getPath());
     267                torrent.completeListener = this;
    154268                _snarks.put(filename, torrent);
    155269            } else {
     
    158272        }
    159273        // ok, snark created, now lets start it up or configure it further
     274        File f = new File(filename);
    160275        if (shouldAutoStart()) {
    161276            torrent.startTorrent();
    162             addMessage("Torrent added and started: '" + filename + "'");
     277            addMessage("Torrent added and started: '" + f.getName() + "'");
    163278        } else {
    164             addMessage("Torrent added: '" + filename + "'");
     279            addMessage("Torrent added: '" + f.getName() + "'");
    165280        }
    166281    }
     
    188303        }
    189304        if (torrent != null) {
     305            boolean wasStopped = torrent.stopped;
    190306            torrent.stopTorrent();
    191307            if (remaining == 0) {
     
    194310                ////I2PSnarkUtil.instance().
    195311            }
    196             addMessage("Torrent stopped: '" + filename + "'");
     312            if (!wasStopped)
     313                addMessage("Torrent stopped: '" + sfile.getName() + "'");
    197314        }
    198315        return torrent;
     
    207324            File torrentFile = new File(filename);
    208325            torrentFile.delete();
    209             addMessage("Torrent removed: '" + filename + "'");
     326            addMessage("Torrent removed: '" + torrentFile.getName() + "'");
    210327        }
    211328    }
     
    221338            }
    222339        }
     340    }
     341   
     342    public void torrentComplete(Snark snark) {
     343        File f = new File(snark.torrent);
     344        long len = snark.meta.getTotalLength();
     345        addMessage("Download complete of " + f.getName()
     346                   + (len < 5*1024*1024 ? " (size: " + (len/1024) + "KB)" : " (size: " + (len/1024*1024) + "MB)"));
    223347    }
    224348   
     
    242366                // already known.  noop
    243367            } else {
    244                 addTorrent((String)foundNames.get(i));
     368                if (I2PSnarkUtil.instance().connect())
     369                    addTorrent((String)foundNames.get(i));
     370                else
     371                    addMessage("Unable to connect to I2P");
    245372            }
    246373        }
  • apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java

    rb37bb93 r3ec92c8  
    4949
    5050  private boolean stop;
     51  private boolean started;
    5152
    5253  private long interval;
     
    6364
    6465    stop = false;
     66    started = false;
    6567  }
    6668
    6769  public void start() {
    68       stop = false;
     70      if (stop) throw new RuntimeException("Dont rerun me, create a copy");
    6971      super.start();
     72      started = true;
    7073  }
    7174 
    7275  public boolean halted() { return stop; }
     76  public boolean started() { return started; }
    7377 
    7478  /**
     
    108112                                             uploaded, downloaded, left,
    109113                                             STARTED_EVENT);
     114                Set peers = info.getPeers();
     115                coordinator.trackerSeenPeers = peers.size();
    110116                if (!completed) {
    111                     Iterator it = info.getPeers().iterator();
     117                    Iterator it = peers.iterator();
    112118                    while (it.hasNext()) {
    113119                      Peer cur = (Peer)it.next();
     
    119125                }
    120126                started = true;
     127                coordinator.trackerProblems = null;
    121128              }
    122129            catch (IOException ioe)
     
    126133                  ("WARNING: Could not contact tracker at '"
    127134                   + announce + "': " + ioe, Snark.WARNING);
     135                coordinator.trackerProblems = ioe.getMessage();
    128136              }
    129137
     
    183191                                                 event);
    184192
     193                    Set peers = info.getPeers();
     194                    coordinator.trackerSeenPeers = peers.size();
    185195                    if ( (left > 0) && (!completed) ) {
    186196                        // we only want to talk to new people if we need things
    187197                        // from them (duh)
    188                         Iterator it = info.getPeers().iterator();
     198                        Iterator it = peers.iterator();
    189199                        while (it.hasNext()) {
    190200                          Peer cur = (Peer)it.next();
     
    245255    }
    246256   
    247     fetched.deleteOnExit();
    248     InputStream in = new FileInputStream(fetched);
    249 
    250     TrackerInfo info = new TrackerInfo(in, coordinator.getID(),
    251                                        coordinator.getMetaInfo());
    252     if (Snark.debug >= Snark.INFO)
    253       Snark.debug("TrackerClient response: " + info, Snark.INFO);
    254     lastRequestTime = System.currentTimeMillis();
    255    
    256     String failure = info.getFailureReason();
    257     if (failure != null)
    258       throw new IOException(failure);
    259    
    260     interval = info.getInterval() * 1000;
    261     return info;
     257    try {
     258        InputStream in = new FileInputStream(fetched);
     259
     260        TrackerInfo info = new TrackerInfo(in, coordinator.getID(),
     261                                           coordinator.getMetaInfo());
     262        if (Snark.debug >= Snark.INFO)
     263          Snark.debug("TrackerClient response: " + info, Snark.INFO);
     264        lastRequestTime = System.currentTimeMillis();
     265
     266        String failure = info.getFailureReason();
     267        if (failure != null)
     268          throw new IOException(failure);
     269
     270        interval = info.getInterval() * 1000;
     271        return info;
     272    } finally {
     273        fetched.delete();
     274    }
    262275  }
    263276
  • apps/routerconsole/jsp/nav.jsp

    rb37bb93 r3ec92c8  
    2626 <a href="susidns/index.jsp">SusiDNS</a> |
    2727 <a href="syndie/">Syndie</a> |
     28 <a href="i2psnark/">I2PSnark</a> |
    2829 <a href="http://localhost:7658/">My Eepsite</a> <br>
    2930 <a href="i2ptunnel/index.jsp">I2PTunnel</a> |
  • build.xml

    rb37bb93 r3ec92c8  
    3232        <ant dir="apps/susidns/src" target="all" />
    3333        <ant dir="apps/syndie/java/" target="jar" />
    34         <ant dir="apps/i2psnark/java/" target="jar" />
     34        <ant dir="apps/i2psnark/java/" target="war" />
    3535    </target>
    3636    <target name="buildrouter">
     
    109109        <copy file="apps/syndie/java/build/syndie.jar" todir="build/" />
    110110        <copy file="apps/syndie/java/build/sucker.jar" todir="build/" />
    111         <copy file="apps/syndie/syndie.war" todir="build/" />
     111        <copy file="apps/i2psnark/i2psnark.war" todir="build/" />
    112112        <copy file="apps/i2psnark/java/build/i2psnark.jar" todir="build/" />
    113113        <copy file="apps/jdom/jdom.jar" todir="build/" />
     
    251251        <copy file="build/susidns.war" todir="pkg-temp/webapps/" />
    252252        <copy file="build/syndie.war" todir="pkg-temp/webapps/" />
     253        <copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
    253254        <copy file="installer/resources/clients.config" todir="pkg-temp/" />
    254255        <copy file="installer/resources/eepget" todir="pkg-temp/" />
     
    360361        <copy file="build/susidns.war" todir="pkg-temp/webapps/" />
    361362        <copy file="build/syndie.war" todir="pkg-temp/webapps/" />
     363        <copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
    362364        <copy file="history.txt" todir="pkg-temp/" />
    363365        <mkdir dir="pkg-temp/docs/" />
  • history.txt

    rb37bb93 r3ec92c8  
    1 $Id: history.txt,v 1.355 2005/12/14 04:32:52 jrandom Exp $
     1$Id: history.txt,v 1.356 2005/12/15 03:58:31 jrandom Exp $
     2
     32005-12-15  jrandom
     4    * Added a first pass to the I2PSnark web UI (see /i2psnark/)
    25
    362005-12-15  jrandom
Note: See TracChangeset for help on using the changeset viewer.