summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xfot.py8
-rw-r--r--ipv6.py127
2 files changed, 133 insertions, 2 deletions
diff --git a/fot.py b/fot.py
index ff277e4..c6e3e6c 100755
--- a/fot.py
+++ b/fot.py
@@ -9,7 +9,7 @@ import os, re
from ConfigParser import ConfigParser
-import login
+import login, ipv6
config = ConfigParser()
@@ -178,7 +178,11 @@ def start_server(server):
print '%s' % server
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)
print 'Starting per-network instances...'
for server in (server for server in config.sections() if server.startswith('server/')):
diff --git a/ipv6.py b/ipv6.py
new file mode 100644
index 0000000..9dd1f32
--- /dev/null
+++ b/ipv6.py
@@ -0,0 +1,127 @@
+
+import socket
+from twisted.internet import tcp
+from twisted.internet import default
+from twisted.internet import protocol
+from twisted.internet import reactor
+
+from twisted.names.client import Resolver
+resolver = Resolver('/etc/resolv.conf')
+
+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:
+ resolver.lookupIPV6Address(self.addr[0]).addCallbacks(
+ self.resolvedAddress, self.failIfNotConnected
+ )
+
+ def resolvedAddress(self, addr):
+ aaaas = [x for x in addr[0] if x.type == 28] # 28 = AAAA record
+ if not len(aaaas):
+ self.failIfNotConnected(Exception('Unable to resolve IPv6 address.'))
+ return
+ aaaa = aaaas[0].payload
+ self._setRealAddress(aaaa._address)
+
+ 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()
+