If we've got a full output buffer queue and cannot send

anything for two mintues (see ``set choked'' and ``show
bundle''), nuke the ip, mp and link level buffer queues.

This should fix problems where ``ppp -auto'' seems to stop
responding after failing to connect to the peer a few times.
This commit is contained in:
Brian Somers 1998-08-25 17:48:43 +00:00
parent 12e14047a4
commit 6f8e9f0a8a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=38544
15 changed files with 180 additions and 17 deletions

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.c,v 1.31 1998/08/07 18:42:47 brian Exp $
* $Id: bundle.c,v 1.32 1998/08/09 15:34:11 brian Exp $
*/
#include <sys/param.h>
@ -207,6 +207,36 @@ bundle_Notify(struct bundle *bundle, char c)
}
}
static void
bundle_ClearQueues(void *v)
{
struct bundle *bundle = (struct bundle *)v;
struct datalink *dl;
log_Printf(LogPHASE, "Clearing choked output queue\n");
timer_Stop(&bundle->choked.timer);
/*
* Emergency time:
*
* We've had a full queue for PACKET_DEL_SECS seconds without being
* able to get rid of any of the packets. We've probably given up
* on the redials at this point, and the queued data has almost
* definitely been timed out by the layer above. As this is preventing
* us from reading the TUN_NAME device (we don't want to buffer stuff
* indefinitely), we may as well nuke this data and start with a clean
* slate !
*
* Unfortunately, this has the side effect of shafting any compression
* dictionaries in use (causing the relevant RESET_REQ/RESET_ACK).
*/
ip_DeleteQueue();
mp_DeleteQueue(&bundle->ncp.mp);
for (dl = bundle->links; dl; dl = dl->next)
physical_DeleteQueue(dl->physical);
}
static void
bundle_AutoLoadTimeout(void *v)
{
@ -547,11 +577,19 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
want = 20;
if (queued < want) {
/* Not enough - select() for more */
if (bundle->choked.timer.state == TIMER_RUNNING)
timer_Stop(&bundle->choked.timer); /* Not needed any more */
FD_SET(bundle->dev.fd, r);
if (*n < bundle->dev.fd + 1)
*n = bundle->dev.fd + 1;
log_Printf(LogTIMER, "%s: fdset(r) %d\n", TUN_NAME, bundle->dev.fd);
result++;
} else if (bundle->choked.timer.state == TIMER_STOPPED) {
bundle->choked.timer.func = bundle_ClearQueues;
bundle->choked.timer.name = "output choke";
bundle->choked.timer.load = bundle->cfg.choked.timeout * SECTICKS;
bundle->choked.timer.arg = bundle;
timer_Start(&bundle->choked.timer);
}
}
}
@ -833,6 +871,7 @@ bundle_Create(const char *prefix, int type, const char **argv)
bundle.cfg.autoload.max.timeout = 0;
bundle.cfg.autoload.min.packets = 0;
bundle.cfg.autoload.min.timeout = 0;
bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
bundle.phys_type.all = type;
bundle.phys_type.open = 0;
@ -871,6 +910,7 @@ bundle_Create(const char *prefix, int type, const char **argv)
memset(&bundle.autoload.timer, '\0', sizeof bundle.autoload.timer);
bundle.autoload.done = 0;
bundle.autoload.running = 0;
memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
/* Clean out any leftover crud */
bundle_CleanInterface(&bundle);
@ -924,6 +964,7 @@ bundle_Destroy(struct bundle *bundle)
* out under exceptional conditions such as a descriptor exception.
*/
timer_Stop(&bundle->idle.timer);
timer_Stop(&bundle->choked.timer);
timer_Stop(&bundle->autoload.timer);
mp_Down(&bundle->ncp.mp);
ipcp_CleanInterface(&bundle->ncp.ipcp);
@ -1218,6 +1259,8 @@ bundle_ShowStatus(struct cmdargs const *arg)
" packets queued\n", arg->bundle->autoload.running ?
"" : "not ", ip_QueueLen());
prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
arg->bundle->cfg.choked.timeout);
prompt_Printf(arg->prompt, " Idle Timer: ");
if (arg->bundle->cfg.idle_timeout) {
prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: bundle.h,v 1.11 1998/07/29 18:21:13 brian Exp $
* $Id: bundle.h,v 1.12 1998/08/07 18:42:47 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
@ -98,6 +98,10 @@ struct bundle {
int timeout; /* this number of seconds */
} max, min;
} autoload;
struct {
int timeout; /* How long to leave the output queue choked */
} choked;
} cfg;
struct {
@ -127,6 +131,10 @@ struct bundle {
unsigned running : 1;
unsigned comingup : 1;
} autoload;
struct {
struct pppTimer timer; /* choked output queue timer */
} choked;
};
#define descriptor2bundle(d) \

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.158 1998/07/31 19:50:24 brian Exp $
* $Id: command.c,v 1.159 1998/08/07 18:42:48 brian Exp $
*
*/
#include <sys/types.h>
@ -106,6 +106,7 @@
#define VAR_MODE 23
#define VAR_CALLBACK 24
#define VAR_CBCP 25
#define VAR_CHOKED 26
/* ``accept|deny|disable|enable'' masks */
#define NEG_HISMASK (1)
@ -125,7 +126,7 @@
#define NEG_DNS 50
const char Version[] = "2.0";
const char VersionDate[] = "$Date: 1998/07/31 19:50:24 $";
const char VersionDate[] = "$Date: 1998/08/07 18:42:48 $";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@ -1497,6 +1498,13 @@ SetVariable(struct cmdargs const *arg)
}
}
break;
case VAR_CHOKED:
arg->bundle->cfg.choked.timeout = atoi(argp);
if (arg->bundle->cfg.choked.timeout <= 0)
arg->bundle->cfg.choked.timeout = CHOKED_TIMEOUT;
break;
}
return err ? 1 : 0;
@ -1537,6 +1545,8 @@ static struct cmdtab const SetCommands[] = {
"FSM retry period", "set ccpretry value", (const void *)VAR_CCPRETRY},
{"chapretry", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
"CHAP retry period", "set chapretry value", (const void *)VAR_CHAPRETRY},
{"choked", NULL, SetVariable, LOCAL_AUTH,
"choked timeout", "set choked [secs]", (const void *)VAR_CHOKED},
{"ctsrts", "crtscts", SetCtsRts, LOCAL_AUTH | LOCAL_CX,
"Use hardware flow control", "set ctsrts [on|off]"},
{"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: defs.h,v 1.34 1998/07/11 02:48:36 brian Exp $
* $Id: defs.h,v 1.35 1998/08/07 18:42:48 brian Exp $
*
* TODO:
*/
@ -45,7 +45,8 @@
#define SCRIPT_LEN 512 /* Size of login scripts */
#define LINE_LEN SCRIPT_LEN /* Size of login scripts */
#define MAXARGS 40 /* How many args per config line */
#define NCP_IDLE_TIMEOUT 180 /* Drop all links */
#define NCP_IDLE_TIMEOUT 180 /* Drop all links */
#define CHOKED_TIMEOUT 120 /* Delete queued packets w/ blocked tun */
#define LINK_MINWEIGHT 20
#define MIN_LQRPERIOD 2 /* Minimum LQR frequency */

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ip.c,v 1.49 1998/07/11 19:05:24 brian Exp $
* $Id: ip.c,v 1.50 1998/08/07 18:42:48 brian Exp $
*
* TODO:
* o Return ICMP message for filterd packet
@ -505,6 +505,16 @@ ip_Enqueue(int pri, char *ptr, int count)
mbuf_Enqueue(&IpOutputQueues[pri], bp);
}
void
ip_DeleteQueue()
{
struct mqueue *queue;
for (queue = IpOutputQueues; queue < IpOutputQueues + PRI_MAX; queue++)
while (queue->top)
mbuf_Free(mbuf_Dequeue(queue));
}
int
ip_QueueLen()
{

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ip.h,v 1.8.2.9 1998/05/01 19:24:46 brian Exp $
* $Id: ip.h,v 1.9 1998/05/21 21:45:40 brian Exp $
*
*/
@ -30,4 +30,5 @@ extern int ip_FlushPacket(struct link *, struct bundle *);
extern int PacketCheck(struct bundle *, char *, int, struct filter *);
extern void ip_Enqueue(int, char *, int);
extern void ip_Input(struct bundle *, struct mbuf *);
extern void ip_DeleteQueue(void);
extern int ip_QueueLen(void);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: link.c,v 1.3 1998/06/27 23:48:49 brian Exp $
* $Id: link.c,v 1.4 1998/08/07 18:42:49 brian Exp $
*
*/
@ -67,6 +67,16 @@ link_SequenceQueue(struct link *l)
mbuf_Enqueue(l->Queue + PRI_LINK, mbuf_Dequeue(l->Queue + PRI_NORMAL));
}
void
link_DeleteQueue(struct link *l)
{
struct mqueue *queue;
for (queue = l->Queue; queue < l->Queue + LINK_QUEUES; queue++)
while (queue->top)
mbuf_Free(mbuf_Dequeue(queue));
}
int
link_QueueLen(struct link *l)
{

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: link.h,v 1.2 1998/05/21 21:46:14 brian Exp $
* $Id: link.h,v 1.3 1998/05/23 17:05:27 brian Exp $
*
*/
@ -55,6 +55,7 @@ extern void link_AddInOctets(struct link *, int);
extern void link_AddOutOctets(struct link *, int);
extern void link_SequenceQueue(struct link *);
extern void link_DeleteQueue(struct link *);
extern int link_QueueLen(struct link *);
extern int link_QueueBytes(struct link *);
extern struct mbuf *link_Dequeue(struct link *);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: mbuf.c,v 1.20 1998/08/21 18:09:57 brian Exp $
* $Id: mbuf.c,v 1.21 1998/08/21 18:10:15 brian Exp $
*
*/
#include <sys/types.h>
@ -197,6 +197,7 @@ mbuf_Dequeue(struct mqueue *q)
return bp;
}
void
mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
{

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp.c,v 1.12 1998/06/30 23:04:17 brian Exp $
* $Id: mp.c,v 1.13 1998/08/07 18:42:50 brian Exp $
*/
#include <sys/types.h>
@ -1013,3 +1013,9 @@ mp_LinkLost(struct mp *mp, struct datalink *dl)
/* We've lost the link that's holding everything up ! */
mp_Input(mp, NULL, NULL);
}
void
mp_DeleteQueue(struct mp *mp)
{
link_DeleteQueue(&mp->link);
}

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp.h,v 1.2 1998/05/21 21:47:08 brian Exp $
* $Id: mp.h,v 1.3 1998/05/23 17:05:28 brian Exp $
*/
struct mbuf;
@ -133,3 +133,4 @@ extern int mp_ShowStatus(struct cmdargs const *);
extern const char *mp_Enddisc(u_char, const char *, int);
extern int mp_SetEnddisc(struct cmdargs const *);
extern void mp_LinkLost(struct mp *, struct datalink *);
extern void mp_DeleteQueue(struct mp *);

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.c,v 1.4 1998/06/27 14:18:09 brian Exp $
* $Id: physical.c,v 1.5 1998/08/07 18:42:50 brian Exp $
*
*/
@ -227,3 +227,13 @@ physical_SetMode(struct physical *p, int mode)
p->type = mode;
return 1;
}
void
physical_DeleteQueue(struct physical *p)
{
if (p->out) {
mbuf_Free(p->out);
p->out = NULL;
}
link_DeleteQueue(&p->link);
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.h,v 1.2 1998/05/21 21:47:40 brian Exp $
* $Id: physical.h,v 1.3 1998/05/29 18:33:10 brian Exp $
*
*/
@ -100,3 +100,4 @@ extern void physical_Logout(struct physical *);
extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *,
fd_set *);
extern int physical_SetMode(struct physical *, int);
extern void physical_DeleteQueue(struct physical *);

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.117 1998/08/09 23:40:31 brian Exp $
.\" $Id: ppp.8,v 1.118 1998/08/11 18:59:36 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -2697,6 +2697,36 @@ be agreeable with the peer), or if
is specified,
.Nm
will expect the peer to specify the number.
.It set choked Op Ar timeout
This sets the number of seconds that
.Nm
will keep a choked output queue before dropping all pending output packets.
If
.Ar timeout
is less than or equal to zero or if
.Ar timeout
isn't specified, it is set to the default value of
.Em 120 seconds .
.Pp
A choked output queue occurs when
.Nm
has read a certain number of packets from the local network for transmission,
but cannot send the data due to link failure (the peer is busy etc.).
.Nm Ppp
will not read packets indefinitely. Instead, it reads up to
.Em 20
packets (or
.Em 20 No +
.Em nlinks No *
.Em 2
packets in multi-link mode), then stops reading the network interface
until either
.Ar timeout
seconds have passed or at least one packet has been sent.
.Pp
If
.Ar timeout
seconds pass, all pending output packets are dropped.
.It set ctsrts|crtscts on|off
This sets hardware flow control. Hardware flow control is
.Ar on

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.117 1998/08/09 23:40:31 brian Exp $
.\" $Id: ppp.8,v 1.118 1998/08/11 18:59:36 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@ -2697,6 +2697,36 @@ be agreeable with the peer), or if
is specified,
.Nm
will expect the peer to specify the number.
.It set choked Op Ar timeout
This sets the number of seconds that
.Nm
will keep a choked output queue before dropping all pending output packets.
If
.Ar timeout
is less than or equal to zero or if
.Ar timeout
isn't specified, it is set to the default value of
.Em 120 seconds .
.Pp
A choked output queue occurs when
.Nm
has read a certain number of packets from the local network for transmission,
but cannot send the data due to link failure (the peer is busy etc.).
.Nm Ppp
will not read packets indefinitely. Instead, it reads up to
.Em 20
packets (or
.Em 20 No +
.Em nlinks No *
.Em 2
packets in multi-link mode), then stops reading the network interface
until either
.Ar timeout
seconds have passed or at least one packet has been sent.
.Pp
If
.Ar timeout
seconds pass, all pending output packets are dropped.
.It set ctsrts|crtscts on|off
This sets hardware flow control. Hardware flow control is
.Ar on