~ubuntu-branches/ubuntu/edgy/torrentflux/edgy-security

« back to all changes in this revision

Viewing changes to html/TF_BitTornado/BitTornado/RawServer.py

  • Committer: Bazaar Package Importer
  • Author(s): Cameron Dale
  • Date: 2006-04-14 15:13:06 UTC
  • Revision ID: james.westby@ubuntu.com-20060414151306-dwc5yc3hof3l2kmf
Tags: upstream-2.1
ImportĀ upstreamĀ versionĀ 2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Written by Bram Cohen
 
2
# see LICENSE.txt for license information
 
3
 
 
4
from bisect import insort
 
5
from SocketHandler import SocketHandler, UPnP_ERROR
 
6
import socket
 
7
from cStringIO import StringIO
 
8
from traceback import print_exc
 
9
from select import error
 
10
from threading import Thread, Event
 
11
from time import sleep
 
12
from clock import clock
 
13
import sys
 
14
try:
 
15
    True
 
16
except:
 
17
    True = 1
 
18
    False = 0
 
19
 
 
20
 
 
21
def autodetect_ipv6():
 
22
    try:
 
23
        assert sys.version_info >= (2,3)
 
24
        assert socket.has_ipv6
 
25
        socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
 
26
    except:
 
27
        return 0
 
28
    return 1
 
29
 
 
30
def autodetect_socket_style():
 
31
        if sys.platform.find('linux') < 0:
 
32
                return 1
 
33
        else:
 
34
                try:
 
35
                        f = open('/proc/sys/net/ipv6/bindv6only','r')
 
36
                        dual_socket_style = int(f.read())
 
37
                        f.close()
 
38
                        return int(not dual_socket_style)
 
39
                except:
 
40
                        return 0
 
41
 
 
42
 
 
43
READSIZE = 100000
 
44
 
 
45
class RawServer:
 
46
    def __init__(self, doneflag, timeout_check_interval, timeout, noisy = True,
 
47
                 ipv6_enable = True, failfunc = lambda x: None, errorfunc = None,
 
48
                 sockethandler = None, excflag = Event()):
 
49
        self.timeout_check_interval = timeout_check_interval
 
50
        self.timeout = timeout
 
51
        self.servers = {}
 
52
        self.single_sockets = {}
 
53
        self.dead_from_write = []
 
54
        self.doneflag = doneflag
 
55
        self.noisy = noisy
 
56
        self.failfunc = failfunc
 
57
        self.errorfunc = errorfunc
 
58
        self.exccount = 0
 
59
        self.funcs = []
 
60
        self.externally_added = []
 
61
        self.finished = Event()
 
62
        self.tasks_to_kill = []
 
63
        self.excflag = excflag
 
64
        
 
65
        if sockethandler is None:
 
66
            sockethandler = SocketHandler(timeout, ipv6_enable, READSIZE)
 
67
        self.sockethandler = sockethandler
 
68
        self.add_task(self.scan_for_timeouts, timeout_check_interval)
 
69
 
 
70
    def get_exception_flag(self):
 
71
        return self.excflag
 
72
 
 
73
    def _add_task(self, func, delay, id = None):
 
74
        assert float(delay) >= 0
 
75
        insort(self.funcs, (clock() + delay, func, id))
 
76
 
 
77
    def add_task(self, func, delay = 0, id = None):
 
78
        assert float(delay) >= 0
 
79
        self.externally_added.append((func, delay, id))
 
80
 
 
81
    def scan_for_timeouts(self):
 
82
        self.add_task(self.scan_for_timeouts, self.timeout_check_interval)
 
83
        self.sockethandler.scan_for_timeouts()
 
84
 
 
85
    def bind(self, port, bind = '', reuse = False,
 
86
                        ipv6_socket_style = 1, upnp = False):
 
87
        self.sockethandler.bind(port, bind, reuse, ipv6_socket_style, upnp)
 
88
 
 
89
    def find_and_bind(self, minport, maxport, bind = '', reuse = False,
 
90
                      ipv6_socket_style = 1, upnp = 0, randomizer = False):
 
91
        return self.sockethandler.find_and_bind(minport, maxport, bind, reuse,
 
92
                                 ipv6_socket_style, upnp, randomizer)
 
93
 
 
94
    def start_connection_raw(self, dns, socktype, handler = None):
 
95
        return self.sockethandler.start_connection_raw(dns, socktype, handler)
 
96
 
 
97
    def start_connection(self, dns, handler = None, randomize = False):
 
98
        return self.sockethandler.start_connection(dns, handler, randomize)
 
99
 
 
100
    def get_stats(self):
 
101
        return self.sockethandler.get_stats()
 
102
 
 
103
    def pop_external(self):
 
104
        while self.externally_added:
 
105
            (a, b, c) = self.externally_added.pop(0)
 
106
            self._add_task(a, b, c)
 
107
 
 
108
 
 
109
    def listen_forever(self, handler):
 
110
        self.sockethandler.set_handler(handler)
 
111
        try:
 
112
            while not self.doneflag.isSet():
 
113
                try:
 
114
                    self.pop_external()
 
115
                    self._kill_tasks()
 
116
                    if self.funcs:
 
117
                        period = self.funcs[0][0] + 0.001 - clock()
 
118
                    else:
 
119
                        period = 2 ** 30
 
120
                    if period < 0:
 
121
                        period = 0
 
122
                    events = self.sockethandler.do_poll(period)
 
123
                    if self.doneflag.isSet():
 
124
                        return
 
125
                    while self.funcs and self.funcs[0][0] <= clock():
 
126
                        garbage1, func, id = self.funcs.pop(0)
 
127
                        if id in self.tasks_to_kill:
 
128
                            pass
 
129
                        try:
 
130
#                            print func.func_name
 
131
                            func()
 
132
                        except (SystemError, MemoryError), e:
 
133
                            self.failfunc(str(e))
 
134
                            return
 
135
                        except KeyboardInterrupt:
 
136
#                            self.exception(True)
 
137
                            return
 
138
                        except:
 
139
                            if self.noisy:
 
140
                                self.exception()
 
141
                    self.sockethandler.close_dead()
 
142
                    self.sockethandler.handle_events(events)
 
143
                    if self.doneflag.isSet():
 
144
                        return
 
145
                    self.sockethandler.close_dead()
 
146
                except (SystemError, MemoryError), e:
 
147
                    self.failfunc(str(e))
 
148
                    return
 
149
                except error:
 
150
                    if self.doneflag.isSet():
 
151
                        return
 
152
                except KeyboardInterrupt:
 
153
#                    self.exception(True)
 
154
                    return
 
155
                except:
 
156
                    self.exception()
 
157
                if self.exccount > 10:
 
158
                    return
 
159
        finally:
 
160
#            self.sockethandler.shutdown()
 
161
            self.finished.set()
 
162
 
 
163
    def is_finished(self):
 
164
        return self.finished.isSet()
 
165
 
 
166
    def wait_until_finished(self):
 
167
        self.finished.wait()
 
168
 
 
169
    def _kill_tasks(self):
 
170
        if self.tasks_to_kill:
 
171
            new_funcs = []
 
172
            for (t, func, id) in self.funcs:
 
173
                if id not in self.tasks_to_kill:
 
174
                    new_funcs.append((t, func, id))
 
175
            self.funcs = new_funcs
 
176
            self.tasks_to_kill = []
 
177
 
 
178
    def kill_tasks(self, id):
 
179
        self.tasks_to_kill.append(id)
 
180
 
 
181
    def exception(self, kbint = False):
 
182
        if not kbint:
 
183
            self.excflag.set()
 
184
        self.exccount += 1
 
185
        if self.errorfunc is None:
 
186
            print_exc()
 
187
        else:
 
188
            data = StringIO()
 
189
            print_exc(file = data)
 
190
#            print data.getvalue()   # report exception here too
 
191
            if not kbint:           # don't report here if it's a keyboard interrupt
 
192
                self.errorfunc(data.getvalue())
 
193
 
 
194
    def shutdown(self):
 
195
        self.sockethandler.shutdown()