Changeset 8e40b35


Ignore:
Timestamp:
Dec 21, 2010 3:04:10 AM (9 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
f15b329
Parents:
8451610
Message:

metadata handling - untested, still some stubs

Location:
apps/i2psnark/java/src/org/klomp/snark
Files:
2 added
1 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • apps/i2psnark/java/src/org/klomp/snark/MetaInfo.java

    r8451610 r8e40b35  
    2626import java.security.NoSuchAlgorithmException;
    2727import java.util.ArrayList;
     28import java.util.Collections;
    2829import java.util.HashMap;
    2930import java.util.Iterator;
     
    6061  private final byte[] piece_hashes;
    6162  private final long length;
    62   private final Map infoMap;
    63 
    64   private byte[] torrentdata;
    65 
     63  private Map infoMap;
     64
     65  /**
     66   *  Called by Storage when creating a new torrent from local data
     67   */
    6668  MetaInfo(String announce, String name, String name_utf8, List files, List lengths,
    6769           int piece_length, byte[] piece_hashes, long length)
     
    7880
    7981    this.info_hash = calculateInfoHash();
    80     infoMap = null;
     82    //infoMap = null;
    8183  }
    8284
     
    105107   * the original bencoded info dictonary (this is a hack, we could
    106108   * reconstruct the bencoded stream and recalculate the hash). Will
    107    * throw a InvalidBEncodingException if the given map does not
     109   * NOT throw a InvalidBEncodingException if the given map does not
    108110   * contain a valid announce string or info dictonary.
    109111   */
     
    113115        _log.debug("Creating a metaInfo: " + m, new Exception("source"));
    114116    BEValue val = (BEValue)m.get("announce");
    115     if (val == null)
    116         throw new InvalidBEncodingException("Missing announce string");
    117     this.announce = val.getString();
     117    // Disabled check, we can get info from a magnet now
     118    if (val == null) {
     119        //throw new InvalidBEncodingException("Missing announce string");
     120        this.announce = null;
     121    } else {
     122        this.announce = val.getString();
     123    }
    118124
    119125    val = (BEValue)m.get("info");
     
    216222  /**
    217223   * Returns the string representing the URL of the tracker for this torrent.
     224   * @return may be null!
    218225   */
    219226  public String getAnnounce()
     
    389396  }
    390397
    391   public byte[] getTorrentData()
    392   {
    393     if (torrentdata == null)
    394       {
     398  /**
     399   *  Called by servlet to save a new torrent file generated from local data
     400   */
     401  public synchronized byte[] getTorrentData()
     402  {
    395403        Map m = new HashMap();
    396404        m.put("announce", announce);
    397405        Map info = createInfoMap();
    398406        m.put("info", info);
    399         torrentdata = BEncoder.bencode(m);
    400       }
    401     return torrentdata;
    402   }
    403 
    404   private Map createInfoMap()
    405   {
     407        // don't save this locally, we should only do this once
     408        return BEncoder.bencode(m);
     409  }
     410
     411  /** @since 0.8.4 */
     412  public synchronized byte[] getInfoBytes() {
     413    if (infoMap == null)
     414        createInfoMap();
     415    return BEncoder.bencode(infoMap);
     416  }
     417
     418  /** @return an unmodifiable view of the Map */
     419  private Map<String, BEValue> createInfoMap()
     420  {
     421    // if we loaded this metainfo from a file, we have the map
     422    if (infoMap != null)
     423        return Collections.unmodifiableMap(infoMap);
     424    // otherwise we must create it
    406425    Map info = new HashMap();
    407     if (infoMap != null) {
    408         info.putAll(infoMap);
    409         return info;
    410     }
    411426    info.put("name", name);
    412427    if (name_utf8 != null)
     
    430445        info.put("files", l);
    431446      }
    432     return info;
     447    infoMap = info;
     448    return Collections.unmodifiableMap(infoMap);
    433449  }
    434450
  • apps/i2psnark/java/src/org/klomp/snark/Peer.java

    r8451610 r8e40b35  
    2929import java.util.Arrays;
    3030import java.util.List;
     31import java.util.Map;
    3132
    3233import net.i2p.client.streaming.I2PSocket;
    3334import net.i2p.data.DataHelper;
    3435import net.i2p.util.Log;
     36
     37import org.klomp.snark.bencode.BEValue;
    3538
    3639public class Peer implements Comparable
     
    4245  private final byte[] my_id;
    4346  private final byte[] infohash;
    44   final MetaInfo metainfo;
     47  /** will start out null in magnet mode */
     48  private MetaInfo metainfo;
     49  private Map<String, BEValue> handshakeMap;
    4550
    4651  // The data in/output streams set during the handshake and used by
     
    5257  // was successful, the connection setup and runs
    5358  PeerState state;
     59
     60  /** shared across all peers on this torrent */
     61  MagnetState magnetState;
    5462
    5563  private I2PSocket sock;
     
    198206   * message.
    199207   */
    200   public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField bitfield)
     208  public void runConnection(I2PSnarkUtil util, PeerListener listener, BitField bitfield, MagnetState mState)
    201209  {
    202210    if (state != null)
     
    256264            if (_log.shouldLog(Log.DEBUG))
    257265                _log.debug("Peer supports extensions, sending test message");
    258             out.sendExtension(0, ExtensionHandshake.getPayload());
     266            out.sendExtension(0, ExtensionHandler.getHandshake());
    259267        }
    260268
     
    272280        // We are up and running!
    273281        state = s;
     282        magnetState = mState;
    274283        listener.connected(this);
    275284 
     
    372381  }
    373382
     383  /**
     384   *  Shared state across all peers, callers must sync on returned object
     385   *  @return non-null
     386   *  @since 0.8.4
     387   */
     388  public MagnetState getMagnetState() {
     389      return magnetState;
     390  }
     391
     392  /** @return could be null @since 0.8.4 */
     393  public Map<String, BEValue> getHandshakeMap() {
     394      return handshakeMap;
     395  }
     396
     397  /** @since 0.8.4 */
     398  public void setHandshakeMap(Map<String, BEValue> map) {
     399      handshakeMap = map;
     400  }
     401
     402  /** @since 0.8.4 */
     403  public void sendExtension(int type, byte[] payload) {
     404    PeerState s = state;
     405    if (s != null)
     406        s.out.sendExtension(type, payload);
     407  }
     408
     409  /**
     410   *  Switch from magnet mode to normal mode
     411   *  @since 0.8.4
     412   */
     413  public void gotMetaInfo(MetaInfo meta) {
     414    PeerState s = state;
     415    if (s != null)
     416        s.gotMetaInfo(meta);
     417  }
     418
    374419  public boolean isConnected()
    375420  {
  • apps/i2psnark/java/src/org/klomp/snark/PeerConnectionIn.java

    r8451610 r8e40b35  
    9191                ps.keepAliveMessage();
    9292                if (_log.shouldLog(Log.DEBUG))
    93                     _log.debug("Received keepalive from " + peer + " on " + peer.metainfo.getName());
     93                    _log.debug("Received keepalive from " + peer);
    9494                continue;
    9595              }
     
    103103                ps.chokeMessage(true);
    104104                if (_log.shouldLog(Log.DEBUG))
    105                     _log.debug("Received choke from " + peer + " on " + peer.metainfo.getName());
     105                    _log.debug("Received choke from " + peer);
    106106                break;
    107107              case 1:
    108108                ps.chokeMessage(false);
    109109                if (_log.shouldLog(Log.DEBUG))
    110                     _log.debug("Received unchoke from " + peer + " on " + peer.metainfo.getName());
     110                    _log.debug("Received unchoke from " + peer);
    111111                break;
    112112              case 2:
    113113                ps.interestedMessage(true);
    114114                if (_log.shouldLog(Log.DEBUG))
    115                     _log.debug("Received interested from " + peer + " on " + peer.metainfo.getName());
     115                    _log.debug("Received interested from " + peer);
    116116                break;
    117117              case 3:
    118118                ps.interestedMessage(false);
    119119                if (_log.shouldLog(Log.DEBUG))
    120                     _log.debug("Received not interested from " + peer + " on " + peer.metainfo.getName());
     120                    _log.debug("Received not interested from " + peer);
    121121                break;
    122122              case 4:
     
    124124                ps.haveMessage(piece);
    125125                if (_log.shouldLog(Log.DEBUG))
    126                     _log.debug("Received havePiece(" + piece + ") from " + peer + " on " + peer.metainfo.getName());
     126                    _log.debug("Received havePiece(" + piece + ") from " + peer);
    127127                break;
    128128              case 5:
     
    131131                ps.bitfieldMessage(bitmap);
    132132                if (_log.shouldLog(Log.DEBUG))
    133                     _log.debug("Received bitmap from " + peer + " on " + peer.metainfo.getName() + ": size=" + (i-1) /* + ": " + ps.bitfield */ );
     133                    _log.debug("Received bitmap from " + peer + ": size=" + (i-1) /* + ": " + ps.bitfield */ );
    134134                break;
    135135              case 6:
     
    139139                ps.requestMessage(piece, begin, len);
    140140                if (_log.shouldLog(Log.DEBUG))
    141                     _log.debug("Received request(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
     141                    _log.debug("Received request(" + piece + "," + begin + ") from " + peer);
    142142                break;
    143143              case 7:
     
    153153                    ps.pieceMessage(req);
    154154                    if (_log.shouldLog(Log.DEBUG))
    155                         _log.debug("Received data(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
     155                        _log.debug("Received data(" + piece + "," + begin + ") from " + peer);
    156156                  }
    157157                else
     
    161161                    din.readFully(piece_bytes);
    162162                    if (_log.shouldLog(Log.DEBUG))
    163                         _log.debug("Received UNWANTED data(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
     163                        _log.debug("Received UNWANTED data(" + piece + "," + begin + ") from " + peer);
    164164                  }
    165165                break;
     
    170170                ps.cancelMessage(piece, begin, len);
    171171                if (_log.shouldLog(Log.DEBUG))
    172                     _log.debug("Received cancel(" + piece + "," + begin + ") from " + peer + " on " + peer.metainfo.getName());
     172                    _log.debug("Received cancel(" + piece + "," + begin + ") from " + peer);
    173173                break;
    174174              case 9:  // PORT message
     
    176176                ps.portMessage(port);
    177177                if (_log.shouldLog(Log.DEBUG))
    178                     _log.debug("Received port message from " + peer + " on " + peer.metainfo.getName());
     178                    _log.debug("Received port message from " + peer);
    179179              case 20:  // Extension message
    180180                int id = din.readUnsignedByte();
     
    183183                ps.extensionMessage(id, payload);
    184184                if (_log.shouldLog(Log.DEBUG))
    185                     _log.debug("Received extension message from " + peer + " on " + peer.metainfo.getName());
     185                    _log.debug("Received extension message from " + peer);
    186186                break;
    187187              default:
     
    190190                ps.unknownMessage(b, bs);
    191191                if (_log.shouldLog(Log.DEBUG))
    192                     _log.debug("Received unknown message from " + peer + " on " + peer.metainfo.getName());
     192                    _log.debug("Received unknown message from " + peer);
    193193              }
    194194          }
  • apps/i2psnark/java/src/org/klomp/snark/PeerConnectionOut.java

    r8451610 r8e40b35  
    152152              {
    153153                if (_log.shouldLog(Log.DEBUG))
    154                     _log.debug("Send " + peer + ": " + m + " on " + peer.metainfo.getName());
     154                    _log.debug("Send " + peer + ": " + m);
    155155
    156156                // This can block for quite a while.
  • apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java

    r8451610 r8e40b35  
    106106  private boolean halted = false;
    107107
     108  private final MagnetState magnetState;
    108109  private final CoordinatorListener listener;
    109110  private final I2PSnarkUtil _util;
     
    129130    partialPieces = new ArrayList(getMaxConnections() + 1);
    130131    peers = new LinkedBlockingQueue();
     132    magnetState = new MagnetState(infohash, metainfo);
    131133
    132134    // Install a timer to check the uploaders.
     
    485487            public void run()
    486488            {
    487               peer.runConnection(_util, listener, bitfield);
     489              peer.runConnection(_util, listener, bitfield, magnetState);
    488490            }
    489491          };
     
    11501152
    11511153  /** @since 0.8.4 */
    1152   public void gotExtension(Peer peer, int id, byte[] bs) {}
     1154  public void gotExtension(Peer peer, int id, byte[] bs) {
     1155      if (_log.shouldLog(Log.DEBUG))
     1156          _log.debug("Got extension message " + id + " from " + peer);
     1157      // basic handling done in PeerState... here we just check if we are done
     1158      if (metainfo == null && id == ExtensionHandler.ID_METADATA) {
     1159          synchronized (magnetState) {
     1160              if (magnetState.isComplete()) {
     1161                  if (_log.shouldLog(Log.WARN))
     1162                      _log.warn("Got completed metainfo via extension");
     1163                  MetaInfo newinfo = magnetState.getMetaInfo();
     1164                  // more validation
     1165                  // set global
     1166                  // instantiate storage
     1167                  // tell Snark listener
     1168                  // tell all peers
     1169              }
     1170          }
     1171      }
     1172  }
    11531173
    11541174  /** @since 0.8.4 */
    1155   public void gotPort(Peer peer, int port) {}
     1175  public void gotPort(Peer peer, int port) {
     1176      // send to DHT
     1177  }
    11561178
    11571179  /** Return number of allowed uploaders for this torrent.
  • apps/i2psnark/java/src/org/klomp/snark/PeerState.java

    r8451610 r8e40b35  
    498498  void extensionMessage(int id, byte[] bs)
    499499  {
     500      ExtensionHandler.handleMessage(peer, id, bs);
     501      // Peer coord will get metadata from MagnetState,
     502      // verify, and then call gotMetaInfo()
    500503      listener.gotExtension(peer, id, bs);
     504  }
     505
     506  /**
     507   *  Switch from magnet mode to normal mode
     508   *  @since 0.8.4
     509   */
     510  public void gotMetaInfo(MetaInfo meta) {
     511      // set metainfo
     512      // fix bitfield
    501513  }
    502514
  • apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java

    r8451610 r8e40b35  
    595595                                  false, getDataDir().getPath());
    596596
    597         // Tell the dir monitor not to delete us
    598         _magnets.add(name);
    599597        synchronized (_snarks) {
     598            for (Snark snark : _snarks.values()) {
     599                if (DataHelper.eq(ih, snark.getInfoHash())) {
     600                    addMessage(_("Torrent already running: {0}", snark.getBaseName()));
     601                    return;
     602                }
     603            }
     604            // Tell the dir monitor not to delete us
     605            _magnets.add(name);
    600606            _snarks.put(name, torrent);
    601607        }
Note: See TracChangeset for help on using the changeset viewer.