make MRU configurable, NAK config requests for larger values
[l2tpns.git] / throttlectl.c
1 #include <string.h>
2 #include "l2tpns.h"
3 #include "plugin.h"
4 #include "control.h"
5
6 /* throttle control */
7
8 char const *cvs_id = "$Id: throttlectl.c,v 1.7 2005-06-28 14:48:28 bodea Exp $";
9
10 int plugin_api_version = PLUGIN_API_VERSION;
11 static struct pluginfuncs *p = 0;
12
13 char *plugin_control_help[] = {
14 " throttle USER|SID [RATE|[in|out] RATE ...] Throttle user traffic",
15 " unthrottle USER|SID Stop throttling user",
16 0
17 };
18
19 int plugin_control(struct param_control *data)
20 {
21 sessionidt session;
22 sessiont *s = 0;
23 int flag;
24 char *end;
25 int rate_in = 0;
26 int rate_out = 0;
27
28 if (data->argc < 1)
29 return PLUGIN_RET_OK;
30
31 if (strcmp(data->argv[0], "throttle")
32 && strcmp(data->argv[0], "unthrottle"))
33 return PLUGIN_RET_OK; // not for us
34
35 if (!data->iam_master)
36 return PLUGIN_RET_NOTMASTER;
37
38 flag = data->argv[0][0] == 't';
39
40 if (flag)
41 {
42 if (data->argc < 2 || data->argc > 6)
43 {
44 data->response = NSCTL_RES_ERR;
45 data->additional = "requires username or session id and optional rate(s)";
46 return PLUGIN_RET_STOP;
47 }
48 }
49 else
50 {
51 if (data->argc != 2)
52 {
53 data->response = NSCTL_RES_ERR;
54 data->additional = "requires username or session id";
55 return PLUGIN_RET_STOP;
56 }
57 }
58
59 if (!(session = strtol(data->argv[1], &end, 10)) || *end)
60 session = p->get_session_by_username(data->argv[1]);
61
62 if (session)
63 s = p->get_session_by_id(session);
64
65 if (!s || !s->ip)
66 {
67 data->response = NSCTL_RES_ERR;
68 data->additional = "session not found";
69 return PLUGIN_RET_STOP;
70 }
71
72 if (flag)
73 {
74 rate_in = rate_out = -1;
75 if (data->argc == 2)
76 {
77 unsigned long *rate = p->getconfig("throttle_speed", UNSIGNED_LONG);
78 rate_in = rate_out = *rate;
79 }
80 else if (data->argc == 3)
81 {
82 rate_in = rate_out = atoi(data->argv[2]);
83 }
84 else
85 {
86 int i;
87 for (i = 2; i < data->argc - 1; i += 2)
88 {
89 int len = strlen(data->argv[i]);
90 if (!strncmp(data->argv[i], "in", len))
91 {
92 rate_in = atoi(data->argv[i+1]);
93 }
94 else if (!strncmp(data->argv[i], "out", len))
95 {
96 rate_out = atoi(data->argv[i+1]);
97 }
98 else
99 {
100 data->response = NSCTL_RES_ERR;
101 data->additional = "invalid rate";
102 return PLUGIN_RET_STOP;
103 }
104 }
105 }
106
107 if (!rate_in || !rate_out)
108 {
109 data->response = NSCTL_RES_ERR;
110 data->additional = "invalid rate";
111 return PLUGIN_RET_STOP;
112 }
113 }
114
115 if (rate_in != -1 && rate_in == s->throttle_in &&
116 rate_out != -1 && rate_out == s->throttle_out)
117 {
118 data->response = NSCTL_RES_ERR;
119 data->additional = flag ? "already throttled" : "not throttled";
120 return PLUGIN_RET_STOP;
121 }
122
123 p->throttle(session, rate_in, rate_out);
124 p->session_changed(session);
125
126 data->response = NSCTL_RES_OK;
127 data->additional = 0;
128
129 return PLUGIN_RET_STOP;
130 }
131
132 int plugin_radius_reset(struct param_radius_reset *data)
133 {
134 p->throttle(p->get_id_by_session(data->s), 0, 0);
135 return PLUGIN_RET_OK;
136 }
137
138 int plugin_init(struct pluginfuncs *funcs)
139 {
140 return ((p = funcs)) ? 1 : 0;
141 }