From 5f858d3e20fc2cbf8e6b4bcf392de6e8cb2029ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joanne=20Hug=C3=A9?= <joanne.huge@nexedi.com>
Date: Wed, 21 Jun 2023 11:26:37 +0200
Subject: [PATCH] python2 to python3: Use 2to3 script

---
 demo/demo                                     | 46 +++++------
 demo/fixnemu.py                               | 10 +--
 demo/ping.py                                  |  2 +-
 demo/py                                       |  2 +-
 demo/test_hmac.py                             |  4 +-
 re6st/cache.py                                | 16 ++--
 re6st/cli/conf.py                             | 16 ++--
 re6st/cli/node.py                             | 14 ++--
 re6st/cli/registry.py                         | 10 +--
 re6st/ctl.py                                  |  6 +-
 re6st/debug.py                                |  5 +-
 re6st/plib.py                                 |  2 +-
 re6st/registry.py                             | 80 +++++++++----------
 re6st/tests/test_unit/test_conf.py            |  2 +-
 re6st/tests/test_unit/test_registry.py        |  8 +-
 re6st/tests/test_unit/test_registry_client.py | 10 +--
 re6st/tunnel.py                               | 36 ++++-----
 re6st/upnpigd.py                              |  8 +-
 re6st/utils.py                                | 10 +--
 setup.py                                      |  2 +-
 20 files changed, 144 insertions(+), 145 deletions(-)

diff --git a/demo/demo b/demo/demo
index a37ac71..8a13f96 100755
--- a/demo/demo
+++ b/demo/demo
@@ -72,7 +72,7 @@ if args.duration:
     signal.signal(signal.SIGALRM, handler)
     signal.alarm(args.duration)
 
-execfile("fixnemu.py")
+exec(compile(open("fixnemu.py", "rb").read(), "fixnemu.py", 'exec'))
 
 # create nodes
 for name in """internet=I registry=R
@@ -89,9 +89,9 @@ for name in """internet=I registry=R
         'net.ipv4.icmp_echo_ignore_broadcasts=0')).wait()
     node._screen = node.Popen((SCREEN, '-DmS', name))
     node.screen = (lambda name: lambda *cmd:
-        subprocess.call([SCREEN, '-r', name, '-X', 'eval'] + map(
+        subprocess.call([SCREEN, '-r', name, '-X', 'eval'] + list(map(
             """screen sh -c 'set %s; "\$@"; echo "\$@"; exec $SHELL'"""
-            .__mod__, cmd)))(name)
+            .__mod__, cmd))))(name)
 
 # create switch
 switch1 = nemu.Switch()
@@ -208,10 +208,10 @@ for m in machine6, machine7, machine8:
 null = file(os.devnull, "r+")
 for ip in '10.1.1.2', '10.1.1.3', '10.2.1.2', '10.2.1.3':
     if machine1.Popen(('ping', '-c1', ip), stdout=null).wait():
-        print 'Failed to ping %s' % ip
+        print('Failed to ping %s' % ip)
         break
 else:
-    print "Connectivity IPv4 OK!"
+    print("Connectivity IPv4 OK!")
 
 nodes = []
 gateway1.screen('miniupnpd -d -f miniupnpd.conf -P miniupnpd.pid'
@@ -297,7 +297,7 @@ if args.ping:
             '2001:db8:43:1::1' if i == 10 else
             # Only 1 address for machine2 because prefix_len = 80,+48 = 128
             '2001:db8:42:%s::1' % i
-            for i in xrange(11)
+            for i in range(11)
             if i != j]
         name = machine.name if machine.short[0] == 'R' else 'm' + machine.short
         machine.screen('python ping.py {} {}'.format(name, ' '.join(ips)))
@@ -314,30 +314,30 @@ class testHMAC(Thread):
         reg1_db.text_factory = reg2_db.text_factory = str
         m_net1 = 'registry', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8'
         m_net2 = 'registry2', 'm10'
-        print 'Testing HMAC, letting the time to machines to create tunnels...'
+        print('Testing HMAC, letting the time to machines to create tunnels...')
         time.sleep(45)
-        print 'Check that the initial HMAC config is deployed on network 1'
+        print('Check that the initial HMAC config is deployed on network 1')
         test_hmac.checkHMAC(reg1_db, m_net1)
-        print 'Test that a HMAC update works with nodes that are up'
+        print('Test that a HMAC update works with nodes that are up')
         registry.backticks_raise(updateHMAC)
-        print 'Updated HMAC (config = hmac0 & hmac1), waiting...'
+        print('Updated HMAC (config = hmac0 & hmac1), waiting...')
         time.sleep(60)
-        print 'Checking HMAC on machines connected to registry 1...'
+        print('Checking HMAC on machines connected to registry 1...')
         test_hmac.checkHMAC(reg1_db, m_net1)
-        print ('Test that machines can update upon reboot ' +
-               'when they were off during a HMAC update.')
+        print(('Test that machines can update upon reboot ' +
+               'when they were off during a HMAC update.'))
         test_hmac.killRe6st(machine1)
-        print 'Re6st on machine 1 is stopped'
+        print('Re6st on machine 1 is stopped')
         time.sleep(5)
         registry.backticks_raise(updateHMAC)
-        print 'Updated HMAC on registry (config = hmac1 & hmac2), waiting...'
+        print('Updated HMAC on registry (config = hmac1 & hmac2), waiting...')
         time.sleep(60)
         machine1.screen(machine1.re6st_cmdline)
-        print 'Started re6st on machine 1, waiting for it to get new conf'
+        print('Started re6st on machine 1, waiting for it to get new conf')
         time.sleep(60)
-        print 'Checking HMAC on machines connected to registry 1...'
+        print('Checking HMAC on machines connected to registry 1...')
         test_hmac.checkHMAC(reg1_db, m_net1)
-        print 'Testing of HMAC done!'
+        print('Testing of HMAC done!')
         # TODO: missing last step
         reg1_db.close()
         reg2_db.close()
@@ -399,7 +399,7 @@ def route_svg(ipv4, z = 4, default = type('', (), {'short': None})):
         gv.append('%s[pos="%s,%s!"];'
             % (n.name, z * math.cos(a * i), z * math.sin(a * i)))
         l = []
-        for p, r in graph[n].iteritems():
+        for p, r in graph[n].items():
             j = abs(nodes.index(p[0]) - i)
             l.append((min(j, N - j), p, r))
         for j, (l, (p, t), r) in enumerate(sorted(l)):
@@ -427,9 +427,9 @@ def route_svg(ipv4, z = 4, default = type('', (), {'short': None})):
         ).communicate('\n'.join(gv))[0]
 
 if args.port:
-    import SimpleHTTPServer, SocketServer
+    import http.server, socketserver
 
-    class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+    class Handler(http.server.SimpleHTTPRequestHandler):
 
         _path_match = re.compile('/(.+)\.(html|svg)$').match
         pages = 'ipv6', 'ipv4', 'tunnels'
@@ -439,7 +439,7 @@ if args.port:
             try:
                 name, ext = self._path_match(self.path).groups()
                 page = self.pages.index(name)
-            except AttributeError, ValueError:
+            except AttributeError as ValueError:
                 if self.path == '/':
                     self.send_response(302)
                     self.send_header('Location', self.pages[0] + '.html')
@@ -513,7 +513,7 @@ if args.port:
             self.end_headers()
             self.wfile.write(body)
 
-    class TCPServer(SocketServer.TCPServer):
+    class TCPServer(socketserver.TCPServer):
         allow_reuse_address = True
 
     TCPServer(('', args.port), Handler).serve_forever()
diff --git a/demo/fixnemu.py b/demo/fixnemu.py
index 4b16a28..4da08b7 100644
--- a/demo/fixnemu.py
+++ b/demo/fixnemu.py
@@ -56,7 +56,7 @@ def _get_all_route_data():
             metric))
     return ret
 
-get_all_route_data.func_code = _get_all_route_data.func_code
+get_all_route_data.__code__ = _get_all_route_data.__code__
 
 interface__init__ = interface.__init__
 def __init__(self, *args, **kw):
@@ -65,12 +65,12 @@ def __init__(self, *args, **kw):
         self.name = self.name.split('@',1)[0]
 interface.__init__ = __init__
 
-get_addr_data.orig = function(get_addr_data.func_code,
-                              get_addr_data.func_globals)
+get_addr_data.orig = function(get_addr_data.__code__,
+                              get_addr_data.__globals__)
 def _get_addr_data():
     byidx, bynam = get_addr_data.orig()
-    return byidx, {name.split('@',1)[0]: a for name, a in bynam.iteritems()}
-get_addr_data.func_code = _get_addr_data.func_code
+    return byidx, {name.split('@',1)[0]: a for name, a in bynam.items()}
+get_addr_data.__code__ = _get_addr_data.__code__
 
 @staticmethod
 def _gen_if_name():
diff --git a/demo/ping.py b/demo/ping.py
index 0c24e73..c36b12d 100644
--- a/demo/ping.py
+++ b/demo/ping.py
@@ -64,7 +64,7 @@ class Ping(Thread):
                 os.utime(csv_path, (time.time(), time.time()))
 
         for add in no_responses:
-            print('No response from %s with seq no %d' % (add, seq))
+            print(('No response from %s with seq no %d' % (add, seq)))
 
 parser = argparse.ArgumentParser()
 parser.add_argument('n', help = 'my machine name (m1,m2...)')
diff --git a/demo/py b/demo/py
index 6aff571..5282626 100755
--- a/demo/py
+++ b/demo/py
@@ -30,4 +30,4 @@ def __file__():
 
     return os.path.join(sys.path[0], sys.argv[1])
 __file__ = __file__()
-execfile(__file__)
+exec(compile(open(__file__, "rb").read(), __file__, 'exec'))
diff --git a/demo/test_hmac.py b/demo/test_hmac.py
index 5d7b408..362176b 100644
--- a/demo/test_hmac.py
+++ b/demo/test_hmac.py
@@ -34,10 +34,10 @@ def checkHMAC(db, machines):
             else:
                 i = 0 if hmac[0] else 1
                 if hmac[i] != sign or hmac[i+1] != accept:
-                    print 'HMAC config wrong for in %s' % args
+                    print('HMAC config wrong for in %s' % args)
                     rc = False
     if rc:
         print('All nodes use Babel with the correct HMAC configuration')
     else:
-        print('Expected config: %s' % dict(zip(BABEL_HMAC, hmac)))
+        print(('Expected config: %s' % dict(list(zip(BABEL_HMAC, hmac)))))
     return rc
diff --git a/re6st/cache.py b/re6st/cache.py
index e05542c..65f4291 100644
--- a/re6st/cache.py
+++ b/re6st/cache.py
@@ -93,20 +93,18 @@ class Cache(object):
                 self._registry.getNetworkConfig(self._prefix)))
             base64 = x.pop('', ())
             config = {}
-            for k, v in x.iteritems():
+            for k, v in x.items():
                 k = str(k)
                 if k.startswith('babel_hmac'):
                     if v:
                         v = self._decrypt(v.decode('base64'))
                 elif k in base64:
                     v = v.decode('base64')
-                elif type(v) is unicode:
-                    v = str(v)
                 elif isinstance(v, (list, dict)):
                     k += ':json'
                     v = json.dumps(v)
                 config[k] = v
-        except socket.error, e:
+        except socket.error as e:
             logging.warning(e)
             return
         except Exception:
@@ -135,11 +133,11 @@ class Cache(object):
             db.executemany("INSERT OR REPLACE INTO config VALUES(?,?)",
                            ((k, buffer(v) if k in base64 or
                              k.startswith('babel_hmac') else v)
-                            for k, v in config.iteritems()))
-        self._loadConfig(config.iteritems())
+                            for k, v in config.items()))
+        self._loadConfig(iter(config.items()))
         return [k[:-5] if k.endswith(':json') else k
                 for k in chain(remove, (k
-                    for k, v in config.iteritems()
+                    for k, v in config.items()
                     if k not in old or old[k] != v))]
 
     def warnProtocol(self):
@@ -240,7 +238,7 @@ class Cache(object):
         try:
             bootpeer = self._registry.getBootstrapPeer(self._prefix)
             prefix, address = self._decrypt(bootpeer).split()
-        except (socket.error, subprocess.CalledProcessError, ValueError), e:
+        except (socket.error, subprocess.CalledProcessError, ValueError) as e:
             logging.warning('Failed to bootstrap (%s)',
                             e if bootpeer else 'no peer returned')
         else:
@@ -276,5 +274,5 @@ class Cache(object):
     def getCountry(self, ip):
         try:
             return self._registry.getCountry(self._prefix, ip)
-        except socket.error, e:
+        except socket.error as e:
             logging.warning('Failed to get country (%s)', ip)
diff --git a/re6st/cli/conf.py b/re6st/cli/conf.py
index 57f4dee..d2608af 100755
--- a/re6st/cli/conf.py
+++ b/re6st/cli/conf.py
@@ -101,7 +101,7 @@ def main():
     if config.req:
         components.update(config.req)
     subj = req.get_subject()
-    for k, v in components.iteritems():
+    for k, v in list(components.items()):
         if k in reserved:
             sys.exit(k + " field is reserved.")
         if v:
@@ -116,11 +116,11 @@ def main():
             token = ''
         elif not token:
             if not config.email:
-                config.email = raw_input('Please enter your email address: ')
+                config.email = eval(input('Please enter your email address: '))
             s.requestToken(config.email)
             token_advice = "Use --token to retry without asking a new token\n"
             while not token:
-                token = raw_input('Please enter your token: ')
+                token = eval(input('Please enter your token: '))
 
         try:
             with open(key_path) as f:
@@ -131,7 +131,7 @@ def main():
             if e.errno != errno.ENOENT:
                 raise
             bits = ca.get_pubkey().bits()
-            print "Generating %s-bit key ..." % bits
+            print(("Generating %s-bit key ..." % bits))
             pkey = crypto.PKey()
             pkey.generate_key(crypto.TYPE_RSA, bits)
             key = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
@@ -164,13 +164,13 @@ def main():
 
     cert = loadCert(cert)
     not_after = x509.notAfter(cert)
-    print("Setup complete. Certificate is valid until %s UTC"
+    print(("Setup complete. Certificate is valid until %s UTC"
           " and will be automatically renewed after %s UTC.\n"
           "Do not forget to backup to your private key (%s) or"
           " you will lose your assigned subnet." % (
         time.asctime(time.gmtime(not_after)),
         time.asctime(time.gmtime(not_after - registry.RENEW_PERIOD)),
-        key_path))
+        key_path)))
 
     if not os.path.lexists(conf_path):
         create(conf_path, """\
@@ -193,8 +193,8 @@ key %s
 
     cn = x509.subnetFromCert(cert)
     subnet = network + utils.binFromSubnet(cn)
-    print "Your subnet: %s/%u (CN=%s)" \
-        % (utils.ipFromBin(subnet), len(subnet), cn)
+    print(("Your subnet: %s/%u (CN=%s)" \
+        % (utils.ipFromBin(subnet), len(subnet), cn)))
 
 if __name__ == "__main__":
     main()
diff --git a/re6st/cli/node.py b/re6st/cli/node.py
index 04b94c9..d33ea7e 100755
--- a/re6st/cli/node.py
+++ b/re6st/cli/node.py
@@ -246,7 +246,7 @@ def main():
             try:
                 from re6st.upnpigd import Forwarder
                 forwarder = Forwarder('re6stnet openvpn server')
-            except Exception, e:
+            except Exception as e:
                 if ipv4:
                     raise
                 logging.info("%s: assume we are not NATed", e)
@@ -256,10 +256,10 @@ def main():
                     forwarder.addRule(port, proto)
                 address.append(forwarder.checkExternalIp())
         elif 'any' not in ipv4:
-            address += map(ip_changed, ipv4)
+            address += list(map(ip_changed, ipv4))
             ipv4_any = ()
         if ipv6:
-            address += map(ip_changed, ipv6)
+            address += list(map(ip_changed, ipv6))
             ipv6_any = ()
     else:
         ip_changed = remote_gateway = None
@@ -299,7 +299,7 @@ def main():
         timeout = 4 * cache.hello
         cleanup = [lambda: cache.cacheMinimize(config.client_count),
                    lambda: shutil.rmtree(config.run, True)]
-        utils.makedirs(config.run, 0700)
+        utils.makedirs(config.run, 0o700)
         control_socket = os.path.join(config.run, 'babeld.sock')
         if config.client_count and not config.client:
             tunnel_manager = tunnel.TunnelManager(control_socket,
@@ -362,7 +362,7 @@ def main():
                 if not dh:
                     dh = os.path.join(config.state, "dh.pem")
                     cache.getDh(dh)
-                for iface, (port, proto) in server_tunnels.iteritems():
+                for iface, (port, proto) in server_tunnels.items():
                     r, x = socket.socketpair(socket.AF_UNIX, socket.SOCK_DGRAM)
                     utils.setCloexec(r)
                     cleanup.append(plib.server(iface, config.max_clients,
@@ -442,7 +442,7 @@ def main():
                 except:
                     pass
             exit.release()
-    except ReexecException, e:
+    except ReexecException as e:
         logging.info(e)
     except Exception:
         utils.log_exception()
@@ -455,7 +455,7 @@ def main():
 if __name__ == "__main__":
     try:
         main()
-    except SystemExit, e:
+    except SystemExit as e:
         if type(e.code) is str:
             if hasattr(logging, 'trace'): # utils.setupLog called
                 logging.critical(e.code)
diff --git a/re6st/cli/registry.py b/re6st/cli/registry.py
index 34136b3..a7d5146 100755
--- a/re6st/cli/registry.py
+++ b/re6st/cli/registry.py
@@ -1,8 +1,8 @@
 #!/usr/bin/python2
-import httplib, logging, os, socket, sys
-from BaseHTTPServer import BaseHTTPRequestHandler
-from SocketServer import ThreadingTCPServer
-from urlparse import parse_qsl
+import http.client, logging, os, socket, sys
+from http.server import BaseHTTPRequestHandler
+from socketserver import ThreadingTCPServer
+from urllib.parse import parse_qsl
 if 're6st' not in sys.modules:
     sys.path[0] = os.path.dirname(os.path.dirname(sys.path[0]))
 from re6st import registry, utils, version
@@ -36,7 +36,7 @@ class RequestHandler(BaseHTTPRequestHandler):
                 return self.server.handle_request(self, path, query)
         except Exception:
             logging.info(self.requestline, exc_info=1)
-        self.send_error(httplib.BAD_REQUEST)
+        self.send_error(http.client.BAD_REQUEST)
 
     def log_error(*args):
         pass
diff --git a/re6st/ctl.py b/re6st/ctl.py
index 5f87157..a551185 100644
--- a/re6st/ctl.py
+++ b/re6st/ctl.py
@@ -44,7 +44,7 @@ class Array(object):
         r = []
         o = offset + 2
         decode = self._item.decode
-        for i in xrange(*uint16.unpack_from(buffer, offset)):
+        for i in range(*uint16.unpack_from(buffer, offset)):
             o, x = decode(buffer, o)
             r.append(x)
         return o, r
@@ -206,7 +206,7 @@ class Babel(object):
         def select(*args):
             try:
                 s.connect(self.socket_path)
-            except socket.error, e:
+            except socket.error as e:
                 logging.debug("Can't connect to %r (%r)", self.socket_path, e)
                 return e
             s.send("\1")
@@ -323,7 +323,7 @@ class iterRoutes(object):
             c.select(*args)
             utils.select(*args)
         return (prefix
-            for neigh_routes in c.neighbours.itervalues()
+            for neigh_routes in c.neighbours.values()
             for prefix in neigh_routes[1]
             if prefix)
 
diff --git a/re6st/debug.py b/re6st/debug.py
index 814d82e..41db6ee 100644
--- a/re6st/debug.py
+++ b/re6st/debug.py
@@ -37,7 +37,8 @@ class Socket(object):
         try:
             self._socket.recv(0)
             return True
-        except socket.error, (err, _):
+        except socket.error as e:
+            (err, _) = e
             if err != errno.EAGAIN:
                 raise
             self._socket.setblocking(1)
@@ -52,7 +53,7 @@ class Console(object):
             socket.SOCK_STREAM | socket.SOCK_CLOEXEC)
         try:
             self._removeSocket()
-        except OSError, e:
+        except OSError as e:
             if e.errno != errno.ENOENT:
                 raise
         s.bind(path)
diff --git a/re6st/plib.py b/re6st/plib.py
index db7a2ab..f987deb 100644
--- a/re6st/plib.py
+++ b/re6st/plib.py
@@ -132,7 +132,7 @@ def router(ip, ip4, rt6, hello_interval, log_path, state_path, pidfile,
     # WKRD: babeld fails to start if pidfile already exists
     try:
         os.remove(pidfile)
-    except OSError, e:
+    except OSError as e:
         if e.errno != errno.ENOENT:
             raise
     logging.info('%r', cmd)
diff --git a/re6st/registry.py b/re6st/registry.py
index 5ba7ff7..ff1a706 100644
--- a/re6st/registry.py
+++ b/re6st/registry.py
@@ -18,16 +18,16 @@ Authenticated communication:
   - the last one that was really used by the client (!hello)
   - the one of the last handshake (hello)
 """
-import base64, hmac, hashlib, httplib, inspect, json, logging
+import base64, hmac, hashlib, http.client, inspect, json, logging
 import mailbox, os, platform, random, select, smtplib, socket, sqlite3
 import string, sys, threading, time, weakref, zlib
 from collections import defaultdict, deque
 from datetime import datetime
-from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+from http.server import HTTPServer, BaseHTTPRequestHandler
 from email.mime.text import MIMEText
 from operator import itemgetter
 from OpenSSL import crypto
-from urllib import splittype, splithost, unquote, urlencode
+from urllib.parse import splittype, splithost, unquote, urlencode
 from . import ctl, tunnel, utils, version, x509
 
 HMAC_HEADER = "Re6stHMAC"
@@ -41,7 +41,7 @@ def rpc(f):
         defaults = ()
     i = len(args) - len(defaults)
     f.getcallargs = eval("lambda %s: locals()" % ','.join(args[1:i]
-        + map("%s=%r".__mod__, zip(args[i:], defaults))))
+        + list(map("%s=%r".__mod__, list(zip(args[i:], defaults))))))
     return f
 
 def rpc_private(f):
@@ -59,7 +59,7 @@ class RegistryServer(object):
     cert_duration = 365 * 86400
 
     def _geoiplookup(self, ip):
-        raise HTTPError(httplib.BAD_REQUEST)
+        raise HTTPError(http.client.BAD_REQUEST)
 
     def __init__(self, config):
         self.config = config
@@ -76,7 +76,7 @@ class RegistryServer(object):
                     if x and not x.startswith('#'):
                         x = x.split()
                         self.community_map[x.pop(0)] = x
-            if sum('*' in x for x in self.community_map.itervalues()) != 1:
+            if sum('*' in x for x in self.community_map.values()) != 1:
                 sys.exit("Invalid community configuration: missing or multiple default location ('*')")
         else:
             self.community_map[''] = '*'
@@ -169,8 +169,8 @@ class RegistryServer(object):
     def updateNetworkConfig(self, _it0=itemgetter(0)):
         kw = {
             'babel_default': 'max-rtt-penalty 5000 rtt-max 500 rtt-decay 125',
-            'crl': map(_it0, self.db.execute(
-                "SELECT serial FROM crl ORDER BY serial")),
+            'crl': list(map(_it0, self.db.execute(
+                "SELECT serial FROM crl ORDER BY serial"))),
             'protocol': version.protocol,
             'registry_prefix': self.prefix,
         }
@@ -286,7 +286,7 @@ class RegistryServer(object):
             x_forwarded_for = request.headers.get('X-Forwarded-For')
             if request.client_address[0] not in authorized_origin or \
                x_forwarded_for and x_forwarded_for not in authorized_origin:
-                return request.send_error(httplib.FORBIDDEN)
+                return request.send_error(http.client.FORBIDDEN)
         key = m.getcallargs(**kw).get('cn')
         if key:
             h = base64.b64decode(request.headers[HMAC_HEADER])
@@ -313,16 +313,16 @@ class RegistryServer(object):
                         request.headers.get("host"))
         try:
             result = m(**kw)
-        except HTTPError, e:
+        except HTTPError as e:
             return request.send_error(*e.args)
         except:
             logging.warning(request.requestline, exc_info=1)
-            return request.send_error(httplib.INTERNAL_SERVER_ERROR)
+            return request.send_error(http.client.INTERNAL_SERVER_ERROR)
         if result:
-            request.send_response(httplib.OK)
+            request.send_response(http.client.OK)
             request.send_header("Content-Length", str(len(result)))
         else:
-            request.send_response(httplib.NO_CONTENT)
+            request.send_response(http.client.NO_CONTENT)
         if key:
             request.send_header(HMAC_HEADER, base64.b64encode(
                 hmac.HMAC(key, result, hashlib.sha1).digest()))
@@ -367,7 +367,7 @@ class RegistryServer(object):
     def addToken(self, email, token):
         prefix_len = self.config.prefix_length
         if not prefix_len:
-            raise HTTPError(httplib.FORBIDDEN)
+            raise HTTPError(http.client.FORBIDDEN)
         request = token is None
         with self.lock:
             while True:
@@ -381,7 +381,7 @@ class RegistryServer(object):
                     break
                 except sqlite3.IntegrityError:
                     if not request:
-                        raise HTTPError(httplib.CONFLICT)
+                        raise HTTPError(http.client.CONFLICT)
             self.timeout = 1
         if request:
             return token
@@ -389,7 +389,7 @@ class RegistryServer(object):
     @rpc
     def requestToken(self, email):
         if not self.config.mailhost:
-            raise HTTPError(httplib.FORBIDDEN)
+            raise HTTPError(http.client.FORBIDDEN)
 
         token = self.addToken(email, None)
 
@@ -418,11 +418,11 @@ class RegistryServer(object):
             s.quit()
 
     def getCommunity(self, country, continent):
-        for prefix, location_list in self.community_map.iteritems():
+        for prefix, location_list in self.community_map.items():
             if country in location_list:
                 return prefix
         default = ''
-        for prefix, location_list in self.community_map.iteritems():
+        for prefix, location_list in self.community_map.items():
             if continent in location_list:
                 return prefix
             if '*' in location_list:
@@ -434,9 +434,9 @@ class RegistryServer(object):
         prev_prefix = None
         max_len = 128,
         while True:
-            max_len = q("SELECT max(length(prefix)) FROM cert"
+            max_len = next(q("SELECT max(length(prefix)) FROM cert"
                         " WHERE cert is null AND length(prefix) < ?",
-                        max_len).next()
+                        max_len))
             if not max_len[0]:
                 break
             for prefix, in q("SELECT prefix FROM cert"
@@ -460,25 +460,25 @@ class RegistryServer(object):
         while True:
             try:
                 # Find longest free prefix whithin community.
-                prefix, = q(
+                prefix, = next(q(
                     "SELECT prefix FROM cert"
                     " WHERE prefix LIKE ?"
                     "   AND length(prefix) <= ? AND cert is null"
                     " ORDER BY length(prefix) DESC",
-                    (community + '%', prefix_len)).next()
+                    (community + '%', prefix_len)))
             except StopIteration:
                 # Community not yet allocated?
                 # There should be exactly 1 row whose
                 # prefix is the beginning of community.
-                prefix, x = q("SELECT prefix, cert FROM cert"
+                prefix, x = next(q("SELECT prefix, cert FROM cert"
                               " WHERE substr(?,1,length(prefix)) = prefix",
-                              (community,)).next()
+                              (community,)))
                 if x is not None:
                     logging.error('No more free /%u prefix available',
                                   prefix_len)
                     raise
             # Split the tree until prefix has wanted length.
-            for x in xrange(len(prefix), prefix_len):
+            for x in range(len(prefix), prefix_len):
                 # Prefix starts with community, then we complete with 0.
                 x = community[x] if x < community_len else '0'
                 q("UPDATE cert SET prefix = ? WHERE prefix = ?",
@@ -496,11 +496,11 @@ class RegistryServer(object):
             with self.db:
                 if token:
                     if not self.config.prefix_length:
-                        raise HTTPError(httplib.FORBIDDEN)
+                        raise HTTPError(http.client.FORBIDDEN)
                     try:
-                        token, email, prefix_len, _ = self.db.execute(
+                        token, email, prefix_len, _ = next(self.db.execute(
                             "SELECT * FROM token WHERE token = ?",
-                            (token,)).next()
+                            (token,)))
                     except StopIteration:
                         return
                     self.db.execute("DELETE FROM token WHERE token = ?",
@@ -508,7 +508,7 @@ class RegistryServer(object):
                 else:
                     prefix_len = self.config.anonymous_prefix_length
                     if not prefix_len:
-                        raise HTTPError(httplib.FORBIDDEN)
+                        raise HTTPError(http.client.FORBIDDEN)
                     email = None
                 country, continent = '*', '*'
                 if self.geoip_db:
@@ -624,7 +624,7 @@ class RegistryServer(object):
             if age < time.time() or not peers:
                 self.request_dump()
                 peers = [prefix
-                    for neigh_routes in self.ctl.neighbours.itervalues()
+                    for neigh_routes in self.ctl.neighbours.values()
                     for prefix in neigh_routes[1]
                     if prefix]
                 peers.append(self.prefix)
@@ -706,8 +706,8 @@ class RegistryServer(object):
     def getNodePrefix(self, email):
         with self.lock, self.db:
             try:
-                cert, = self.db.execute("SELECT cert FROM cert WHERE email = ?",
-                                        (email,)).next()
+                cert, = next(self.db.execute("SELECT cert FROM cert WHERE email = ?",
+                                        (email,)))
             except StopIteration:
                 return
         certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
@@ -728,7 +728,7 @@ class RegistryServer(object):
             peer = utils.binFromSubnet(peer)
             with self.peers_lock:
                 self.request_dump()
-                for neigh_routes in self.ctl.neighbours.itervalues():
+                for neigh_routes in self.ctl.neighbours.values():
                     for prefix in neigh_routes[1]:
                         if prefix == peer:
                             break
@@ -745,7 +745,7 @@ class RegistryServer(object):
         with self.peers_lock:
             self.request_dump()
             peers = {prefix
-                for neigh_routes in self.ctl.neighbours.itervalues()
+                for neigh_routes in self.ctl.neighbours.values()
                 for prefix in neigh_routes[1]
                 if prefix}
         peers.add(self.prefix)
@@ -794,7 +794,7 @@ class RegistryServer(object):
                     self.sendto(utils.binFromSubnet(peers.popleft()), 5)
                 elif not r:
                     break
-        return json.dumps({k: list(v) for k, v in graph.iteritems()})
+        return json.dumps({k: list(v) for k, v in graph.items()})
 
 
 class RegistryClient(object):
@@ -807,8 +807,8 @@ class RegistryClient(object):
         self.auto_close = auto_close
         scheme, host = splittype(url)
         host, path = splithost(host)
-        self._conn = dict(http=httplib.HTTPConnection,
-                          https=httplib.HTTPSConnection,
+        self._conn = dict(http=http.client.HTTPConnection,
+                          https=http.client.HTTPSConnection,
                           )[scheme](unquote(host), timeout=60)
         self._path = path.rstrip('/')
 
@@ -818,7 +818,7 @@ class RegistryClient(object):
             kw = getcallargs(*args, **kw)
             query = '/' + name
             if kw:
-                if any(type(v) is not str for v in kw.itervalues()):
+                if any(type(v) is not str for v in kw.values()):
                     raise TypeError
                 query += '?' + urlencode(kw)
             url = self._path + query
@@ -846,14 +846,14 @@ class RegistryClient(object):
                     self._conn.endheaders()
                     response = self._conn.getresponse()
                     body = response.read()
-                    if response.status in (httplib.OK, httplib.NO_CONTENT):
+                    if response.status in (http.client.OK, http.client.NO_CONTENT):
                         if (not client_prefix or
                                 hmac.HMAC(key, body, hashlib.sha1).digest() ==
                                 base64.b64decode(response.msg[HMAC_HEADER])):
                             if self.auto_close and name != 'hello':
                                 self._conn.close()
                             return body
-                    elif response.status == httplib.FORBIDDEN:
+                    elif response.status == http.client.FORBIDDEN:
                         # XXX: We should improve error handling, while making
                         #      sure re6st nodes don't crash on temporary errors.
                         #      This is currently good enough for re6st-conf, to
diff --git a/re6st/tests/test_unit/test_conf.py b/re6st/tests/test_unit/test_conf.py
index 8c9d1ea..7da8c7d 100644
--- a/re6st/tests/test_unit/test_conf.py
+++ b/re6st/tests/test_unit/test_conf.py
@@ -6,7 +6,7 @@ import os
 import sys
 import unittest
 from shutil import rmtree
-from StringIO import StringIO
+from io import StringIO
 from mock import patch
 from OpenSSL import crypto
 
diff --git a/re6st/tests/test_unit/test_registry.py b/re6st/tests/test_unit/test_registry.py
index a035bd3..1f051b8 100644
--- a/re6st/tests/test_unit/test_registry.py
+++ b/re6st/tests/test_unit/test_registry.py
@@ -3,7 +3,7 @@ import os
 import random
 import string
 import json
-import httplib
+import http.client
 import base64
 import unittest
 import hmac
@@ -162,7 +162,7 @@ class TestRegistryServer(unittest.TestCase):
                          [(hashlib.sha1(key).digest(), protocol)])
         func.assert_called_once_with(**params)
         # http response check
-        request.send_response.assert_called_once_with(httplib.OK)
+        request.send_response.assert_called_once_with(http.client.OK)
         request.send_header.assert_any_call("Content-Length", str(len(result)))
         request.send_header.assert_any_call(
             registry.HMAC_HEADER,
@@ -189,8 +189,8 @@ class TestRegistryServer(unittest.TestCase):
         self.server.handle_request(request_bad, method, params)
 
         func.assert_called_once_with(**params)
-        request_bad.send_error.assert_called_once_with(httplib.FORBIDDEN)
-        request_good.send_response.assert_called_once_with(httplib.NO_CONTENT)
+        request_bad.send_error.assert_called_once_with(http.client.FORBIDDEN)
+        request_good.send_response.assert_called_once_with(http.client.NO_CONTENT)
 
     # will cause valueError, if a node send hello twice to a registry
     def test_getPeerProtocol(self):
diff --git a/re6st/tests/test_unit/test_registry_client.py b/re6st/tests/test_unit/test_registry_client.py
index 6acdd61..69eb66d 100644
--- a/re6st/tests/test_unit/test_registry_client.py
+++ b/re6st/tests/test_unit/test_registry_client.py
@@ -2,7 +2,7 @@ import sys
 import os
 import unittest
 import hmac
-import httplib
+import http.client
 import base64
 import hashlib
 from mock import Mock, patch
@@ -26,15 +26,15 @@ class TestRegistryClient(unittest.TestCase):
 
         self.assertEqual(client1._path, "/example")
         self.assertEqual(client1._conn.host, "localhost")
-        self.assertIsInstance(client1._conn, httplib.HTTPSConnection)
-        self.assertIsInstance(client2._conn, httplib.HTTPConnection)
+        self.assertIsInstance(client1._conn, http.client.HTTPSConnection)
+        self.assertIsInstance(client2._conn, http.client.HTTPConnection)
 
     def test_rpc_hello(self):
         prefix = "0000000011111111"
         protocol = "7"
         body = "a_hmac_key"
         query = "/hello?client_prefix=0000000011111111&protocol=7"
-        response = fakeResponse(body, httplib.OK)
+        response = fakeResponse(body, http.client.OK)
         self.client._conn.getresponse.return_value = response
 
         res = self.client.hello(prefix, protocol)
@@ -58,7 +58,7 @@ class TestRegistryClient(unittest.TestCase):
         key = hashlib.sha1(key).digest()
         # response part
         body = None
-        response = fakeResponse(body, httplib.NO_CONTENT)
+        response = fakeResponse(body, http.client.NO_CONTENT)
         response.msg = dict(Re6stHMAC=hmac.HMAC(key, body, hashlib.sha1).digest())
         self.client._conn.getresponse.return_value = response
 
diff --git a/re6st/tunnel.py b/re6st/tunnel.py
index bb80140..bd1ad47 100644
--- a/re6st/tunnel.py
+++ b/re6st/tunnel.py
@@ -242,14 +242,14 @@ class BaseTunnelManager(object):
             self._country = {}
 
             address_dict = {family: self._updateCountry(address)
-                            for family, address in address_dict.iteritems()}
+                            for family, address in address_dict.items()}
         elif cache.same_country:
             sys.exit("Can not respect 'same_country' network configuration"
                      " (GEOIP2_MMDB not set)")
         self._address = {family: utils.dump_address(address)
-                         for family, address in address_dict.iteritems()
+                         for family, address in address_dict.items()
                          if address}
-        cache.my_address = ';'.join(self._address.itervalues())
+        cache.my_address = ';'.join(iter(self._address.values()))
 
         self.sock = socket.socket(socket.AF_INET6,
             socket.SOCK_DGRAM | socket.SOCK_CLOEXEC)
@@ -346,7 +346,7 @@ class BaseTunnelManager(object):
     def _sendto(self, to, msg, peer=None):
         try:
             r = self.sock.sendto(peer.encode(msg) if peer else msg, to)
-        except socket.error, e:
+        except socket.error as e:
             (logging.info if e.errno == errno.ENETUNREACH else logging.error)(
                 'Failed to send message to %s (%s)', to, e)
             return
@@ -410,7 +410,7 @@ class BaseTunnelManager(object):
                 serial = cert.get_serial_number()
                 if serial in self.cache.crl:
                     raise ValueError("revoked")
-            except (x509.VerifyError, ValueError), e:
+            except (x509.VerifyError, ValueError) as e:
                 if retry:
                     return True
                 logging.debug('ignored invalid certificate from %r (%s)',
@@ -467,8 +467,8 @@ class BaseTunnelManager(object):
                     # Don't send country to old nodes
                     if self._getPeer(peer).protocol < 7:
                         return ';'.join(','.join(a.split(',')[:3]) for a in
-                            ';'.join(self._address.itervalues()).split(';'))
-                return ';'.join(self._address.itervalues())
+                            ';'.join(iter(self._address.values())).split(';'))
+                return ';'.join(iter(self._address.values()))
         elif not code: # network version
             if peer:
                 try:
@@ -553,8 +553,8 @@ class BaseTunnelManager(object):
         if (not self.NEED_RESTART.isdisjoint(changed)
             or version.protocol < self.cache.min_protocol
             # TODO: With --management, we could kill clients without restarting.
-            or not all(crl.isdisjoint(serials.itervalues())
-                       for serials in self._served.itervalues())):
+            or not all(crl.isdisjoint(iter(serials.values()))
+                       for serials in self._served.values())):
             # Wait at least 1 second to broadcast new version to neighbours.
             self.selectTimeout(time.time() + 1 + self.cache.delay_restart,
                                self._restart)
@@ -606,7 +606,7 @@ class BaseTunnelManager(object):
         with open('/proc/net/ipv6_route', "r", 4096) as f:
             try:
                 routing_table = f.read()
-            except IOError, e:
+            except IOError as e:
                 # ???: If someone can explain why the kernel sometimes fails
                 #      even when there's a lot of free memory.
                 if e.errno != errno.ENOMEM:
@@ -683,7 +683,7 @@ class TunnelManager(BaseTunnelManager):
 
         self._client_count = client_count
         self.new_iface_list = deque('re6stnet' + str(i)
-            for i in xrange(1, self._client_count + 1))
+            for i in range(1, self._client_count + 1))
         self._free_iface_list = []
 
     def close(self):
@@ -752,7 +752,7 @@ class TunnelManager(BaseTunnelManager):
     def babel_dump(self):
         t = time.time()
         if self._killing:
-            for prefix, tunnel_killer in self._killing.items():
+            for prefix, tunnel_killer in list(self._killing.items()):
                 if tunnel_killer.timeout < t:
                     if tunnel_killer.state != 'unlocking':
                         logging.info(
@@ -780,7 +780,7 @@ class TunnelManager(BaseTunnelManager):
 
     def _cleanDeads(self):
         disconnected = False
-        for prefix in self._connection_dict.keys():
+        for prefix in list(self._connection_dict.keys()):
             status = self._connection_dict[prefix].refresh()
             if status:
                 disconnected |= status > 0
@@ -902,7 +902,7 @@ class TunnelManager(BaseTunnelManager):
             neighbours = self.ctl.neighbours
             # Collect all nodes known by Babel
             peers = {prefix
-                for neigh_routes in neighbours.itervalues()
+                for neigh_routes in neighbours.values()
                 for prefix in neigh_routes[1]
                 if prefix}
             # Keep only distant peers.
@@ -987,7 +987,7 @@ class TunnelManager(BaseTunnelManager):
                         break
 
     def killAll(self):
-        for prefix in self._connection_dict.keys():
+        for prefix in list(self._connection_dict.keys()):
             self._kill(prefix)
 
     def handleClientEvent(self):
@@ -999,7 +999,7 @@ class TunnelManager(BaseTunnelManager):
         if c and c.time < float(time):
             try:
                 c.connected(serial)
-            except (KeyError, TypeError), e:
+            except (KeyError, TypeError) as e:
                 logging.error("%s (route_up %s)", e, common_name)
         else:
             logging.info("ignore route_up notification for %s %r",
@@ -1010,10 +1010,10 @@ class TunnelManager(BaseTunnelManager):
                 if self.cache.same_country:
                     address = self._updateCountry(address)
                 self._address[family] = utils.dump_address(address)
-                self.cache.my_address = ';'.join(self._address.itervalues())
+                self.cache.my_address = ';'.join(iter(self._address.values()))
 
     def broadcastNewVersion(self):
         self._babel_dump_new_version()
-        for prefix, c in self._connection_dict.items():
+        for prefix, c in list(self._connection_dict.items()):
             if c.serial in self.cache.crl:
                 self._kill(prefix)
diff --git a/re6st/upnpigd.py b/re6st/upnpigd.py
index bcdb042..a17fce1 100644
--- a/re6st/upnpigd.py
+++ b/re6st/upnpigd.py
@@ -40,7 +40,7 @@ class Forwarder(object):
         def wrapper(*args, **kw):
             try:
                 return wrapped(*args, **kw)
-            except Exception, e:
+            except Exception as e:
                 raise UPnPException(str(e))
         return wraps(wrapped)(wrapper)
 
@@ -68,14 +68,14 @@ class Forwarder(object):
         else:
             try:
                 return self._refresh()
-            except UPnPException, e:
+            except UPnPException as e:
                 logging.debug("UPnP failure", exc_info=1)
                 self.clear()
         try:
             self.discover()
             self.selectigd()
             return self._refresh()
-        except UPnPException, e:
+        except UPnPException as e:
             self.next_refresh = self._next_retry = time.time() + 60
             logging.info(str(e))
             self.clear()
@@ -109,7 +109,7 @@ class Forwarder(object):
                 try:
                     self.addportmapping(port, *args)
                     break
-                except UPnPException, e:
+                except UPnPException as e:
                     if str(e) != 'ConflictInMappingEntry':
                         raise
                     port = None
diff --git a/re6st/utils.py b/re6st/utils.py
index 251bfdd..3912bf3 100644
--- a/re6st/utils.py
+++ b/re6st/utils.py
@@ -164,7 +164,7 @@ class Popen(subprocess.Popen):
         self._args = tuple(args[0] if args else kw['args'])
         try:
             super(Popen, self).__init__(*args, **kw)
-        except OSError, e:
+        except OSError as e:
             if e.errno != errno.ENOMEM:
                 raise
             self.returncode = -1
@@ -209,7 +209,7 @@ def select(R, W, T):
 def makedirs(*args):
     try:
         os.makedirs(*args)
-    except OSError, e:
+    except OSError as e:
         if e.errno != errno.EEXIST:
             raise
 
@@ -240,7 +240,7 @@ def parse_address(address_list):
             a = address.split(',')
             int(a[1]) # Check if port is an int
             yield tuple(a[:4])
-        except ValueError, e:
+        except ValueError as e:
             logging.warning("Failed to parse node address %r (%s)",
                             address, e)
 
@@ -262,7 +262,7 @@ newHmacSecret = newHmacSecret()
 # - the 3 first bits code the number of bytes
 
 def packInteger(i):
-    for n in xrange(8):
+    for n in range(8):
         x = 32 << 8 * n
         if i < x:
             return struct.pack("!Q", i + n * x)[7-n:]
@@ -275,7 +275,7 @@ def unpackInteger(x):
         i, = struct.unpack("!Q", '\0' * (7 - n) + x[:n+1])
     except struct.error:
         return
-    return sum((32 << 8 * i for i in xrange(n)),
+    return sum((32 << 8 * i for i in range(n)),
                 i - (n * 32 << 8 * n)), n + 1
 
 ###
diff --git a/setup.py b/setup.py
index 1be97ba..079c73a 100644
--- a/setup.py
+++ b/setup.py
@@ -14,7 +14,7 @@ def copy_file(self, infile, outfile, *args, **kw):
         if not self.dry_run:
             log.info("generating %s -> %s", infile, outfile)
             with open(outfile, "wb") as f:
-                for x in sorted(version.iteritems()):
+                for x in sorted(version.items()):
                     if not x[0].startswith("_"):
                         f.write("%s = %r\n" % x)
         return outfile, 1
-- 
2.30.9