Ejemplo n.º 1
0
 def reconnect(self, address, bind_address=None):
     self.address = address
     if bind_address != self.uopts.laddress:
         self.uopts.laddress = bind_address
         self.worker.shutdown()
         self.worker = Udp_server(self.global_config, self.uopts)
         self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 2
0
 def reconnect(self, address, bind_address=None):
     self.address = address
     if bind_address != self.bind_address:
         self.worker.shutdown()
         self.worker = Udp_server(self.global_config, bind_address, \
           self.process_reply, flags = 0)
         self.bind_address = bind_address
Ejemplo n.º 3
0
 def __init__(self, global_config, address, bind_address=None):
     self.address = address
     self.is_local = False
     self.worker = Udp_server(global_config, bind_address, \
       self.process_reply, flags = 0)
     self.pending_requests = {}
     self.bind_address = bind_address
     self.global_config = global_config
Ejemplo n.º 4
0
 def __init__(self, global_config, address, bind_address = None, nworkers = None):
     self.address = address
     self.is_local = False
     if nworkers == None:
         self.worker = Udp_server(global_config, bind_address, \
           self.process_reply, flags = 0)
     else:
         self.worker = Udp_server(global_config, bind_address, \
           self.process_reply, flags = 0, nworkers = nworkers)
     self.pending_requests = {}
     self.bind_address = bind_address
     self.global_config = global_config
Ejemplo n.º 5
0
class Rtp_proxy_client_udp(object):
    pending_requests = None
    is_local = False
    worker = None
    bind_address = None
    global_config = None

    def __init__(self, global_config, address, bind_address = None, nworkers = None):
        self.address = address
        self.is_local = False
        if nworkers == None:
            self.worker = Udp_server(global_config, bind_address, \
              self.process_reply, flags = 0)
        else:
            self.worker = Udp_server(global_config, bind_address, \
              self.process_reply, flags = 0, nworkers = nworkers)
        self.pending_requests = {}
        self.bind_address = bind_address
        self.global_config = global_config

    def send_command(self, command, result_callback = None, *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, 1, -1, cookie)
        self.pending_requests[cookie] = [3, timer, command, result_callback, callback_parameters]
        self.worker.send_to(command, self.address)

    def retransmit(self, cookie):
        triesleft, timer, command, result_callback, callback_parameters = self.pending_requests[cookie]
        if triesleft == 0:
            timer.cancel()
            del self.pending_requests[cookie]
            self.go_offline()
            if result_callback != None:
                result_callback(None, *callback_parameters)
            return
        self.worker.send_to(command, self.address)
        self.pending_requests[cookie][0] -= 1

    def process_reply(self, data, address, worker):
        cookie, result = data.split(None, 1)
        parameters = self.pending_requests.pop(cookie, None)
        if parameters == None:
            return
        parameters[1].cancel()
        if parameters[3] != None:
            parameters[3](result.strip(), *parameters[4])

    def reconnect(self, address, bind_address = None):
        self.address = address
        if bind_address != self.bind_address:
            self.worker.shutdown()
            self.worker = Udp_server(self.global_config, bind_address, \
              self.process_reply, flags = 0)
            self.bind_address = bind_address

    def shutdown(self):
        self.worker.shutdown()
        self.worker = None
Ejemplo n.º 6
0
 def __init__(self,
              global_config,
              address,
              bind_address=None,
              family=None,
              nworkers=None):
     self.address = address
     self.is_local = False
     self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
     self.uopts.flags = 0
     if nworkers != None:
         self.uopts.nworkers = nworkers
     self.worker = Udp_server(global_config, self.uopts)
     self.pending_requests = {}
     self.global_config = global_config
     self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 7
0
 def reconnect(self, address, bind_address = None):
     self.address = address
     if bind_address != self.bind_address:
         self.worker.shutdown()
         self.worker = Udp_server(self.global_config, bind_address, \
           self.process_reply, flags = 0)
         self.bind_address = bind_address
Ejemplo n.º 8
0
 def __init__(self, global_config, handleIncoming):
     self.global_config = global_config
     self.cache_r2l = {}
     self.cache_r2l_old = {}
     self.cache_l2s = {}
     self.handleIncoming = handleIncoming
     try:
         # Python can be compiled with IPv6 support, but if kernel
         # has not we would get exception creating the socket.
         # Workaround that by trying create socket and checking if
         # we get an exception.
         socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
     except:
         socket.has_ipv6 = False
     if 'my' in dir(global_config['_sip_address']):
         if socket.has_ipv6:
             laddresses = (('0.0.0.0', global_config['_sip_port']),
                           ('[::]', global_config['_sip_port']))
         else:
             laddresses = (('0.0.0.0', global_config['_sip_port']), )
     else:
         laddresses = ((global_config['_sip_address'],
                        global_config['_sip_port']), )
         self.fixed = True
     for laddress in laddresses:
         server = Udp_server(laddress, handleIncoming)
         self.cache_l2s[laddress] = server
Ejemplo n.º 9
0
 def reconnect(self, address, bind_address = None):
     self.address = address
     if bind_address != self.uopts.laddress:
         self.uopts.laddress = bind_address
         self.worker.shutdown()
         self.worker = Udp_server(self.global_config, self.uopts)
         self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 10
0
class Rtp_proxy_client_udp(object):
    pending_requests = None
    is_local = False

    def __init__(self, global_config, address):
        self.address = address
        self.is_local = False
        self.udp_server = Udp_server(None, self.process_reply)
        self.pending_requests = {}
        self.proxy_address = address[0]

    def send_command(self,
                     command,
                     result_callback=None,
                     *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, 1, -1, cookie)
        self.pending_requests[cookie] = [
            3, timer, command, result_callback, callback_parameters
        ]
        self.udp_server.send_to(command, self.address)

    def retransmit(self, cookie):
        triesleft, timer, command, result_callback, callback_parameters = self.pending_requests[
            cookie]
        if triesleft == 0:
            timer.cancel()
            del self.pending_requests[cookie]
            self.go_offline()
            if result_callback != None:
                result_callback(None, *callback_parameters)
            return
        self.udp_server.send_to(command, self.address)
        self.pending_requests[cookie][0] -= 1

    def process_reply(self, data, address, udp_server):
        cookie, result = data.split(None, 1)
        parameters = self.pending_requests.pop(cookie, None)
        if parameters == None:
            return
        parameters[1].cancel()
        if parameters[3] != None:
            parameters[3](result.strip(), *parameters[4])
Ejemplo n.º 11
0
 def __init__(self,
              global_config,
              address,
              bind_address=None,
              family=AF_INET,
              nworkers=None):
     # print('Rtp_proxy_client_udp(family=%s)' % family)
     self.address = self.getdestbyaddr(address, family)
     self.is_local = False
     self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
     self.uopts.flags = 0
     self.uopts.ploss_out_rate = self.ploss_out_rate
     self.uopts.pdelay_out_max = self.pdelay_out_max
     if nworkers != None:
         self.uopts.nworkers = nworkers
     self.worker = Udp_server(global_config, self.uopts)
     self.pending_requests = {}
     self.global_config = global_config
     self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 12
0
 def __init__(self, global_config, address, bind_address = None, family = None, nworkers = None):
     self.address = address
     self.is_local = False
     self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
     self.uopts.flags = 0
     if nworkers != None:
         self.uopts.nworkers = nworkers
     self.worker = Udp_server(global_config, self.uopts)
     self.pending_requests = {}
     self.global_config = global_config
     self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 13
0
 def __init__(self, global_config, address, bind_address = None, family = AF_INET, nworkers = None):
     #print('Rtp_proxy_client_udp(family=%s)' % family)
     self.address = self.getdestbyaddr(address, family)
     self.is_local = False
     self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
     self.uopts.flags = 0
     self.uopts.ploss_out_rate = self.ploss_out_rate
     self.uopts.pdelay_out_max = self.pdelay_out_max
     if nworkers != None:
         self.uopts.nworkers = nworkers
     self.worker = Udp_server(global_config, self.uopts)
     self.pending_requests = {}
     self.global_config = global_config
     self.delay_flt = recfilter(0.95, 0.25)
Ejemplo n.º 14
0
 def getServer(self, address, is_local=False):
     if self.fixed:
         return self.cache_l2s.items()[0][1]
     if not is_local:
         laddress = self.cache_r2l.get(address[0], None)
         if laddress == None:
             laddress = self.cache_r2l_old.get(address[0], None)
             if laddress != None:
                 self.cache_r2l[address[0]] = laddress
         if laddress != None:
             #print 'local4remot-1: local address for %s is %s' % (address[0], laddress[0])
             return self.cache_l2s[laddress]
         if address[0].startswith('['):
             family = socket.AF_INET6
             lookup_address = address[0][1:-1]
         else:
             family = socket.AF_INET
             lookup_address = address[0]
         self.skt = socket.socket(family, socket.SOCK_DGRAM)
         ai = socket.getaddrinfo(lookup_address, None, family)
         if family == socket.AF_INET:
             _address = (ai[0][4][0], address[1])
         else:
             _address = (ai[0][4][0], address[1], ai[0][4][2], ai[0][4][3])
         self.skt.connect(_address)
         if family == socket.AF_INET:
             laddress = (self.skt.getsockname()[0],
                         self.global_config['_sip_port'])
         else:
             laddress = ('[%s]' % self.skt.getsockname()[0],
                         self.global_config['_sip_port'])
         self.cache_r2l[address[0]] = laddress
     else:
         laddress = address
     server = self.cache_l2s.get(laddress, None)
     if server == None:
         server = Udp_server(laddress, self.handleIncoming)
         self.cache_l2s[laddress] = server
     #print 'local4remot-2: local address for %s is %s' % (address[0], laddress[0])
     return server
Ejemplo n.º 15
0
class Rtp_proxy_client_udp(object):
    pending_requests = None
    is_local = False
    worker = None
    uopts = None
    global_config = None
    delay_flt = None

    def __init__(self,
                 global_config,
                 address,
                 bind_address=None,
                 family=None,
                 nworkers=None):
        self.address = address
        self.is_local = False
        self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
        self.uopts.flags = 0
        ##self.uopts.ploss_in_rate = 0.025
        ##self.uopts.pdelay_out_max = 1.0
        if nworkers != None:
            self.uopts.nworkers = nworkers
        self.worker = Udp_server(global_config, self.uopts)
        self.pending_requests = {}
        self.global_config = global_config
        self.delay_flt = recfilter(0.95, 0.025)

    def send_command(self,
                     command,
                     result_callback=None,
                     *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        next_retr = self.delay_flt.lastval * 4.0
        rtime = 3.0
        if isinstance(command, Rtp_proxy_cmd):
            if command.type == 'I':
                rtime = 10.0
            if command.type == 'G':
                rtime = 1.0
            nretr = command.nretr
            command = str(command)
        else:
            if command.startswith('I'):
                rtime = 10.0
            elif command.startswith('G'):
                rtime = 1.0
            nretr = None
        if nretr == None:
            nretr = getnretrans(next_retr, rtime)
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        stime = MonoTime()
        self.worker.send_to(command, self.address)
        nretr -= 1
        self.pending_requests[cookie] = (next_retr, nretr, timer, command,
                                         result_callback, stime,
                                         callback_parameters)

    def retransmit(self, cookie):
        next_retr, triesleft, timer, command, result_callback, stime, callback_parameters = self.pending_requests[
            cookie]
        #print 'command to %s timeout %s cookie %s triesleft %d' % (str(self.address), command, cookie, triesleft)
        if triesleft <= 0 or self.worker == None:
            del self.pending_requests[cookie]
            self.go_offline()
            if result_callback != None:
                result_callback(None, *callback_parameters)
            return
        #next_retr *= 2
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        stime = MonoTime()
        self.worker.send_to(command, self.address)
        triesleft -= 1
        self.pending_requests[cookie] = (next_retr, triesleft, timer, command,
                                         result_callback, stime,
                                         callback_parameters)

    def process_reply(self, data, address, worker, rtime):
        try:
            cookie, result = data.split(None, 1)
        except:
            print('Rtp_proxy_client_udp.process_reply(): invalid response %s' %
                  data)
            return
        parameters = self.pending_requests.pop(cookie, None)
        if parameters == None:
            return
        next_retr, triesleft, timer, command, result_callback, stime, callback_parameters = parameters
        timer.cancel()
        if result_callback != None:
            result_callback(result.strip(), *callback_parameters)
        ##self.delay_flt.apply(rtime - stime)
        #print 'Rtp_proxy_client_udp.process_reply(): delay %f' % (rtime - stime)

    def reconnect(self, address, bind_address=None):
        self.address = address
        if bind_address != self.uopts.laddress:
            self.uopts.laddress = bind_address
            self.worker.shutdown()
            self.worker = Udp_server(self.global_config, self.uopts)
            self.delay_flt = recfilter(0.95, 0.25)

    def shutdown(self):
        self.worker.shutdown()
        self.worker = None

    def get_rtpc_delay(self):
        return self.delay_flt.lastval
Ejemplo n.º 16
0
 def __init__(self, global_config, address):
     self.address = address
     self.is_local = False
     self.udp_server = Udp_server(None, self.process_reply)
     self.pending_requests = {}
     self.proxy_address = address[0]
Ejemplo n.º 17
0
 def __init__(self, global_config, address):
     self.udp_server = Udp_server(None, self.process_reply)
     self.pending_requests = {}
     self.address = address
     self.proxy_address = address[0]
     self.heartbeat()
Ejemplo n.º 18
0
class Rtp_proxy_client_udp(object):
    udp_server = None
    pending_requests = None
    address = None
    online = False
    copy_supported = False
    stat_supported = False
    tnot_supported = False
    shutdown = False
    proxy_address = None
    caps_done = False

    def __init__(self, global_config, address):
        self.udp_server = Udp_server(None, self.process_reply)
        self.pending_requests = {}
        self.address = address
        self.proxy_address = address[0]
        self.heartbeat()

    def send_command(self, command, result_callback = None, *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, 1, -1, cookie)
        self.pending_requests[cookie] = [3, timer, command, result_callback, callback_parameters]
        self.udp_server.send_to(command, self.address)

    def retransmit(self, cookie):
        triesleft, timer, command, result_callback, callback_parameters = self.pending_requests[cookie]
        if triesleft == 0:
            timer.cancel()
            del self.pending_requests[cookie]
            self.online = False
            if result_callback != None:
                result_callback(None, *callback_parameters)
            return
        self.udp_server.send_to(command, self.address)
        self.pending_requests[cookie][0] -= 1

    def process_reply(self, data, address, udp_server):
        cookie, result = data.split(None, 1)
        parameters = self.pending_requests.pop(cookie, None)
        if parameters == None:
            return
        parameters[1].cancel()
        if parameters[3] != None:
            parameters[3](result.strip(), *parameters[4])

    def caps_query1(self, result):
        if self.shutdown:
            return
        if result != '1':
            if result != None:
                self.copy_supported = False
                self.stat_supported = False
                self.tnot_supported = False
                self.caps_done = True
            Timeout(self.heartbeat, 60)
            return
        self.copy_supported = True
        self.send_command('VF 20080403', self.caps_query2)

    def caps_query2(self, result):
        if self.shutdown:
            return
        if result != None:
            if result == '1':
                self.stat_supported = True
                self.send_command('VF 20081224', self.caps_query3)
                return
            else:
                self.stat_supported = False
                self.tnot_supported = False
                self.caps_done = True
        Timeout(self.heartbeat, 60)

    def caps_query3(self, result):
        if self.shutdown:
            return
        if result != None:
            if result == '1':
                self.tnot_supported = True
            else:
                self.tnot_supported = False
            self.caps_done = True
        Timeout(self.heartbeat, 60)

    def heartbeat(self):
        self.send_command('V', self.heartbeat_reply)

    def heartbeat_reply(self, version):
        if self.shutdown:
            return
        if version == '20040107':
            self.online = True
            if not self.caps_done:
                self.send_command('VF 20071218', self.caps_query1)
                return
        else:
            self.online = False
        Timeout(self.heartbeat, 60)
Ejemplo n.º 19
0
class Rtp_proxy_client_udp(object):
    pending_requests = None
    is_local = False
    worker = None
    uopts = None
    global_config = None
    delay_flt = None
    ploss_out_rate = 0.0
    pdelay_out_max = 0.0

    def __init__(self, global_config, address, bind_address = None, family = None, nworkers = None):
        self.address = address
        self.is_local = False
        self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
        self.uopts.flags = 0
        self.uopts.ploss_out_rate = self.ploss_out_rate
        self.uopts.pdelay_out_max = self.pdelay_out_max
        if nworkers != None:
            self.uopts.nworkers = nworkers
        self.worker = Udp_server(global_config, self.uopts)
        self.pending_requests = {}
        self.global_config = global_config
        self.delay_flt = recfilter(0.95, 0.25)

    def send_command(self, command, result_callback = None, *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        next_retr = self.delay_flt.lastval * 4.0
        exp_time = 3.0
        if isinstance(command, Rtp_proxy_cmd):
            if command.type == 'I':
                exp_time = 10.0
            if command.type == 'G':
                exp_time = 1.0
            nretr = command.nretr
            command = str(command)
        else:
            if command.startswith('I'):
                exp_time = 10.0
            elif command.startswith('G'):
                exp_time = 1.0
            nretr = None
        if nretr == None:
            nretr = getnretrans(next_retr, exp_time)
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        preq = Rtp_proxy_pending_req(next_retr, nretr - 1, timer, command, \
          result_callback, callback_parameters)
        self.worker.send_to(command, self.address)
        self.pending_requests[cookie] = preq

    def retransmit(self, cookie):
        preq = self.pending_requests[cookie]
        #print 'command to %s timeout %s cookie %s triesleft %d' % (str(self.address), preq.command, cookie, preq.triesleft)
        if preq.triesleft <= 0 or self.worker == None:
            del self.pending_requests[cookie]
            self.go_offline()
            if preq.result_callback != None:
                preq.result_callback(None, *preq.callback_parameters)
            return
        preq.retransmits += 1
        preq.next_retr *= 2
        preq.timer = Timeout(self.retransmit, preq.next_retr, 1, cookie)
        self.worker.send_to(preq.command, self.address)
        preq.triesleft -= 1

    def go_offline(self):
        # To be replaced in the upper level class
        pass

    def process_reply(self, data, address, worker, rtime):
        try:
            cookie, result = data.split(None, 1)
        except:
            print('Rtp_proxy_client_udp.process_reply(): invalid response from %s: "%s"' % \
              (str(address), data))
            return
        preq = self.pending_requests.pop(cookie, None)
        if preq == None:
            return
        preq.timer.cancel()
        if rtime <= preq.stime:
            # MonoTime as the name suggests is supposed to be monotonic,
            # so if we get response earlier than request went out something
            # is very wrong. Fail immediately.
            rtime_fix = MonoTime()
            raise AssertionError('cookie=%s: MonoTime stale/went' \
              ' backwards (%f <= %f, now=%f)' % (cookie, rtime.monot, \
              preq.stime.monot, rtime_fix.monot))
        if preq.result_callback != None:
            preq.result_callback(result.strip(), *preq.callback_parameters)

        # When we had to do retransmit it is not possible to figure out whether
        # or not this reply is related to the original request or one of the
        # retransmits. Therefore, using it to estimate delay could easily produce
        # bogus value that is too low or even negative if we cook up retransmit
        # while the original response is already in the queue waiting to be
        # processed. This should not be a big issue since UDP command channel does
        # not work very well if the packet loss goes to more than 30-40%.
        if preq.retransmits == 0:
            self.delay_flt.apply(rtime - preq.stime)
            #print 'Rtp_proxy_client_udp.process_reply(): delay %f' % (rtime - preq.stime)

    def reconnect(self, address, bind_address = None):
        self.address = address
        if bind_address != self.uopts.laddress:
            self.uopts.laddress = bind_address
            self.worker.shutdown()
            self.worker = Udp_server(self.global_config, self.uopts)
            self.delay_flt = recfilter(0.95, 0.25)

    def shutdown(self):
        self.worker.shutdown()
        self.worker = None

    def get_rtpc_delay(self):
        return self.delay_flt.lastval
Ejemplo n.º 20
0
class Rtp_proxy_client_udp(Rtp_proxy_client_net):
    pending_requests = None
    is_local = False
    worker = None
    uopts = None
    global_config = None
    delay_flt = None
    ploss_out_rate = 0.0
    pdelay_out_max = 0.0
    sock_type = SOCK_DGRAM

    def __init__(self,
                 global_config,
                 address,
                 bind_address=None,
                 family=AF_INET,
                 nworkers=None):
        # print('Rtp_proxy_client_udp(family=%s)' % family)
        self.address = self.getdestbyaddr(address, family)
        self.is_local = False
        self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
        self.uopts.flags = 0
        self.uopts.ploss_out_rate = self.ploss_out_rate
        self.uopts.pdelay_out_max = self.pdelay_out_max
        if nworkers != None:
            self.uopts.nworkers = nworkers
        self.worker = Udp_server(global_config, self.uopts)
        self.pending_requests = {}
        self.global_config = global_config
        self.delay_flt = recfilter(0.95, 0.25)

    def send_command(self,
                     command,
                     result_callback=None,
                     *callback_parameters):
        entropy = str(random()) + str(time())
        cookie = md5(entropy.encode()).hexdigest()
        next_retr = self.delay_flt.lastval * 4.0
        exp_time = 3.0
        if isinstance(command, Rtp_proxy_cmd):
            if command.type == 'I':
                exp_time = 10.0
            if command.type == 'G':
                exp_time = 1.0
            nretr = command.nretr
            command = str(command)
        else:
            if command.startswith('I'):
                exp_time = 10.0
            elif command.startswith('G'):
                exp_time = 1.0
            nretr = None
        if nretr == None:
            nretr = getnretrans(next_retr, exp_time)
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        preq = Rtp_proxy_pending_req(next_retr, nretr - 1, timer, command, \
                                     result_callback, callback_parameters)
        self.worker.send_to(command, self.address)
        self.pending_requests[cookie] = preq

    def retransmit(self, cookie):
        preq = self.pending_requests[cookie]
        # print('command to %s timeout %s cookie %s triesleft %d' % (str(self.address), preq.command, cookie, preq.triesleft))
        if preq.triesleft <= 0 or self.worker == None:
            del self.pending_requests[cookie]
            self.go_offline()
            if preq.result_callback != None:
                preq.result_callback(None, *preq.callback_parameters)
            return
        preq.retransmits += 1
        preq.next_retr *= 2
        preq.timer = Timeout(self.retransmit, preq.next_retr, 1, cookie)
        self.worker.send_to(preq.command, self.address)
        preq.triesleft -= 1

    def go_offline(self):
        # To be replaced in the upper level class
        pass

    def process_reply(self, data, address, worker, rtime):
        try:
            cookie, result = data.split(None, 1)
        except:
            print('Rtp_proxy_client_udp.process_reply(): invalid response from %s: "%s"' % \
                  (str(address), data))
            return
        preq = self.pending_requests.pop(cookie, None)
        if preq == None:
            return
        preq.timer.cancel()
        if rtime <= preq.stime:
            # MonoTime as the name suggests is supposed to be monotonic,
            # so if we get response earlier than request went out something
            # is very wrong. Fail immediately.
            rtime_fix = MonoTime()
            raise AssertionError('cookie=%s: MonoTime stale/went' \
                                 ' backwards (%f <= %f, now=%f)' % (cookie, rtime.monot, \
                                                                    preq.stime.monot, rtime_fix.monot))
        if preq.result_callback != None:
            preq.result_callback(result.strip(), *preq.callback_parameters)

        # When we had to do retransmit it is not possible to figure out whether
        # or not this reply is related to the original request or one of the
        # retransmits. Therefore, using it to estimate delay could easily produce
        # bogus value that is too low or even negative if we cook up retransmit
        # while the original response is already in the queue waiting to be
        # processed. This should not be a big issue since UDP command channel does
        # not work very well if the packet loss goes to more than 30-40%.
        if preq.retransmits == 0:
            self.delay_flt.apply(rtime - preq.stime)
            # print('Rtp_proxy_client_udp.process_reply(): delay %f' % (rtime - preq.stime))

    def reconnect(self, address, bind_address=None):
        # print('reconnect', address)
        address = self.getdestbyaddr(address, self.uopts.family)
        self.rtpp_class._reconnect(self, address, bind_address)

    def _reconnect(self, address, bind_address=None):
        self.address = address
        if bind_address != self.uopts.laddress:
            self.uopts.laddress = bind_address
            self.worker.shutdown()
            self.worker = Udp_server(self.global_config, self.uopts)
            self.delay_flt = recfilter(0.95, 0.25)

    def shutdown(self):
        self.worker.shutdown()
        self.worker = None

    def get_rtpc_delay(self):
        return self.delay_flt.lastval
Ejemplo n.º 21
0
 def __init__(self, global_config, address):
     self.address = address
     self.is_local = False
     self.udp_server = Udp_server(None, self.process_reply)
     self.pending_requests = {}
     self.proxy_address = address[0]
Ejemplo n.º 22
0
class Rtp_proxy_client_udp(object):
    pending_requests = None
    is_local = False
    worker = None
    uopts = None
    global_config = None
    delay_flt = None

    def __init__(self, global_config, address, bind_address = None, family = None, nworkers = None):
        self.address = address
        self.is_local = False
        self.uopts = Udp_server_opts(bind_address, self.process_reply, family)
        self.uopts.flags = 0
        ##self.uopts.ploss_in_rate = 0.025
        ##self.uopts.pdelay_out_max = 1.0
        if nworkers != None:
            self.uopts.nworkers = nworkers
        self.worker = Udp_server(global_config, self.uopts)
        self.pending_requests = {}
        self.global_config = global_config
        self.delay_flt = recfilter(0.95, 0.025)

    def send_command(self, command, result_callback = None, *callback_parameters):
        cookie = md5(str(random()) + str(time())).hexdigest()
        next_retr = self.delay_flt.lastval * 4.0
        rtime = 3.0
        if isinstance(command, Rtp_proxy_cmd):
            if command.type == 'I':
                rtime = 10.0
            if command.type == 'G':
                rtime = 1.0
            nretr = command.nretr
            command = str(command)
        else:
            if command.startswith('I'):
                rtime = 10.0
            elif command.startswith('G'):
                rtime = 1.0
            nretr = None
        if nretr == None:
            nretr = getnretrans(next_retr, rtime)
        command = '%s %s' % (cookie, command)
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        stime = MonoTime()
        self.worker.send_to(command, self.address)
        nretr -= 1
        self.pending_requests[cookie] = (next_retr, nretr, timer, command, result_callback, stime, callback_parameters)

    def retransmit(self, cookie):
        next_retr, triesleft, timer, command, result_callback, stime, callback_parameters = self.pending_requests[cookie]
        #print 'command to %s timeout %s cookie %s triesleft %d' % (str(self.address), command, cookie, triesleft)
        if triesleft <= 0 or self.worker == None:
            del self.pending_requests[cookie]
            self.go_offline()
            if result_callback != None:
                result_callback(None, *callback_parameters)
            return
        #next_retr *= 2
        timer = Timeout(self.retransmit, next_retr, 1, cookie)
        stime = MonoTime()
        self.worker.send_to(command, self.address)
        triesleft -= 1
        self.pending_requests[cookie] = (next_retr, triesleft, timer, command, result_callback, stime, callback_parameters)

    def process_reply(self, data, address, worker, rtime):
        try:
            cookie, result = data.split(None, 1)
        except:
            print('Rtp_proxy_client_udp.process_reply(): invalid response %s' % data)
            return
        parameters = self.pending_requests.pop(cookie, None)
        if parameters == None:
            return
        next_retr, triesleft, timer, command, result_callback, stime, callback_parameters = parameters
        timer.cancel()
        if result_callback != None:
            result_callback(result.strip(), *callback_parameters)
        ##self.delay_flt.apply(rtime - stime)
        #print 'Rtp_proxy_client_udp.process_reply(): delay %f' % (rtime - stime)

    def reconnect(self, address, bind_address = None):
        self.address = address
        if bind_address != self.uopts.laddress:
            self.uopts.laddress = bind_address
            self.worker.shutdown()
            self.worker = Udp_server(self.global_config, self.uopts)
            self.delay_flt = recfilter(0.95, 0.25)

    def shutdown(self):
        self.worker.shutdown()
        self.worker = None

    def get_rtpc_delay(self):
        return self.delay_flt.lastval