📄 ckcfn3.c
字号:
*/#define FACTOR 20L z = ( (long) s * FACTOR ) / ( (long) s + (long) r ); x = ( z * ( (long) size / FACTOR ) ); if (x < 0) return(-1); /* Catch overflow */ bigsbsiz = x - 5; /* Size of send buffer */ bigsbuf = bigbufp; /* Address of send buffer */ debug(F101,"inibufs bigsbsiz","",bigsbsiz); bigrbsiz = size - x - 5; /* Size of receive buffer */ bigrbuf = bigbufp + x; /* Addresss of receive buffer */ debug(F101,"inibufs bigrbsiz","",bigrbsiz); return(0); /* Success */#else /* No dynamic allocation */ bigsbsiz = SBSIZ; /* Just use the symbols */ bigrbsiz = RBSIZ; /* ... */ return(0); /* Success. */#endif /* DYNAMIC */}/* M A K E B U F -- Makes and clears a new buffers. *//* Call with: *//* slots: number of buffer slots to make, 1 to 32 *//* bufsiz: size of the big buffer *//* buf: address of the big buffer *//* xx: pointer to array of pktinfo structures for these buffers *//* Subdivides the big buffer into "slots" buffers. *//* Returns: *//* -1 if too many or too few slots requested, *//* -2 if slots would be too small. *//* n (positive) on success = size of one buffer. *//* with pktinfo structure initialized for this set of buffers. */intmakebuf(slots,bufsiz,buf,xx)/* makebuf */ int slots, bufsiz; CHAR buf[]; struct pktinfo *xx; { CHAR *a; int i, size; debug(F101,"makebuf","",slots); debug(F101,"makebuf bufsiz","",bufsiz); debug(F101,"makebuf MAXWS","",MAXWS); if (slots > MAXWS || slots < 1) return(-1); if (bufsiz < slots * 10 ) return(-2); size = bufsiz / slots; /* Divide up the big buffer. */ a = buf; /* Address of first piece. */ for (i = 0; i < slots; i++) { struct pktinfo *x = &xx[i]; x->bf_adr = a; /* Address of this buffer */ x->bf_len = size; /* Length of this buffer */ x->pk_len = 0; /* Length of data field */ x->pk_typ = ' '; /* packet type */ x->pk_seq = -1; /* packet sequence number */ x->pk_rtr = 0; /* retransmissions */ *a = '\0'; /* Clear the buffer */ a += size; /* Position to next buffer slot */ } return(size);}/* M A K S B U F -- Makes the send-packet buffer */intmksbuf(slots) int slots; { int i, x; sbufnum = 0; if ((x = makebuf(slots,bigsbsiz,bigsbuf,s_pkt)) < 0) { debug(F101,"mksbuf makebuf return","",x); return(x); } debug(F101,"mksbuf makebuf return","",x); for (i = 0; i < 64; i++) { /* Initialize sequence-number- */ sseqtbl[i] = -1; /* to-buffer-number table. */ sacktbl[i] = 0; } for (i = 0; i < MAXWS; i++) sbufuse[i] = 0; /* Mark each buffer as free */ sbufnum = slots; wcur = 0; return(x);}/* M A K R B U F -- Makes the receive-packet buffer */intmkrbuf(slots) int slots; { int i, x; rbufnum = 0; if ((x = makebuf(slots,bigrbsiz,bigrbuf,r_pkt)) < 0) { debug(F101,"mkrbuf makebuf return","",x); return(x); } debug(F101,"mkrbuf makebuf return","",x); for (i = 0; i < 64; i++) { /* Initialize sequence-number- */ rseqtbl[i] = -1; /* to-buffer-number table. */ } for (i = 0; i < MAXWS; i++) rbufuse[i] = 0; /* Mark each buffer as free */ rbufnum = slots; wcur = 0; return(x);}/* W I N D O W -- Resize the window to n */intwindow(n) int n; { debug(F101,"window","",n); if (n < 1 || n > MAXWS) return(-1); if (mksbuf(n) < 0) return(-1); if (mkrbuf(n) < 0) return(-1); wslots = n;#ifdef DEBUG if (deblog) dumpsbuf(); if (deblog) dumprbuf();#endif /* DEBUG */ return(0);}/* G E T S B U F -- Allocate a send-buffer. *//* Call with packet sequence number to allocate buffer for. *//* Returns: *//* -4 if argument is invalid (negative, or greater than 63) *//* -3 if buffers were thought to be available but really weren't (bug!) *//* -2 if the number of free buffers is negative (bug!) *//* -1 if no free buffers. *//* 0 or positive, packet sequence number, with buffer allocated for it. */intgetsbuf(n) int n; { /* Allocate a send-buffer */ int i; CHAR * p = NULL; if (n < 0 || n > 63) { debug(F101,"getsbuf bad arg","",n); return(-4); /* Bad argument */ } debug(F101,"getsbuf packet","",n); /* debug(F101,"getsbuf, sbufnum","",sbufnum); */ if (sbufnum == 0) return(-1); /* No free buffers. */ if (sbufnum < 0) return(-2); /* Shouldn't happen. */ for (i = 0; i < wslots; i++) /* Find the first one not in use. */ if (sbufuse[i] == 0) { /* Got one? */ sbufuse[i] = 1; /* Mark it as in use. */ sbufnum--; /* One less free buffer. */ *s_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */ s_pkt[i].pk_seq = n; /* Put in the sequence number */ sseqtbl[n] = i; /* Back pointer from sequence number */ sacktbl[n] = 0; /* ACK flag */ s_pkt[i].pk_len = 0; /* Data field length now zero. */ s_pkt[i].pk_typ = ' '; /* Blank the packet type too. */ s_pkt[i].pk_rtr = 0; /* Zero the retransmission count */ p = s_pkt[i].bf_adr + 7; /* Set global "data" address. */ debug(F101,"getsbuf p","",0); data = p; if (!data) { debug(F100,"getsbuf data == NULL","",0); return(-3); } if ((what & (W_SEND|W_REMO)) && (++wcur > wmax)) wmax = wcur; /* For statistics. */ /* debug(F101,"getsbuf wcur","",wcur); */ return(n); /* Return its index. */ } sbufnum = 0; /* Didn't find one. */ return(-3); /* Shouldn't happen! */}intgetrbuf() { /* Allocate a receive buffer */ int i;#ifdef COMMENT /* This code is pretty stable by now... */ debug(F101,"getrbuf rbufnum","",rbufnum); debug(F101,"getrbuf wslots","",wslots); debug(F101,"getrbuf dum002","",dum002); debug(F101,"getrbuf dum003","",dum003);#endif /* COMMENT */ if (rbufnum == 0) return(-1); /* No free buffers. */ if (rbufnum < 0) return(-2); /* Shouldn't happen. */ for (i = 0; i < wslots; i++) /* Find the first one not in use. */ if (rbufuse[i] == 0) { /* Got one? */ rbufuse[i] = 1; /* Mark it as in use. */ *r_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */ rbufnum--; /* One less free buffer. */ debug(F101,"getrbuf new rbufnum","",rbufnum); if ((what & W_RECV) && (++wcur > wmax)) wmax = wcur; /* For statistics. */ /* debug(F101,"getrbuf wcur","",wcur); */ return(i); /* Return its index. */ } /* debug(F101,"getrbuf foulup","",i); */ rbufnum = 0; /* Didn't find one. */ return(-3); /* Shouldn't happen! */}/* F R E E S B U F -- Free send-buffer for given packet sequence number *//* Returns: *//* 1 upon success *//* -1 if specified buffer does not exist */intfreesbuf(n) int n; { /* Release send-buffer for packet n. */ int i; debug(F101,"freesbuf","",n); if (n < 0 || n > 63) /* No such packet. */ return(-1); i = sseqtbl[n]; /* Get the window slot number. */ if (i > -1 && i <= wslots) { sseqtbl[n] = -1; /* If valid, remove from seqtbl */ sbufnum++; /* and count one more free buffer */ sbufuse[i] = 0; /* and mark it as free, */ if (what & (W_SEND|W_REMO)) /* decrement active slots */ wcur--; /* for statistics and display. */ } else { debug(F101," sseqtbl[n]","",sseqtbl[n]); return(-1); }/* The following is done only so dumped buffers will look right. */ if (1) { *s_pkt[i].bf_adr = '\0'; /* Zero the buffer data field */ s_pkt[i].pk_seq = -1; /* Invalidate the sequence number */ s_pkt[i].pk_len = 0; /* Data field length now zero. */ s_pkt[i].pk_typ = ' '; /* Blank the packet type too. */ s_pkt[i].pk_rtr = 0; /* And the retries field. */ } return(1);}intfreerbuf(i) int i; { /* Release receive-buffer slot "i". */ int n;/* NOTE !! Currently, this function frees the indicated buffer, but *//* does NOT erase the data. The program counts on this. Will find a *//* better way later.... */ /* debug(F101,"freerbuf, slot","",i); */ if (i < 0 || i >= wslots) { /* No such slot. */ debug(F101,"freerbuf no such slot","",i); return(-1); } n = r_pkt[i].pk_seq; /* Get the packet sequence number */ debug(F101,"freerbuf packet","",n); if (n > -1 && n < 64) /* If valid, remove from seqtbl */ rseqtbl[n] = -1; if (rbufuse[i] != 0) { /* If really allocated, */ rbufuse[i] = 0; /* mark it as free, */ rbufnum++; /* and count one more free buffer. */ if (what & W_RECV) /* Keep track of current slots */ wcur--; /* for statistics and display */ debug(F101,"freerbuf rbufnum","",rbufnum); }/* The following is done only so dumped buffers will look right. */ if (1) { /* *r_pkt[i].bf_adr = '\0'; */ /* Zero the buffer data field */ r_pkt[i].pk_seq = -1; /* And from packet list */ r_pkt[i].pk_len = 0; /* Data field length now zero. */ r_pkt[i].pk_typ = ' '; /* Blank the packet type too. */ r_pkt[i].pk_rtr = 0; /* And the retries field. */ } return(1);}/* This is like freerbuf, except it's called with a packet sequence number *//* rather than a packet buffer index. */VOIDfreerpkt(seq) int seq; { int k; debug(F101,"freerpkt seq","",seq); k = rseqtbl[seq]; /* debug(F101,"freerpkt k","",k); */ if (k > -1) { k = freerbuf(k); /* debug(F101,"freerpkt freerbuf","",k); */ }}/* C H K W I N -- Check if packet n is in window. *//* Returns: *//* 0 if it is in the current window, *//* +1 if it would have been in previous window (e.g. if ack was lost), *//* -1 if it is outside any window (protocol error), *//* -2 if either of the argument packet numbers is out of range. *//* Call with packet number to check (n), lowest packet number in window *//* (bottom), and number of slots in window (slots). */intchkwin(n,bottom,slots) int n, bottom, slots; { int top, prev; debug(F101,"chkwin packet","",n); debug(F101,"chkwin winlo","",bottom); debug(F101,"chkwin slots","",slots);/* First do the easy and common cases, where the windows are not split. */ if (n < 0 || n > 63 || bottom < 0 || bottom > 63) return(-2); if (n == bottom) return(0); /* In a perfect world... */ top = bottom + slots; /* Calculate window top. */ if (top < 64 && n < top && n >= bottom) return(0); /* In current window. */ prev = bottom - slots; /* Bottom of previous window. */ if (prev > -1 && n < bottom && n > prev) return(1); /* In previous. *//* Now consider the case where the current window is split. */ if (top > 63) { /* Wraparound... */ top -= 64; /* Get modulo-64 sequence number */ if (n < top || n >= bottom) { return(0); /* In current window. */ } else { /* Not in current window. */ if (n < bottom && n >= prev) /* Previous window can't be split. */ return(1); /* In previous window. */ else return(-1); /* Not in previous window. */ } }/* Now the case where current window not split, but previous window is. */ if (prev < 0) { /* Is previous window split? */ prev += 64; /* Yes. */ if (n < bottom || n >= prev) return(1); /* In previous window. */ } else { /* Previous window not split. */ if (n < bottom && n >= prev) return(1); /* In previous window. */ }/* It's not in the current window, and not in the previous window... */ return(-1); /* So it's not in any window. */}intdumpsbuf() { /* Dump send-buffers */#ifdef DEBUG int j, x; /* to debug log. */ if (! deblog) return(0); x = zsoutl(ZDFILE,"SEND BUFFERS:"); if (x < 0) { deblog = 0; return(0); } x=zsoutl(ZDFILE,"buffer inuse address length data type seq flag retries"); if (x < 0) { deblog = 0; return(0); } for ( j = 0; j < wslots; j++ ) { sprintf(xbuf, "%4d%6d%10d%5d%6d%4c%5d%6d\n", j, sbufuse[j], (int) s_pkt[j].bf_adr, s_pkt[j].bf_len, s_pkt[j].pk_len, s_pkt[j].pk_typ, s_pkt[j].pk_seq, s_pkt[j].pk_rtr ); if (zsout(ZDFILE,xbuf) < 0) { deblog = 0; return(0); } if (s_pkt[j].pk_adr) { x = (int)strlen((char *) s_pkt[j].pk_adr); if (x) sprintf(xbuf,"[%.72s%s]\n",s_pkt[j].pk_adr, x > 72 ? "..." : ""); else sprintf(xbuf,"[(empty string)]\n"); } else { sprintf(xbuf,"[(null pointer)]\n"); } if (zsout(ZDFILE,xbuf) < 0) { deblog = 0; return(0); } } sprintf(xbuf,"free: %d, winlo: %d\n", sbufnum, winlo); if (zsout(ZDFILE,xbuf) < 0) { deblog = 0; return(0); }#endif /* DEBUG */ return(0);}intdumprbuf() { /* Dump receive-buffers */#ifdef DEBUG int j, x; if (! deblog) return(0); if (zsoutl(ZDFILE,"RECEIVE BUFFERS:") < 0) { deblog = 0; return(0); } x=zsoutl(ZDFILE,"buffer inuse address length data type seq flag retries"); if (x < 0) { deblog = 0; return(0); } for ( j = 0; j < wslots; j++ ) { sprintf(xbuf, "%4d%6d%10d%5d%6d%4c%5d%6d\n", j, rbufuse[j], (int) r_pkt[j].bf_adr, r_pkt[j].bf_len, r_pkt[j].pk_len, r_pkt[j].pk_typ, r_pkt[j].pk_seq, r_pkt[j].pk_rtr ); if (zsout(ZDFILE,xbuf) < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -