~ubuntu-branches/ubuntu/maverick/libtorrent-rasterbar/maverick

« back to all changes in this revision

Viewing changes to src/kademlia/refresh.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cristian Greco
  • Date: 2008-07-02 10:46:21 UTC
  • Revision ID: james.westby@ubuntu.com-20080702104621-jzx3pfke9lkcxfxn
Tags: upstream-0.13.1
ImportĀ upstreamĀ versionĀ 0.13.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Copyright (c) 2006, Arvid Norberg & Daniel Wallin
 
4
All rights reserved.
 
5
 
 
6
Redistribution and use in source and binary forms, with or without
 
7
modification, are permitted provided that the following conditions
 
8
are met:
 
9
 
 
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.
 
18
 
 
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.
 
30
 
 
31
*/
 
32
 
 
33
#include "libtorrent/pch.hpp"
 
34
 
 
35
#include <libtorrent/kademlia/refresh.hpp>
 
36
#include <libtorrent/kademlia/routing_table.hpp>
 
37
#include <libtorrent/kademlia/rpc_manager.hpp>
 
38
#include <libtorrent/kademlia/logging.hpp>
 
39
#include <libtorrent/kademlia/msg.hpp>
 
40
 
 
41
#include <libtorrent/io.hpp>
 
42
 
 
43
#include <boost/bind.hpp>
 
44
 
 
45
using boost::bind;
 
46
 
 
47
namespace libtorrent { namespace dht
 
48
{
 
49
 
 
50
using asio::ip::udp;
 
51
 
 
52
#ifdef TORRENT_DHT_VERBOSE_LOGGING
 
53
TORRENT_DEFINE_LOG(refresh)
 
54
#endif
 
55
 
 
56
refresh_observer::~refresh_observer()
 
57
{
 
58
        if (m_algorithm) m_algorithm->failed(m_self, true);
 
59
}
 
60
 
 
61
void refresh_observer::reply(msg const& in)
 
62
{
 
63
        if (!m_algorithm) return;
 
64
 
 
65
        if (!in.nodes.empty())
 
66
        {
 
67
                for (msg::nodes_t::const_iterator i = in.nodes.begin()
 
68
                        , end(in.nodes.end()); i != end; ++i)
 
69
                {
 
70
                        m_algorithm->traverse(i->id, i->addr);
 
71
                }
 
72
        }
 
73
        m_algorithm->finished(m_self);
 
74
        m_algorithm = 0;
 
75
}
 
76
 
 
77
void refresh_observer::timeout()
 
78
{
 
79
        if (!m_algorithm) return;
 
80
        m_algorithm->failed(m_self);
 
81
        m_algorithm = 0;
 
82
}
 
83
 
 
84
ping_observer::~ping_observer()
 
85
{
 
86
        if (m_algorithm) m_algorithm->ping_timeout(m_self, true);
 
87
}
 
88
 
 
89
void ping_observer::reply(msg const& m)
 
90
{
 
91
        if (!m_algorithm) return;
 
92
        
 
93
        m_algorithm->ping_reply(m_self);
 
94
        m_algorithm = 0;
 
95
}
 
96
 
 
97
void ping_observer::timeout()
 
98
{
 
99
        if (!m_algorithm) return;
 
100
        m_algorithm->ping_timeout(m_self);
 
101
        m_algorithm = 0;
 
102
}
 
103
 
 
104
void refresh::invoke(node_id const& nid, udp::endpoint addr)
 
105
{
 
106
        observer_ptr o(new (m_rpc.allocator().malloc()) refresh_observer(
 
107
                this, nid, m_target));
 
108
#ifndef NDEBUG
 
109
        o->m_in_constructor = false;
 
110
#endif
 
111
 
 
112
        m_rpc.invoke(messages::find_node, addr, o);
 
113
}
 
114
 
 
115
void refresh::done()
 
116
{
 
117
        m_leftover_nodes_iterator = (int)m_results.size() > m_max_results ?
 
118
                m_results.begin() + m_max_results : m_results.end();
 
119
 
 
120
        invoke_pings_or_finish();
 
121
}
 
122
 
 
123
void refresh::ping_reply(node_id nid)
 
124
{
 
125
        m_active_pings--;
 
126
        invoke_pings_or_finish();
 
127
}
 
128
 
 
129
void refresh::ping_timeout(node_id nid, bool prevent_request)
 
130
{
 
131
        m_active_pings--;
 
132
        invoke_pings_or_finish(prevent_request);
 
133
}
 
134
 
 
135
void refresh::invoke_pings_or_finish(bool prevent_request)
 
136
{
 
137
        if (prevent_request)
 
138
        {
 
139
                --m_max_active_pings;
 
140
                if (m_max_active_pings <= 0)
 
141
                        m_max_active_pings = 1;
 
142
        }
 
143
        else
 
144
        {
 
145
                while (m_active_pings < m_max_active_pings)
 
146
                {
 
147
                        if (m_leftover_nodes_iterator == m_results.end()) break;
 
148
 
 
149
                        result const& node = *m_leftover_nodes_iterator;
 
150
 
 
151
                        // Skip initial nodes
 
152
                        if (node.flags & result::initial)
 
153
                        {
 
154
                                ++m_leftover_nodes_iterator;
 
155
                                continue;
 
156
                        }
 
157
 
 
158
                        try
 
159
                        {
 
160
                                observer_ptr o(new (m_rpc.allocator().malloc()) ping_observer(
 
161
                                        this, node.id));
 
162
#ifndef NDEBUG
 
163
                                o->m_in_constructor = false;
 
164
#endif
 
165
                                m_rpc.invoke(messages::ping, node.addr, o);
 
166
                                ++m_active_pings;
 
167
                                ++m_leftover_nodes_iterator;
 
168
                        }
 
169
                        catch (std::exception& e) {}
 
170
                }
 
171
        }
 
172
 
 
173
        if (m_active_pings == 0)
 
174
        {
 
175
                m_done_callback();
 
176
        }
 
177
}
 
178
 
 
179
} } // namespace libtorrent::dht
 
180