dynamicEndpoints.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/python2
  2. # You may redistribute this program and/or modify it under the terms of
  3. # the GNU General Public License as published by the Free Software Foundation,
  4. # either version 3 of the License, or (at your option) any later version.
  5. #
  6. # This program is distributed in the hope that it will be useful,
  7. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. # GNU General Public License for more details.
  10. #
  11. # You should have received a copy of the GNU General Public License
  12. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. from cjdnsadmin.cjdnsadmin import connectWithAdminInfo;
  14. from cjdnsadmin.bencode import *
  15. import sys;
  16. import socket,re
  17. import select
  18. import time
  19. import os
  20. class Node(object):
  21. __slots__ = ("host","port","password","key","lastAddr")
  22. def __init__(self,host,port,password,key):
  23. self.host = host
  24. self.port = port
  25. self.password = password
  26. self.key = key
  27. self.lastAddr = None
  28. nodes = dict()
  29. unresponsive = dict()
  30. def addNode(host,port,password,key):
  31. nodes[key] = Node(host, port, password, key)
  32. # This is just an example... should use a configuration file for this probably.
  33. addNode("verge.info.tm",6324,"ns6vn00hw0buhrtc4wbk8sv230",
  34. "lhjs0njqtvh1z4p2922bbyp2mksmyzf5lb63kvs3ppy78y1dj130.k")
  35. addNode("google.com",13245,"googlesuxmunkeybalz",
  36. "thisisakey.k")
  37. def lookup(node):
  38. for info in socket.getaddrinfo(node.host,node.port,
  39. socket.AF_UNSPEC,socket.SOCK_DGRAM):
  40. sockaddr = info[-1]
  41. #if node.lastAddr == sockaddr: return
  42. node.lastAddr = sockaddr
  43. sockaddr = sockaddr[0] + ":" + str(sockaddr[1])
  44. print("Connecting to {} {}".format(node.key,sockaddr))
  45. cjdns.UDPInterface_beginConnection(password=node.password,
  46. publicKey=node.key,
  47. address=sockaddr)
  48. try: del unresponsive[node.key]
  49. except KeyError: pass
  50. break
  51. isUnresponsive = re.compile("Pinging unresponsive peer \\[(.*\\.k)\\]\\.")
  52. assert(isUnresponsive.match("Pinging unresponsive peer [lhjs0njqtvh1z4p2922bbyp2mksmyzf5lb63kvs3.k]."))
  53. def doLog(message):
  54. print(message)
  55. if message[0]!='P': return;
  56. p = isUnresponsive.match(message)
  57. if not p: return
  58. downKey = p.group(1)
  59. node = nodes.get(downKey,None)
  60. if not node:
  61. print("Unknown neighbor {} is down".format(node))
  62. return
  63. unresponsive[downKey] = node
  64. lookup(node)
  65. def recieve(cjdns,txid):
  66. while True:
  67. doLog(cjdns.getMessage(txid))
  68. cjdns = connectWithAdminInfo()
  69. sub = cjdns.AdminLog_subscribe(206, 'DefaultInterfaceController.c', 'DEBUG')
  70. if (sub['error'] == 'none'):
  71. for node in nodes.values():
  72. lookup(node)
  73. print("Peers added!")
  74. # This is not not not the wrong way to do things.
  75. if os.environ.get('nowait',False): raise SystemExit
  76. print("Watching for unresponsive peers")
  77. recieve(cjdns, sub['txid'])
  78. else:
  79. print(sub)