The token of announce_peer in DHT - bittorrent

In http://www.bittorrent.org/beps/bep_0005.html, the announce_peer query needs a token which has the require ,"the "token" received in response to a previous get_peers query".
Does it mean that if node A has never send a get_peer query to node B, then node A would never receive a peer_announce query from node B ?

Does it mean that if node A has never send a get_peer query to node B, then node A would never receive a peer_announce query from node B ?
No, it's the other way around:
Node A wants to announce that it is downloading a certain torrent.
Node A makes a get_peers query to Node B.
Node B sends a response to Node A for the get_peers query that it has just sent. Node B's response includes the token.
Node A, now, can send an announce_peer query to Node B using the token it has just received from Node B's response.
Why all this fuss?
The return value for a query for peers includes an opaque value known as the "token." For a node to announce that its controlling peer is downloading a torrent, it must present the token received from the same queried node in a recent query for peers. When a node attempts to "announce" a torrent, the queried node checks the token against the querying node's IP address. This is to prevent malicious hosts from signing up other hosts for torrents.
http://www.bittorrent.org/beps/bep_0005.html

The token represents a capability to announce that one is joining a swarm. It's like first you ask about the swarm -- "Hey, what's up with this swarm?" -- and the peer you ask tells you what it knows about that swarm, and it also gives you a ticket you can return, or not, if you want to join that swarm too. Fine-grained capability security for the win!

Yes that's right. It ensures that someone announcing a peer is actually interested in the corresponding torrent, and has demonstrated control over the announced address.

Related

How do I get the number of connected clients from Alfred?

I found that Alfred knows all connected clients for a given (tenant, document) pair. However, I haven't found any HTTP or WebSocket APIs to get to this information. Did I miss something?
Why do I need this?
I'm building a bot (a server-side client to fluid) that will be responsible for converting file representation to fluid and vice versa. My bot needs to know when the last client is gone so that it can convert the fluid ops back into a (legacy) file.
We don't provide a service side API to fetch list of connected clients. However, we maintain the list of all writer clients in our quorum. Using this, you can always track list of writers connected to the session.
Note that for your scenario, this will require your bot to be already running so that it can track when everyone leaves the session. If you only want to spawn the bot only when every client leaves, you can track the noClient op. We send this op when everyone leaves the session.

How make big real time app use socket.io or lightstreamer and scale horizontal

I have got some questions with real time app.
I am making a real time app at this time. I used socket.io,mongodb and nodejs. This app works nice in prototype but what will happen when the number of users increases?
I want to grow horizontal scale.
e.g I have got two server (server A, server B)
client A connect server A
Client B connect server B
How can Client A send message Client B? It has been confusing me with different servers
I found the use redis for this. Is there a possibility that redis-server enough?
As a result, what should I use and which tech(redis,lightstreamer,jabber, socket.io,nginx)?
You can't send directly a message from A to B because they arn't connected to the same server.
The solution to this is to enable communication between the two node server.
You mentionned redis so if you go that route you can have a central redis server that has two lists (on for each server). When client A want to join client B, he send to server A his message. Server A will not find client B in his local sockets and will push to redis the message. Soon or later, server B will collect his pending messages from redis and dispatch them to client B.
It's a basic implementation that you can change to fit your needs. You can have for example a single list of messages per server, but also why not a list per user (and the server which has this
Also as a side note, any central data store such as a database server (mongo? MySQL?) can do the same as redis. It all comes down to what you allready have, what you can have and what type of persistence you want.

What is bi-direction protocol in TChannel?

I have read about TChannel which is a networking framing protocol used for general RPC.
https://github.com/uber/tchannel/blob/master/docs/protocol.md
But I misunderstand some concepts.
"Tchannel is a bi-directional request/response protocol. Each connection between peers is considered equivalent, regardless of which side initiated it. It's possible, perhaps even desirable, to have multiple connections between the same pair of peers. Message ids are scoped to a connection. It is not valid to send a request down one connection and a response down another."
What is bi-direction protocol?
Start considering the "request/response" part in the statement. It means that for every successful request sent by the host A there will be always a response sent back by host B.
This does not necessarly implies a syncronous behaviour (e.g. A block waiting for B's reply). Indeed TChannel works with an async behavior. Many requests can be sent in sequence, and the requester expects an out of order responses. In this way, the slow requests do not block faster requests.
How this work? Very simple. A specifies a message id when sending a request. When B responds, it uses the same message id for the response. In this way A can easily correlate a response with the corresponding request.
Now look at the "bi-directional" part in the statement. It means that if host B wants to send a request to host A, it can re-use the same channel that was created originally by A. Despite there is a request/response logic, A and B are considered peers, and each connection between peers is considered equivalent, regardless of which host initiated it.

How to persist HTTP response in redis

I am creating a long-polling chat application on nodeJS without using Socket.io and scaling it using clusters.
I have to find a way to store all the long-polled HTTP requests and response objects in such a way that it is available across all node clusters(so that when a message is received for a long-polled request, I can get that request and respond to it)
I have tried using redis, however, when I stringify http request and response objects, I get "Cannot Stringify Cyclic Structure" Error.
Maybe I am approaching it in a wrong way. In that case, how do we generally implement lon-polling across different clusters?
What you're asking seems to be a bit confused.
In a long-polling situation, a client makes an http request that is routed to a specific HTTP server. If no data to satisfy that request is immediately available, the request is then kept alive for some extended period of time and either it will eventually timeout and the client will then issue another long polling request or some data will become available and a response will be returned to the request.
As such, you do not make this work in clusters by trying to centrally save request and response objects. Those belong to a specific TCP connection between a specific server and a specific client. You can't save them and use them elsewhere and it also isn't something that helps any of this work with clustering either.
What I would think the clustering problem you have here is that when some data does become available for a specific client, you need to know which server that client has a long polling request that is currently live so you can instruct that specific server to return the data from that request.
The usual way that you do this is you have some sort of userID that represents each client. When any client connects in with a long polling request, that connection is cluster distributed to one of your servers. That server that gets the request, then writes to a central database (often redis) that this userID userA is now connected to server12. Then, when some data becomes available for userA, any agent can lookup that user in the redis store and see that the user is currently connected to server12. So, they can instruct server12 to send the data to userA using the current long polling connection for userA.
This is just one strategy for dealing with clustering - there are many others such as sticky load balancing, algorithmic distribution, broadcast distribution, etc... You can see an answer that describes some of the various schemes here.
If you are sure you want to store all the request and responses, have a look at this question.
Serializing Cyclic objects
you can also try cycle.js
However, I think you would only be interested in serializing few elements from request/response. An easier (probably better too) approach would be to just copy the required key/value pairs from request/response object in to a separate object and store them.

How to get the first peer from a torrent-magnet link?

I've been trying to understand the torrent-magnet technology, but I can't seem to figure out how you get connected to the first peer when opening a magnet link.
When you get a magnet link like below, it contains no initial peer - only the BitTorrent Info Hash (btih) and the file name.
magnet:?xt=urn:btih:bbb6db69965af769f664b6636e7914f8735141b3&dn=ubuntu-12.04-desktop-i386.iso
According to BitTorrent & Magnets: How Do They Work? (MakeUseOf)
If you click a magnet link that does not specify a tracker (tr) the first peer will be found using DHT. Once you’ve got a peer, peer exchange kicks in too.
The DHT article on Wikipedia does not specify how to find a peer, but in the Kademlia article (upon which BitTorrent DHT is based), it says
A node that would like to join the net must first go through a bootstrap process. In this phase, the joining node needs to know the IP address and port of another node—a bootstrap node (obtained from the user, or from a stored list)—that is already participating in the Kademlia network.
But where does it know that node from? I don't see an address or anything present in the magnet link. Since it's decentralized (trackerless), I wouldn't expect it to know the node in advance. Or is the DHT in fact not decentralized?
For the most part, when you start a bittorrent client, bootstrap off of:
nodes from your last session, that were saved to disk
other peers that you have on any of the swarms you're on
There are a few well-known bootstrap nodes which clients can use if they have no other means of finding any. Essentially the only case this happens is when you install a client for the first time, and the first torrent you download is a magnet link without a tracker.
You can then hit router.utorrent.com:6881. I believe transmission, azureus and bitcomet run similar routers, and possibly other clients as well.
By "router", I mean a node that appear to behave like any other node in the DHT, but probably has a different mechanism for determining which nodes to hand out, and probably is optimized specifically for the use case of just introducing dht nodes to each other.
UPDATE: you can run your own DHT bootstrap machine, here's the source code.

Resources