AUTO_LT_SYNC
[tore.git] / libtorrent / include / libtorrent / kademlia / node.hpp
blobffbe4ddc71ff6b61176b267ad294abe7746b7c76
1 /*
3 Copyright (c) 2006, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #ifndef NODE_HPP
34 #define NODE_HPP
36 #include <algorithm>
37 #include <map>
38 #include <set>
40 #include <libtorrent/kademlia/routing_table.hpp>
41 #include <libtorrent/kademlia/rpc_manager.hpp>
42 #include <libtorrent/kademlia/node_id.hpp>
43 #include <libtorrent/kademlia/msg.hpp>
45 #include <libtorrent/io.hpp>
46 #include <libtorrent/session_settings.hpp>
47 #include <libtorrent/assert.hpp>
49 #include <boost/cstdint.hpp>
50 #include <boost/optional.hpp>
51 #include <boost/iterator/transform_iterator.hpp>
52 #include <boost/ref.hpp>
53 #include <boost/thread/mutex.hpp>
55 #include "libtorrent/socket.hpp"
57 namespace libtorrent {
59 namespace aux { struct session_impl; }
60 struct session_status;
64 namespace libtorrent { namespace dht
67 #ifdef TORRENT_DHT_VERBOSE_LOGGING
68 TORRENT_DECLARE_LOG(node);
69 #endif
71 struct traversal_algorithm;
73 // this is the entry for every peer
74 // the timestamp is there to make it possible
75 // to remove stale peers
76 struct peer_entry
78 tcp::endpoint addr;
79 ptime added;
82 // this is a group. It contains a set of group members
83 struct torrent_entry
85 std::set<peer_entry> peers;
88 inline bool operator<(peer_entry const& lhs, peer_entry const& rhs)
90 return lhs.addr.address() == rhs.addr.address()
91 ? lhs.addr.port() < rhs.addr.port()
92 : lhs.addr.address() < rhs.addr.address();
95 struct null_type {};
97 class announce_observer : public observer
99 public:
100 announce_observer(boost::pool<>& allocator
101 , sha1_hash const& info_hash
102 , int listen_port
103 , entry const& write_token)
104 : observer(allocator)
105 , m_info_hash(info_hash)
106 , m_listen_port(listen_port)
107 , m_token(write_token)
110 void send(msg& m)
112 m.port = m_listen_port;
113 m.info_hash = m_info_hash;
114 m.write_token = m_token;
117 void timeout() {}
118 void reply(msg const&) {}
119 void abort() {}
121 private:
122 sha1_hash m_info_hash;
123 int m_listen_port;
124 entry m_token;
127 class get_peers_observer : public observer
129 public:
130 get_peers_observer(sha1_hash const& info_hash
131 , int listen_port
132 , rpc_manager& rpc
133 , boost::function<void(std::vector<tcp::endpoint> const&, sha1_hash const&)> f)
134 : observer(rpc.allocator())
135 , m_info_hash(info_hash)
136 , m_listen_port(listen_port)
137 , m_rpc(rpc)
138 , m_fun(f)
141 void send(msg& m)
143 m.port = m_listen_port;
144 m.info_hash = m_info_hash;
147 void timeout() {}
148 void reply(msg const& r)
150 observer_ptr o(new (m_rpc.allocator().malloc()) announce_observer(
151 m_rpc.allocator(), m_info_hash, m_listen_port, r.write_token));
152 #ifndef NDEBUG
153 o->m_in_constructor = false;
154 #endif
155 m_rpc.invoke(messages::announce_peer, r.addr, o);
156 m_fun(r.peers, m_info_hash);
158 void abort() {}
160 private:
161 sha1_hash m_info_hash;
162 int m_listen_port;
163 rpc_manager& m_rpc;
164 boost::function<void(std::vector<tcp::endpoint> const&, sha1_hash const&)> m_fun;
167 class node_impl : boost::noncopyable
169 typedef std::map<node_id, torrent_entry> table_t;
170 public:
171 node_impl(libtorrent::aux::session_impl& ses, boost::function<void(msg const&)> const& f
172 , dht_settings const& settings);
174 virtual ~node_impl() {}
176 void refresh(node_id const& id, boost::function0<void> f);
177 void bootstrap(std::vector<udp::endpoint> const& nodes
178 , boost::function0<void> f);
179 void find_node(node_id const& id, boost::function<
180 void(std::vector<node_entry> const&)> f);
181 void add_router_node(udp::endpoint router);
183 void unreachable(udp::endpoint const& ep);
184 void incoming(msg const& m);
186 void refresh();
187 void refresh_bucket(int bucket);
188 int bucket_size(int bucket);
190 typedef routing_table::iterator iterator;
192 iterator begin() const { return m_table.begin(); }
193 iterator end() const { return m_table.end(); }
195 typedef table_t::iterator data_iterator;
197 void set_node_id(node_id const& nid) { m_id = nid; }
198 node_id const& nid() const { return m_id; }
200 boost::tuple<int, int> size() const{ return m_table.size(); }
201 size_type num_global_nodes() const
202 { return m_table.num_global_nodes(); }
204 data_iterator begin_data() { return m_map.begin(); }
205 data_iterator end_data() { return m_map.end(); }
206 int data_size() const { return int(m_map.size()); }
208 #ifdef TORRENT_DHT_VERBOSE_LOGGING
209 void print_state(std::ostream& os) const
210 { m_table.print_state(os); }
211 #endif
213 void announce(sha1_hash const& info_hash, int listen_port
214 , boost::function<void(std::vector<tcp::endpoint> const&
215 , sha1_hash const&)> f);
217 bool verify_token(msg const& m);
218 entry generate_token(msg const& m);
220 // the returned time is the delay until connection_timeout()
221 // should be called again the next time
222 time_duration connection_timeout();
223 time_duration refresh_timeout();
225 // generates a new secret number used to generate write tokens
226 void new_write_key();
228 // pings the given node, and adds it to
229 // the routing table if it respons and if the
230 // bucket is not full.
231 void add_node(udp::endpoint node);
233 void replacement_cache(bucket_t& nodes) const
234 { m_table.replacement_cache(nodes); }
236 int branch_factor() const { return m_settings.search_branching; }
238 void add_traversal_algorithm(traversal_algorithm* a)
240 mutex_t::scoped_lock l(m_mutex);
241 m_running_requests.insert(a);
244 void remove_traversal_algorithm(traversal_algorithm* a)
246 mutex_t::scoped_lock l(m_mutex);
247 m_running_requests.erase(a);
250 void status(libtorrent::session_status& s);
252 protected:
253 // is called when a find data request is received. Should
254 // return false if the data is not stored on this node. If
255 // the data is stored, it should be serialized into 'data'.
256 bool on_find(msg const& m, std::vector<tcp::endpoint>& peers) const;
258 // this is called when a store request is received. The data
259 // is store-parameters and the data to be stored.
260 void on_announce(msg const& m, msg& reply);
262 dht_settings const& m_settings;
264 // the maximum number of peers to send in a get_peers
265 // reply. Ordinary trackers usually limit this to 50.
266 // 50 => 6 * 50 = 250 bytes + packet overhead
267 int m_max_peers_reply;
269 private:
270 typedef boost::mutex mutex_t;
271 mutex_t m_mutex;
273 // this list must be destructed after the rpc manager
274 // since it might have references to it
275 std::set<traversal_algorithm*> m_running_requests;
277 void incoming_request(msg const& h);
279 node_id m_id;
281 public:
282 routing_table m_table;
283 rpc_manager m_rpc;
285 private:
286 table_t m_map;
288 ptime m_last_tracker_tick;
290 // secret random numbers used to create write tokens
291 int m_secret[2];
293 libtorrent::aux::session_impl& m_ses;
297 } } // namespace libtorrent::dht
299 #endif // NODE_HPP