[comp.mail.uucp] packet troubles

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