1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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()
|