Beispiel #1
0
    def allocateRequest(sock, m, remote):  # serve the allocate request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        lifetime = timeout
        if Attribute.LIFETIME in m:
            lt = struct.unpack("!L", m[Attribute.LIFETIME].value)
            if lt < lifetime:
                lifetime = lt
        if fivetuple in binding:  # already found
            newsock = binding[fivetuple]
            if lifetime == 0:  # terminate the binding
                del binding[fivetuple]
                del binding[newsock]
        else:
            if lifetime > 0:  # allocate, otherwise it is already missing.
                newsock = socket.socket(sock.family, sock.type)
                newsock.bind(("0.0.0.0", 0))  # bind to any
                binding[newsock] = fivetuple
                binding[fivetuple] = newsock

        res = Message()
        res.method, res.type, res.tid = m.method, Message.RESPONSE, m.tid
        mapped = Attribute(Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (newsock.family, (external, newsock and newsock.getsockname()[1] or 0))
        res.attrs.append(mapped)
        res.attrs.append(Attribute(Attribute.LIFETIME, struct.pack("!L", lifetime)))

        if lifetime == 0 and newsock:  # close any previous listening function
            newsock.close()  # this should trigger close of functions
        else:
            if sock.type == socket.SOCK_STREAM:
                multitask.add(relayaccepter(newsock, fivetuple))
            else:
                multitask.add(relayreceiver(newsock, fivetuple))

        yield respond(sock, str(res), remote)
Beispiel #2
0
 def start(self, delay=None):
     from p2psip.external import multitask
     if self.running: self.stop()  # stop previous one first.
     if delay is not None: self.delay = delay  # set the new delay
     self.running = True
     self.gen = self.run()
     multitask.add(self.gen)
Beispiel #3
0
 def start(self, delay=None):
     from p2psip.external import multitask
     if self.running: self.stop() # stop previous one first.
     if delay is not None: self.delay = delay # set the new delay
     self.running = True
     self.gen = self.run()
     multitask.add(self.gen)
Beispiel #4
0
    def start(self, net=None, servers=None):
        '''Start the p2p node as ordinary node. Create a network object if none.'''
        if self.net is None:
            self.net = net or Network(
                Ks=crypto.generateRSA()[0], cert=None, port=self.port)
            self.net.start()

            # convert from serevrs ip:port list to Node list
            if servers:
                servers = [
                    Node(ip=ip,
                         port=port,
                         type=socket.SOCK_DGRAM,
                         guid=H(ip + ':' + str(port))) for ip, port in servers
                ]
                if _debug: print 'using servers=', servers

            self.client = Client(self.net, server=self.server).start(servers)
            if self.server:
                if self.router is None:
                    self.router = dht.Router(self.net).start()
                if self.storage is None:
                    self.storage = dht.Storage(self.net, self.router).start()
                if not self.router.initialized: self.router.initialized = True
        if not self._gens:
            for gen in [self.handler()]:
                multitask.add(gen)
                self._gens.append(gen)
        return self
Beispiel #5
0
def _testServer():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    sock.bind(("0.0.0.0", 0))  # should use any port for testing
    multitask.add(server(sock))
    sockaddr = getlocaladdr(sock)
    multitask.add(_testDiscoverBehavior([sockaddr, defaultServers[0]]))
    yield multitask.sleep(5)
    sock.close()
Beispiel #6
0
    def process(self, data):  # process incoming message
        if not isinstance(data, Message): data = Message(str(data))
        self.append(data)

        def add(self, data):
            if self._queue is not None: yield self._queue.put(data)

        multitask.add(add(self, data))
Beispiel #7
0
def _testServer():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    sock.bind(('0.0.0.0', 0))  # should use any port for testing
    multitask.add(server(sock))
    sockaddr = getlocaladdr(sock)
    multitask.add(_testDiscoverBehavior([sockaddr, defaultServers[0]]))
    yield multitask.sleep(5)
    sock.close()
Beispiel #8
0
        def fset(self, value):
            self._presence = value
            if self.connection is not None and value is not None:

                def sendPresence(value):
                    if self.connection is not None:
                        yield self.connection.put(msg=value)

                multitask.add(sendPresence(value))
Beispiel #9
0
def _testAlgorithm():
    def testInternal():
        #global _debug
        #_debug = dht._debug = True
        nodes = [ServerSocket(True).start()]
        for x in xrange(10):
            nodes.append(ServerSocket().start())
        yield
    multitask.add(testInternal())
Beispiel #10
0
def _testClient():
    def internalTest():
        n1 = Network(crypto.PrivateKey(), '').start()
        n2 = Network(crypto.PrivateKey(), '').start()
        c1 = Client(n1, server=True).start()
        c2 = Client(n2).start()
        msg = yield n2.get(lambda x: x.name=='Discover:Indication', timeout=8)
        assert msg is not None and msg.neighbors[0] == n1.node
    multitask.add(internalTest()) # need to use a generator for test
Beispiel #11
0
def _testAlgorithm():
    def testInternal():
        #global _debug
        #_debug = dht._debug = True
        nodes = [ServerSocket(True).start()]
        for x in xrange(10):
            nodes.append(ServerSocket().start())
        yield

    multitask.add(testInternal())
Beispiel #12
0
 def relayreceiver(sock, fivetuple):
     while True:  # start the main listening loop of the udp server
         try:
             data, remote = (yield multitask.recvfrom(sock, maxsize)
                             )  # receive a packet
             if data:
                 if _debug: print 'server().recvfrom() from', remote
                 multitask.add(datahandler(sock1, data, remote))
         except:  # some other socket error, probably sock1 is closed.
             break
     if _debug: print 'server() exiting'
Beispiel #13
0
def _testClient():
    def internalTest():
        n1 = Network(crypto.PrivateKey(), '').start()
        n2 = Network(crypto.PrivateKey(), '').start()
        c1 = Client(n1, server=True).start()
        c2 = Client(n2).start()
        msg = yield n2.get(lambda x: x.name == 'Discover:Indication',
                           timeout=8)
        assert msg is not None and msg.neighbors[0] == n1.node

    multitask.add(internalTest())  # need to use a generator for test
Beispiel #14
0
 def handler(self):
     '''Handle various messages from other modules such as Discover:Indication.'''
     supported = ['Discover:Indication']
     gen = None
     while True:
         msg = yield self.net.get(lambda x: x.name in supported)
         if msg.name == 'Discover:Indication':
             if msg.neighbors and gen is None: # need to promote
                 gen = self.promotionhandler(); multitask.add(gen)
             elif not msg.neighbors and gen is not None: # demotion: close promotion handler
                 gen.close(); gen = None
Beispiel #15
0
    def __init__(self, app, **kwargs):
        """Initialize the network."""
        s1, s2 = self._initialize(app, **kwargs)

        if s1 and s2:
            self.rtp, self.rtcp = s1, s2
            self._rtpgen = self.receiveRTP(self.rtp)
            self._rtcpgen = self.receiveRTCP(self.rtcp)
            multitask.add(self._rtpgen)
            multitask.add(self._rtcpgen)
        else:
            raise ValueError, "cannot allocate sockets"
Beispiel #16
0
 def relayreceiver(sock, fivetuple):
     while True:  # start the main listening loop of the udp server
         try:
             data, remote = (yield multitask.recvfrom(sock, maxsize))  # receive a packet
             if data:
                 if _debug:
                     print "server().recvfrom() from", remote
                 multitask.add(datahandler(sock1, data, remote))
         except:  # some other socket error, probably sock1 is closed.
             break
     if _debug:
         print "server() exiting"
Beispiel #17
0
    def __init__(self, app, **kwargs):
        '''Initialize the network.'''
        s1, s2 = self._initialize(app, **kwargs)

        if s1 and s2:
            self.rtp, self.rtcp = s1, s2
            self._rtpgen = self.receiveRTP(self.rtp)
            self._rtcpgen = self.receiveRTCP(self.rtcp)
            multitask.add(self._rtpgen)
            multitask.add(self._rtcpgen)
        else:
            raise ValueError, 'cannot allocate sockets'
Beispiel #18
0
 def start(self, servers=None):
     '''Start the client with the given set of optional servers list.'''
     if not self._gens:
         guid  = H(ADDRESS + ':' + str(PORT))
         try: bs = [Node(ip=socket.gethostbyname(BOOTSTRAP), port=PORT, type=socket.SOCK_STREAM, guid=guid)]
         except: bs = []
         self.candidates = (servers or []) + [self.net.nodemcast] + bs
         if _debug: print 'Client.start candidates=', self.candidates
         self.neighbors  = []
         self._gens = [self.discoverhandler(), self.bootstrap(), self.clienthandler()] # , self.pinghandler()
         for gen in self._gens: multitask.add(gen)
     return self
Beispiel #19
0
 def handler(self):
     '''Handle various messages from other modules such as Discover:Indication.'''
     supported = ['Discover:Indication']
     gen = None
     while True:
         msg = yield self.net.get(lambda x: x.name in supported)
         if msg.name == 'Discover:Indication':
             if msg.neighbors and gen is None:  # need to promote
                 gen = self.promotionhandler()
                 multitask.add(gen)
             elif not msg.neighbors and gen is not None:  # demotion: close promotion handler
                 gen.close()
                 gen = None
Beispiel #20
0
 def connected(self, old, new): # connection or disconnection callback
     if new is not None: 
         def filter(data):
             if data.tag == 'presence': return True
             elif data.tag == 'iq' and data.type == 'set': query = F(data('query')); return query and query.xmlns == 'jabber:iq:roster'
             else: return False
         self.filter = filter
         multitask.add(self.fetch()) # when connected, install the onRosterSet listener and fetch the roster
         self.presence = Presence()
     else:
         self.filter = None
         self.presence = None
         self.clear()
Beispiel #21
0
 def send(self, msg, node, timeout=None):
     '''Send some msg to dest node (Node), and if timeout is specified then return a success (True)
     or failure (False) within that timeout. Otherwise, the function may return immediately.'''
     try:
         start = time.time()
         if node.type == socket.SOCK_DGRAM and timeout is not None:  # no ack required for tcp
             msg['ack'] = True  # require a NetworkAck
         data = dht.int2bin(self.node.guid) + str(
             msg)  # TODO: this assumes guid is same for all transports.
         if _debug and msg.name[:4] != 'Hash':
             print self.name, 'sending %d bytes %s=>%s: %r' % (
                 len(data), self.node.hostport, node.hostport, msg)
         if node.type == socket.SOCK_DGRAM:
             self.udp.sendto(data, (node.ip, node.port))
         else:
             if node in self.tcpc:
                 sock = self.tcpc[node]
             else:
                 sock = socket.socket(type=socket.SOCK_STREAM)
                 sock.setblocking(0)
                 try:
                     if _debug: print 'connecting to %s' % (node.hostport, )
                     sock.connect((node.ip, node.port))
                 except (socket.timeout, socket.error):
                     yield multitask.sleep(2.0)
                     ret = select.select((), (sock, ), (), 0)
                     if len(ret[1]) == 0:
                         if _debug:
                             print 'connection timedout to %s' % (
                                 node.hostport, )
                         raise multitask.Timeout, 'Cannot connect to the destination'
                 self.tcpc[node] = sock
                 # yield multitask.sleep()
                 multitask.add(self.tcphandler(sock, (node.ip, node.port)))
             data = struct.pack('!H',
                                len(data)) + data  # put a length first.
             sock.send(data)
         if msg.ack:
             hash = H(
                 data
             )  # hash property to associate the ack to the data request.
             ack = yield self.get(
                 lambda x: x.name == 'Ack:Indication' and x.hash == hash,
                 timeout=(timeout - (time.time() - start)))
             if _debug: 'received ack %r' % (ack)
             if ack is None: raise StopIteration(False)  # no ack received
         raise StopIteration(True)
     except (multitask.Timeout, socket.error):
         raise StopIteration(False)  # timeout in sendto or get
Beispiel #22
0
 def relayaccepter(sock, fivetuple):
     sock.listen(5)  # accept queue
     while True:  # start the main listening loop of the tcp server
         try:
             conn, remote = (yield multitask.accept(sock))
             if conn:
                 if _debug: print 'relayaccepter().accept() from', remote
                 sock.close(
                 )  # close the original listening socket -- no more connections
                 binding[fivetuple] = conn  # update the binding
                 del binding[sock]
                 binding[conn] = fivetuple
                 multitask.add(relaytcpreceiver(conn, fivetuple, remote))
                 break
         except:  # some other socket error, probably sock is closed.
             break
     if _debug: print 'relaytcpaccepter() exiting'
Beispiel #23
0
def _testRelay():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock1.bind(("0.0.0.0", 0))
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock2.bind(("0.0.0.0", 0))
        yield multitask.sleep(2)
        response, mapped = request(sock2, sockaddr, method=Message.ALLOCATE)
        print "mapped=", mapped
        sock1.close()
        sock2.close()
        yield multitask.sleep(6)
    except:
        print "exception", sys.exc_info(), traceback.print_exc(file=sys.stdout)
Beispiel #24
0
def _testTcpRequest():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock1.bind(('0.0.0.0', 0))  # should use any port for testing
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock2.bind(('0.0.0.0', 0))
        yield multitask.sleep(2)  # wait for server to be started.
        response, external = (yield request(sock2, sockaddr))
        print 'external=', external
        sock1.close()
        yield multitask.sleep(6)
        print '_testTcpRequest() exiting'
    except (ValueError, multitask.Timeout), E:
        print 'exception - ValueError or Timeout', E
Beispiel #25
0
def _testTcpRequest():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock1.bind(("0.0.0.0", 0))  # should use any port for testing
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock2.bind(("0.0.0.0", 0))
        yield multitask.sleep(2)  # wait for server to be started.
        response, external = (yield request(sock2, sockaddr))
        print "external=", external
        sock1.close()
        yield multitask.sleep(6)
        print "_testTcpRequest() exiting"
    except (ValueError, multitask.Timeout), E:
        print "exception - ValueError or Timeout", E
Beispiel #26
0
def _testRelay():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock1.bind(('0.0.0.0', 0))
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock2.bind(('0.0.0.0', 0))
        yield multitask.sleep(2)
        response, mapped = request(sock2, sockaddr, method=Message.ALLOCATE)
        print 'mapped=', mapped
        sock1.close()
        sock2.close()
        yield multitask.sleep(6)
    except:
        print 'exception', sys.exc_info(), traceback.print_exc(file=sys.stdout)
Beispiel #27
0
 def relayaccepter(sock, fivetuple):
     sock.listen(5)  # accept queue
     while True:  # start the main listening loop of the tcp server
         try:
             conn, remote = (yield multitask.accept(sock))
             if conn:
                 if _debug:
                     print "relayaccepter().accept() from", remote
                 sock.close()  # close the original listening socket -- no more connections
                 binding[fivetuple] = conn  # update the binding
                 del binding[sock]
                 binding[conn] = fivetuple
                 multitask.add(relaytcpreceiver(conn, fivetuple, remote))
                 break
         except:  # some other socket error, probably sock is closed.
             break
     if _debug:
         print "relaytcpaccepter() exiting"
Beispiel #28
0
 def clienthandler(self):
     '''Receive requests from client and send to the router module, and viceversa.'''
     net = self.net
     def requesthandler(msg):
         p = msg.payload; response = None
         if self.server: # only if a server
             if p.name=='Put:Request':
                 result = yield dht.put(net, p.dest, p.value, p.nonce, p.expires, p.Ks, p.put)
                 response = Message(name='Put:Response', seq=p.seq, result=result)
             elif p.name=='Get:Request':
                 result = yield dht.get(net, p.dest, p.maxvalues, p.Kp)
                 response = Message(name='Get:Response', seq=p.seq, guid=p.guid, vals=result)
             if response: yield self.net.send(Message(name='Proxy:Response', src=net.node, payload=response), node=msg.src, timeout=5)
     def responsehandler(msg):
         if not self.server: # only if a client
             yield net.put(msg.payload, timeout=5)
     while True:
         msg = yield self.net.get(lambda x: x.name=='Proxy:Request' or x.name=='Proxy:Response')
         if msg: multitask.add(requesthandler(msg) if msg.name=='Proxy:Request' else responsehandler(msg))
Beispiel #29
0
 def start(self, net=None, servers=None):
     '''Start the p2p node as ordinary node. Create a network object if none.'''
     if self.net is None:
         self.net = net or Network(Ks=crypto.generateRSA()[0], cert=None, port=self.port) 
         self.net.start()
         
         # convert from serevrs ip:port list to Node list
         if servers:
             servers=[Node(ip=ip, port=port, type=socket.SOCK_DGRAM, guid=H(ip + ':' + str(port))) for ip, port in servers]
             if _debug: print 'using servers=', servers
         
         self.client = Client(self.net, server=self.server).start(servers)
         if self.server:
             if self.router is None: self.router = dht.Router(self.net).start()
             if self.storage is None: self.storage = dht.Storage(self.net, self.router).start()
             if not self.router.initialized: self.router.initialized = True
     if not self._gens:
         for gen in [self.handler()]: multitask.add(gen); self._gens.append(gen)
     return self
Beispiel #30
0
    def connected(self, old, new):  # connection or disconnection callback
        if new is not None:

            def filter(data):
                if data.tag == 'presence': return True
                elif data.tag == 'iq' and data.type == 'set':
                    query = F(data('query'))
                    return query and query.xmlns == 'jabber:iq:roster'
                else:
                    return False

            self.filter = filter
            multitask.add(
                self.fetch()
            )  # when connected, install the onRosterSet listener and fetch the roster
            self.presence = Presence()
        else:
            self.filter = None
            self.presence = None
            self.clear()
Beispiel #31
0
 def _sipreceiver(self, stack, maxsize=16386):
     '''Handle the messages or connections on the given SIP stack's socket, and pass it to the stack so that stack can invoke 
     appropriate callback on this object such as receivedRequest.'''
     sock = stack.sock
     while True:
         if sock.type == socket.SOCK_DGRAM:
             data, remote = yield multitask.recvfrom(sock, maxsize)
             logger.debug('%r=>%r on type=%r\n%s', remote, sock.getsockname(), stack.transport.type, data)
             if data: 
                 try: stack.received(data, remote)
                 except: logger.exception('received')
         elif sock.type == socket.SOCK_STREAM:
             conn, remote = yield multitask.accept(sock)
             if conn:
                 logger.debug('%r=>%r connection type %r', remote, conn.getsockname(), stack.transport.type)
                 if stack.transport.type in ('ws', 'wss'):
                     multitask.add(self._wsreceiver(stack, conn, remote, maxsize))
                 else:
                     multitask.add(self._tcpreceiver(stack, conn, remote, maxsize))
         else: raise ValueError, 'invalid socket type'
Beispiel #32
0
 def send(self, msg, node, timeout=None):
     '''Send some msg to dest node (Node), and if timeout is specified then return a success (True)
     or failure (False) within that timeout. Otherwise, the function may return immediately.'''
     try:
         start = time.time()
         if node.type==socket.SOCK_DGRAM and timeout is not None: # no ack required for tcp 
             msg['ack'] = True # require a NetworkAck
         data = dht.int2bin(self.node.guid) + str(msg) # TODO: this assumes guid is same for all transports.
         if _debug and msg.name[:4] != 'Hash': print self.name, 'sending %d bytes %s=>%s: %r'%(len(data), self.node.hostport, node.hostport, msg)
         if node.type == socket.SOCK_DGRAM:
             self.udp.sendto(data, (node.ip, node.port))
         else:
             if node in self.tcpc:
                 sock = self.tcpc[node]
             else:
                 sock = socket.socket(type=socket.SOCK_STREAM)
                 sock.setblocking(0)
                 try:
                     if _debug: print 'connecting to %s'%(node.hostport,)
                     sock.connect((node.ip, node.port))
                 except (socket.timeout, socket.error):
                     yield multitask.sleep(2.0)
                     ret = select.select((), (sock,), (), 0)
                     if len(ret[1]) == 0:
                         if _debug: print 'connection timedout to %s'%(node.hostport,)
                         raise multitask.Timeout, 'Cannot connect to the destination'
                 self.tcpc[node] = sock
                 # yield multitask.sleep()
                 multitask.add(self.tcphandler(sock, (node.ip, node.port)))
             data = struct.pack('!H', len(data)) + data # put a length first.
             sock.send(data)
         if msg.ack:
             hash = H(data)    # hash property to associate the ack to the data request.
             ack = yield self.get(lambda x: x.name=='Ack:Indication' and x.hash==hash, timeout=(timeout - (time.time() - start)))
             if _debug: 'received ack %r'%(ack)
             if ack is None: raise StopIteration(False) # no ack received
         raise StopIteration(True)
     except (multitask.Timeout, socket.error):
         raise StopIteration(False) # timeout in sendto or get
Beispiel #33
0
    def clienthandler(self):
        '''Receive requests from client and send to the router module, and viceversa.'''
        net = self.net

        def requesthandler(msg):
            p = msg.payload
            response = None
            if self.server:  # only if a server
                if p.name == 'Put:Request':
                    result = yield dht.put(net, p.dest, p.value, p.nonce,
                                           p.expires, p.Ks, p.put)
                    response = Message(name='Put:Response',
                                       seq=p.seq,
                                       result=result)
                elif p.name == 'Get:Request':
                    result = yield dht.get(net, p.dest, p.maxvalues, p.Kp)
                    response = Message(name='Get:Response',
                                       seq=p.seq,
                                       guid=p.guid,
                                       vals=result)
                if response:
                    yield self.net.send(Message(name='Proxy:Response',
                                                src=net.node,
                                                payload=response),
                                        node=msg.src,
                                        timeout=5)

        def responsehandler(msg):
            if not self.server:  # only if a client
                yield net.put(msg.payload, timeout=5)

        while True:
            msg = yield self.net.get(lambda x: x.name == 'Proxy:Request' or x.
                                     name == 'Proxy:Response')
            if msg:
                multitask.add(
                    requesthandler(msg) if msg.name ==
                    'Proxy:Request' else responsehandler(msg))
Beispiel #34
0
    def allocateRequest(sock, m, remote):  # serve the allocate request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        lifetime = timeout
        if Attribute.LIFETIME in m:
            lt = struct.unpack('!L', m[Attribute.LIFETIME].value)
            if lt < lifetime: lifetime = lt
        if fivetuple in binding:  # already found
            newsock = binding[fivetuple]
            if lifetime == 0:  # terminate the binding
                del binding[fivetuple]
                del binding[newsock]
        else:
            if lifetime > 0:  # allocate, otherwise it is already missing.
                newsock = socket.socket(sock.family, sock.type)
                newsock.bind(('0.0.0.0', 0))  # bind to any
                binding[newsock] = fivetuple
                binding[fivetuple] = newsock

        res = Message()
        res.method, res.type, res.tid = m.method, Message.RESPONSE, m.tid
        mapped = Attribute(
            Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (newsock.family,
                          (external, newsock and newsock.getsockname()[1]
                           or 0))
        res.attrs.append(mapped)
        res.attrs.append(
            Attribute(Attribute.LIFETIME, struct.pack('!L', lifetime)))

        if lifetime == 0 and newsock:  # close any previous listening function
            newsock.close()  # this should trigger close of functions
        else:
            if sock.type == socket.SOCK_STREAM:
                multitask.add(relayaccepter(newsock, fivetuple))
            else:
                multitask.add(relayreceiver(newsock, fivetuple))

        yield respond(sock, str(res), remote)
Beispiel #35
0
 def send(self, data, remote, stack):
     '''Send a given data to remote for the SIP stack.'''
     def _send(self, data, remote, stack): # a generator function that does the sending
         logger.debug('%r=>%r on type=%r\n%s', stack.sock.getsockname(), remote, stack.transport.type, data)
         try:
             if stack.sock.type == socket.SOCK_STREAM: # for TCP send only if a connection exists to the remote.
                 if stack.transport.type in ('ws', 'wss'):
                     if len(data) < 126:
                         init = struct.pack('>BB', 0x81, len(data))
                     elif len(data) < 65536:
                         init = struct.pack('>BBH', 0x81, 126, len(data))
                     else:
                         raise ValueError, 'cannot send long message'
                     data = init + data
                 if remote in self.conn:
                     yield multitask.send(self.conn[remote], data) # and send using that connected TCP socket.
                 else:
                     logger.warning('ignoring message to %r as no existing connection', remote)
             else: # for UDP send using the stack's UDP socket.
                 yield multitask.sendto(stack.sock, data, remote)
         except StopIteration: pass
         except: 
             logger.exception('sending')
     multitask.add(_send(self, data, remote, stack))
Beispiel #36
0
 def start(self, servers=None):
     '''Start the client with the given set of optional servers list.'''
     if not self._gens:
         guid = H(ADDRESS + ':' + str(PORT))
         try:
             bs = [
                 Node(ip=socket.gethostbyname(BOOTSTRAP),
                      port=PORT,
                      type=socket.SOCK_STREAM,
                      guid=guid)
             ]
         except:
             bs = []
         self.candidates = (servers or []) + [self.net.nodemcast] + bs
         if _debug: print 'Client.start candidates=', self.candidates
         self.neighbors = []
         self._gens = [
             self.discoverhandler(),
             self.bootstrap(),
             self.clienthandler()
         ]  # , self.pinghandler()
         for gen in self._gens:
             multitask.add(gen)
     return self
Beispiel #37
0
def server(sock1, **kwargs):
    """A simple server implementation to test the code or to use in real deployment.
    The application should start the server as multitask.add(server(sock)).
    
    The caller should make sure that the sock1 argument is a UDP or TCP socket
    which is already bound. Additionally, sock2, sock3, and sock4 can be supplied
    as keyword arguments and represent the socket to use for change-IP, change-port
    and change IP+port commands respectively. Other keyword arguments are as follows:
      timeout: optional acivity timeout (second) if relay is activated, defaults to 180.
      external: optional external (ip, port) of the socket in case it is behind
        a full-cone NAT and still acts as a (relay) server.
      handler: optional function that gets invoked as handler(sock, remote, data) for 
        non-STUN data, and allows the application to demultiplex other types of data.
      maxsize: optional maximum size of packet to handle, defaults to 1500."""

    sock2, sock3, sock4 = kwargs.get("sock2", None), kwargs.get("sock3", None), kwargs.get("sock4", None)
    addr1 = getlocaladdr(sock1)
    addr4 = sock4 and getlocaladdr(sock4) or None
    timeout = kwargs.get("timeout", 180)  # three minutes
    external = kwargs.get("external", addr1)
    handler = kwargs.get("handler", None)
    maxsize = kwargs.get("maxsize", 1500)

    tcp = sock1.type == socket.SOCK_STREAM  # whether the server is on tcp or udp.
    binding = dict()  # allocated relay bindings if any

    def respond(sock, data, remote):
        if sock.type == socket.SOCK_STREAM:
            yield multitask.send(sock, data)
        else:
            yield multitask.sendto(sock, data, remote)

    def bindingRequest(sock, m, remote):  # Serve a binding request of STUN
        res = Message()
        res.method, res.type, res.tid = Message.BINDING, Message.RESPONSE, m.tid
        mapped = Attribute(Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (sock.family, addr1[0], addr1[1])
        res.attrs.append(mapped)
        if Attribute.CHANGE_REQUEST not in m:  # send from same address:port
            if addr4:  # add the other address attribute
                other = Attribute(Attribute.OTHER_ADDRESS)
                other.address = (sock4.family, addr4[0], addr4[1])
                res.attrs.append(other)
        else:
            change = m[Attribute.CHANGE_REQUEST]
            sock = (
                change.value == "\x00\x00\x00\x06"
                and sock4
                or change.value == "\x00\x00\x00\x02"
                and sock3
                or change.value == "\x00\x00\x00\x04"
                and sock2
                or None
            )
        if sock:
            yield respond(sock, str(res), remote)
        raise StopIteration()

    def allocateRequest(sock, m, remote):  # serve the allocate request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        lifetime = timeout
        if Attribute.LIFETIME in m:
            lt = struct.unpack("!L", m[Attribute.LIFETIME].value)
            if lt < lifetime:
                lifetime = lt
        if fivetuple in binding:  # already found
            newsock = binding[fivetuple]
            if lifetime == 0:  # terminate the binding
                del binding[fivetuple]
                del binding[newsock]
        else:
            if lifetime > 0:  # allocate, otherwise it is already missing.
                newsock = socket.socket(sock.family, sock.type)
                newsock.bind(("0.0.0.0", 0))  # bind to any
                binding[newsock] = fivetuple
                binding[fivetuple] = newsock

        res = Message()
        res.method, res.type, res.tid = m.method, Message.RESPONSE, m.tid
        mapped = Attribute(Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (newsock.family, (external, newsock and newsock.getsockname()[1] or 0))
        res.attrs.append(mapped)
        res.attrs.append(Attribute(Attribute.LIFETIME, struct.pack("!L", lifetime)))

        if lifetime == 0 and newsock:  # close any previous listening function
            newsock.close()  # this should trigger close of functions
        else:
            if sock.type == socket.SOCK_STREAM:
                multitask.add(relayaccepter(newsock, fivetuple))
            else:
                multitask.add(relayreceiver(newsock, fivetuple))

        yield respond(sock, str(res), remote)

    def relaytcpreceiver(sock, fivetuple):
        pass

    def relayaccepter(sock, fivetuple):
        sock.listen(5)  # accept queue
        while True:  # start the main listening loop of the tcp server
            try:
                conn, remote = (yield multitask.accept(sock))
                if conn:
                    if _debug:
                        print "relayaccepter().accept() from", remote
                    sock.close()  # close the original listening socket -- no more connections
                    binding[fivetuple] = conn  # update the binding
                    del binding[sock]
                    binding[conn] = fivetuple
                    multitask.add(relaytcpreceiver(conn, fivetuple, remote))
                    break
            except:  # some other socket error, probably sock is closed.
                break
        if _debug:
            print "relaytcpaccepter() exiting"

    def relayreceiver(sock, fivetuple):
        while True:  # start the main listening loop of the udp server
            try:
                data, remote = (yield multitask.recvfrom(sock, maxsize))  # receive a packet
                if data:
                    if _debug:
                        print "server().recvfrom() from", remote
                    multitask.add(datahandler(sock1, data, remote))
            except:  # some other socket error, probably sock1 is closed.
                break
        if _debug:
            print "server() exiting"

    def sendRequest(sock, m, remote):  # serve the send request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        try:
            if fivetuple not in binding:  # not found
                raise ValueError, "no turn binding found"
            newsock = binding[fivetuple]
            destaddr = Attribute.DESTINATION_ADDRESS in m and m[Attribute.DESTINATION_ADDRESS].address[1:] or None
            data = Attribute.DATA in m and m[Attribute.DATA] or None
            if sock.type == socket.SOCK_STREAM:
                try:
                    remote = newsock.getpeername()
                except:
                    remote = None
                if not remote:
                    newsock.connect(destaddr)
                    remote = destaddr
                yield multitask.send(newsock, data)
            else:
                yield multitask.sendto(newsock, data, destaddr)
            # TODO: we don't lock to destaddr. This is a security risk.
            result = True
        except:
            if _debug:
                print "sendRequest() exception", sys.exc_info()
            result = False
        res = Message()
        res.method, res.type, res.tid = m.method, (result and Message.RESPONSE or Message.ERROR), m.tid
        if not result:
            error = Attribute(Attribute.ERROR_CODE)
            error.error = (400, "cannot send request")  # TODO: be more explicit.
            res.attrs.append(error)
        yield respond(sock, str(res), remote)

    def datahandler(sock, data, remote):  # handle a new data from given remote (ip, port)
        try:
            m = Message(data)  # parse the message
            func = (
                m.type == Message.REQUEST
                and (
                    m.method == Message.BINDING
                    and bindingRequest
                    or m.method == Message.ALLOCATE
                    and allocateRequest
                    or m.method == Message.SEND
                    and sendRequest
                )
                or None
            )
            if func:
                yield func(sock, m, remote)
            else:
                raise ValueError, "unhandled request or message"
        except StopIteration:
            if _debug:
                print "datahandler: stop iteration"
            raise
        except:  # parsing error or unhandled message
            if _debug:
                print "datahandler() exception", sys.exc_info()
            if handler:
                handler(sock, remote, data)  # invoke the application's handler.

    def tcpreceiver(sock, remote):  # handle a new incoming TCP connection
        while True:
            data = (yield multitask.recv(sock, maxsize))
            if not data:
                break  # socket closed
            type, length, magic = struct.unpack("!HHL", data[:8])
            valid = (type & 0xC000 == 0) and magic == Message.MAGIC and length <= (maxsize - 8)  # valid
            if valid:
                yield datahandler(sock, data, remote)
                if _debug:
                    print "tcpreceiver() finished data handler"
            else:
                handler(sock, data, remote)

    if tcp:
        sock1.listen(5)  # create the listen queue

    if _debug:
        print "server listening on", addr1
    while True:  # start the main listening loop of the server
        try:
            tcp = sock1.type == socket.SOCK_STREAM
        except:
            break  # probably a bad file descriptor because sock1 is closed.
        try:
            if tcp:
                conn, remote = (yield multitask.accept(sock1, timeout=5))
                if conn:
                    if _debug:
                        print "server().accept() from", remote
                    multitask.add(tcpreceiver(conn, remote))
            else:
                data, remote = (yield multitask.recvfrom(sock1, maxsize, timeout=5))  # receive a packet
                if data:
                    if _debug:
                        print "server().recvfrom() from", remote
                    multitask.add(datahandler(sock1, data, remote))
        except multitask.Timeout:
            continue
        except:  # some other socket error, probably sock1 is closed.
            break
    if _debug:
        print "server() exiting"
Beispiel #38
0
    except:
        print "exception", sys.exc_info()


def _testRelay():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock1.bind(("0.0.0.0", 0))
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock2.bind(("0.0.0.0", 0))
        yield multitask.sleep(2)
        response, mapped = request(sock2, sockaddr, method=Message.ALLOCATE)
        print "mapped=", mapped
        sock1.close()
        sock2.close()
        yield multitask.sleep(6)
    except:
        print "exception", sys.exc_info(), traceback.print_exc(file=sys.stdout)


if __name__ == "__main__":
    # multitask.add(_testRequest())
    # multitask.add(_testDiscoverBehavior())
    # multitask.add(_testTcpRequest())
    # multitask.add(_testServer())
    multitask.add(_testRelay())
    multitask.run()
Beispiel #39
0
def _testServerSocket():
    def testInternal():
        s1 = ServerSocket(True).start()
        s2 = ServerSocket().start()
    multitask.add(testInternal())
Beispiel #40
0
    except:
        print 'exception', sys.exc_info()


def _testRelay():
    try:
        sock1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock1.bind(('0.0.0.0', 0))
        multitask.add(server(sock1))
        sockaddr = getlocaladdr(sock1)

        sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock2.bind(('0.0.0.0', 0))
        yield multitask.sleep(2)
        response, mapped = request(sock2, sockaddr, method=Message.ALLOCATE)
        print 'mapped=', mapped
        sock1.close()
        sock2.close()
        yield multitask.sleep(6)
    except:
        print 'exception', sys.exc_info(), traceback.print_exc(file=sys.stdout)


if __name__ == "__main__":
    #multitask.add(_testRequest())
    #multitask.add(_testDiscoverBehavior())
    #multitask.add(_testTcpRequest())
    #multitask.add(_testServer())
    multitask.add(_testRelay())
    multitask.run()
Beispiel #41
0
    u1.roster.presence = Presence(show='dnd', status='Online')

    h1 = u1.chat('*****@*****.**')
    yield h1.send(Message(body='Hello How are you?'))

    count = 5
    for i in xrange(5):
        try:
            msg = yield h1.recv(timeout=120)
            print msg
            print '%s: %s'%(msg.frm, msg.body.cdata)
            yield h1.send(Message(body='You said "%s"'%(msg.body.cdata)))
        except Exception, e:
            print str(type(e)), e
            break
        
    yield u1.logout()
    print 'testPresence exiting'

def testClose(): yield multitask.sleep(25); exit()

if __name__ == '__main__':
    import doctest; doctest.testmod()    # first run doctest,
    for f in dir():      # then run all _test* functions
        if str(f).find('_test') == 0 and callable(eval(f)):
            multitask.add(globals()[f]())
    try: multitask.run()
    except KeyboardInterrupt: pass
    except select.error: print 'select error'; pass
    sys.exit()
Beispiel #42
0
 def tcpreceiver(self):
     '''Receive incoming TCP connection.'''
     while True:
         sock, addr = yield multitask.accept(self.tcp)
         if sock:
             multitask.add(self.tcphandler(sock, addr))
Beispiel #43
0
    def sendRTCP(self, sendbye=False):
        '''Send a RTCP packet with SR or RR and SDES, and optionally BYE if sendbye is True.
        It returns the size of the packet sent.'''
        reports = []
        toremove = []
        for member in self.members.values():
            if member.received > 0:
                ntp1, ntp2 = time2ntp(member.lastntp)
                lsr = ((ntp1 & 0x0ffff) << 16) | ((ntp2 >> 16) & 0x0ffff)
                dlsr = int((self.tc - member.lastntp) * 65536)
                member.updatelostandexpected()
                report = RTCP.packet(ssrc=member.ssrc,
                                     flost=member.fraction,
                                     clost=member.lost,
                                     hseq=member.cycles + member.maxseq,
                                     jitter=int(member.jitter),
                                     lsr=lsr,
                                     dlsr=dlsr)
                reports.append(report)
                member.received = 0
            if member.timeout == 5:  # if no packet within five RTCP intervals
                toremove.append(member.ssrc)  # schedule it to be removed
            else:
                member.timeout = member.timeout + 1
        if toremove:  # remove all timedout members
            for ssrc in toremove:
                del self.members[ssrc]

        packet = RTCP()
        if self.wesent:  # add a sender report
            p = RTCP.packet(pt=RTCP.SR,
                            ntp=self.tc,
                            ts=self.tsnow + self.ts0,
                            pktcount=self.member.pktcount,
                            octcount=self.member.octcount,
                            reports=reports[:32])
            self.wesent = False
        else:
            p = RTCP.packet(pt=RTCP.RR, reports=reports[:32])
        packet.append(p)

        if len(reports) >= 32:  # add additional RR if needed
            reports = reports[32:]
            while reports:
                p, reports = RTCP.packet(pt=RTCP.RR,
                                         reports=reports[:32]), reports[32:]
                packet.append(p)

        p = RTCP.packet(
            pt=RTCP.SDES, items=self.member.items
        )  # add SDES. Should add items only every few packets, except for CNAME which is added in every.
        packet.append(p)

        if sendbye:  # add a BYE packet as well
            p = RTCP.packet(pt=RTCP.BYE,
                            ssrcs=[self.member.ssrc
                                   ])  # Need to add a reason as well
            packet.append(p)

        data = str(packet)  # format for network data
        if self.net is not None:
            multitask.add(self.net.sendRTCP(
                data))  # invoke app or net to send the packet
        elif hasattr(self.app, 'sendRTCP') and callable(self.app.sendRTCP):
            self.app.sendRTCP(self, data)
        elif _debug:
            print 'ignoring send RTCP'
        self.rtcpsent = True
        return len(data)
Beispiel #44
0
 def fset(self, value): 
     self._presence = value
     if self.connection is not None and value is not None:
         def sendPresence(value): 
             if self.connection is not None: yield self.connection.put(msg=value)
         multitask.add(sendPresence(value))
Beispiel #45
0
 def start(self):
     '''Start the listening tasks in this agent. It returns self for cascaded method calls.'''
     for s in self.stack.values(): gen = self._sipreceiver(s); self._gens.append(gen); multitask.add(gen)
     return self
Beispiel #46
0
 def process(self, data):
     if not data: multitask.add(self.logout())
Beispiel #47
0
def server(sock1, **kwargs):
    '''A simple server implementation to test the code or to use in real deployment.
    The application should start the server as multitask.add(server(sock)).
    
    The caller should make sure that the sock1 argument is a UDP or TCP socket
    which is already bound. Additionally, sock2, sock3, and sock4 can be supplied
    as keyword arguments and represent the socket to use for change-IP, change-port
    and change IP+port commands respectively. Other keyword arguments are as follows:
      timeout: optional acivity timeout (second) if relay is activated, defaults to 180.
      external: optional external (ip, port) of the socket in case it is behind
        a full-cone NAT and still acts as a (relay) server.
      handler: optional function that gets invoked as handler(sock, remote, data) for 
        non-STUN data, and allows the application to demultiplex other types of data.
      maxsize: optional maximum size of packet to handle, defaults to 1500.'''

    sock2, sock3, sock4 = kwargs.get('sock2', None), kwargs.get(
        'sock3', None), kwargs.get('sock4', None)
    addr1 = getlocaladdr(sock1)
    addr4 = sock4 and getlocaladdr(sock4) or None
    timeout = kwargs.get('timeout', 180)  # three minutes
    external = kwargs.get('external', addr1)
    handler = kwargs.get('handler', None)
    maxsize = kwargs.get('maxsize', 1500)

    tcp = (sock1.type == socket.SOCK_STREAM
           )  # whether the server is on tcp or udp.
    binding = dict()  # allocated relay bindings if any

    def respond(sock, data, remote):
        if sock.type == socket.SOCK_STREAM:
            yield multitask.send(sock, data)
        else:
            yield multitask.sendto(sock, data, remote)

    def bindingRequest(sock, m, remote):  # Serve a binding request of STUN
        res = Message()
        res.method, res.type, res.tid = Message.BINDING, Message.RESPONSE, m.tid
        mapped = Attribute(
            Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (sock.family, addr1[0], addr1[1])
        res.attrs.append(mapped)
        if Attribute.CHANGE_REQUEST not in m:  # send from same address:port
            if addr4:  # add the other address attribute
                other = Attribute(Attribute.OTHER_ADDRESS)
                other.address = (sock4.family, addr4[0], addr4[1])
                res.attrs.append(other)
        else:
            change = m[Attribute.CHANGE_REQUEST]
            sock = change.value == '\x00\x00\x00\x06' and sock4 or change.value == '\x00\x00\x00\x02' and sock3 or change.value == '\x00\x00\x00\x04' and sock2 or None
        if sock:
            yield respond(sock, str(res), remote)
        raise StopIteration()

    def allocateRequest(sock, m, remote):  # serve the allocate request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        lifetime = timeout
        if Attribute.LIFETIME in m:
            lt = struct.unpack('!L', m[Attribute.LIFETIME].value)
            if lt < lifetime: lifetime = lt
        if fivetuple in binding:  # already found
            newsock = binding[fivetuple]
            if lifetime == 0:  # terminate the binding
                del binding[fivetuple]
                del binding[newsock]
        else:
            if lifetime > 0:  # allocate, otherwise it is already missing.
                newsock = socket.socket(sock.family, sock.type)
                newsock.bind(('0.0.0.0', 0))  # bind to any
                binding[newsock] = fivetuple
                binding[fivetuple] = newsock

        res = Message()
        res.method, res.type, res.tid = m.method, Message.RESPONSE, m.tid
        mapped = Attribute(
            Attribute.MAPPED_ADDRESS)  # mapped-address attribute
        mapped.address = (newsock.family,
                          (external, newsock and newsock.getsockname()[1]
                           or 0))
        res.attrs.append(mapped)
        res.attrs.append(
            Attribute(Attribute.LIFETIME, struct.pack('!L', lifetime)))

        if lifetime == 0 and newsock:  # close any previous listening function
            newsock.close()  # this should trigger close of functions
        else:
            if sock.type == socket.SOCK_STREAM:
                multitask.add(relayaccepter(newsock, fivetuple))
            else:
                multitask.add(relayreceiver(newsock, fivetuple))

        yield respond(sock, str(res), remote)

    def relaytcpreceiver(sock, fivetuple):
        pass

    def relayaccepter(sock, fivetuple):
        sock.listen(5)  # accept queue
        while True:  # start the main listening loop of the tcp server
            try:
                conn, remote = (yield multitask.accept(sock))
                if conn:
                    if _debug: print 'relayaccepter().accept() from', remote
                    sock.close(
                    )  # close the original listening socket -- no more connections
                    binding[fivetuple] = conn  # update the binding
                    del binding[sock]
                    binding[conn] = fivetuple
                    multitask.add(relaytcpreceiver(conn, fivetuple, remote))
                    break
            except:  # some other socket error, probably sock is closed.
                break
        if _debug: print 'relaytcpaccepter() exiting'

    def relayreceiver(sock, fivetuple):
        while True:  # start the main listening loop of the udp server
            try:
                data, remote = (yield multitask.recvfrom(sock, maxsize)
                                )  # receive a packet
                if data:
                    if _debug: print 'server().recvfrom() from', remote
                    multitask.add(datahandler(sock1, data, remote))
            except:  # some other socket error, probably sock1 is closed.
                break
        if _debug: print 'server() exiting'

    def sendRequest(sock, m, remote):  # serve the send request of TURN
        fivetuple = (sock.type, getlocaladdr(sock), remote)
        try:
            if fivetuple not in binding:  # not found
                raise ValueError, 'no turn binding found'
            newsock = binding[fivetuple]
            destaddr = Attribute.DESTINATION_ADDRESS in m and m[
                Attribute.DESTINATION_ADDRESS].address[1:] or None
            data = Attribute.DATA in m and m[Attribute.DATA] or None
            if sock.type == socket.SOCK_STREAM:
                try:
                    remote = newsock.getpeername()
                except:
                    remote = None
                if not remote:
                    newsock.connect(destaddr)
                    remote = destaddr
                yield multitask.send(newsock, data)
            else:
                yield multitask.sendto(newsock, data, destaddr)
            # TODO: we don't lock to destaddr. This is a security risk.
            result = True
        except:
            if _debug: print 'sendRequest() exception', sys.exc_info()
            result = False
        res = Message()
        res.method, res.type, res.tid = m.method, (result and Message.RESPONSE
                                                   or Message.ERROR), m.tid
        if not result:
            error = Attribute(Attribute.ERROR_CODE)
            error.error = (400, 'cannot send request'
                           )  # TODO: be more explicit.
            res.attrs.append(error)
        yield respond(sock, str(res), remote)

    def datahandler(sock, data,
                    remote):  #handle a new data from given remote (ip, port)
        try:
            m = Message(data)  # parse the message
            func = m.type == Message.REQUEST and ( \
                    m.method == Message.BINDING and bindingRequest \
                    or m.method == Message.ALLOCATE and allocateRequest \
                    or m.method == Message.SEND and sendRequest \
                    ) or None
            if func:
                yield func(sock, m, remote)
            else:
                raise ValueError, 'unhandled request or message'
        except StopIteration:
            if _debug: print 'datahandler: stop iteration'
            raise
        except:  # parsing error or unhandled message
            if _debug: print 'datahandler() exception', sys.exc_info()
            if handler:
                handler(sock, remote,
                        data)  # invoke the application's handler.

    def tcpreceiver(sock, remote):  # handle a new incoming TCP connection
        while True:
            data = (yield multitask.recv(sock, maxsize))
            if not data: break  # socket closed
            type, length, magic = struct.unpack('!HHL', data[:8])
            valid = (type & 0xC000
                     == 0) and magic == Message.MAGIC and length <= (
                         maxsize - 8)  # valid
            if valid:
                yield datahandler(sock, data, remote)
                if _debug: print 'tcpreceiver() finished data handler'
            else:
                handler(sock, data, remote)

    if tcp: sock1.listen(5)  # create the listen queue

    if _debug: print 'server listening on', addr1
    while True:  # start the main listening loop of the server
        try:
            tcp = (sock1.type == socket.SOCK_STREAM)
        except:
            break  # probably a bad file descriptor because sock1 is closed.
        try:
            if tcp:
                conn, remote = (yield multitask.accept(sock1, timeout=5))
                if conn:
                    if _debug: print 'server().accept() from', remote
                    multitask.add(tcpreceiver(conn, remote))
            else:
                data, remote = (yield multitask.recvfrom(sock1,
                                                         maxsize,
                                                         timeout=5)
                                )  # receive a packet
                if data:
                    if _debug: print 'server().recvfrom() from', remote
                    multitask.add(datahandler(sock1, data, remote))
        except multitask.Timeout:
            continue
        except:  # some other socket error, probably sock1 is closed.
            break
    if _debug: print 'server() exiting'
Beispiel #48
0
 def tcpreceiver(self):
     '''Receive incoming TCP connection.'''
     while True:
         sock, addr = yield multitask.accept(self.tcp)
         if sock:
             multitask.add(self.tcphandler(sock, addr))
Beispiel #49
0
            print msg
            print '%s: %s' % (msg.frm, msg.body.cdata)
            yield h1.send(Message(body='You said "%s"' % (msg.body.cdata)))
        except Exception, e:
            print str(type(e)), e
            break

    yield u1.logout()
    print 'testPresence exiting'


def testClose():
    yield multitask.sleep(25)
    exit()


if __name__ == '__main__':
    import doctest
    doctest.testmod()  # first run doctest,
    for f in dir():  # then run all _test* functions
        if str(f).find('_test') == 0 and callable(eval(f)):
            multitask.add(globals()[f]())
    try:
        multitask.run()
    except KeyboardInterrupt:
        pass
    except select.error:
        print 'select error'
        pass
    sys.exit()
Beispiel #50
0
def _testServerSocket():
    def testInternal():
        s1 = ServerSocket(True).start()
        s2 = ServerSocket().start()

    multitask.add(testInternal())
Beispiel #51
0
 def process(self, data): # process incoming message
     if not isinstance(data, Message): data = Message(str(data))
     self.append(data)
     def add(self, data): 
         if self._queue is not None: yield self._queue.put(data)
     multitask.add(add(self, data))
Beispiel #52
0
 def process(self, data):
     if not data: multitask.add(self.logout())
Beispiel #53
0
    def sendRTCP(self, sendbye=False):
        """Send a RTCP packet with SR or RR and SDES, and optionally BYE if sendbye is True.
        It returns the size of the packet sent."""
        reports = []
        toremove = []
        for member in self.members.values():
            if member.received > 0:
                ntp1, ntp2 = time2ntp(member.lastntp)
                lsr = ((ntp1 & 0x0FFFF) << 16) | ((ntp2 >> 16) & 0x0FFFF)
                dlsr = int((self.tc - member.lastntp) * 65536)
                member.updatelostandexpected()
                report = RTCP.packet(
                    ssrc=member.ssrc,
                    flost=member.fraction,
                    clost=member.lost,
                    hseq=member.cycles + member.maxseq,
                    jitter=int(member.jitter),
                    lsr=lsr,
                    dlsr=dlsr,
                )
                reports.append(report)
                member.received = 0
            if member.timeout == 5:  # if no packet within five RTCP intervals
                toremove.append(member.ssrc)  # schedule it to be removed
            else:
                member.timeout = member.timeout + 1
        if toremove:  # remove all timedout members
            for ssrc in toremove:
                del self.members[ssrc]

        packet = RTCP()
        if self.wesent:  # add a sender report
            p = RTCP.packet(
                pt=RTCP.SR,
                ntp=self.tc,
                ts=self.tsnow + self.ts0,
                pktcount=self.member.pktcount,
                octcount=self.member.octcount,
                reports=reports[:32],
            )
            self.wesent = False
        else:
            p = RTCP.packet(pt=RTCP.RR, reports=reports[:32])
        packet.append(p)

        if len(reports) >= 32:  # add additional RR if needed
            reports = reports[32:]
            while reports:
                p, reports = RTCP.packet(pt=RTCP.RR, reports=reports[:32]), reports[32:]
                packet.append(p)

        p = RTCP.packet(
            pt=RTCP.SDES, items=self.member.items
        )  # add SDES. Should add items only every few packets, except for CNAME which is added in every.
        packet.append(p)

        if sendbye:  # add a BYE packet as well
            p = RTCP.packet(pt=RTCP.BYE, ssrcs=[self.member.ssrc])  # Need to add a reason as well
            packet.append(p)

        data = str(packet)  # format for network data
        if self.net is not None:
            multitask.add(self.net.sendRTCP(data))  # invoke app or net to send the packet
        elif hasattr(self.app, "sendRTCP") and callable(self.app.sendRTCP):
            self.app.sendRTCP(self, data)
        elif _debug:
            print "ignoring send RTCP"
        self.rtcpsent = True
        return len(data)