1 import Behaviour
2 import xmpp
3 import SocketServer
4 import pickle
5 import random
6
10 self.server.requests.append(self.request)
11 try:
12 data = ""
13 while True:
14
15 length = self.rfile.read(8)
16 if not length:
17
18 break
19 data = self.rfile.read(int(length))
20 self.server.owner.DEBUG("P2P message received.","ok")
21 if data:
22 try:
23
24 ACLmsg = pickle.loads(data)
25 self.server.postMessage(ACLmsg)
26 self.server.owner.DEBUG("The p2p message is serialized.")
27 except:
28
29 n = xmpp.simplexml.XML2Node(str(data))
30 m = xmpp.Message(node=n)
31 self.server._jabber_messageCB(None,m,raiseFlag=False)
32 self.server.owner.DEBUG("The p2p message is XML:"+str(m))
33 data = ""
34 except Exception, e:
35 self.server.owner.DEBUG("P2P Socket Closed to "+ str(self.client_address),"err")
36
37
39 try:
40 self.server.handle_request()
41 except Exception,e:
42 self.myAgent.DEBUG("P2P server failed: "+str(e),"err")
43
45 self.myAgent.p2p_ready = False
46 self.server.stop()
47 if not self.finished:
48 try:
49 for sock in self.server.requests:
50 try:
51 sock.close()
52 del sock
53 except:
54 pass
55 self.server.socket.close()
56 del self.server
57 except:
58 pass
59 iq = xmpp.Iq("result",queryNS=xmpp.NS_DISCO_INFO)
60 for to in self.myAgent.p2p_routes.keys():
61 iq.setTo(to)
62 self.myAgent.send(iq)
63 self.finished = True
64
66 open = False
67 SocketServer.ThreadingTCPServer.allow_reuse_address = True
68 while open == False:
69 try:
70 self.server = SocketServer.ThreadingTCPServer(('', self.myAgent.P2PPORT), self.P2PRequestHandler)
71 self.server.owner = self.myAgent
72 open = True
73 except:
74 self.myAgent.P2PPORT = random.randint(1025,65535)
75 self.myAgent.DEBUG("Changing P2P port to " + str(self.myAgent.P2PPORT))
76
77 self.server._jabber_messageCB = self.myAgent._jabber_messageCB
78 self.server.postMessage = self.myAgent.postMessage
79 self.server.requests = []
80 self.myAgent.DEBUG(self.getName()+": P2P Behaviour Started at port "+ str(self.myAgent.P2PPORT))
81 self.finished = False
82 self.myAgent.p2p_ready = True
83
125
126
128
130 self.msg = self._receive(False)
131 if self.msg != None:
132 if self.msg.getType() == "get":
133
134 reply = self.msg.buildReply("result")
135 if self.myAgent.p2p_ready:
136 reply.getTag("query").addChild("feature", {"var":"http://jabber.org/protocol/si"})
137 reply.getTag("query").addChild("feature", {"var":"http://jabber.org/protocol/si/profile/spade-p2p-messaging"})
138 self.myAgent.send(reply)
139 self.myAgent.DEBUG(self.myAgent.getName()+": Sent Disco reply to "+ str(reply.getTo()))
140 elif self.msg.getType() == "result":
141 services = []
142 for child in self.msg.getQueryChildren():
143 services.append(str(child.getAttr("var")))
144 if "http://jabber.org/protocol/si/profile/spade-p2p-messaging" not in services:
145 frm = str(self.msg.getFrom().getStripped())
146 if str(frm) in self.myAgent.p2p_routes.keys():
147
148 self.myAgent.p2p_lock.acquire()
149 try:
150 self.myAgent.DEBUG("Deleting "+str(frm)+" from P2P routes: "+ str(self.myAgent.p2p_routes),"warn")
151 del self.myAgent.p2p_routes[frm]
152 except:
153 pass
154 self.myAgent.p2p_lock.release()
155 else:
156 self.myAgent.DEBUG("DiscoBehaviour returned with no message", "warn")
157
159
166
167
169 self.result = False
170
171 self.myAgent.DEBUG( "Offer StreamInitiation to" + str(self.to))
172 iq = xmpp.Iq(attrs={'id':self.id})
173 iq.setTo(self.to)
174 iq.setType("set")
175 si = xmpp.Node("si", {"profile":"http://jabber.org/protocol/si/profile/spade-p2p-messaging"})
176 si.setNamespace("http://jabber.org/protocol/si")
177 if self.myAgent.p2p_ready:
178 p2pnode = xmpp.Node("p2p")
179 p2pnode.setNamespace('http://jabber.org/protocol/si/profile/spade-p2p-messaging')
180 p2pnode.setData(self.myAgent.getP2PUrl())
181 si.addChild(node=p2pnode)
182 iq.addChild(node=si)
183 self.myAgent.send(iq)
184
185 msg = self._receive(True, 4)
186 if msg:
187 self.result = False
188 if msg.getType() =="result":
189 self.myAgent.DEBUG("StreamRequest Agreed","ok")
190 try:
191 remote_address = str(msg.getTag("si").getTag("p2p").getTag("value").getData())
192 d = {"url":remote_address, "p2p":True}
193 if self.myAgent.p2p_routes.has_key(str(msg.getFrom().getStripped())):
194 self.myAgent.p2p_routes[str(msg.getFrom().getStripped())].update(d)
195 self.result = True
196 else:
197 self.myAgent.p2p_routes[str(msg.getFrom().getStripped())] = d
198 except Exception, e:
199 self.myAgent.DEBUG("Malformed StreamRequest Answer: "+ str(e),"err")
200 self.myAgent.p2p_routes[str(msg.getFrom().getStripped())] = {}
201 elif msg.getType() == "error":
202 self.myAgent.DEBUG("StreamRequest REFUSED","warn")
203 self.myAgent.p2p_routes[str(msg.getFrom().getStripped())] = {'p2p':False}
204 else:
205
206 self.myAgent.DEBUG("StreamRequest REFUSED","warn")
207 self.myAgent.p2p_routes[str(iq.getTo().getStripped())] = {'p2p':False}
208
209
211
219
220
222 self.result = []
223 iq = xmpp.Iq(queryNS=xmpp.NS_DISCO_INFO, attrs={'id':self.id})
224 iq.setTo(self.to)
225 iq.setType("get")
226 self.myAgent.DEBUG("Send IQ message: "+str(iq))
227
228 self.myAgent.send(iq)
229
230 msg = self._receive(True)
231 if msg:
232 if msg.getType() == "result":
233 for child in msg.getQueryChildren():
234 self.result.append(str(child.getAttr("var")))
235 self.myAgent.DEBUG("Retrieved services: " + str(self.result))
236 else:
237 self.myAgent.DEBUG("Disco Info returned no results from " + str(self.to), "warn")
238 else:
239 self.myAgent.DEBUG("No Disco Info retrieved from " + str(self.to), "warn")
240