interval.h
来自「OpenVPN -- A Secure tunneling daemon」· C头文件 代码 · 共 242 行
H
242 行
/* * OpenVPN -- An application to securely tunnel IP networks * over a single UDP port, with support for SSL/TLS-based * session authentication and key exchange, * packet encryption, packet authentication, and * packet compression. * * Copyright (C) 2002-2003 James Yonan <jim@yonan.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program (see the file COPYING included with this * distribution); if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * These routines are designed to optimize the calling of a routine * (normally used for tls_multi_process()) * which can be called less frequently between triggers. * * We won't optimize if we are within I_HORIZON seconds * of a trigger. * * If we are optimizing, we will call routine at least once * per I_REFRESH seconds. */#ifndef INTERVAL_H#define INTERVAL_H#include "error.h"#include "misc.h"/* * Used to determine in how many seconds we should be * called again. */static inline voidinterval_earliest_wakeup (interval_t *wakeup, time_t at, time_t current) { if (at > current) { const interval_t delta = (interval_t) (at - current); if (!*wakeup || delta < *wakeup) *wakeup = delta; }}/* * Designed to limit calls to expensive functions that need to be called * regularly. */struct interval{ interval_t refresh; interval_t horizon; time_t future_trigger; time_t last_action; time_t last_test_true;};static inline voidinterval_init (struct interval *top, int horizon, int refresh){ CLEAR (*top); top->refresh = refresh; top->horizon = horizon;}/* * IF * last_action less than horizon seconds ago * OR last_test_true more than refresh seconds ago * OR hit future_trigger * THEN * return true * ELSE * set wakeup to the number of seconds until a true return * return false */static inline boolinterval_test (struct interval* top, time_t current){ bool trigger = false; if (top->future_trigger && current >= top->future_trigger) { trigger = true; top->future_trigger = 0; } if (top->last_action + top->horizon > current || top->last_test_true + top->refresh <= current || trigger) { top->last_test_true = current; msg (D_INTERVAL, "INTERVAL interval_test true"); return true; } else { return false; }}static inline voidinterval_schedule_wakeup (struct interval* top, time_t current, interval_t *wakeup){ interval_earliest_wakeup (wakeup, top->last_test_true + top->refresh, current); interval_earliest_wakeup (wakeup, top->future_trigger, current); msg (D_INTERVAL, "INTERVAL interval_schedule wakeup=%d", (int)*wakeup);}/* * In wakeup seconds, interval_test will return true once. */static inline voidinterval_future_trigger (struct interval* top, interval_t wakeup, time_t current) { if (wakeup) { msg (D_INTERVAL, "INTERVAL interval_future_trigger %d", (int)wakeup); top->future_trigger = current + wakeup; }}/* * Once an action is triggered, interval_test will remain true for * horizon seconds. */static inline voidinterval_action (struct interval* top, time_t current){ msg (D_INTERVAL, "INTERVAL action"); top->last_action = current;}/* * Measure when n seconds past an event have elapsed */struct event_timeout{ interval_t n; time_t last; /* time of last event */};static inline voidevent_timeout_init (struct event_timeout* et, time_t current, interval_t n){ et->n = n; et->last = current;}static inline voidevent_timeout_reset (struct event_timeout* et, time_t current){ et->last = current;}static inline boolevent_timeout_trigger (struct event_timeout* et, time_t current){ if (et->n && et->last + et->n <= current) { msg (D_INTERVAL, "EVENT event_timeout_trigger (%d)", et->n); et->last = current; return true; } return false;}static inline voidevent_timeout_wakeup (struct event_timeout* et, time_t current, struct timeval* tv){ if (et->n) { const int wakeup = (int) (et->last + et->n - current); if (wakeup > 0 && (!tv->tv_sec || wakeup < tv->tv_sec)) { msg (D_INTERVAL, "EVENT event_timeout_wakeup (%d/%d)", wakeup, et->n); tv->tv_sec = wakeup; tv->tv_usec = 0; } }}/* * Measure time intervals in microseconds */#define USEC_TIMER_MAX 60 /* maximum interval size in seconds */#define USEC_TIMER_MAX_USEC (USEC_TIMER_MAX * 1000000)struct usec_timer { struct timeval start; struct timeval end;};#ifdef HAVE_GETTIMEOFDAYstatic inline voidusec_timer_start (struct usec_timer *obj){ CLEAR (*obj); gettimeofday (&obj->start, NULL);}static inline voidusec_timer_end (struct usec_timer *obj){ gettimeofday (&obj->end, NULL);}#endif /* HAVE_GETTIMEOFDAY */static inline boolusec_timer_interval_defined (struct usec_timer *obj){ return obj->start.tv_sec && obj->end.tv_sec;}static inline intusec_timer_interval (struct usec_timer *obj){ return tv_subtract (&obj->end, &obj->start, USEC_TIMER_MAX);}#endif /* INTERVAL_H */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?