]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/fsm.c
Fixed uninitialized 'pw' variable in HAS_SHADOW logic in session.c due
[ppp.git] / pppd / fsm.c
index 387f7012928f0d2d7d9bab6a0c1ab3fccb34d143..c200cc3a84387cefc952bdd37bac6650bf32161d 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: fsm.c,v 1.21 2004/02/02 02:52:51 carlsonj Exp $"
+#define RCSID  "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $"
 
 /*
  * TODO:
@@ -208,8 +208,9 @@ fsm_open(f)
  * send a terminate-request message as configured.
  */
 static void
-terminate_layer(f)
+terminate_layer(f, nextstate)
     fsm *f;
+    int nextstate;
 {
     if( f->state != OPENED )
        UNTIMEOUT(fsm_timeout, f);      /* Cancel timeout */
@@ -227,7 +228,7 @@ terminate_layer(f)
         * We've already fired off one Terminate-Request just to be nice
         * to the peer, but we're not going to wait for a reply.
         */
-       f->state = CLOSED;
+       f->state = nextstate == CLOSING ? CLOSED : STOPPED;
        if( f->callbacks->finished )
            (*f->callbacks->finished)(f);
        return;
@@ -236,7 +237,7 @@ terminate_layer(f)
     TIMEOUT(fsm_timeout, f, f->timeouttime);
     --f->retransmits;
 
-    f->state = CLOSING;
+    f->state = nextstate;
 }
 
 /*
@@ -267,7 +268,7 @@ fsm_close(f, reason)
     case ACKRCVD:
     case ACKSENT:
     case OPENED:
-       terminate_layer(f);
+       terminate_layer(f, CLOSING);
        break;
     }
 }
@@ -495,6 +496,7 @@ fsm_rconfack(f, id, inp, len)
        return;
     }
     f->seen_ack = 1;
+    f->rnakloops = 0;
 
     switch (f->state) {
     case CLOSED:
@@ -543,17 +545,29 @@ fsm_rconfnakrej(f, code, id, inp, len)
     u_char *inp;
     int len;
 {
-    int (*proc) __P((fsm *, u_char *, int));
     int ret;
+    int treat_as_reject;
 
     if (id != f->reqid || f->seen_ack) /* Expected id? */
        return;                         /* Nope, toss... */
-    proc = (code == CONFNAK)? f->callbacks->nakci: f->callbacks->rejci;
-    if (!proc || !(ret = proc(f, inp, len))) {
-       /* Nak/reject is bad - ignore it */
-       error("Received bad configure-nak/rej: %P", inp, len);
-       return;
+
+    if (code == CONFNAK) {
+       ++f->rnakloops;
+       treat_as_reject = (f->rnakloops >= f->maxnakloops);
+       if (f->callbacks->nakci == NULL
+           || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) {
+           error("Received bad configure-nak: %P", inp, len);
+           return;
+       }
+    } else {
+       f->rnakloops = 0;
+       if (f->callbacks->rejci == NULL
+           || !(ret = f->callbacks->rejci(f, inp, len))) {
+           error("Received bad configure-rej: %P", inp, len);
+           return;
+       }
     }
+
     f->seen_ack = 1;
 
     switch (f->state) {
@@ -714,7 +728,7 @@ fsm_protreject(f)
        break;
 
     case OPENED:
-       terminate_layer(f);
+       terminate_layer(f, STOPPING);
        break;
 
     default:
@@ -740,6 +754,7 @@ fsm_sconfreq(f, retransmit)
        if( f->callbacks->resetci )
            (*f->callbacks->resetci)(f);
        f->nakloops = 0;
+       f->rnakloops = 0;
     }
 
     if( !retransmit ){