File: throttlectl.c

package info (click to toggle)
l2tpns 2.1.21-1.1
  • links: PTS
  • area: main
  • in suites: lenny, squeeze, wheezy
  • size: 820 kB
  • ctags: 1,621
  • sloc: ansic: 16,737; makefile: 160; sh: 142; perl: 139
file content (135 lines) | stat: -rw-r--r-- 2,919 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <string.h>
#include "l2tpns.h"
#include "plugin.h"
#include "control.h"

/* throttle control */

char const *cvs_id = "$Id: throttlectl.c,v 1.9 2005/10/11 09:04:53 bodea Exp $";

int plugin_api_version = PLUGIN_API_VERSION;
static struct pluginfuncs *f = 0;

char *plugin_control_help[] = {
    "  throttle USER|SID [RATE|[in|out] RATE ...]  Throttle user traffic",
    "  unthrottle USER|SID                         Stop throttling user",
    0
};

int plugin_control(struct param_control *data)
{
    sessionidt session;
    sessiont *s = 0;
    int flag;
    char *end;
    int rate_in = 0;
    int rate_out = 0;

    if (data->argc < 1)
	return PLUGIN_RET_OK;

    if (strcmp(data->argv[0], "throttle") &&
    	strcmp(data->argv[0], "unthrottle"))
	return PLUGIN_RET_OK; // not for us

    if (!data->iam_master)
	return PLUGIN_RET_NOTMASTER;

    flag = data->argv[0][0] == 't';

    if (flag)
    {
	if (data->argc < 2 || data->argc > 6)
	{
	    data->response = NSCTL_RES_ERR;
	    data->additional = "requires username or session id and optional rate(s)";
	    return PLUGIN_RET_STOP;
	}
    }
    else
    {
	if (data->argc != 2)
	{
	    data->response = NSCTL_RES_ERR;
	    data->additional = "requires username or session id";
	    return PLUGIN_RET_STOP;
	}
    }

    if (!(session = strtol(data->argv[1], &end, 10)) || *end)
	session = f->get_session_by_username(data->argv[1]);

    if (session)
	s = f->get_session_by_id(session);

    if (!s || !s->ip)
    {
	data->response = NSCTL_RES_ERR;
	data->additional = "session not found";
	return PLUGIN_RET_STOP;
    }

    if (flag)
    {
	rate_in = rate_out = -1;
	if (data->argc == 2)
	{
	    unsigned long *rate = f->getconfig("throttle_speed", UNSIGNED_LONG);
	    rate_in = rate_out = *rate;
	}
	else if (data->argc == 3)
	{
	    rate_in = rate_out = atoi(data->argv[2]);
	}
	else
	{
	    int i;
	    for (i = 2; i < data->argc - 1; i += 2)
	    {
		int len = strlen(data->argv[i]);
		if (!strncmp(data->argv[i], "in", len))
		{
		    rate_in = atoi(data->argv[i+1]);
		}
		else if (!strncmp(data->argv[i], "out", len))
		{
		    rate_out = atoi(data->argv[i+1]);
		}
		else
		{
		    data->response = NSCTL_RES_ERR;
		    data->additional = "invalid rate";
		    return PLUGIN_RET_STOP;
		}
	    }
	}

	if (!rate_in || !rate_out)
	{
	    data->response = NSCTL_RES_ERR;
	    data->additional = "invalid rate";
	    return PLUGIN_RET_STOP;
	}
    }

    if (rate_in != -1 && rate_in == s->throttle_in &&
	rate_out != -1 && rate_out == s->throttle_out)
    {
	data->response = NSCTL_RES_ERR;
	data->additional = flag ? "already throttled" : "not throttled";
	return PLUGIN_RET_STOP;
    }

    f->throttle(session, rate_in, rate_out);
    f->session_changed(session);

    data->response = NSCTL_RES_OK;
    data->additional = 0;

    return PLUGIN_RET_STOP;
}

int plugin_init(struct pluginfuncs *funcs)
{
    return ((f = funcs)) ? 1 : 0;
}