Package org.klomp.snark.dht
Class KRPC
- java.lang.Object
-
- org.klomp.snark.dht.KRPC
-
- All Implemented Interfaces:
I2PSessionListener
,I2PSessionMuxedListener
,DHT
public class KRPC extends Object implements I2PSessionMuxedListener, DHT
Standard BEP 5 Mods for I2P:- The UDP port need not be pinged after receiving a PORT message. - The UDP (datagram) port listed in the compact node info is used to receive repliable (signed) datagrams. This is used for queries, except for announces. We call this the "query port". In addition to that UDP port, we use a second datagram port equal to the signed port + 1. This is used to receive unsigned (raw) datagrams for replies, errors, and announce queries.. We call this the "response port". - Compact peer info is 32 bytes (32 byte SHA256 Hash) instead of 4 byte IP + 2 byte port. There is no peer port. - Compact node info is 54 bytes (20 byte SHA1 Hash + 32 byte SHA256 Hash + 2 byte port) instead of 20 byte SHA1 Hash + 4 byte IP + 2 byte port. Port is the query port, the response port is always the query port + 1. - The trackerless torrent dictionary "nodes" key is a list of 32 byte binary strings (SHA256 Hashes) instead of a list of lists containing a host string and a port integer.
Questions: - nodes (in the find_node and get_peers response) is one concatenated string, not a list of strings, right? - Node ID enforcement, keyspace rotation?- Since:
- 0.9.2
- Author:
- zzz
-
-
Field Summary
Fields Modifier and Type Field Description static String
DHT_FILE_SUFFIX
static NID
FAKE_NID
all-zero NID used for pingsstatic boolean
SECURE_NID
-
Constructor Summary
Constructors Constructor Description KRPC(I2PAppContext ctx, String baseName, I2PSession session)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
announce(byte[] ih, boolean isSeed)
Announce to ourselves.void
announce(byte[] ih, byte[] peerHash, boolean isSeed)
Announce somebody else we know about to ourselves.int
announce(byte[] ih, int max, long maxWait, boolean isSeed)
Not recommended - use getPeersAndAnnounce().void
clear()
Clears the tracker and DHT data.void
disconnected(I2PSession session)
Notify the client that the session has been terminated.void
errorOccurred(I2PSession session, String message, Throwable error)
Notify the client that some error occurred.List<NodeInfo>
findClosest(byte[] ih, int max)
Local lookup onlyCollection<Hash>
getPeersAndAnnounce(byte[] ih, int max, long maxWait, int annMax, long annMaxWait, boolean isSeed, boolean noSeeds)
Get peers for a torrent, and announce to the closest annMax nodes we find.int
getPort()
int
getRPort()
(package private) NodeInfo
heardAbout(NodeInfo nInfo)
Called for bootstrap or for all nodes in a receiveNodes reply.void
messageAvailable(I2PSession session, int msgId, long size)
for non-muxedvoid
messageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort)
Instruct the client that the given session has received a message Will be called only if you register via addMuxedSessionListener().void
ping(Destination dest, int port)
Ping.String
renderStatusHTML()
Debug info, HTML formattedvoid
reportAbuse(I2PSession session, int severity)
Instruct the client that the session specified seems to be under attack and that the client may wish to move its destination to another router.int
size()
Known nodes, not estimated total network size.void
start()
Loads the DHT from file.void
stop()
Stop everything.void
unannounce(byte[] ih)
Remove reference to ourselves in the local tracker.
-
-
-
Field Detail
-
FAKE_NID
public static final NID FAKE_NID
all-zero NID used for pings
-
SECURE_NID
public static final boolean SECURE_NID
- See Also:
- Constant Field Values
-
DHT_FILE_SUFFIX
public static final String DHT_FILE_SUFFIX
- See Also:
- Constant Field Values
-
-
Constructor Detail
-
KRPC
public KRPC(I2PAppContext ctx, String baseName, I2PSession session)
- Parameters:
baseName
- generally "i2psnark"
-
-
Method Detail
-
size
public int size()
Known nodes, not estimated total network size.
-
getRPort
public int getRPort()
-
ping
public void ping(Destination dest, int port)
Ping. We don't have a NID yet so the node is presumed to be absent from our DHT. Non-blocking, does not wait for pong. If and when the pong is received the node will be inserted in our DHT.
-
findClosest
public List<NodeInfo> findClosest(byte[] ih, int max)
Local lookup only- Parameters:
ih
- a 20-byte info hashmax
- max to return- Returns:
- list or empty list (never null)
-
getPeersAndAnnounce
public Collection<Hash> getPeersAndAnnounce(byte[] ih, int max, long maxWait, int annMax, long annMaxWait, boolean isSeed, boolean noSeeds)
Get peers for a torrent, and announce to the closest annMax nodes we find. This is an iterative lookup in the DHT. Blocking! Caller should run in a thread.- Specified by:
getPeersAndAnnounce
in interfaceDHT
- Parameters:
ih
- the Info Hash (torrent)max
- maximum number of peers to returnmaxWait
- the maximum time to wait (ms) must be > 0annMax
- the number of peers to announce toannMaxWait
- the maximum total time to wait for announces, may be 0 to return immediately without waiting for acksisSeed
- true if seed, false if leechnoSeeds
- true if we do not want seeds in the result- Returns:
- possibly empty (never null)
-
announce
public void announce(byte[] ih, boolean isSeed)
Announce to ourselves. Non-blocking.
-
announce
public void announce(byte[] ih, byte[] peerHash, boolean isSeed)
Announce somebody else we know about to ourselves. Non-blocking.
-
unannounce
public void unannounce(byte[] ih)
Remove reference to ourselves in the local tracker. Use when shutting down the torrent locally. Non-blocking.- Specified by:
unannounce
in interfaceDHT
- Parameters:
ih
- the Info Hash (torrent)
-
announce
public int announce(byte[] ih, int max, long maxWait, boolean isSeed)
Not recommended - use getPeersAndAnnounce(). Announce to the closest peers in the local DHT. This is NOT iterative - call getPeers() first to get the closest peers into the local DHT. Blocking unless maxWait <= 0 Caller should run in a thread. This also automatically announces ourself to our local tracker. For best results do a getPeersAndAnnounce() instead, as this announces to the closest in the kbuckets, it does NOT sort through the known nodes hashmap.- Specified by:
announce
in interfaceDHT
- Parameters:
ih
- the Info Hash (torrent)max
- maximum number of peers to announce tomaxWait
- the maximum total time to wait (ms) or 0 to do all in parallel and return immediately.isSeed
- true if seed, false if leech- Returns:
- the number of successful announces, not counting ourselves.
-
start
public void start()
Loads the DHT from file. Can't be restarted after stopping?
-
clear
public void clear()
Clears the tracker and DHT data. Call after saving DHT data to disk.
-
renderStatusHTML
public String renderStatusHTML()
Debug info, HTML formatted- Specified by:
renderStatusHTML
in interfaceDHT
-
heardAbout
NodeInfo heardAbout(NodeInfo nInfo)
Called for bootstrap or for all nodes in a receiveNodes reply. Package private for PersistDHT.- Returns:
- non-null nodeInfo from DB if present, otherwise the nInfo parameter is returned
-
messageAvailable
public void messageAvailable(I2PSession session, int msgId, long size, int proto, int fromPort, int toPort)
Instruct the client that the given session has received a message Will be called only if you register via addMuxedSessionListener(). Will be called only for the proto(s) and toPort(s) you register for.- Specified by:
messageAvailable
in interfaceI2PSessionMuxedListener
- Parameters:
session
- session to notifymsgId
- message number availablesize
- size of the message - why it's a long and not an int is a mysteryproto
- 1-254 or 0 for unspecifiedfromPort
- 1-65535 or 0 for unspecifiedtoPort
- 1-65535 or 0 for unspecified
-
messageAvailable
public void messageAvailable(I2PSession session, int msgId, long size)
for non-muxed- Specified by:
messageAvailable
in interfaceI2PSessionListener
- Specified by:
messageAvailable
in interfaceI2PSessionMuxedListener
- Parameters:
session
- session to notifymsgId
- message number availablesize
- size of the message - why it's a long and not an int is a mystery
-
reportAbuse
public void reportAbuse(I2PSession session, int severity)
Description copied from interface:I2PSessionMuxedListener
Instruct the client that the session specified seems to be under attack and that the client may wish to move its destination to another router. All registered listeners will be called. Unused. Not fully implemented.- Specified by:
reportAbuse
in interfaceI2PSessionListener
- Specified by:
reportAbuse
in interfaceI2PSessionMuxedListener
- Parameters:
session
- session to report abuse toseverity
- how bad the abuse is
-
disconnected
public void disconnected(I2PSession session)
Description copied from interface:I2PSessionMuxedListener
Notify the client that the session has been terminated. All registered listeners will be called.- Specified by:
disconnected
in interfaceI2PSessionListener
- Specified by:
disconnected
in interfaceI2PSessionMuxedListener
-
errorOccurred
public void errorOccurred(I2PSession session, String message, Throwable error)
Description copied from interface:I2PSessionMuxedListener
Notify the client that some error occurred. All registered listeners will be called.- Specified by:
errorOccurred
in interfaceI2PSessionListener
- Specified by:
errorOccurred
in interfaceI2PSessionMuxedListener
error
- can be null? or not?
-
-