📄 ckcfn2.c
字号:
/* C K C F N 2 -- System-independent Kermit protocol support functions... *//* ...Part 2 (continued from ckcfns.c) *//* Author: Frank da Cruz <fdc@columbia.edu>, Columbia University Academic Information Systems, New York City. Copyright (C) 1985, 2000, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions.*//* Note -- if you change this file, please amend the version number and date at the top of ckcfns.c accordingly.*/#include "ckcsym.h" /* Compilation options */#include "ckcdeb.h" /* Debugging and other symbols */#include "ckcasc.h" /* ASCII symbols */#include "ckcker.h" /* Kermit symbols */#include "ckcxla.h" /* Translation */#include "ckcnet.h" /* IKS and VMS #define TCPSOCKET */#ifdef TCPSOCKET /* For TELNET business in spack() */extern int tn_nlm, ttnproto, tn_b_nlm;#endif /* TCPSOCKET */extern int parity, network, local, interrupted, fatalio, wasclosed;int kstartactive = 0; /* Flag for kstart() in a packet */static CHAR p_tbl[] = { /* Even parity table for dopar(). */ (CHAR) '\000', /* ANSI C casts '\ooo' constants */ (CHAR) '\201', /* to signed char, so we have to */ (CHAR) '\202', /* cast back to unsigned char... */ (CHAR) '\003', (CHAR) '\204', (CHAR) '\005', (CHAR) '\006', (CHAR) '\207', (CHAR) '\210', (CHAR) '\011', (CHAR) '\012', (CHAR) '\213', (CHAR) '\014', (CHAR) '\215', (CHAR) '\216', (CHAR) '\017', (CHAR) '\220', (CHAR) '\021', (CHAR) '\022', (CHAR) '\223', (CHAR) '\024', (CHAR) '\225', (CHAR) '\226', (CHAR) '\027', (CHAR) '\030', (CHAR) '\231', (CHAR) '\232', (CHAR) '\033', (CHAR) '\234', (CHAR) '\035', (CHAR) '\036', (CHAR) '\237', (CHAR) '\240', (CHAR) '\041', (CHAR) '\042', (CHAR) '\243', (CHAR) '\044', (CHAR) '\245', (CHAR) '\246', (CHAR) '\047', (CHAR) '\050', (CHAR) '\251', (CHAR) '\252', (CHAR) '\053', (CHAR) '\254', (CHAR) '\055', (CHAR) '\056', (CHAR) '\257', (CHAR) '\060', (CHAR) '\261', (CHAR) '\262', (CHAR) '\063', (CHAR) '\264', (CHAR) '\065', (CHAR) '\066', (CHAR) '\267', (CHAR) '\270', (CHAR) '\071', (CHAR) '\072', (CHAR) '\273', (CHAR) '\074', (CHAR) '\275', (CHAR) '\276', (CHAR) '\077', (CHAR) '\300', (CHAR) '\101', (CHAR) '\102', (CHAR) '\303', (CHAR) '\104', (CHAR) '\305', (CHAR) '\306', (CHAR) '\107', (CHAR) '\110', (CHAR) '\311', (CHAR) '\312', (CHAR) '\113', (CHAR) '\314', (CHAR) '\115', (CHAR) '\116', (CHAR) '\317', (CHAR) '\120', (CHAR) '\321', (CHAR) '\322', (CHAR) '\123', (CHAR) '\324', (CHAR) '\125', (CHAR) '\126', (CHAR) '\327', (CHAR) '\330', (CHAR) '\131', (CHAR) '\132', (CHAR) '\333', (CHAR) '\134', (CHAR) '\335', (CHAR) '\336', (CHAR) '\137', (CHAR) '\140', (CHAR) '\341', (CHAR) '\342', (CHAR) '\143', (CHAR) '\344', (CHAR) '\145', (CHAR) '\146', (CHAR) '\347', (CHAR) '\350', (CHAR) '\151', (CHAR) '\152', (CHAR) '\353', (CHAR) '\154', (CHAR) '\355', (CHAR) '\356', (CHAR) '\157', (CHAR) '\360', (CHAR) '\161', (CHAR) '\162', (CHAR) '\363', (CHAR) '\164', (CHAR) '\365', (CHAR) '\366', (CHAR) '\167', (CHAR) '\170', (CHAR) '\371', (CHAR) '\372', (CHAR) '\173', (CHAR) '\374', (CHAR) '\175', (CHAR) '\176', (CHAR) '\377'};/* D O P A R -- Add an appropriate parity bit to a character */CHAR#ifdef CK_ANSICdopar(register CHAR ch)#elsedopar(ch) register CHAR ch;#endif /* CK_ANSIC */ { register unsigned int a; if (!parity#ifdef TCPSOCKET || (network && (ttnproto == NP_TELNET) && (TELOPT_ME(TELOPT_BINARY)))#ifndef NOXFER || (!local && sstelnet) /* TELNET BINARY MODE */#endif /* NOXFER */#endif /* TCPSOCKET */ ) return((CHAR) (ch & 255)); else a = ch & 127; switch (parity) { case 'e': return(p_tbl[a]); /* Even */ case 'm': return((CHAR) (a | 128)); /* Mark */ case 'o': return((CHAR) (p_tbl[a] ^ 128)); /* Odd */ case 's': return((CHAR) a); /* Space */ default: return((CHAR) a); /* Something illegal */ }}#ifndef NOXFER /* Rest of this file... */#define NEWDPL /* New dynamic packet length method */#ifdef VMSextern int batch;#elseextern int backgrd;#endif /* VMS */#ifdef DYNAMICextern struct pktinfo *s_pkt; /* array of pktinfo structures */extern struct pktinfo *r_pkt; /* array of pktinfo structures */#elseextern struct pktinfo s_pkt[]; /* array of pktinfo structures */extern struct pktinfo r_pkt[]; /* array of pktinfo structures */#endif /* DYNAMIC */extern int sseqtbl[], rseqtbl[], sbufuse[], sacktbl[], wslots, winlo, sbufnum, rbufnum, pktpaus, reliable;#ifdef STREAMINGstatic int dontsend = 0;extern int streaming;#endif /* STREAMING */extern int ttprty; /* from ck*tio.c */extern int autopar;extern int spsiz, spmax, rpsiz, timint, timef, npad, bestlen, maxsend;extern int rpt, rptq, rptflg, capas, spsizf, en_fin, tsecs, flow;extern int pktnum, sndtyp, rcvtyp, bctr, bctu, bctl, rsn, rln, maxtry, size;extern int osize, maxsize, spktl, rpktl, nfils, stdouf, fsecs;extern int turn, turnch, displa, pktlog, seslog, xflg, mypadn;extern int hcflg, server, cxseen, czseen, discard, slostart;extern int nakstate, quiet, success, xitsta, what, filestatus;extern int spackets, rpackets, timeouts, retrans, crunched, urpsiz;extern int carrier, fdispla, srvidl;#ifdef GFTIMERextern CKFLOAT fptsecs, fpfsecs, fpxfsecs;#endif /* GFTIMER */extern long filcnt, filrej, ffc, flci, flco, tlci, tlco, tfc, speed;extern long filcps, tfcps;extern char *cmarg, filnam[];extern CHAR padch, mypadc, eol, seol, ctlq, sstate;extern CHAR *recpkt, *data, myinit[];extern CHAR *srvptr, stchr, mystch, *rdatap;extern CHAR padbuf[];extern CHAR * epktmsg;extern int epktrcvd, epktsent;#ifdef OS2 /* AUTODOWNLOAD parameters */extern int adl_kmode, adl_zmode; /* Match Packet to signal download */extern char * adl_kstr; /* KERMIT Download String */extern char * adl_zstr; /* ZMODEM Download String */#endif /* OS2 */#ifdef CK_AUTODLCHAR ksbuf[96] = { NUL, NUL }; /* Autodownload "Kermit Start" buf */#endif /* CK_AUTODL */int numerrs = 0; /* Number of packet errors so far */int rcvtimo = 0; /* Timeout for receiving a packet */int idletmo = 0; /* Flag for idle timeout */long filcps = 0L; /* CPS most recent file transferred */long tfcps = 0L; /* CPS most recent transaction */long xfsecs = 0L; /* Elapsed time for most recent file */#ifdef GFTIMERCKFLOAT fpxfsecs = 0.0; /* Ditto, but floating point */#endif /* GFTIMER */#ifdef CK_TIMERSint rrttbl[64], srttbl[64]; /* Packet timestamp tables */extern int rttflg;#define RTT_SCALE 1000long rttsamples, /* Round trip time samples */ rttdelay, /* RTT delay */ pktintvl, /* Interpacket arrival time */ rttvariance, /* RTT variance */ rttstddev; /* RTT standard deviation */#endif /* CK_TIMERS *//* CRC generation tables */long crcta[16] = { 0L, 010201L, 020402L, 030603L, 041004L, 051205L, 061406L, 071607L, 0102010L, 0112211L, 0122412L, 0132613L, 0143014L, 0153215L, 0163416L, 0173617L};long crctb[16] = { 0L, 010611L, 021422L, 031233L, 043044L, 053655L, 062466L, 072277L, 0106110L, 0116701L, 0127532L, 0137323L, 0145154L, 0155745L, 0164576L, 0174367L};#ifdef CK_TIMERS/* Round-trip timer calculations adapted from Tim Kientzle's article, "Improving Kermit Performance", Dr Dobb's Journal, February 1996.*//* R T T I N I T -- Initialize timers at start of transaction */VOIDrttinit() { /* Initialize round-trip timing */ int i; if (timint == 0) return; rttsamples = 0L; /* Samples (packets) */ rttvariance = 0L; /* Variance in delay */ rttdelay = (long) timint * RTT_SCALE; /* Delay */ pktintvl = (long) timint * RTT_SCALE; /* Delay */ rttstddev = (long) timint * RTT_SCALE; /* Standard deviation of delay */ /* Tables of timestamps indexed by packet sequence number */ for (i = 0; i < 64; i++) { rrttbl[i] = -1; /* Time each packet was received */ srttbl[i] = -1; /* Time each packet was sent */ } rcvtimo = timint; /* Initial timeout is what user said */}/* G E T R T T -- Get packet round trip time *//* Call with nakstate == 0 if file sender, nonzero if receiver, and n == packet sequence number of the packet we just received. Returns: -1 on failure with rcvtimo set to timint (what the user said), or: 0 on success with rcvtimo set to dynamically calculated value: 1 <= rcvtimo <= timint * 3.*/intgetrtt(nakstate, n) int nakstate, n; { long rttdiff; extern int mintime, maxtime; int x, y, yy, z = 0, zz = 0; /* How long did it take to get here? */ rcvtimo = timint; /* Default timeout is what user said */ if (timint == 0) /* We're not timing out. */ return(0); if (!rttflg) /* Not supposed to be doing this? */ return(-1); /* So don't */ if (!RTT_SCALE) /* Paranoia... */ return(-1); /* rtimer() (reset timer) is not called until 1st data packet */#ifdef GFTIMER /* rftimer(); */#endif /* GFTIMER */ /* S (F [ A ] D* Z)* B */ /* NOTE: we calculate both the round-trip time AND the packet */ /* arrival rate. We don't use the RTT for anything, we just display it. */ /* Timeouts are based on the packet arrival rate. */ if (spackets > 3) { /* Don't start till 4th packet */ if (nakstate) { /* File receiver */ x = rrttbl[n]; /* Time when I got packet n */ y = rrttbl[n > 0 ? n - 1 : 63]; /* Time when I got packet n-1 */ yy = srttbl[n > 0 ? n - 1 : 63]; /* Time when I sent ACK(n-1) */ if (x > -1 && y > -1) { /* Be careful */ z = x - y; /* Packet rate */ zz = x - yy; /* Round trip time */ debug(F101,"RTT RECV","",z); } else { /* This shouldn't happen */ debug(F101,"RTT RECV ERROR spackets","",spackets); debug(F101,"RTT RECV ERROR sequence","",n); return(-1); } } else { /* File sender */ x = rrttbl[n]; /* Time when I got ACK(n) */ y = rrttbl[n > 0 ? n - 1 : 63]; /* Time when I got packet n-1 */ yy = srttbl[n]; /* Time when I sent n */ if (x > -1 && y > -1) { z = x - y; /* Packet rate */ zz = x - yy; /* Round trip time */ debug(F101,"RTT SEND","",z); } else { debug(F100,"RTT SEND ERROR","",0); return(-1); } } if (z < 1) /* For fast connections */ z = RTT_SCALE / 2; /* Convert to scale... */ else z *= RTT_SCALE; if (zz < 1) /* For fast connections */ zz = RTT_SCALE / 2; /* Convert to scale... */ else zz *= RTT_SCALE; rttdelay = zz; /* Round trip time of this packet */ if (rttsamples++ == 0L) { /* First sample */ pktintvl = z; rttdiff = 0; } else { /* Subsequent samples */ long oldavg = pktintvl; long rttdiffsq; if (rttsamples > 30) /* Use real average for first 30 */ rttsamples = 30; /* then decaying average. */ /* Average delay, difference squared, variance, std deviation */ pktintvl += (z - pktintvl) / rttsamples; rttdiffsq = (z - oldavg) * (z - oldavg); rttvariance += (rttdiffsq - rttvariance) / rttsamples; debug(F101,"RTT stddev1","",rttstddev); if (rttstddev < 1L) /* It can be zero, in which case */ rttstddev = RTT_SCALE / 3; /* set it to something small... */ rttstddev = (rttstddev + rttvariance / rttstddev) / 2; } debug(F101,"RTT stddev2","",rttstddev); debug(F101,"RTT delay ","",pktintvl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -