summaryrefslogtreecommitdiff
path: root/accel-pppd/ctrl/pppoe/dpado.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/ctrl/pppoe/dpado.c')
-rw-r--r--accel-pppd/ctrl/pppoe/dpado.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/pppoe/dpado.c b/accel-pppd/ctrl/pppoe/dpado.c
new file mode 100644
index 00000000..3f565198
--- /dev/null
+++ b/accel-pppd/ctrl/pppoe/dpado.c
@@ -0,0 +1,162 @@
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+
+#include "list.h"
+#include "cli.h"
+#include "triton.h"
+#include "log.h"
+#include "memdebug.h"
+
+#include "pppoe.h"
+
+struct dpado_range_t
+{
+ struct list_head entry;
+ unsigned int conn_cnt;
+ int pado_delay;
+};
+
+static pthread_mutex_t dpado_range_lock = PTHREAD_MUTEX_INITIALIZER;
+static LIST_HEAD(dpado_range_list);
+static struct dpado_range_t *dpado_range_next;
+static struct dpado_range_t *dpado_range_prev;
+int pado_delay;
+
+void dpado_check_next(int conn_cnt)
+{
+ pthread_mutex_lock(&dpado_range_lock);
+ if (dpado_range_next && conn_cnt == dpado_range_next->conn_cnt) {
+ pado_delay = dpado_range_next->pado_delay;
+ dpado_range_prev = dpado_range_next;
+ if (dpado_range_next->entry.next != &dpado_range_list)
+ dpado_range_next = list_entry(dpado_range_next->entry.next, typeof(*dpado_range_next), entry);
+ else
+ dpado_range_next = NULL;
+ /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active,
+ dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0,
+ dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0,
+ pado_delay);*/
+ }
+ pthread_mutex_unlock(&dpado_range_lock);
+}
+
+void dpado_check_prev(int conn_cnt)
+{
+ pthread_mutex_lock(&dpado_range_lock);
+ if (dpado_range_prev && conn_cnt == dpado_range_prev->conn_cnt) {
+ dpado_range_next = dpado_range_prev;
+ dpado_range_prev = list_entry(dpado_range_prev->entry.prev, typeof(*dpado_range_prev), entry);
+ pado_delay = dpado_range_prev->pado_delay;
+ /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active,
+ dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0,
+ dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0,
+ pado_delay);*/
+ }
+ pthread_mutex_unlock(&dpado_range_lock);
+}
+
+static void strip(char *str)
+{
+ char *ptr = str;
+ char *endptr = strchr(str, 0);
+ while (1) {
+ ptr = strchr(ptr, ' ');
+ if (ptr)
+ memmove(ptr, ptr + 1, endptr - ptr - 1);
+ else
+ break;
+ }
+}
+
+int dpado_parse(const char *str)
+{
+ char *str1 = _strdup(str);
+ char *ptr1, *ptr2, *ptr3, *endptr;
+ LIST_HEAD(range_list);
+ struct dpado_range_t *r;
+
+ strip(str1);
+
+ ptr1 = str1;
+
+ while (1) {
+ ptr2 = strchr(ptr1, ',');
+ if (ptr2)
+ *ptr2 = 0;
+ ptr3 = strchr(ptr1, ':');
+ if (ptr3)
+ *ptr3 = 0;
+
+ r = _malloc(sizeof(*r));
+ memset(r, 0, sizeof(*r));
+
+ r->pado_delay = strtol(ptr1, &endptr, 10);
+ if (*endptr)
+ goto out_err;
+
+ if (list_empty(&range_list))
+ r->conn_cnt = INT_MAX;
+ else {
+ if (!ptr3)
+ goto out_err;
+ r->conn_cnt = strtol(ptr3 + 1, &endptr, 10);
+ if (*endptr)
+ goto out_err;
+ }
+
+ list_add_tail(&r->entry, &range_list);
+ //printf("parsed range: %i:%i\n", r->pado_delay, r->conn_cnt);
+
+ if (!ptr2)
+ break;
+
+ ptr1 = ptr2 + 1;
+ }
+
+ pthread_mutex_lock(&dpado_range_lock);
+ while (!list_empty(&dpado_range_list)) {
+ r = list_entry(dpado_range_list.next, typeof(*r), entry);
+ list_del(&r->entry);
+ _free(r);
+ }
+
+ dpado_range_next = NULL;
+ dpado_range_prev = NULL;
+
+ while (!list_empty(&range_list)) {
+ r = list_entry(range_list.next, typeof(*r), entry);
+ list_del(&r->entry);
+ list_add_tail(&r->entry, &dpado_range_list);
+
+ if (!dpado_range_prev || stat_active >= r->conn_cnt)
+ dpado_range_prev = r;
+ else if (!dpado_range_next)
+ dpado_range_next = r;
+ }
+
+ pado_delay = dpado_range_prev->pado_delay;
+
+ if (conf_pado_delay)
+ _free(conf_pado_delay);
+ conf_pado_delay = _strdup(str);
+ /*printf("active=%i, prev=%i:%i, next=%i:%i, pado_delay=%i\n", stat_active,
+ dpado_range_prev?dpado_range_prev->pado_delay:0,dpado_range_prev?dpado_range_prev->conn_cnt:0,
+ dpado_range_next?dpado_range_next->pado_delay:0,dpado_range_next?dpado_range_next->conn_cnt:0,
+ pado_delay);*/
+
+ pthread_mutex_unlock(&dpado_range_lock);
+
+ _free(str1);
+ return 0;
+
+out_err:
+ _free(str1);
+ log_emerg("pppoe: pado_delay: invalid format\n");
+ return -1;
+}
+