Exemplo n.º 1
0
 def keepAliveResp(self, resp):
     if self.ua.state != self:
         return
     code, reason = resp.getSCode()
     if code == 401 and resp.countHFs('www-authenticate') != 0 and \
       self.ua.username != None and self.ua.password != None and not self.triedauth:
         challenge = resp.getHFBody('www-authenticate')
         req = self.ua.genRequest('INVITE', self.ua.lSDP, challenge.getNonce(), challenge.getRealm())
         self.ua.lCSeq += 1
         self.ka_tr = self.ua.global_config['_sip_tm'].newTransaction(req, self.keepAliveResp, \
           laddress = self.ua.source_address)
         self.triedauth = True
         return
     if code == 407 and resp.countHFs('proxy-authenticate') != 0 and \
       self.ua.username != None and self.ua.password != None and not self.triedauth:
         challenge = resp.getHFBody('proxy-authenticate')
         req = self.ua.genRequest('INVITE', self.ua.lSDP, challenge.getNonce(), challenge.getRealm(), SipProxyAuthorization)
         self.ua.lCSeq += 1
         self.ka_tr = self.ua.global_config['_sip_tm'].newTransaction(req, self.keepAliveResp, \
           laddress = self.ua.source_address)
         self.triedauth = True
         return
     if code < 200:
         return
     self.ka_tr = None
     self.keepalives += 1
     if code in (408, 481, 486):
         if self.keepalives == 1:
             print '%s: Remote UAS at %s:%d does not support re-INVITES, disabling keep alives' % (self.ua.cId, self.ua.rAddr[0], self.ua.rAddr[1])
             Timeout(self.ua.disconnect, 600)
             return
         print '%s: Received %d response to keep alive from %s:%d, disconnecting the call' % (self.ua.cId, code, self.ua.rAddr[0], self.ua.rAddr[1])
         self.ua.disconnect()
         return
     Timeout(self.keepAlive, self.ua.kaInterval)
Exemplo n.º 2
0
 def sendResponse(self, resp, t=None, retrans=False, ack_cb=None):
     #print self.tserver
     if t == None:
         tid = resp.getTId(wBRN=True)
         t = self.tserver[tid]
     if t.state not in (TRYING, RINGING) and not retrans:
         raise ValueError(
             'BUG: attempt to send reply on already finished transaction!!!'
         )
     scode = resp.getSCode()[0]
     toHF = resp.getHFBody('to')
     if scode > 100 and toHF.getTag() == None:
         toHF.genTag()
     t.data = resp.localStr(*t.userv.uopts.laddress, compact=t.compact)
     t.address = resp.getHFBody('via').getTAddr()
     self.transmitData(t.userv, t.data, t.address, t.checksum)
     if scode < 200:
         t.state = RINGING
         if self.provisional_retr > 0 and scode > 100:
             if t.teF != None:
                 t.teF.cancel()
             t.teF = Timeout(self.timerF, self.provisional_retr, 1, t)
     else:
         t.state = COMPLETED
         if t.teE != None:
             t.teE.cancel()
             t.teE = None
         if t.teF != None:
             t.teF.cancel()
             t.teF = None
         if t.needack:
             # Schedule removal of the transaction
             t.ack_cb = ack_cb
             t.teD = Timeout(self.timerD, 32.0, 1, t)
             if scode >= 200:
                 # Black magick to allow proxy send us another INVITE
                 # same branch and From tag. Use To tag to match
                 # ACK transaction after this point. Branch tag in ACK
                 # could differ as well.
                 del self.tserver[t.tid]
                 t.tid = list(t.tid[:-1])
                 t.tid.append(resp.getHFBody('to').getTag())
                 t.tid = tuple(t.tid)
                 self.tserver[t.tid] = t
             # Install retransmit timer if necessary
             t.tout = 0.5
             t.teA = Timeout(self.timerA, t.tout, 1, t)
         else:
             # We have done with the transaction
             del self.tserver[t.tid]
             t.cleanup()
Exemplo n.º 3
0
 def newTransaction(self, msg, resp_cb = None, laddress = None, userv = None, \
   cb_ifver = 1, compact = False):
     t = SipTransaction()
     t.rtime = time()
     t.compact = compact
     t.method = msg.getMethod()
     t.cb_ifver = cb_ifver
     t.tid = msg.getTId(True, True)
     if self.tclient.has_key(t.tid):
         raise ValueError(
             'BUG: Attempt to initiate transaction with the same TID as existing one!!!'
         )
     t.tout = 0.5
     t.fcode = None
     t.address = msg.getTarget()
     if userv == None:
         if laddress == None:
             t.userv = self.l4r.getServer(t.address)
         else:
             t.userv = self.l4r.getServer(laddress, is_local=True)
     else:
         t.userv = userv
     t.data = msg.localStr(*t.userv.uopts.laddress, compact=t.compact)
     if t.method == 'INVITE':
         try:
             t.expires = msg.getHFBody('expires').getNum()
             if t.expires <= 0:
                 t.expires = 300
         except IndexError:
             t.expires = 300
         t.needack = True
         t.ack = msg.genACK()
         t.cancel = msg.genCANCEL()
     else:
         t.expires = 32
         t.needack = False
         t.ack = None
         t.cancel = None
     t.cancelPending = False
     t.resp_cb = resp_cb
     t.teA = Timeout(self.timerA, t.tout, 1, t)
     if resp_cb != None:
         t.r408 = msg.genResponse(408, 'Request Timeout')
     t.teB = Timeout(self.timerB, 32.0, 1, t)
     t.teC = None
     t.state = TRYING
     self.tclient[t.tid] = t
     self.transmitData(t.userv, t.data, t.address)
     return t
Exemplo n.º 4
0
 def __init__(self, ua):
     self.keepalives = 0
     self.ka_tr = None
     UaStateGeneric.__init__(self, ua)
     self.ua.branch = None
     if self.ua.kaInterval > 0:
         Timeout(self.keepAlive, self.ua.kaInterval)
Exemplo n.º 5
0
 def heartbeat_reply(self, stats):
     #print 'heartbeat_reply', self.address, stats, self.online
     if self.shut_down:
         return
     if not self.online:
         return
     if stats == None:
         self.active_sessions = None
         self.go_offline()
     else:
         sessions_created = active_sessions = active_streams = preceived = ptransmitted = 0
         for line in stats.splitlines():
             line_parts = line.split(':', 1)
             if line_parts[0] == 'sessions created':
                 sessions_created = int(line_parts[1])
             elif line_parts[0] == 'active sessions':
                 active_sessions = int(line_parts[1])
             elif line_parts[0] == 'active streams':
                 active_streams = int(line_parts[1])
             elif line_parts[0] == 'packets received':
                 preceived = int(line_parts[1])
             elif line_parts[0] == 'packets transmitted':
                 ptransmitted = int(line_parts[1])
             self.update_active(active_sessions, sessions_created,
                                active_streams, preceived, ptransmitted)
     Timeout(self.heartbeat, randomize(self.hrtb_ival, 0.1))
Exemplo n.º 6
0
 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)
Exemplo n.º 7
0
 def go_offline(self):
     if self.shut_down:
         return
     #print 'go_offline', self.address, self.online
     if self.online:
         self.online = False
         Timeout(self.version_check, randomize(self.hrtb_retr_ival, 0.1))
Exemplo n.º 8
0
 def sendResponse(self, resp, t=None, retrans=False):
     #print self.tserver
     if t == None:
         tid = resp.getTId()
         t = self.tserver[tid]
     if t.state not in (TRYING, RINGING) and not retrans:
         raise ValueError(
             'BUG: attempt to send reply on already finished transaction!!!'
         )
     scode = resp.getSCode()[0]
     toHF = resp.getHFBody('to')
     if scode > 100 and toHF.getTag() == None:
         toHF.genTag()
     t.data = resp.localStr(t.userv.laddress[0], t.userv.laddress[1])
     t.address = resp.getHFBody('via').getTAddr()
     self.transmitData(t.userv, t.data, t.address, t.checksum)
     if scode < 200:
         t.state = RINGING
         if self.provisional_retr > 0 and scode > 100:
             if t.teF != None:
                 t.teF.cancel()
             t.teF = Timeout(self.timerF, self.provisional_retr, 1, t)
     else:
         t.state = COMPLETED
         if t.teE != None:
             t.teE.cancel()
             t.teE = None
         if t.teF != None:
             t.teF.cancel()
             t.teF = None
         if t.needack:
             # Schedule removal of the transaction
             t.teD = Timeout(self.timerD, 32.0, 1, t)
             if scode >= 300:
                 # Black magick to allow proxy send us another INVITE with diffetent branch
                 del self.tserver[t.tid]
                 t.tid = list(t.tid)
                 t.tid.append(t.branch)
                 t.tid = tuple(t.tid)
                 self.tserver[t.tid] = t
             # Install retransmit timer if necessary
             t.tout = 0.5
             t.teA = Timeout(self.timerA, t.tout, 1, t)
         else:
             # We have done with the transaction
             del self.tserver[t.tid]
             t.cleanup()
Exemplo n.º 9
0
 def __init__(self, ua):
     UaStateGeneric.__init__(self, ua)
     ua.on_local_sdp_change = None
     ua.on_remote_sdp_change = None
     # 300 provides good estimate on the amount of time during which
     # we can wait for receiving non-negative response to CANCELled
     # INVITE transaction.
     self.te = Timeout(self.goIdle, 300.0)
Exemplo n.º 10
0
 def version_check_reply(self, version):
     if self.shut_down:
         return
     if version == '20040107':
         self.go_online()
     elif self.online:
         self.go_offline()
     else:
         Timeout(self.version_check, randomize(self.hrtb_retr_ival, 0.1))
Exemplo n.º 11
0
 def __init__(self, global_config, req_cb=None):
     self.global_config = global_config
     self.l4r = local4remote(global_config, self.handleIncoming)
     self.tclient = {}
     self.tserver = {}
     self.req_cb = req_cb
     self.l1rcache = {}
     self.l2rcache = {}
     self.req_consumers = {}
     Timeout(self.rCachePurge, 32, -1)
Exemplo n.º 12
0
 def version_check_reply(self, version):
     if self.shutdown:
         self.worker.shutdown()
         return
     if version == '20040107':
         self.go_online()
     elif self.online:
         self.go_offline()
     else:
         Timeout(self.version_check, 60)
Exemplo n.º 13
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)
Exemplo n.º 14
0
 def version_check_reply(self, version):
     if self.shutdown:
         if self.worker != None:
             self.worker.shutdown()
             self.worker = None
         return
     if version == '20040107':
         self.go_online()
     elif self.online:
         self.go_offline()
     else:
         Timeout(self.version_check, randomize(60, 0.1))
Exemplo n.º 15
0
 def timerB(self, t):
     #print 'timerB', t
     t.teB = None
     if t.teA != None:
         t.teA.cancel()
         t.teA = None
     t.state = TERMINATED
     #print '2: Timeout(self.timerC, 32.0, 1, t)', t
     t.teC = Timeout(self.timerC, 32.0, 1, t)
     if t.resp_cb == None:
         return
     t.r408.rtime = time()
     t.resp_cb(t.r408)
Exemplo n.º 16
0
 def timerB(self, t):
     #print 'timerB', t
     t.teB = None
     if t.teA != None:
         t.teA.cancel()
         t.teA = None
     t.state = TERMINATED
     #print '2: Timeout(self.timerC, 32.0, 1, t)', t
     t.teC = Timeout(self.timerC, 32.0, 1, t)
     if t.resp_cb == None:
         return
     fake_resp = SipRequest(t.data).genResponse(408, 'Request Timeout')
     fake_resp.rtime = time()
     t.resp_cb(fake_resp)
Exemplo n.º 17
0
 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
Exemplo n.º 18
0
 def heartbeat_reply(self, stats):
     #print 'heartbeat_reply', self.address, stats, self.online
     if self.shutdown:
         self.udp_server.shutdown()
         return
     if not self.online:
         return
     if stats == None:
         self.active_sessions = None
         self.go_offline()
     else:
         for line in stats.splitlines():
             if not line.startswith('active sessions'):
                 continue
             self.update_active(int(line.split(':', 1)[1]))
     Timeout(self.heartbeat, 10)
Exemplo n.º 19
0
 def conn(self, ua, rtime, origin):
     if self.crec:
         return
     self.crec = True
     self.iTime = ua.setup_ts
     self.cTime = ua.connect_ts
     if ua.remote_ua != None and self.user_agent == None:
         self.user_agent = ua.remote_ua
     if ua.p1xx_ts != None:
         self.p1xx_ts = ua.p1xx_ts
     if ua.p100_ts != None:
         self.p100_ts = ua.p100_ts
     if self.send_start:
         self.asend('Start', rtime, origin, ua)
     self._attributes.extend((('h323-voice-quality', 0), ('Acct-Terminate-Cause', 'User-Request')))
     if self.lperiod != None and self.lperiod > 0:
         self.el = Timeout(self.asend, self.lperiod, -1, 'Alive')
Exemplo n.º 20
0
 def handle_read(self, data, address, rtime, delayed=False):
     if len(data) > 0 and self.uopts.data_callback != None:
         self.stats[2] += 1
         if self.uopts.ploss_in_rate > 0.0 and not delayed:
             if random() < self.uopts.ploss_in_rate:
                 return
         if self.uopts.pdelay_in_max > 0.0 and not delayed:
             pdelay = self.uopts.pdelay_in_max * random()
             Timeout(self.handle_read, pdelay, 1, data, address, rtime + pdelay, True)
             return
         try:
             self.uopts.data_callback(data, address, self, rtime)
         except:
             print(datetime.now(), 'Udp_server: unhandled exception when processing incoming data')
             print('-' * 70)
             traceback.print_exc(file=sys.stdout)
             print('-' * 70)
             sys.stdout.flush()
Exemplo n.º 21
0
 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)
Exemplo n.º 22
0
 def send_to(self, data, address, delayed=False):
     if not isinstance(address, tuple):
         raise Exception('Invalid address, not a tuple: %s' % str(address))
     if self.uopts.ploss_out_rate > 0.0 and not delayed:
         if random() < self.uopts.ploss_out_rate:
             return
     if self.uopts.pdelay_out_max > 0.0 and not delayed:
         pdelay = self.uopts.pdelay_out_max * random()
         Timeout(self.send_to, pdelay, 1, data, address, True)
         return
     addr, port = address
     if self.uopts.family == socket.AF_INET6:
         if not addr.startswith('['):
             raise Exception('Invalid IPv6 address: %s' % addr)
         address = (addr[1:-1], port)
     self.wi_available.acquire()
     self.wi.append((data, address))
     self.wi_available.notify()
     self.wi_available.release()
Exemplo n.º 23
0
 def timerA(self, t):
     #print 'timerA', t
     self.transmitData(t.userv, t.data, t.address)
     t.tout *= 2
     t.teA = Timeout(self.timerA, t.tout, 1, t)
Exemplo n.º 24
0
    def incomingResponse(self, msg, t, checksum):
        # In those two states upper level already notified, only do ACK retransmit
        # if needed
        if t.state == TERMINATED:
            return

        if t.state == TRYING:
            # Stop timers
            if t.teA != None:
                t.teA.cancel()
                t.teA = None

        if t.state in (TRYING, RINGING):
            if t.teB != None:
                t.teB.cancel()
                t.teB = None

            if msg.getSCode()[0] < 200:
                # Privisional response - leave everything as is, except that
                # change state and reload timeout timer
                if t.state == TRYING:
                    t.state = RINGING
                    if t.cancelPending:
                        self.newTransaction(t.cancel, userv=t.userv)
                        t.cancelPending = False
                t.teB = Timeout(self.timerB, t.expires, 1, t)
                self.l1rcache[checksum] = (None, None, None)
                if t.resp_cb != None:
                    if t.cb_ifver == 1:
                        t.resp_cb(msg)
                    else:
                        t.resp_cb(msg, t)
            else:
                # Final response - notify upper layer and remove transaction
                if t.resp_cb != None:
                    if t.cb_ifver == 1:
                        t.resp_cb(msg)
                    else:
                        t.resp_cb(msg, t)
                if t.needack:
                    # Prepare and send ACK if necessary
                    fcode = msg.getSCode()[0]
                    tag = msg.getHFBody('to').getTag()
                    if tag != None:
                        t.ack.getHFBody('to').setTag(tag)
                    rAddr = None
                    if msg.getSCode()[0] >= 200 and msg.getSCode()[0] < 300:
                        # Some hairy code ahead
                        if msg.countHFs('contact') > 0:
                            rTarget = msg.getHFBody(
                                'contact').getUrl().getCopy()
                        else:
                            rTarget = None
                        routes = [
                            x.getCopy() for x in msg.getHFBodys('record-route')
                        ]
                        routes.reverse()
                        if len(routes) > 0:
                            if not routes[0].getUrl().lr:
                                if rTarget != None:
                                    routes.append(
                                        SipRoute(address=SipAddress(
                                            url=rTarget)))
                                rTarget = routes.pop(0).getUrl()
                                rAddr = rTarget.getAddr()
                            else:
                                rAddr = routes[0].getAddr()
                        elif rTarget != None:
                            rAddr = rTarget.getAddr()
                        if rTarget != None:
                            t.ack.setRURI(rTarget)
                        if rAddr != None:
                            t.ack.setTarget(rAddr)
                        t.ack.delHFs('route')
                        t.ack.appendHeaders(
                            [SipHeader(name='route', body=x) for x in routes])
                    if fcode >= 200 and fcode < 300:
                        t.ack.getHFBody('via').genBranch()
                    if rAddr == None:
                        rAddr = t.address
                    if not t.uack:
                        self.transmitMsg(t.userv, t.ack, rAddr, checksum,
                                         t.compact)
                    else:
                        t.state = UACK
                        t.ack_rAddr = rAddr
                        t.ack_checksum = checksum
                        self.l1rcache[checksum] = (None, None, None)
                        t.teG = Timeout(self.timerG, 64, 1, t)
                        return
                else:
                    self.l1rcache[checksum] = (None, None, None)
                del self.tclient[t.tid]
                t.cleanup()
Exemplo n.º 25
0
 def go_offline(self):
     #print 'go_offline', self.address, self.online
     if self.online:
         self.online = False
         Timeout(self.version_check, 60)
Exemplo n.º 26
0
 def __init__(self, ua):
     UaStateGeneric.__init__(self, ua)
     ua.on_local_sdp_change = None
     ua.on_remote_sdp_change = None
     Timeout(self.goDead, ua.godead_timeout)
Exemplo n.º 27
0
 def go_offline(self):
     #print 'go_offline', self.address, self.online
     if self.online:
         self.online = False
         Timeout(self.version_check, randomize(60, 0.1))
Exemplo n.º 28
0
 def timerF(self, t):
     #print 'timerF', t.state
     t.teF = None
     if t.state == RINGING and self.provisional_retr > 0:
         self.transmitData(t.userv, t.data, t.address)
         t.teF = Timeout(self.timerF, self.provisional_retr, 1, t)
Exemplo n.º 29
0
 def incomingRequest(self, msg, checksum, tids, server):
     for tid in tids:
         if self.tclient.has_key(tid):
             t = self.tclient[tid]
             resp = msg.genResponse(482, 'Loop Detected')
             self.transmitMsg(server, resp, resp.getHFBody('via').getTAddr(), checksum, \
               t.compact)
             return
     if msg.getMethod() != 'ACK':
         tid = msg.getTId(wBRN=True)
     else:
         tid = msg.getTId(wTTG=True)
     t = self.tserver.get(tid, None)
     if t != None:
         #print 'existing transaction'
         if msg.getMethod() == t.method:
             # Duplicate received, check that we have sent any response on this
             # request already
             if t.data != None:
                 self.transmitData(t.userv, t.data, t.address, checksum)
             return
         elif msg.getMethod() == 'CANCEL':
             # RFC3261 says that we have to reply 200 OK in all cases if
             # there is such transaction
             resp = msg.genResponse(200, 'OK')
             self.transmitMsg(t.userv, resp, resp.getHFBody('via').getTAddr(), checksum, \
               t.compact)
             if t.state in (TRYING, RINGING):
                 self.doCancel(t, msg.rtime, msg)
         elif msg.getMethod() == 'ACK' and t.state == COMPLETED:
             t.state = CONFIRMED
             if t.teA != None:
                 t.teA.cancel()
                 t.teA = None
             t.teD.cancel()
             # We have done with the transaction, no need to wait for timeout
             del self.tserver[t.tid]
             if t.ack_cb != None:
                 t.ack_cb(msg)
             t.cleanup()
             self.l1rcache[checksum] = (None, None, None)
     elif msg.getMethod() == 'ACK':
         # Some ACK that doesn't match any existing transaction.
         # Drop and forget it - upper layer is unlikely to be interested
         # to seeing this anyway.
         print datetime.now(), 'unmatched ACK transaction - ignoring'
         sys.stdout.flush()
         self.l1rcache[checksum] = (None, None, None)
     elif msg.getMethod() == 'CANCEL':
         resp = msg.genResponse(481, 'Call Leg/Transaction Does Not Exist')
         self.transmitMsg(server, resp,
                          resp.getHFBody('via').getTAddr(), checksum)
     else:
         #print 'new transaction', msg.getMethod()
         t = SipTransaction()
         t.tid = tid
         t.state = TRYING
         t.teA = None
         t.teD = None
         t.teE = None
         t.teF = None
         t.teG = None
         t.method = msg.getMethod()
         t.rtime = msg.rtime
         t.data = None
         t.address = None
         t.noack_cb = None
         t.ack_cb = None
         t.cancel_cb = None
         t.checksum = checksum
         if server.uopts.laddress[0] not in ('0.0.0.0', '[::]'):
             t.userv = server
         else:
             # For messages received on the wildcard interface find
             # or create more specific server.
             t.userv = self.l4r.getServer(msg.getSource())
         if msg.getMethod() == 'INVITE':
             t.r487 = msg.genResponse(487, 'Request Terminated')
             t.needack = True
             t.branch = msg.getHFBody('via').getBranch()
             try:
                 e = msg.getHFBody('expires').getNum()
                 if e <= 0:
                     e = 300
             except IndexError:
                 e = 300
             t.teE = Timeout(self.timerE, e, 1, t)
         else:
             t.r487 = None
             t.needack = False
             t.branch = None
         self.tserver[t.tid] = t
         for consumer in self.req_consumers.get(t.tid[0], ()):
             cobj = consumer.cobj.isYours(msg)
             if cobj != None:
                 t.compact = consumer.compact
                 rval = cobj.recvRequest(msg, t)
                 break
         else:
             rval = self.req_cb(msg, t)
         if rval == None:
             if t.teA != None or t.teD != None or t.teE != None or t.teF != None:
                 return
             if self.tserver.has_key(t.tid):
                 del self.tserver[t.tid]
             t.cleanup()
             return
         resp, t.cancel_cb, t.noack_cb = rval
         if resp != None:
             self.sendResponse(resp, t)