📄 np_tcp.py
字号:
self.mach.logfun(str) self.rcv_wnd = p.window self.snd_highack = ack ## remove acked pkts from received list #print'#%d ack = %d\nrcv list =' % (p.indx, ack) #for p in self.rcv_segs: #p.printself_rel() p_acked = 0 rtt = 0 llen = len(self.rcv_segs) while llen: pkt = self.rcv_segs[0] highseq = seq_add(pkt.seq, pkt.len) if seq_lte(highseq, ack): if ack == highseq: rtt = p.tm - pkt.tm p.arrseg2ack_rtt = rtt self.rcv_segs.pop(0) llen = llen -1 p_acked = p_acked + 1 else: break## if p_acked:## print '%s#%d dep acked %d ack_rtt = %.3f' % (self.nm, ## p.indx, p_acked, rtt/1000.0) ############################################################################### # Size of separting seg makes sense?# - does it suggest advertised mss is not being used?# def check_segsz(self, p): trace = 1 #IFFY_SEGSZ_THRESH = 2 IFFY_SEGSZ_THRESH = 4 plen = p.len self.maxseg = MAX(self.maxseg, plen) if plen >= self.maxseg and plen != self.segsz: #cprint(F_BLUE, '%s#%d seg %d not mss %d' % (self.nm, p.indx, plen, self.segsz)) self.segiffy = self.segiffy + 1 if not self.segiffy_szs.has_key(plen): self.segiffy_szs[plen] = 1 else: self.segiffy_szs[plen] = self.segiffy_szs[plen]+1 if self.dep_octs > self.segsz*IFFY_SEGSZ_THRESH and self.segiffy_szs[plen]*IFFY_SEGSZ_THRESH > self.dep_segs: ## nm = self.imp.new_name('_MSS', plen)## if trace and self.trace:## inform('%s#%d trying new mss %d imp name %s' % (self.nm, p.indx, plen, nm))## self.new_imp = self.imp.clone(nm)## self.new_imp.mss = plen self.retry(self.imp.clone([('mss', plen), ('nmss', self.segsz)])) ############################################################################## ## Check seq no. of segment# def check_segseq(self, p): trace = 1 seq = p.seq end = p.end if seq == self.snd_nxt: self.snd_nxt = end # TODO - check len within snd wnd elif seq_gt(seq, self.snd_nxt): # there's a gap if trace and self.trace: print '%s#%d seg departing - seq gap' % (self.nm, p.indx) #p.remark = 1 p.markers = p.markers | P_SEQ_HELD self.snd_segheld.append(p) elif seq_gt(end, self.snd_nxt): # some o'lap if trace and self.trace: print '%s#%d seg departing - overlap' % (self.nm, p.indx) self.snd_olap_p = self.snd_olap_p + 1 self.snd_olap_o = self.snd_olap_o + seq_sub(self.snd_nxt, seq) self.snd_nxt = end #p.remark = 1 p.markers = p.markers | P_SEQ_OLAP else: if trace and self.trace: cprint(F_RED, '%s#%d seg departing - dup pkt' % (self.nm, p.indx)) p.remark = 1 # totally duplicated self.snd_rtmts_p = self.snd_rtmts_p + 1 self.snd_rtmts_o = self.snd_rtmts_o + p.len p.markers = p.markers | P_SEQ_RTMT # remove from sent list self.snd_segs.pop() #return ############################################################################### # Chech the departing segment against pending releases# def cmp_release(self, p): trace = 1 seq = p.seq end = p.end plen = p.len if not len(self.releases): # no releases pending #p.remark = 1 str = 'TCPConn #%d SEG DEPARTING: - No releases: %s#%d' % (self.connid, self.nm, p.indx) if trace and self.trace: whoops(str) self.mach.logfun(str) elif end > self.releases[-1].end: # outside window #p.remark = 1 str = 'TCPConn #%d SEG END EXCEEDS HIGH RELEASE: %s#%d seg %d-%d last release %d-%d' % (self.connid, self.nm, p.indx, seq, end, self.releases[-1].start, self.releases[-1].end) if trace and self.trace: inform(str) self.print_releases() self.mach.logfun(str) for d in range(len(self.releases)): # loop to catch pkts spanning releases rel = self.releases[0] sdiff, ediff = rel.seq_cmp(seq, end) if trace and self.trace: print '%s#%d rel by %d sdiff %d ediff %d' % (self.nm, p.indx, rel.ack_pkt.indx, sdiff, ediff) if sdiff >= 0: # seg starts at or before release if sdiff + plen < 0: # ends before release - retransmission? if not (p.markers & P_SEQ_RTMT): #p.remark = 1 str = 'TCPConn #%d SEG BEFORE RELEASES - NOT RETRANSMIT: %s#%d seg %d - %d rel %d - %d (%d)' % (self.connid, self.nm, p.indx, seq, end, rel.start, rel.end, rel.highseq) if trace and self.trace: whoops(str) self.mach.logfun(str) break else: # its the next seg expected #last part of pkt within this release? - trim if trace and self.trace: print '%s#%d last part within release' % (self.nm, p.indx) plen = plen - sdiff if trace and self.trace: print '%s#%d in release %d - %d ( by %d) pkt %d of release ' % (self.nm, p.indx, rel.start, rel.end, rel.ack_pkt.indx, rel.pkts_released), if rel.pkts_released == 0: rtm = rel.ack_pkt.tm if trace and self.trace: print ' - first of release', if p.trig != TRIG_SYNACK: if rtm + self.last_valid_prtt.prtt > self.lastp.tm: # release after prev pkt -> valid prtt p.trig = TRIG_REL p.lag = p.tm - rtm if trace and self.trace: print 'rel lag = %.3f' % (p.lag/1000.0), else: p.trig = TRIG_PREV p.lag = p.tm - self.lastp.tm if ediff == 0: # last seg of release if trace and self.trace: print '- completes release' #p.rel = rel rel.pkts_released = rel.pkts_released + 1 rel.highseq = end rel.range = rel.range - plen if rel.range != 0: if trace and self.trace: whoops('%s#%d complete rel range' % (self.nm, p.indx)) if trace and self.trace: print '%s#%d popping release %d-%d' % (self.nm, p.indx, self.releases[0].start, self.releases[0].end) self.releases.pop(0) self.check_rel_cause(p, rel) break elif ediff > 0: if trace and self.trace: print ' - within release' # seg doesn't complete release #p.rel = rel rel.pkts_released = rel.pkts_released + 1 rel.highseq = end rel.range = rel.range - plen self.check_rel_cause(p, rel) break else: if trace and self.trace: print ' - last of release + balance of segment left' # seg o'laps next release #seq = rel.end #plen = plen + ediff rel.highseq = end rel.pkts_released = rel.pkts_released + 1 rel.range = rel.range - plen - ediff if rel.range != 0: p.remark = 1 if trace and self.trace: whoops('%s#%d rel range' % (self.nm, p.indx)) self.releases.pop(0) if not len(self.releases): if trace and self.trace: whoops('end of segment beyond release') continue else: # seg starts after release #\p.remark = 1 str = 'TCPConn #%d SEG AFTER RELEASE: %s#%d seq = %d r = #%d %d-%d' % (self.connid, self.nm, p.indx, seq, rel.ack_pkt.indx, rel.start, rel.end) if trace and self.trace: whoops(str) self.mach.logfun(str) # tmp #raise TCPNoModel()############################################################################## def check_rel_cause(self, p, rel): # # Identify packet send trigger cause over-riding TCP mechanisms # trace = 1 gotit = 0 p.tstr = '' dir = self.dir tm = p.tm ttms = self.ttms if ttms != None: rqs = ttms.rqs rqe = ttms.rqe rps = ttms.rps rpe = ttms.rpe rapt = rel.ack_pkt.tm #last_prtt = self.last_valid_prtt.prtt #raptbk = rapt + last_prtt # is this the first or last of an HTTP reply? if dir == SERVER and ttms != None: gdel = TRIG_SERV_DEL repi = self.repi # may be > 1 per pkt while 1: if tm == rps: # first seg of response if trace and self.trace: print '%s#%d First of response %d' % (self.nm, p.indx, repi), if len(p.tstr) == 12: p.tstr += '\n' p.tstr += '(%d' % (repi) if not gotit: gotit = 1 last_prtt = self.last_valid_prtt.prtt raptbk = rapt + last_prtt rqebk = rqe + last_prtt if repi > 0: #there's a previous transaction latest = MAX3(self.mach.ttms[repi-1].rpe, rqebk, raptbk) #print 'latest of %.3f %.3f %.3f = %.3f' % (self.mach.ttms[repi-1].rpe/1000.00, rqe/1000.00, rapt/1000.00, latest/1000.00) else: latest = MAX(rqebk, raptbk) if latest == rqebk: #released by request arrival if trace and self.trace: print '%s#%d - released by req at %.3f' % (self.nm, p.indx, latest/1000.0) if repi == 0: p.trig = TRIG_RESP_FIRST #print 'TRIG_RESP_FIRST' else: p.trig = TRIG_RESP_DEL #print 'TRIG_RESP_DEL' p.lag = tm - rqe elif latest == raptbk: # released by an arriving ack if trace and self.trace: print '%s#%d - released by ACK at %.3f pkt %d' % (self.nm, p.indx, latest/1000.0, rel.ack_pkt.indx) p.trig = TRIG_RESP_REL #print 'TRIG_RESP_REL' p.lag = tm - rapt else: # released by completion of last response if trace and self.trace: print '%s#%d - released by prev response at %.3f' % (self.nm, p.indx, latest/1000.0) p.trig = TRIG_RESP_Q #print 'TRIG_RESP_Q' p.lag = tm - rpe elif trace and self.trace: print if tm == rpe: # last seg of response p.markers |= P_RLAST if trace and self.trace: print '%s#%d last of response %d' % (self.nm, p.indx, repi) if len(p.tstr): p.tstr += ')' else: p.tstr += '%d)' % (repi) repi += 1 try: ttms = self.mach.ttms[repi] rqs = ttms.rqs rqe = ttms.rqe rps = ttms.rps rpe = ttms.rpe except IndexError: # may be out of transactions ttms = None rqs = None rqe = None rps = None rpe = None break else: self.reverse.repi += 1*self.segsz else: # wont be another start break self.ttms = ttms self.repi = repi # is this the first or last of an HTTP request? if dir == CLIENT and ttms != None: reqi = self.reqi gdel = TRIG_CLI_DEL while 1: if tm == rqs: if trace and self.trace: print '%s#%d First of request %d' % (self.nm, p.indx, reqi), if len(p.tstr) == 12: p.tstr += '\n' p.tstr += '(%d' % (reqi) if not gotit: gotit = 1 if reqi == 0: if trace and self.trace: print '%s#%d - released by SYNACK at %.3f' % (self.nm, p.indx, self.snd_synacks[-1].tm/1000.0) p.trig = TRIG_REQ_FIRST p.lag = tm - self.snd_synacks[-1].tm else: #there's a previous transaction last_prtt = self.last_valid_prtt.prtt raptbk = rapt + last_prtt prev_rqe = self.mach.ttms[reqi-1].rqe prev_rpe = self.mach.ttms[reqi-1].rpe prev_rpebk = prev_rpe + last_prtt if prev_rpebk < tm: # prev response received latest = MAX3(prev_rqe, prev_rpebk, raptbk) #print 'latest of %.3f %.3f %.3f = %.3f' % (prev_rqe/1000.00, prev_rpe/1000.00, rapt/1000.00, latest/1000.00) else: latest = MAX(prev_rqe, raptbk) if latest == prev_rpebk: # released by completion of last response p.trig = TRIG_REQ_DEL p.lag = tm - prev_rpe if trace and self.trace: print '%s#%d - released by resp at %.3f lag = %.3f' % (self.nm, p.indx, latest/1000.0, p.lag/1000.00) elif latest == prev_rqe: # released by completion of last request departure if trace and self.trace: print '%s#%d - released by prev request at %.3f' % (self.nm, p.indx, latest/1000.0) p.trig = TRIG_REQ_Q p.lag = tm - prev_rqe else: # released by an arriving ack if trace and self.trace: print '%s#%d - released by ACK at %.3f pkt %d' % (self.nm, p.indx, latest/1000.0, rel.ack_pkt.indx) p.trig = TRIG_REQ_REL p.lag = tm - rapt elif trace and self.trace: print if tm == rqe: # last seg of request p.markers |= P_RLAST if trace and self.trace: print '%s#%d last of request %d' % (self.nm, p.indx, reqi) if len(p.tstr): p.tstr += ')' else: p.tstr += '%d)' % (reqi) reqi += 1 try: ttms = self.mach.ttms[reqi] rqs = ttms.rqs rqe = ttms.rqe rps = ttms.rps rpe = ttms.rpe except IndexError: # may be out of transactions ttms = None rps = None rpe = None rqs = None rqe = None break else: self.reverse.reqi += 1 else: # won't be another start break self.ttms = ttms self.reqi = reqi try: lp = self.lastp if not (lp.markers & (P_RLAST | P_FIRST)) and lp.len != self.segsz: p.trig = gdel p.lag = tm - lp.tm except UnboundLocalError: # more packets after apparently finished str = 'TCPConn #%d DELIVERY AFTER TRANS END: %s#%d' % (self.connid, self.nm, p.indx) if trace and self.trace: whoops(str) self.mach.logfun(str) p.remark =1############################################################################## def dep_seg(self, p): trace = 1 if not self.conn_state & CONNECTED: str = 'TCPConn #%d DATA SEG WHILE UNCONNECTED: %s#%d' % (self.connid, self.nm, p.indx) if trace and self.trace: whoops(str) self.mach.logfun(str) p.remark =1 self.give_up() seq = p.seq plen = p.len end = p.end = seq_add(seq, plen)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -