*/
#ifndef lint
-static char rcsid[] = "$Id: fsm.c,v 1.1 1993/11/11 03:54:25 paulus Exp $";
+static char rcsid[] = "$Id: fsm.c,v 1.4 1994/09/01 00:14:03 paulus Exp $";
#endif
/*
#include <stdio.h>
#include <sys/types.h>
-/*#include <malloc.h>*/
#include <syslog.h>
#include "ppp.h"
code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree);
} else if (len)
code = CONFREJ; /* Reject all CI */
+ else
+ code = CONFACK;
/* send the Ack, Nak or Rej to the peer */
fsm_sdata(f, code, id, inp, len);
FSMDEBUG((LOG_INFO, "fsm_rconfack(%s): Rcvd id %d.",
PROTO_NAME(f), id));
- if (id != f->reqid) /* Expected id? */
- return; /* Nope, toss... */
- if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): (len == 0)) ){
+ if (id != f->reqid || f->seen_ack) /* Expected id? */
+ return; /* Nope, toss... */
+ if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len):
+ (len == 0)) ){
/* Ack is bad - ignore it */
FSMDEBUG((LOG_INFO, "%s: received bad Ack (length %d)",
PROTO_NAME(f), len));
return;
}
+ f->seen_ack = 1;
switch (f->state) {
case CLOSED:
break;
case ACKRCVD:
- /* Huh? an extra Ack? oh well... */
+ /* Huh? an extra valid Ack? oh well... */
fsm_sconfreq(f, 0);
f->state = REQSENT;
break;
FSMDEBUG((LOG_INFO, "fsm_rconfnakrej(%s): Rcvd id %d.",
PROTO_NAME(f), id));
- if (id != f->reqid) /* Expected id? */
- return; /* Nope, toss... */
+ if (id != f->reqid || f->seen_ack) /* Expected id? */
+ return; /* Nope, toss... */
proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
- if( !proc || !proc(f, inp, len) ){
+ if (!proc || !proc(f, inp, len)) {
/* Nak/reject is bad - ignore it */
FSMDEBUG((LOG_INFO, "%s: received bad %s (length %d)",
PROTO_NAME(f), (code==CONFNAK? "Nak": "reject"), len));
return;
}
+ f->seen_ack = 1;
switch (f->state) {
case CLOSED:
FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.",
PROTO_NAME(f), id));
- fsm_sdata(f, TERMACK, id, NULL, 0);
switch (f->state) {
case ACKRCVD:
case ACKSENT:
TIMEOUT(fsm_timeout, (caddr_t) f, f->timeouttime);
break;
}
+
+ fsm_sdata(f, TERMACK, id, NULL, 0);
}
f->reqid = ++f->id;
}
+ f->seen_ack = 0;
+
/*
* Make up the request packet
*/
+ outp = outpacket_buf + DLLHEADERLEN + HEADERLEN;
if( f->callbacks->cilen && f->callbacks->addci ){
cilen = (*f->callbacks->cilen)(f);
if( cilen > peer_mru[f->unit] - HEADERLEN )
cilen = peer_mru[f->unit] - HEADERLEN;
- outp = outpacket_buf + DLLHEADERLEN + HEADERLEN;
if (f->callbacks->addci)
(*f->callbacks->addci)(f, outp, &cilen);
} else