summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2010-05-24 22:04:07 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2010-05-24 22:04:07 +0200
commitb97e85feef6b4dad4add23d17e37fd5ee976e1e3 (patch)
treeb586d22cd0947b937c02742dc6f4de283cb1db60
parent070ede1ae77a89728341f7d084e882e04ffd2d2a (diff)
Added IPv6 support.
This currently needs the destination host to be stored in host6. The local address can be bound by setting bind6.
-rwxr-xr-xfot.py10
-rw-r--r--ipv6.py116
2 files changed, 123 insertions, 3 deletions
diff --git a/fot.py b/fot.py
index 8412e8c..75cdfaf 100755
--- a/fot.py
+++ b/fot.py
@@ -9,7 +9,7 @@ import os
from ConfigParser import ConfigParser
-import login
+import login, ipv6
config = ConfigParser()
@@ -130,9 +130,13 @@ for server in (server for server in config.sections() if server.startswith('serv
ch = [x[0] for x in ms if c in x[1]]
channels.append('%s (%s)' % (c, ' '.join(ch)))
print '%s: %s' % (server, ' '.join(channels))
- del channels, ms, c, ch, x
+ #del channels, ms, c, ch, x
factory = BotFactory(server, config.get(server, 'nickname'))
- reactor.connectTCP(config.get(server, 'host'), config.getint(server, 'port'), factory)
+ if config.has_option(server, 'host6'):
+ bind6 = (config.get(server, 'bind6'), 0) if config.has_option(server, 'bind6') else None
+ ipv6.connectTCP6(config.get(server, 'host6'), config.getint(server, 'port6'), factory, bindAddress = bind6)
+ else:
+ reactor.connectTCP(config.get(server, 'host'), config.getint(server, 'port'), factory)
loginfactory = login.getManholeFactory(globals(), os.path.expanduser('~/.fot.users'))
reactor.listenTCP(3333, loginfactory)
diff --git a/ipv6.py b/ipv6.py
new file mode 100644
index 0000000..eb6ce2e
--- /dev/null
+++ b/ipv6.py
@@ -0,0 +1,116 @@
+
+import socket
+from twisted.internet import tcp
+from twisted.internet import default
+from twisted.internet import protocol
+from twisted.internet import reactor
+
+class IPv6Address(object):
+ def __init__(self, type, host, port, flowInfo, scope):
+ self.type = type
+ self.host = host
+ self.port = port
+ self.flowInfo = flowInfo
+ self.scope = scope
+
+ def __eq__(self, other):
+ if isinstance(other, IPv6Address):
+ a = (self.type, self.host, self.port, self.flowInfo, self.scope)
+ b = (other.type, other.host, other.port, other.flowInfo, other.scope)
+ return a == b
+ return False
+
+ def __str__(self):
+ return 'IPv6Address(%s, %r, %d, %d, %d)' % (
+ self.type, self.host, self.port, self.flowInfo, self.scope)
+
+def isIPv6Address(ip):
+ try:
+ socket.inet_pton(socket.AF_INET6, ip)
+ except:
+ return 0
+ return 1
+
+class Client(tcp.Client):
+ addressFamily = socket.AF_INET6
+
+ def resolveAddress(self):
+ if isIPv6Address(self.addr[0]):
+ self._setRealAddress(self.addr[0])
+ else:
+ reactor.resolve(self.addr[0]).addCallbacks(
+ self._setRealAddress, self.failIfNotConnected
+ )
+
+ def getHost(self):
+ return IPv6Address('TCP', *self.socket.getsockname())
+
+ def getPeer(self):
+ return IPv6Address('TCP', *self.socket.getpeername())
+
+
+class Connector(tcp.Connector):
+ def _makeTransport(self):
+ return Client(self.host, self.port, self.bindAddress, self, self.reactor)
+
+ def getDestination(self):
+ return IPv6Address('TCP', self.host, self.port)
+
+class Server(tcp.Server):
+ def getHost(self):
+ return IPv6Address('TCP', *self.socket.getsockname())
+
+ def getPeer(self):
+ return IPv6Address('TCP', *self.client)
+
+class Port(tcp.Port):
+ addressFamily = socket.AF_INET6
+
+ transport = Server
+
+ def _buildAddr(self, address):
+ return IPv6Address('TCP', *address)
+
+ def getHost(self):
+ return IPv6Address('TCP', *self.socket.getsockname())
+
+ def getPeer(self):
+ return IPv6Address('TCP', *self.socket.getpeername())
+
+def connectTCP6(host, port, factory, timeout=30, bindAddress=None, reactor=None):
+ if reactor is None:
+ from twisted.internet import reactor
+ return reactor.connectWith(
+ Connector, host, port, factory, timeout, bindAddress
+ )
+
+
+def listenTCP6(port, factory, backlog=5, interface='::', reactor=None):
+ if reactor is None:
+ from twisted.internet import reactor
+ return reactor.listenWith(Port, port, factory, backlog, interface)
+
+def main():
+ from twisted.internet import reactor
+
+ class TrivialProtocol(protocol.Protocol):
+ def connectionMade(self):
+ print 'I (', self.transport.getHost(), ') am connected! (to ', self.transport.getPeer(), ')'
+ self.transport.write('Hello, world!\n')
+
+ def dataReceived(self, data):
+ print 'Received: ' + repr(data)
+
+ class TrivialServerFactory(protocol.ServerFactory):
+ protocol = TrivialProtocol
+ class TrivialClientFactory(protocol.ClientFactory):
+ protocol = TrivialProtocol
+
+ p = listenTCP6(6666, TrivialServerFactory())
+ c = connectTCP6('::1', 6666, TrivialClientFactory())
+
+ reactor.run()
+
+if __name__ == '__main__':
+ main()
+