csg@pyramid.UUCP (Carl S. Gutekunst) (11/02/85)
Alright all you UUCP hackers out there, tell me if this one is reasonable. The patch is quick and dirty; I want to hear if the concept is reasonable, not the specific fix. (The fix differs considerably on different versions of UUCP.) This was originally posted in a plea for help by Jeffrey Mattox at Heurikon. Description: If a packet is received that is short a character or two (due to line noise, or whatever), uucico loses synch with the transmitting host, makes the usual ten or so retries, and finally gives up. Reproduce By: Difficult to reproduce consistently, unless you can deliberately introduce protocol errors. Easily observed with a data monitor on noisy lines, through. Fix: The pkgetpack() function reads the six-byte packet header and data using three calls to pkcget, one for the leading SYN character, the second for the rest of the header, and the third to read the data. The stripped down pseudo code for this is: if (pkcget (ifn, buffer, 1) == FAIL) /* To read SYN char */ start over; if (pkcget (ifn, buffer+1, 5) == FAIL) /* For rest of header */ start over; if (pkcget (ifn, buffer, data_size) != FAIL) move (buffer, packet_buffer); If the data read fails (i.e. an alarm timeout occurs), then the data is discarded and pkgetpack() returns. However, previous data in the packet buffer can fool the calling routine into believing that no error occurred. The following quick-and-dirty patch can be applied to the Berkeley 5.1 version of pk1.c to retry the entire packet when a read fails on the data portion. A better patch (which I am using in the 4.3bsd UUCP) is to pull the third pkcget inside the error/retry loop that is used to read the header. In addition, to help deal with hosts that don't have this bug fix, I made a mod to pkxstart to append null characters to each packet. This appears so far to markedly improved transmission on noisy lines, since we avoid timeout errors entirely; the normal checksum detection finds error instead. So -- can anyone tell me about any hidden surprises in this? *** pk1.c.old Fri Nov 1 17:07:26 1985 --- pk1.c Fri Nov 1 17:06:43 1985 *************** *** 130,135 pkfail(); ifn = pk->p_ifn; /* find HEADER */ for (tries = 0; tries < GETRIES; ) { p = (caddr_t) &pk->p_ihbuf; --- 130,136 ----- pkfail(); ifn = pk->p_ifn; + pkg_start: /* find HEADER */ for (tries = 0; tries < GETRIES; ) { p = (caddr_t) &pk->p_ihbuf; *************** *** 200,207 return; } ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! if (ret == 0) ! pkdata(h->cntl, h->sum, pk, (char **) bp); return; } --- 201,209 ----- return; } ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! if (ret != 0) ! goto pkg_start; ! pkdata(h->cntl, h->sum, pk, (char **) bp); return; } *************** *** 295,301 PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret); } else { ! char buf[PKMAXBUF + HDRSIZ], *b; int i; for (i = 0, b = buf; i < HDRSIZ; i++) *b++ = *p++; --- 297,304 ----- PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret); } else { ! #define TAILSIZE 2 ! char buf[PKMAXBUF + HDRSIZ + TAILSIZE], *b; int i; for (i = 0, b = buf; i < HDRSIZ; i++) *b++ = *p++; *************** *** 301,306 *b++ = *p++; for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) *b++ = *p++; #ifdef PROTODEBUG GENERROR(buf, pk->p_xsize + HDRSIZ); #endif --- 304,312 ----- *b++ = *p++; for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) *b++ = *p++; + for (i = 0; i < TAILSIZE; i++) + *b++ = '\0'; + #ifdef PROTODEBUG GENERROR(buf, pk->p_xsize + HDRSIZ + TAILSIZE); #endif *************** *** 302,308 for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) *b++ = *p++; #ifdef PROTODEBUG ! GENERROR(buf, pk->p_xsize + HDRSIZ); #endif ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ); PKASSERT(ret == pk->p_xsize + HDRSIZ, --- 308,314 ----- *b++ = '\0'; #ifdef PROTODEBUG ! GENERROR(buf, pk->p_xsize + HDRSIZ + TAILSIZE); #endif ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ + TAILSIZE); PKASSERT(ret == pk->p_xsize + HDRSIZ + TAILSIZE, *************** *** 304,311 #ifdef PROTODEBUG GENERROR(buf, pk->p_xsize + HDRSIZ); #endif ! ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ); ! PKASSERT(ret == pk->p_xsize + HDRSIZ, "PKXSTART ret", "", ret); Connodata = 0; } --- 310,317 ----- #ifdef PROTODEBUG GENERROR(buf, pk->p_xsize + HDRSIZ + TAILSIZE); #endif ! ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ + TAILSIZE); ! PKASSERT(ret == pk->p_xsize + HDRSIZ + TAILSIZE, "PKXSTART ret", "", ret); Connodata = 0; } -- -m------- Pyramid Technology Carl S. Gutekunst, Software R&D ---mmm----- 1295 Charleston Rd {cmcl2,topaz}!pyrnj! -----mmmmm--- Mt. View, CA 94039 {ihnp4,uwvax}!pyrchi!pyramid!csg -------mmmmmmm- +1 415 965 7200 {allegra,decwrl,dual,sun}!