File: endpoints.py

package info (click to toggle)
python-txi2p-tahoe 0.3.7-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 448 kB
  • sloc: python: 3,757; makefile: 163; sh: 3
file content (146 lines) | stat: -rw-r--r-- 5,901 bytes parent folder | download | duplicates (3)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# Copyright (c) str4d <str4d@mail.i2p>
# See COPYING for details.

from builtins import object
from twisted.internet import interfaces
from zope.interface import implementer

from txi2p.bob.factory import BOBI2PClientFactory, BOBI2PServerFactory


def _validateDestination(dest):
    # TODO: Validate I2P domain, B32 etc.
    pass


@implementer(interfaces.IStreamClientEndpoint)
class BOBI2PClientEndpoint(object):
    """I2P client endpoint backed by the BOB API.

    Args:
        reactor: The client endpoint will be constructed with this reactor.
        bobEndpoint (twisted.internet.interfaces.IStreamClientEndpoint): An
            endpoint that will connect to the BOB API.
        host (str): The I2P hostname or Destination to connect to.
        port (int): The port to connect to inside I2P. If unset or `None`, the
            default (null) port is used. Ignored because BOB doesn't support
            ports yet.
        tunnelNick (str): The tunnel nickname to use. If a tunnel with this
            nickname already exists, it will be used. The default is ``txi2p-#``
            where ``#`` is the PID of the current process.

            * The implication of this is that by default, all endpoints (both
              client and server) created by the same process will use the same
              BOB tunnel.

        inhost (str): The host that the tunnel created by BOB will listen on.
            Defaults to ``localhost``.
        inport (int): The port that the tunnel created by BOB will listen on.
            Defaults to a port over 9000.
        options (dict): I2CP options to configure the tunnel with.
    """

    def __init__(self, reactor, bobEndpoint, dest,
                 port=None,
                 tunnelNick=None,
                 inhost='localhost',
                 inport=None,
                 options=None):
        _validateDestination(dest)
        self._reactor = reactor
        self._bobEndpoint = bobEndpoint
        self._dest = dest
        self._port = port
        self._tunnelNick = tunnelNick
        self._inhost = inhost
        self._inport = inport
        self._options = options

    def connect(self, fac):
        """Connect over I2P.

        The provided factory will have its ``buildProtocol`` method called once
        an I2P client tunnel has been successfully created.

        If the factory's ``buildProtocol`` returns ``None``, the connection
        will immediately close.
        """

        i2pFac = BOBI2PClientFactory(self._reactor, fac, self._bobEndpoint, self._dest,
                                     self._tunnelNick,
                                     self._inhost,
                                     self._inport,
                                     self._options)
        d = self._bobEndpoint.connect(i2pFac)
        # Once the BOB IProtocol is returned, wait for the
        # real IProtocol to be returned after tunnel creation,
        # and pass it to any further registered callbacks.
        d.addCallback(lambda proto: i2pFac.deferred)
        return d


@implementer(interfaces.IStreamServerEndpoint)
class BOBI2PServerEndpoint(object):
    """I2P server endpoint backed by the BOB API.

    Args:
        reactor: The server endpoint will be constructed with this reactor.
        bobEndpoint (twisted.internet.interfaces.IStreamClientEndpoint): An
            endpoint that will connect to the BOB API.
        keyfile (str): Path to a local file containing the keypair to use for
            the server Destination. If non-existent, new keys will be generated
            and stored.
        port (int): The port to connect to inside I2P. If unset or `None`, the
            default (null) port is used. Ignored because BOB doesn't support
            ports yet.
        tunnelNick (str): The tunnel nickname to use. If a tunnel with this
            nickname already exists, it will be used. The default is ``txi2p-#``
            where ``#`` is the PID of the current process.

            * The implication of this is that by default, all endpoints (both
              client and server) created by the same process will use the same
              BOB tunnel.

        outhost (str): The host that the tunnel created by BOB will forward data
            to. Defaults to ``localhost``.
        outport (int): The port that the tunnel created by BOB will forward data
            to. Defaults to a port over 9000.
        options (dict): I2CP options to configure the tunnel with.
    """

    def __init__(self, reactor, bobEndpoint, keyfile,
                 port=None,
                 tunnelNick=None,
                 outhost='localhost',
                 outport=None,
                 options=None):
        self._reactor = reactor
        self._bobEndpoint = bobEndpoint
        self._keyfile = keyfile
        self._port = port
        self._tunnelNick = tunnelNick
        self._outhost = outhost
        self._outport = outport
        self._options = options

    def listen(self, fac):
        """Listen over I2P.

        The provided factory will have its ``buildProtocol`` method called once
        an I2P server tunnel has been successfully created.

        If the factory's ``buildProtocol`` returns ``None``, the connection
        will immediately close.
        """

        i2pFac = BOBI2PServerFactory(self._reactor, fac, self._bobEndpoint, self._keyfile,
                                     self._tunnelNick,
                                     self._outhost,
                                     self._outport,
                                     self._options)
        d = self._bobEndpoint.connect(i2pFac)
        # Once the BOB IProtocol is returned, wait for the
        # IListeningPort to be returned after tunnel creation,
        # and pass it to any further registered callbacks.
        d.addCallback(lambda proto: i2pFac.deferred)
        return d