diff options
author | brian <brian@cvs.openbsd.org> | 1997-11-23 20:27:41 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 1997-11-23 20:27:41 +0000 |
commit | 2cb79b0580b6b5629530c4d142a73a9a654f282f (patch) | |
tree | 8b062ff5e99e22ec2c95145149e22b58b7fc0e22 /usr.sbin/ppp/timer.c | |
parent | 518c0071f44dfb9716d70e0d8781585db7a3bd7d (diff) |
Import version 1.5 of ppp.
<sales>
This is a user-level ppp implementation that uses the
tun driver. It was originally created by a Japanese
ISP. It's now piled with features. Check the man pages
for details.
</sales>
The sources are identical to the ones in FreeBSD, except
for the Makefile.
IP aliasing (NAT) is disabled, and can be enabled by simply
doing a ``make install'' of libalias, then rebuilding
ppp. I'll create libalias as a port soon.
Diffstat (limited to 'usr.sbin/ppp/timer.c')
-rw-r--r-- | usr.sbin/ppp/timer.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/usr.sbin/ppp/timer.c b/usr.sbin/ppp/timer.c new file mode 100644 index 00000000000..ebb4cd4453b --- /dev/null +++ b/usr.sbin/ppp/timer.c @@ -0,0 +1,296 @@ +/* + * PPP Timer Processing Module + * + * Written by Toshiharu OHNO (tony-o@iij.ad.jp) + * + * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the Internet Initiative Japan, Inc. The name of the + * IIJ may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * $Id: timer.c,v 1.1 1997/11/23 20:27:36 brian Exp $ + * + * TODO: + */ + +#include <signal.h> +#ifdef SIGALRM +#include <errno.h> +#endif +#include <sys/time.h> +#include <stdio.h> +#include <unistd.h> + +#include "command.h" +#include "mbuf.h" +#include "log.h" +#include "defs.h" +#include "sig.h" +#include "timer.h" + +struct pppTimer *TimerList = NULL; + +static void StopTimerNoBlock(struct pppTimer *); +static void InitTimerService(void); + +void +StopTimer(struct pppTimer * tp) +{ +#ifdef SIGALRM + int omask; + + omask = sigblock(sigmask(SIGALRM)); +#endif + StopTimerNoBlock(tp); +#ifdef SIGALRM + sigsetmask(omask); +#endif +} + +void +StartTimer(struct pppTimer * tp) +{ + struct pppTimer *t, *pt; + u_long ticks = 0; + +#ifdef SIGALRM + int omask; + + omask = sigblock(sigmask(SIGALRM)); +#endif + + if (tp->state != TIMER_STOPPED) { + StopTimerNoBlock(tp); + } + if (tp->load == 0) { + LogPrintf(LogDEBUG, "timer %x has 0 load!\n", tp); + sigsetmask(omask); + return; + } + pt = NULL; + for (t = TimerList; t; t = t->next) { + LogPrintf(LogDEBUG, "StartTimer: %x(%d): ticks: %d, rest: %d\n", + t, t->state, ticks, t->rest); + if (ticks + t->rest >= tp->load) + break; + ticks += t->rest; + pt = t; + } + + tp->state = TIMER_RUNNING; + tp->rest = tp->load - ticks; + LogPrintf(LogDEBUG, "StartTimer: Inserting %x before %x, rest = %d\n", + tp, t, tp->rest); + /* Insert given *tp just before *t */ + tp->next = t; + if (pt) { + pt->next = tp; + } else { + InitTimerService(); + TimerList = tp; + } + if (t) + t->rest -= tp->rest; + +#ifdef SIGALRM + sigsetmask(omask); +#endif +} + +static void +StopTimerNoBlock(struct pppTimer * tp) +{ + struct pppTimer *t, *pt; + + /* + * A Running Timer should be removing TimerList, But STOPPED/EXPIRED is + * already removing TimerList. So just marked as TIMER_STOPPED. Do not + * change tp->enext!! (Might be Called by expired proc) + */ + LogPrintf(LogDEBUG, "StopTimer: %x, next = %x state=%x\n", + tp, tp->next, tp->state); + if (tp->state != TIMER_RUNNING) { + tp->next = NULL; + tp->state = TIMER_STOPPED; + return; + } + pt = NULL; + for (t = TimerList; t != tp && t != NULL; t = t->next) + pt = t; + if (t) { + if (pt) { + pt->next = t->next; + } else { + TimerList = t->next; + if (TimerList == NULL) /* Last one ? */ + TermTimerService(); /* Terminate Timer Service */ + } + if (t->next) + t->next->rest += tp->rest; + } else + LogPrintf(LogERROR, "Oops, timer not found!!\n"); + + tp->next = NULL; + tp->state = TIMER_STOPPED; +} + +void +TimerService() +{ + struct pppTimer *tp, *exp, *wt; + + if (LogIsKept(LogDEBUG)) + ShowTimers(); + tp = TimerList; + if (tp) { + tp->rest--; + if (tp->rest == 0) { + + /* + * Multiple timers may expires at once. Create list of expired timers. + */ + exp = NULL; + do { + tp->state = TIMER_EXPIRED; + wt = tp->next; + tp->enext = exp; + exp = tp; + LogPrintf(LogDEBUG, "TimerService: Add %x to exp\n", tp); + tp = wt; + } while (tp && (tp->rest == 0)); + + TimerList = tp; + if (TimerList == NULL) /* No timers ? */ + TermTimerService(); /* Terminate Timer Service */ + LogPrintf(LogDEBUG, "TimerService: next is %x(%d)\n", + TimerList, TimerList ? TimerList->rest : 0); + + /* + * Process all expired timers. + */ + while (exp) { +#ifdef notdef + StopTimer(exp); +#endif + if (exp->func) + (*exp->func) (exp->arg); + + /* + * Just Removing each item from expired list And exp->enext will be + * intialized at next expire in this funtion. + */ + exp = exp->enext; + } + } + } +} + +void +ShowTimers() +{ + struct pppTimer *pt; + + LogPrintf(LogDEBUG, "---- Begin of Timer Service List---\n"); + for (pt = TimerList; pt; pt = pt->next) + LogPrintf(LogDEBUG, "%x: load = %d, rest = %d, state =%x\n", + pt, pt->load, pt->rest, pt->state); + LogPrintf(LogDEBUG, "---- End of Timer Service List ---\n"); +} + +#ifdef SIGALRM +u_int +nointr_sleep(u_int sec) +{ + struct timeval to, st, et; + long sld, nwd, std; + + gettimeofday(&st, NULL); + to.tv_sec = sec; + to.tv_usec = 0; + std = st.tv_sec * 1000000 + st.tv_usec; + for (;;) { + if (select(0, NULL, NULL, NULL, &to) == 0 || + errno != EINTR) { + break; + } else { + gettimeofday(&et, NULL); + sld = to.tv_sec * 1000000 + to.tv_sec; + nwd = et.tv_sec * 1000000 + et.tv_usec - std; + if (sld > nwd) + sld -= nwd; + else + sld = 1; /* Avoid both tv_sec/usec is 0 */ + + /* Calculate timeout value for select */ + to.tv_sec = sld / 1000000; + to.tv_usec = sld % 1000000; + } + } + return (0L); +} + +void +nointr_usleep(u_int usec) +{ + struct timeval to, st, et; + long sld, nwd, std; + + gettimeofday(&st, NULL); + to.tv_sec = 0; + to.tv_usec = usec; + std = st.tv_sec * 1000000 + st.tv_usec; + for (;;) { + if (select(0, NULL, NULL, NULL, &to) == 0 || + errno != EINTR) { + break; + } else { + gettimeofday(&et, NULL); + sld = to.tv_sec * 1000000 + to.tv_sec; + nwd = et.tv_sec * 1000000 + et.tv_usec - std; + if (sld > nwd) + sld -= nwd; + else + sld = 1; /* Avoid both tv_sec/usec is 0 */ + + /* Calculate timeout value for select */ + to.tv_sec = sld / 1000000; + to.tv_usec = sld % 1000000; + + } + } +} + +static void +InitTimerService() +{ + struct itimerval itimer; + + pending_signal(SIGALRM, (void (*) (int)) TimerService); + itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0; + itimer.it_interval.tv_usec = itimer.it_value.tv_usec = TICKUNIT; + if (setitimer(ITIMER_REAL, &itimer, NULL) == -1) + LogPrintf(LogERROR, "Unable to set itimer.\n"); +} + +void +TermTimerService(void) +{ + struct itimerval itimer; + + itimer.it_interval.tv_usec = itimer.it_interval.tv_sec = 0; + itimer.it_value.tv_usec = itimer.it_value.tv_sec = 0; + if (setitimer(ITIMER_REAL, &itimer, NULL) == -1) + LogPrintf(LogERROR, "Unable to set itimer.\n"); + pending_signal(SIGALRM, SIG_IGN); +} + +#endif |