make MRU configurable, NAK config requests for larger values
[l2tpns.git] / autothrottle.c
1 #include <string.h>
2 #include "l2tpns.h"
3 #include "plugin.h"
4
5 /* set up throttling based on RADIUS reply */
6
7 /*
8 * lcp:interface-config#1=service-policy input N
9 * lcp:interface-config#2=service-policy output N
10 *
11 * throttle=N
12 * throttle=yes (use throttle_rate from config)
13 * throttle=no
14 */
15
16 char const *cvs_id = "$Id: autothrottle.c,v 1.14 2005-05-13 05:28:16 bodea Exp $";
17
18 int plugin_api_version = PLUGIN_API_VERSION;
19 struct pluginfuncs *p;
20
21 #define THROTTLE_KEY "lcp:interface-config"
22
23 int plugin_radius_response(struct param_radius_response *data)
24 {
25 if (!strncmp(data->key, THROTTLE_KEY, sizeof(THROTTLE_KEY) - 1))
26 {
27 char *sp = strchr(data->value, ' ');
28 char type;
29 int rate;
30
31 if (!sp || sp - data->value < 4 ||
32 strncmp("service-policy", data->value, sp - data->value))
33 return PLUGIN_RET_OK;
34
35 while (*sp == ' ') sp++;
36 data->value = sp;
37
38 if (!(sp = strchr(data->value, ' ')) ||
39 (strncmp("input", data->value, sp - data->value) &&
40 strncmp("output", data->value, sp - data->value)))
41 {
42 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
43 " Not throttling user (invalid type %.*s)\n",
44 sp - data->value, data->value);
45
46 return PLUGIN_RET_OK;
47 }
48
49 type = *data->value;
50
51 while (*sp == ' ') sp++;
52 data->value = sp;
53
54 if ((rate = strtol(data->value, &sp, 10)) < 0 || *sp)
55 {
56 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
57 " Not throttling user (invalid rate %s)\n",
58 data->value);
59
60 return PLUGIN_RET_OK;
61 }
62
63 if (type == 'i')
64 {
65 data->s->throttle_in = rate;
66 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
67 " Throttling user input to %dkb/s\n",
68 rate);
69 }
70 else
71 {
72 data->s->throttle_out = rate;
73 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
74 " Throttling user output to %dkb/s\n",
75 rate);
76 }
77 }
78
79 if (!strcmp(data->key, "throttle"))
80 {
81 char *e;
82 int rate;
83
84 if ((rate = strtol(data->value, &e, 10)) < 0 || *e)
85 {
86 rate = -1;
87 if (!strcmp(data->value, "yes"))
88 {
89 unsigned long *ts = p->getconfig("throttle_speed", UNSIGNED_LONG);
90 if (ts)
91 rate = *ts;
92 }
93 else if (!strcmp(data->value, "no"))
94 rate = 0;
95 }
96
97 if (rate < 0)
98 return PLUGIN_RET_OK;
99
100 if (rate)
101 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
102 " Throttling user to %dkb/s\n", rate);
103 else
104 p->log(3, p->get_id_by_session(data->s), data->s->tunnel,
105 " Not throttling user\n");
106
107 data->s->throttle_in = data->s->throttle_out = rate;
108 }
109
110 return PLUGIN_RET_OK;
111 }
112
113 int plugin_init(struct pluginfuncs *funcs)
114 {
115 return ((p = funcs)) ? 1 : 0;
116 }