dg@lakart.UUCP (David Goodenough) (11/09/89)
cambler@polyslo.CalPoly.EDU (Fubar) sez: > The troubles with G protocol continue. Here is a debug script from my > most bug-free version. It appears here unedited, comments in /* */ are > added by me as i interpret things. If this sparks any insight for any > g protocol hackers, PLEASE help!!! > > BEGIN DEBUG SCRIPT: ..... > G3: open complete > G3: buffers allocated > G3: size arrays initialized > > /* their init-c. they still say 7. THis isn't a problem, yes? I realize > that the open is complete, i malloc my buffers, etc... everything's > ok as far as i can see... */ Nothing wrong with a window size of 7 ..... see below > > G3: > MED SEND COMMAND: type = S str = D.polysloA0774 ....... ..... > G3: Sending data packet 1 > G3: > LOW PACKET OUT > G3: sending envelope > G3: sending data... > G3: > MED GET STRING: > G3: > LOW PACKET IN: > G3: reading... > G3: envelope in: tt = 0, xxx = 4, yyy = 0, need = 6 > G3: lenp = 0 oursum = 43658 theirsum = 43658 > G3: sumok. packet received > G3: failure of getpkt, != TT_DATA > G3: got TT_CTRL, xxx = 4 > > /* here's their response. I EXPECT a data packet with the "CY" in it, > but what i get is an xxx = 4, which is an RR 0. According to the > docs, g shouldn't acknowledge copy commands!!! It's not in ANY of > the other code i've looked at... the packets are all ok, as you > can see by the "sumok. packet received" message. */ Since when should it not ack the commands. If the "g" protocol driver is written properly it shouldn't know the difference between a command and a packet from a data file going. Consider the following scenario: Message to send is: D.polysloXA0774 D.polysloXA0774 christopher - D.polysloXA0774 0666 and a brain damaged receiver that only allows a window size of 1 (this is legal, if inefficient). Now what happens? - the message to go is > 64 bytes, so it's going to take two packets. Send packet 1 Can't send packet 2 till he ack's packet 1, but according to your interpretation of the docs, he can't ack packet 1. You are going to have a real long wait before pkt 2 goes. Now let's see how BSD uucico does it: rmesg - 'P' imsg looking for SYNC<\20> imsg input<Ptfg\0>got 4 characters got Ptfg wmesg 'U' g ; all the external setup to get the "g" protocol omsg <Ug> ; in use send 073 ; INITA window size 3 rec h->cntl 077 ; his INITA window size 7 ; window size 7 is perfectly legal, if a shade excessive. We use 3, and ; can keep data streaming at 9600 (provided the load average isn't too ; high :-) ) send 061 ; INITB packet size 64 bytes rec h->cntl 061 ; his INITB packet size 64 send 053 ; INITC window size 3 rec h->cntl 057 ; his INITC window size 7 Proto started g protocol g (11/8-18:23-11604) OK (startup ttydx 1200 baud) *** TOP *** - role=MASTER (11/8-18:23-11604) REQUEST (S D.lakartB1pt2 D.lakartS1pt2 dg) wmesg 'S' D.lakartB1pt2 D.lakartS1pt2 dg - D.lakartB1pt2 0644 send 0210 ; Outgoing data packet rmesg - 'S' ; looking for an 'S' packet coming back rec h->cntl 041 ; Ah - what's this - an ack for the data rec h->cntl 0211 ; NOW comes his reply send 041 ; which we in turn ack got SY ; and give the data to the upper level PROCESS: msg - SY SNDFILE: send 0221 ; file data ..... send 0231 and off it goes. I don't know which uucico you are using, but if you have the source, when it's waiting for a data packet it should handle incoming ack's and then settle down and wait again. -- dg@lakart.UUCP - David Goodenough +---+ IHS | +-+-+ ....... !harvard!xait!lakart!dg +-+-+ | AKA: dg%lakart.uucp@xait.xerox.com +---+
jeh@simpact.com (11/15/89)
In article <1989Nov7.090330.27599@polyslo.CalPoly.EDU>, cambler@polyslo.CalPoly.EDU (Fubar) writes: > ... > /* here's their response. I EXPECT a data packet with the "CY" in it, > but what i get is an xxx = 4, which is an RR 0. According to the > docs, g shouldn't acknowledge copy commands!!! It's not in ANY of > the other code i've looked at... the packets are all ok, as you > can see by the "sumok. packet received" message. */ I don't see why g shouldn't ack copy commands. In OSI terms, think of the message framing stuff (ctl-P, header XORs, checksums on packets, message numbers, RRs (acks), RJs (naks), etc., as the data link layer, and the C, S, R, H, etc., exchanges as, oh, I dunno, the application layer. The data link layer should have UTTERLY NO KNOWLEDGE of what is going on at the application layer. So an "S" message is just a data packet as far as the data link layer is concerned... and it gets ACKed like any other data packet. Now, having said that, I will mention that since uucp 'g' allows "piggybacked acks" (the number of the most recently-correctly-received packet appears in the 'y' field of outgoing data packet headers), you sometimes won't see an explicit ack for every data message. If your neighbor has a data message queued up to send to you, the ack can be implied by the y field in that message's header. Now, the only time this really has a chance to happen under uucp 'g' is during the start-of-file and end-of-file handshake stuff, and even then it doesn't occur often, since it's rare for the data link level to NOT get the explicit ACK out the door before the app. level sends the "SY" in resp. to the "S" or whatever. Also, at least one 'g' implementation (that in early Telebit ROMs; later ones have a fix) can't handle piggybacked acks in all cases, so it's best to explicitly ack everything. Piggybacked acks help performance in environments where the upper protocol layers make frequent full-duplex use of the data link... which doesn't describe uucp 'g'. In any case, the RR 0 is NOT an ack of your S command, it is a nak!!! Read on. Unix uucps are very shy about sending naks (RJs), and for good reason (sending too many naks in a windowed environment will confuse the hell out the sender). Instead they often just timeout and send a ack for the last correctly received packet, which variable is init'd to 0. Remember that your first data packet (the S packet) was packet number 1? (It better be!) You want to see an RR 1 in response. *** An RR <n>, where n is less_than(modulo 8) the number *** of the packet you just sent, should be treated like an RJ. > a thought would be that i should ignore the RR 0 and continue, but > when i do, i then start getting funky RJ 0 and RR 0 packets alternating... Yup. You're ignoring a NAK. If you send too many unexpected packets Unix uucps will occasionally send an honest-to-God RJ. > should i ignore the RR 0 and send a null packet? SHould *I* RR the RR 0?! No, you never send ACKs for ACKs. You should find out why your neighbor system is rejecting your "S" packet. Maybe you still have some checksum calculation troubles. You appear to have some application-level troubles as well, as you shouldn't be expecting a CY after you send an S. After you send an S you should be expecting an SY or an SN<reason>. If SY you send the file, THEN you expect a CY or a CN<reason> as confirmation. --- Jamie Hanrahan, Simpact Associates, San Diego CA Chair, VMSnet [DECUS uucp] and Internals Working Groups, DECUS VAX Systems SIG Internet: jeh@simpact.com, or if that fails, jeh@crash.cts.com Uucp: ...{crash,scubed,decwrl}!simpact!jeh
dal@syntel.mn.org (Dale Schumacher) (11/18/89)
[cambler@polyslo.CalPoly.EDU (Fubar) writes...] > The troubles with G protocol continue. Here is a debug script from my > most bug-free version. It appears here unedited, comments in /* */ are > added by me as i interpret things. If this sparks any insight for any > g protocol hackers, PLEASE help!!! Having recently finished getting a 1-7 window g-proto implementation working in the face of misbehaving neighbors, I have sympathy for you. I've quoted only selections from the debugging script... > /* i'm sending the init-a, asking for a window of 3 */ > /* the remote system init-a's also, asking for a window of 7 */ > /* my init-b */ > /* their init-b. packet size req is 64. Note that my checksumming is working > just fine now... */ > /* i send my init-c. note also that these init packets are coming and > going just fine, with no problems, right? */ > /* their init-c. they still say 7. THis isn't a problem, yes? I realize > that the open is complete, i malloc my buffers, etc... everything's > ok as far as i can see... */ Seems ok. The implementation I'm working on (written by Peter Housel) is now "downshifting" it's INITC window request to the minimum of my window size and their window size. I send my maximum window size as my INITA, but if their INITA specifies a smaller size I send THE SMALLER size as my INITC. Since you're really only telling the remote sender how big your local receiver's window is, there's not a problem with specifying a bigger window than the remore sender can send, he simply fills the window to HIS capacity and waits for acknowledgements. > /* time to send my first send command... */ > G3: queued data packet seq = 2 len = 60 > G3: Sending data packet 1 > G3: sending: k = 2 tt = 2 xxx = 1 yyy = 0 size = 64 > G3: ctrl = 136 sum = 10981 > /* there it goes. checksumming is right, and the data is all there. */> > G3: reading... > G3: envelope in: tt = 0, xxx = 4, yyy = 0, need = 6 > G3: failure of getpkt, != TT_DATA > G3: got TT_CTRL, xxx = 4 > /* here's their response. I EXPECT a data packet with the "CY" in it, > but what i get is an xxx = 4, which is an RR 0. According to the > docs, g shouldn't acknowledge copy commands!!! It's not in ANY of > the other code i've looked at... the packets are all ok, as you > can see by the "sumok. packet received" message. */ First, all data packets are acknowledged. The fact that they are carrying a message is not relevent, since that is at the conversation level, and thus is above the packet protocol. The CONTROL PACKETS are not sequenced, ie INITA, INITB, INITC, RR, RJ, etc. Second, you're right that the RR 0 is a bit strange, but only in that it should be an RR 1 to acknowledge receipt of packet 1. I ran into this problem with some, but not all, of the systems that I talked to. _THIS_ _IS_ _A_ _BUG_! However, it must be dealt with, since there seem to be several "standard" systems which have this problem. My first approach to solving this was the ignore the "out of band" RR 0 and wait for a proper RR 1. The was not forthcoming, however, as the other system timed out and send ANOTHER RR 0, and so forth until we gave up. What I'm doing now is this, if I get an RR which is outside of the expected window, I reset the transmitter counter to the last unacknowledged packet and retransmit from there. This is ugly and painful, but "it shouldn't happen" anyway, so performance is not an issue here. The example sequence then goes like this: initialize send counter to 1 send packet 1 increment send counter to 2 receive RR 0 reset send counter to 1 send packet 1 receive RR 1 The transfer proceeds correctly from there. I've included similar code for handling out of band RJ's as well. Peter has been posting his uucico to comp.os.minix, and may soon post an update (to fix this and a couple of other bugs I've discovered). I'm working on the ST-Minix and ST-TOS versions of uucico (and smail) and plan to post those when they're ready. I suppose comp.sources.misc would be the place for the ST-TOS versions? It's all the same code, just #ifdef'ed for different machine/OS configurations. > Sig: ++Christopher(); | "I am not nuts. I am condements. > Internet: cambler@polyslo.calpoly.edu | I was promoted last thursday!" > Also: chris@fubarsys.slo.ca.us | > Bix: cambler | Support joint US/USSR trip to Mars. \\ / Dale Schumacher 399 Beacon Ave. \\ / (alias: Dalnefre') St. Paul, MN 55104-3527 >< ...umn-cs!midgard.mn.org!syntel!dal United States of America / \\ "What is wanted is not the will to believe, but the will to find out, / \\ which is the exact opposite." -Bertrand Russell