instrumentation: add next-share/
[cs-p2p-next.git] / instrumentation / next-share / BaseLib / Core / DecentralizedTracking / kadtracker / responder.py
1 # Copyright (C) 2009 Raul Jimenez
2 # Released under GNU LGPL 2.1
3 # See LICENSE.txt for more information
4
5 import message
6 import node
7 import sys
8
9 import logging
10
11 logger = logging.getLogger('dht')
12
13
14 class Responder(object ):
15     "docstring for Responder"
16     def __init__(self, my_id, routing_m, tracker, token_m):
17         self.my_id = my_id
18         self.routing_m = routing_m
19         self.tracker = tracker
20         self.token_m = token_m
21         self.query_handler = {message.PING: self._on_ping,
22                               message.FIND_NODE: self._on_find_node,
23                               message.GET_PEERS: self._on_get_peers,
24                               message.ANNOUNCE_PEER: self._on_announce_peer,
25                               }
26         self.notify_routing_m_on_query = None
27
28     def set_on_query_received_callback(self, callback_f):
29         self.notify_routing_m_on_query = callback_f
30         
31     def on_query_received(self, query_msg, addr):
32         logger.debug('query received\n%s\nSource: %s' % (`query_msg`,
33                                                           `addr`))
34         try:
35             handler = self.query_handler[query_msg.query]
36         except (KeyError, ValueError):
37             logger.exception('Invalid QUERY')
38             return # ignore query #TODO2: send error back?
39         response_msg = handler(query_msg)
40         self.notify_routing_m_on_query(node.Node(addr,
41                                                  query_msg.sender_id,
42                                                  query_msg.ns_node))
43         return response_msg
44
45     def _on_ping(self, query_msg):
46         return message.OutgoingPingResponse(self.my_id)
47
48     def _on_find_node(self, query_msg):
49         rnodes = self.routing_m.get_closest_rnodes(query_msg.target)
50         return message.OutgoingFindNodeResponse(self.my_id,
51                                                 nodes2=rnodes)
52
53     def _on_get_peers(self, query_msg):
54         #get peers from the tracker (if any)
55         token = self.token_m.get()
56         peers = self.tracker.get(query_msg.info_hash)
57         if peers:
58             return message.OutgoingGetPeersResponse(self.my_id,
59                                                     token,
60                                                     peers=peers)
61         rnodes = self.routing_m.get_closest_rnodes(query_msg.info_hash)
62         return message.OutgoingGetPeersResponse(self.my_id,
63                                                 token,
64                                                 nodes2=rnodes)
65     def _on_announce_peer(self, query_msg):
66         return message.OutgoingAnnouncePeerResponse(self.my_id)
67