use of org.klomp.snark.bencode.BEValue in project i2p.i2p by i2p.
the class KRPC method receiveResponse.
// Responses.....
/**
* Handle the response and alert whoever sent the query it is responding to.
* Adds sender nodeinfo to our DHT.
* @throws NPE, IllegalArgumentException, and others too
*/
private void receiveResponse(ReplyWaiter waiter, Map<String, BEValue> response) throws InvalidBEncodingException {
NodeInfo nInfo = waiter.getSentTo();
BEValue nodes = response.get("nodes");
BEValue values = response.get("values");
// token handling - save it for later announces
if (nodes != null || values != null) {
BEValue btok = response.get("token");
InfoHash ih = (InfoHash) waiter.getSentObject();
if (btok != null && ih != null) {
byte[] tok = btok.getBytes();
Token token = new Token(_context, tok);
_incomingTokens.put(nInfo.getNID(), token);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got token: " + token + ", must be a response to get_peers");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No token and saved infohash, must be a response to find_node");
}
}
// now do the right thing
if (nodes != null) {
// find node or get peers response - concatenated NodeInfos
byte[] ids = nodes.getBytes();
List<NodeInfo> rlist = receiveNodes(nInfo, ids);
waiter.gotReply(REPLY_NODES, rlist);
} else if (values != null) {
// get peers response - list of Hashes
List<BEValue> peers = values.getList();
List<Hash> rlist = receivePeers(nInfo, peers);
waiter.gotReply(REPLY_PEERS, rlist);
} else {
// a ping response or an announce peer response
byte[] nid = response.get("id").getBytes();
receivePong(nInfo, nid);
waiter.gotReply(REPLY_PONG, null);
}
}
use of org.klomp.snark.bencode.BEValue in project i2p.i2p by i2p.
the class MagnetState method buildMetaInfo.
/**
* @return true if this was the last piece
* @throws NullPointerException IllegalArgumentException, IOException, ...
*/
private MetaInfo buildMetaInfo() throws Exception {
// top map has nothing in it but the info map (no announce)
Map<String, BEValue> map = new HashMap<String, BEValue>();
InputStream is = new ByteArrayInputStream(metainfoBytes);
BDecoder dec = new BDecoder(is);
BEValue bev = dec.bdecodeMap();
map.put("info", bev);
MetaInfo newmeta = new MetaInfo(map);
if (!DataHelper.eq(newmeta.getInfoHash(), infohash)) {
// Disaster. Start over. ExtensionHandler will catch
// the IOE and disconnect the peer, hopefully we will
// find a new peer.
// TODO: Count fails and give up eventually
have = new BitField(totalChunks);
requested = new BitField(totalChunks);
throw new IOException("info hash mismatch");
}
return newmeta;
}
use of org.klomp.snark.bencode.BEValue in project i2p.i2p by i2p.
the class MetaInfo method getNameAndInfoHash.
/**
* Efficiently returns the name and the 20 byte SHA1 hash of the info dictionary in a torrent file
* Caller must close stream.
*
* @param infoHashOut 20-byte out parameter
* @since 0.8.5
*/
public static String getNameAndInfoHash(InputStream in, byte[] infoHashOut) throws IOException {
BDecoder bd = new BDecoder(in);
Map<String, BEValue> m = bd.bdecodeMap().getMap();
BEValue ibev = m.get("info");
if (ibev == null)
throw new InvalidBEncodingException("Missing info map");
Map<String, BEValue> i = ibev.getMap();
BEValue rvbev = i.get("name");
if (rvbev == null)
throw new InvalidBEncodingException("Missing name");
byte[] h = bd.get_special_map_digest();
System.arraycopy(h, 0, infoHashOut, 0, 20);
return rvbev.getString();
}
use of org.klomp.snark.bencode.BEValue in project i2p.i2p by i2p.
the class MetaInfo method createInfoMap.
/**
* @return an unmodifiable view of the Map
*/
private Map<String, BEValue> createInfoMap() {
// or else we will lose any non-standard keys and corrupt the infohash.
if (infoMap != null)
return Collections.unmodifiableMap(infoMap);
// we should only get here if serving a magnet on a torrent we created
if (_log.shouldLog(Log.WARN))
_log.warn("Creating new infomap", new Exception());
// otherwise we must create it
Map<String, BEValue> info = new HashMap<String, BEValue>();
info.put("name", new BEValue(DataHelper.getUTF8(name)));
if (name_utf8 != null)
info.put("name.utf-8", new BEValue(DataHelper.getUTF8(name_utf8)));
// BEP 27
if (privateTorrent)
// switched to number in 0.9.14
// info.put("private", new BEValue(DataHelper.getUTF8("1")));
info.put("private", new BEValue(Integer.valueOf(1)));
info.put("piece length", new BEValue(Integer.valueOf(piece_length)));
info.put("pieces", new BEValue(piece_hashes));
if (files == null)
info.put("length", new BEValue(Long.valueOf(length)));
else {
List<BEValue> l = new ArrayList<BEValue>();
for (int i = 0; i < files.size(); i++) {
Map<String, BEValue> file = new HashMap<String, BEValue>();
List<String> fi = files.get(i);
List<BEValue> befiles = new ArrayList<BEValue>(fi.size());
for (int j = 0; j < fi.size(); j++) {
befiles.add(new BEValue(DataHelper.getUTF8(fi.get(j))));
}
file.put("path", new BEValue(befiles));
if ((files_utf8 != null) && (files_utf8.size() > i)) {
List<String> fiu = files_utf8.get(i);
List<BEValue> beufiles = new ArrayList<BEValue>(fiu.size());
for (int j = 0; j < fiu.size(); j++) {
beufiles.add(new BEValue(DataHelper.getUTF8(fiu.get(j))));
}
file.put("path.utf-8", new BEValue(beufiles));
}
file.put("length", new BEValue(lengths.get(i)));
l.add(new BEValue(file));
}
info.put("files", new BEValue(l));
}
// TODO if we add the ability for other keys in the first constructor
// if (otherInfo != null)
// info.putAll(otherInfo);
infoMap = info;
return Collections.unmodifiableMap(infoMap);
}
use of org.klomp.snark.bencode.BEValue in project i2p.i2p by i2p.
the class MetaInfo method reannounce.
/**
* Creates a copy of this MetaInfo that shares everything except the
* announce URL.
* Drops any announce-list.
* Preserves infohash and info map, including any non-standard fields.
* @param announce may be null
*/
public MetaInfo reannounce(String announce) throws InvalidBEncodingException {
Map<String, BEValue> m = new HashMap<String, BEValue>();
if (announce != null)
m.put("announce", new BEValue(DataHelper.getUTF8(announce)));
Map<String, BEValue> info = createInfoMap();
m.put("info", new BEValue(info));
return new MetaInfo(m);
}
Aggregations