Blame


1 4667e76d 2014-05-05 pjp /*
2 4667e76d 2014-05-05 pjp * Copyright (c) 2014 Peter J. Philipp
3 4667e76d 2014-05-05 pjp * All rights reserved.
4 4667e76d 2014-05-05 pjp *
5 4667e76d 2014-05-05 pjp * Redistribution and use in source and binary forms, with or without
6 4667e76d 2014-05-05 pjp * modification, are permitted provided that the following conditions
7 4667e76d 2014-05-05 pjp * are met:
8 4667e76d 2014-05-05 pjp * 1. Redistributions of source code must retain the above copyright
9 4667e76d 2014-05-05 pjp * notice, this list of conditions and the following disclaimer.
10 4667e76d 2014-05-05 pjp * 2. Redistributions in binary form must reproduce the above copyright
11 4667e76d 2014-05-05 pjp * notice, this list of conditions and the following disclaimer in the
12 4667e76d 2014-05-05 pjp * documentation and/or other materials provided with the distribution.
13 4667e76d 2014-05-05 pjp * 3. The name of the author may not be used to endorse or promote products
14 4667e76d 2014-05-05 pjp * derived from this software without specific prior written permission
15 4667e76d 2014-05-05 pjp *
16 4667e76d 2014-05-05 pjp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 4667e76d 2014-05-05 pjp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 4667e76d 2014-05-05 pjp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 4667e76d 2014-05-05 pjp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 4667e76d 2014-05-05 pjp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 4667e76d 2014-05-05 pjp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 4667e76d 2014-05-05 pjp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 4667e76d 2014-05-05 pjp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 4667e76d 2014-05-05 pjp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 4667e76d 2014-05-05 pjp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 4667e76d 2014-05-05 pjp *
27 4667e76d 2014-05-05 pjp */
28 4667e76d 2014-05-05 pjp #include "include.h"
29 4667e76d 2014-05-05 pjp #include "dns.h"
30 4667e76d 2014-05-05 pjp #include "db.h"
31 4667e76d 2014-05-05 pjp
32 0e7d94ac 2014-05-18 pjp void add_rrlimit(int, u_int16_t *, int, char *);
33 0e7d94ac 2014-05-18 pjp int check_rrlimit(int, u_int16_t *, int, char *);
34 0e7d94ac 2014-05-18 pjp extern void dolog(int, char *, ...);
35 0e7d94ac 2014-05-18 pjp static u_int16_t hash_rrlimit(u_int16_t *, int);
36 0e7d94ac 2014-05-18 pjp char *rrlimit_setup(int);
37 4667e76d 2014-05-05 pjp
38 4667e76d 2014-05-05 pjp struct rrlimit {
39 4667e76d 2014-05-05 pjp u_int8_t pointer;
40 4667e76d 2014-05-05 pjp time_t times[256];
41 4667e76d 2014-05-05 pjp };
42 4667e76d 2014-05-05 pjp
43 4667e76d 2014-05-05 pjp int ratelimit = 0;
44 4667e76d 2014-05-05 pjp int ratelimit_packets_per_second = 6;
45 4667e76d 2014-05-05 pjp
46 4667e76d 2014-05-05 pjp char *
47 4667e76d 2014-05-05 pjp rrlimit_setup(int size)
48 4667e76d 2014-05-05 pjp {
49 4667e76d 2014-05-05 pjp char *ptr;
50 4667e76d 2014-05-05 pjp
51 4667e76d 2014-05-05 pjp if (size > 255)
52 4667e76d 2014-05-05 pjp return NULL;
53 4667e76d 2014-05-05 pjp
54 4667e76d 2014-05-05 pjp size = 65536 * ((size * sizeof(time_t)) + sizeof(u_int8_t));
55 4667e76d 2014-05-05 pjp
56 4667e76d 2014-05-05 pjp ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED |\
57 4667e76d 2014-05-05 pjp MAP_ANON, -1, 0);
58 4667e76d 2014-05-05 pjp
59 4667e76d 2014-05-05 pjp if (ptr == MAP_FAILED) {
60 4667e76d 2014-05-05 pjp dolog(LOG_ERR, "failed to setup rlimit mmap segment, exit\n");
61 4667e76d 2014-05-05 pjp exit(1);
62 4667e76d 2014-05-05 pjp }
63 4667e76d 2014-05-05 pjp
64 4667e76d 2014-05-05 pjp memset(ptr, 0, size);
65 4667e76d 2014-05-05 pjp
66 4667e76d 2014-05-05 pjp return (ptr);
67 4667e76d 2014-05-05 pjp }
68 4667e76d 2014-05-05 pjp
69 4667e76d 2014-05-05 pjp int
70 4667e76d 2014-05-05 pjp check_rrlimit(int size, u_int16_t *ip, int sizeip, char *rrlimit_ptr)
71 4667e76d 2014-05-05 pjp {
72 4667e76d 2014-05-05 pjp struct rrlimit *rl;
73 4667e76d 2014-05-05 pjp u_int16_t hash;
74 4667e76d 2014-05-05 pjp int count = 0, i;
75 4667e76d 2014-05-05 pjp u_int8_t offset;
76 4667e76d 2014-05-05 pjp time_t now;
77 4667e76d 2014-05-05 pjp char *tmp;
78 4667e76d 2014-05-05 pjp
79 4667e76d 2014-05-05 pjp hash = hash_rrlimit(ip, sizeip);
80 4667e76d 2014-05-05 pjp
81 4667e76d 2014-05-05 pjp tmp = rrlimit_ptr + (hash * ((size * sizeof(time_t)) + sizeof(u_int8_t)));
82 4667e76d 2014-05-05 pjp rl = (struct rrlimit *)tmp;
83 4667e76d 2014-05-05 pjp
84 4667e76d 2014-05-05 pjp offset = rl->pointer;
85 4667e76d 2014-05-05 pjp
86 4667e76d 2014-05-05 pjp now = time(NULL);
87 4667e76d 2014-05-05 pjp
88 4667e76d 2014-05-05 pjp for (i = 0; i < size; i++) {
89 4667e76d 2014-05-05 pjp if (difftime(now, rl->times[(offset + i) % size]) <= 1)
90 4667e76d 2014-05-05 pjp count++;
91 4667e76d 2014-05-05 pjp else
92 4667e76d 2014-05-05 pjp break;
93 4667e76d 2014-05-05 pjp }
94 4667e76d 2014-05-05 pjp
95 4667e76d 2014-05-05 pjp if (count > ratelimit_packets_per_second)
96 4667e76d 2014-05-05 pjp return 1;
97 4667e76d 2014-05-05 pjp
98 4667e76d 2014-05-05 pjp return 0;
99 4667e76d 2014-05-05 pjp }
100 4667e76d 2014-05-05 pjp
101 4667e76d 2014-05-05 pjp
102 4667e76d 2014-05-05 pjp void
103 4667e76d 2014-05-05 pjp add_rrlimit(int size, u_int16_t *ip, int sizeip, char *rrlimit_ptr)
104 4667e76d 2014-05-05 pjp {
105 4667e76d 2014-05-05 pjp struct rrlimit *rl;
106 4667e76d 2014-05-05 pjp u_int16_t hash;
107 4667e76d 2014-05-05 pjp int offset;
108 4667e76d 2014-05-05 pjp time_t now;
109 4667e76d 2014-05-05 pjp char *tmp;
110 4667e76d 2014-05-05 pjp
111 4667e76d 2014-05-05 pjp hash = hash_rrlimit(ip, sizeip);
112 4667e76d 2014-05-05 pjp
113 4667e76d 2014-05-05 pjp tmp = rrlimit_ptr + (hash * ((size * sizeof(time_t)) + sizeof(u_int8_t)));
114 4667e76d 2014-05-05 pjp rl = (struct rrlimit *)tmp;
115 4667e76d 2014-05-05 pjp
116 4667e76d 2014-05-05 pjp offset = rl->pointer;
117 4667e76d 2014-05-05 pjp
118 4667e76d 2014-05-05 pjp offset--;
119 4667e76d 2014-05-05 pjp if (offset < 0)
120 4667e76d 2014-05-05 pjp offset = size - 1;
121 4667e76d 2014-05-05 pjp
122 4667e76d 2014-05-05 pjp now = time(NULL);
123 4667e76d 2014-05-05 pjp
124 4667e76d 2014-05-05 pjp rl->times[offset] = now;
125 4667e76d 2014-05-05 pjp rl->pointer = offset; /* XXX race */
126 4667e76d 2014-05-05 pjp
127 4667e76d 2014-05-05 pjp }
128 4667e76d 2014-05-05 pjp
129 4667e76d 2014-05-05 pjp static u_int16_t
130 4667e76d 2014-05-05 pjp hash_rrlimit(u_int16_t *ip, int size)
131 4667e76d 2014-05-05 pjp {
132 4667e76d 2014-05-05 pjp u_int64_t total = 0;
133 5545c2c4 2014-05-07 pjp int i, j;
134 4667e76d 2014-05-05 pjp
135 5545c2c4 2014-05-07 pjp for (i = 0, j = 0; i < size; i += 2) {
136 5545c2c4 2014-05-07 pjp total += (u_int64_t)ip[j++];
137 4667e76d 2014-05-05 pjp }
138 4667e76d 2014-05-05 pjp
139 4667e76d 2014-05-05 pjp total %= 0xffff;
140 4667e76d 2014-05-05 pjp
141 4667e76d 2014-05-05 pjp return ((u_int16_t)total);
142 4667e76d 2014-05-05 pjp }