Ejemplo n.º 1
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

        def tcpreceiver(sock,
                        remote): # handle the messages on the given TCP connection.
            while True:
                data = yield multitask.recv(sock, maxsize)
                if _debug: print '%r=>%r on type=%r\n%s' % (
                    remote, sock.getsockname(), sock.type, data)
                if data: stack.received(data, remote)

        while True:
            if sock.type == socket.SOCK_DGRAM:
                data, remote = yield multitask.recvfrom(sock, maxsize)
                if _debug: print '%r=>%r on type=%r\n%s' % (
                    remote, sock.getsockname(), sock.type, data)
                if data: stack.received(data, remote)
            elif sock.type == socket.SOCK_STREAM:
                conn, remote = yield multitask.accept(sock)
                if conn:
                    self.conn[remote] = conn
                    multitask.add(tcpreceiver(conn, remote))
            else:
                raise ValueError, 'invalid socket type'
Ejemplo n.º 2
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

        def tcpreceiver(
                sock,
                remote):  # handle the messages on the given TCP connection.
            while True:
                data = yield multitask.recv(sock, maxsize)
                if _debug:
                    print '%r=>%r on type=%r\n%s' % (
                        remote, sock.getsockname(), sock.type, data)
                if data: stack.received(data, remote)

        while True:
            if sock.type == socket.SOCK_DGRAM:
                data, remote = yield multitask.recvfrom(sock, maxsize)
                if _debug:
                    print '%r=>%r on type=%r\n%s' % (
                        remote, sock.getsockname(), sock.type, data)
                if data: stack.received(data, remote)
            elif sock.type == socket.SOCK_STREAM:
                conn, remote = yield multitask.accept(sock)
                if conn:
                    self.conn[remote] = conn
                    multitask.add(tcpreceiver(conn, remote))
            else:
                raise ValueError, 'invalid socket type'
Ejemplo n.º 3
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'
Ejemplo n.º 4
0
def echo_server(hostname, port):
    addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
    (family, socktype, proto, canonname, sockaddr) = addrinfo[0]
    with closing(socket.socket(family, socktype, proto)) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind(sockaddr)
        sock.listen(5)
        while True:
            multitask.add(client_handler((yield multitask.accept(sock))[0]))
Ejemplo n.º 5
0
def echo_server(hostname, port):
    addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC,
                                  socket.SOCK_STREAM)
    (family, socktype, proto, canonname, sockaddr) = addrinfo[0]
    with closing(socket.socket(family, socktype, proto)) as sock:
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.bind(sockaddr)
        sock.listen(5)
        while True:
            multitask.add(client_handler((yield multitask.accept(sock))[0]))
Ejemplo n.º 6
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'
Ejemplo n.º 7
0
 def run(self):
     try:
         while True:
             sock, remote = (yield multitask.accept(self.sock))  # receive client TCP
             if sock == None:
                 if _debug: print 'rtmp.Server accept(sock) returned None.' 
                 break
             if _debug: print 'connection received from', remote
             sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # make it non-block
             client = Client(sock, self)
     except: 
         if _debug: print 'rtmp.Server exception ', (sys and sys.exc_info() or None)
     
     if (self.sock):
         try: self.sock.close(); self.sock = None
         except: pass
     if (self.queue):
         yield self.queue.put((None, None))
         self.queue = None
Ejemplo n.º 8
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'
Ejemplo n.º 9
0
def echo_server(hostname, port):
	addrinfo = socket.getaddrinfo(hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM)
	(family, socktype, proto, canoname, sockaddr) = addrinfo[0]
	with closing(socket.socket(family, socktype, proto)) as sock:
		sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		sock.bind(sockaddr)
		sock.listen(5)
		while True:
			multitask.add(client_handler(yield multitask.accept(sock))[0])

	if __name__ == '__main__':
		import sys
		hostname = None
		port = 1111
		if len(sys.argv) > 1:
			hostname = sys.argv[1]
		if len(sys.argv) > 2:
			port = int(sys.argv[2])
		multitask.add(echo_server(hostname, port))
		try:
			multitask.run()
		except KeyboardInterrupt:
			pass
Ejemplo n.º 10
0
def listener(sock):
    while True:
        conn, address = (yield multitask.accept(sock))
        multitask.add(client_handler(conn))
Ejemplo n.º 11
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'
Ejemplo n.º 12
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))
Ejemplo n.º 13
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))
Ejemplo n.º 14
0
def accept_connections(sock):
    with closing(sock):
        while True:
            conn = (yield multitask.accept(sock))
            multitask.add(handle_connection(*conn))
Ejemplo n.º 15
0
def listener(sock):
    while True:
        conn, address = (yield multitask.accept(sock))
        multitask.add(client_handler(conn))
Ejemplo n.º 16
0
def accept_connections(sock):
    with closing(sock):
        while True:
            conn = (yield multitask.accept(sock))
            multitask.add(handle_connection(*conn))