Blame
Date:
Mon Jan 11 09:00:47 2021 UTC
Message:
a usleep makes it unnecessary slow, I guess it forces a context switch...
001
2014-11-14
pjp
/*
002
2019-02-28
pjp
* Copyright (c) 2014-2019 Peter J. Philipp
003
2014-11-14
pjp
* All rights reserved.
004
2014-11-14
pjp
*
005
2014-11-14
pjp
* Redistribution and use in source and binary forms, with or without
006
2014-11-14
pjp
* modification, are permitted provided that the following conditions
007
2014-11-14
pjp
* are met:
008
2014-11-14
pjp
* 1. Redistributions of source code must retain the above copyright
009
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer.
010
2014-11-14
pjp
* 2. Redistributions in binary form must reproduce the above copyright
011
2014-11-14
pjp
* notice, this list of conditions and the following disclaimer in the
012
2014-11-14
pjp
* documentation and/or other materials provided with the distribution.
013
2014-11-14
pjp
* 3. The name of the author may not be used to endorse or promote products
014
2014-11-14
pjp
* derived from this software without specific prior written permission
015
2014-11-14
pjp
*
016
2014-11-14
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017
2014-11-14
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018
2014-11-14
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019
2014-11-14
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020
2014-11-14
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021
2014-11-14
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022
2014-11-14
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023
2014-11-14
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024
2014-11-14
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025
2014-11-14
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
026
2014-11-14
pjp
*
027
2014-11-14
pjp
*/
028
2017-10-26
pjp
029
2019-06-06
pjp
#include <sys/types.h>
030
2019-06-06
pjp
#include <sys/socket.h>
031
2019-06-06
pjp
#include <sys/mman.h>
032
2017-10-26
pjp
033
2019-06-06
pjp
#include <netinet/in.h>
034
2019-06-06
pjp
#include <arpa/inet.h>
035
2019-06-06
pjp
#include <netdb.h>
036
2019-06-06
pjp
037
2019-06-06
pjp
#include <stdio.h>
038
2019-06-06
pjp
#include <stdlib.h>
039
2019-06-06
pjp
#include <string.h>
040
2019-06-06
pjp
#include <errno.h>
041
2019-06-06
pjp
#include <syslog.h>
042
2019-06-06
pjp
#include <time.h>
043
2019-06-06
pjp
044
2019-06-06
pjp
#ifdef __linux__
045
2019-06-06
pjp
#include <grp.h>
046
2019-06-06
pjp
#define __USE_BSD 1
047
2019-06-06
pjp
#include <endian.h>
048
2019-06-06
pjp
#include <bsd/stdlib.h>
049
2019-06-06
pjp
#include <bsd/string.h>
050
2019-06-06
pjp
#include <bsd/sys/queue.h>
051
2019-06-06
pjp
#define __unused
052
2019-06-06
pjp
#include <bsd/sys/tree.h>
053
2019-06-06
pjp
#include <bsd/sys/endian.h>
054
2019-06-06
pjp
#else /* not linux */
055
2019-06-06
pjp
#include <sys/queue.h>
056
2019-06-06
pjp
#include <sys/tree.h>
057
2019-06-06
pjp
#endif /* __linux__ */
058
2019-06-06
pjp
059
2016-07-06
pjp
#include "ddd-dns.h"
060
2016-07-06
pjp
#include "ddd-db.h"
061
2016-07-06
pjp
062
2014-11-14
pjp
void add_rrlimit(int, u_int16_t *, int, char *);
063
2014-11-14
pjp
int check_rrlimit(int, u_int16_t *, int, char *);
064
2014-11-14
pjp
extern void dolog(int, char *, ...);
065
2014-11-14
pjp
static u_int16_t hash_rrlimit(u_int16_t *, int);
066
2014-11-14
pjp
char *rrlimit_setup(int);
067
2014-11-14
pjp
068
2014-11-14
pjp
struct rrlimit {
069
2014-11-14
pjp
u_int8_t pointer;
070
2014-11-14
pjp
time_t times[256];
071
2019-02-28
pjp
} __attribute__((packed));
072
2014-11-14
pjp
073
2014-11-14
pjp
int ratelimit = 0;
074
2014-11-14
pjp
int ratelimit_packets_per_second = 6;
075
2014-11-14
pjp
076
2014-11-14
pjp
char *
077
2014-11-14
pjp
rrlimit_setup(int size)
078
2014-11-14
pjp
{
079
2014-11-14
pjp
char *ptr;
080
2014-11-14
pjp
081
2014-11-14
pjp
if (size > 255)
082
2014-11-14
pjp
return NULL;
083
2014-11-14
pjp
084
2014-11-14
pjp
size = 65536 * ((size * sizeof(time_t)) + sizeof(u_int8_t));
085
2014-11-14
pjp
086
2014-11-14
pjp
ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED |\
087
2014-11-14
pjp
MAP_ANON, -1, 0);
088
2014-11-14
pjp
089
2014-11-14
pjp
if (ptr == MAP_FAILED) {
090
2014-11-14
pjp
dolog(LOG_ERR, "failed to setup rlimit mmap segment, exit\n");
091
2014-11-14
pjp
exit(1);
092
2014-11-14
pjp
}
093
2014-11-14
pjp
094
2014-11-14
pjp
memset(ptr, 0, size);
095
2014-11-14
pjp
096
2014-11-14
pjp
return (ptr);
097
2014-11-14
pjp
}
098
2014-11-14
pjp
099
2014-11-14
pjp
int
100
2014-11-14
pjp
check_rrlimit(int size, u_int16_t *ip, int sizeip, char *rrlimit_ptr)
101
2014-11-14
pjp
{
102
2014-11-14
pjp
struct rrlimit *rl;
103
2014-11-14
pjp
u_int16_t hash;
104
2014-11-14
pjp
int count = 0, i;
105
2014-11-14
pjp
u_int8_t offset;
106
2014-11-14
pjp
time_t now;
107
2014-11-14
pjp
char *tmp;
108
2014-11-14
pjp
109
2014-11-14
pjp
hash = hash_rrlimit(ip, sizeip);
110
2014-11-14
pjp
111
2014-11-14
pjp
tmp = rrlimit_ptr + (hash * ((size * sizeof(time_t)) + sizeof(u_int8_t)));
112
2014-11-14
pjp
rl = (struct rrlimit *)tmp;
113
2014-11-14
pjp
114
2014-11-14
pjp
offset = rl->pointer;
115
2014-11-14
pjp
116
2014-11-14
pjp
now = time(NULL);
117
2014-11-14
pjp
118
2014-11-14
pjp
for (i = 0; i < size; i++) {
119
2014-11-14
pjp
if (difftime(now, rl->times[(offset + i) % size]) <= 1)
120
2014-11-14
pjp
count++;
121
2014-11-14
pjp
else
122
2014-11-14
pjp
break;
123
2014-11-14
pjp
}
124
2014-11-14
pjp
125
2014-11-14
pjp
if (count > ratelimit_packets_per_second)
126
2014-11-14
pjp
return 1;
127
2014-11-14
pjp
128
2014-11-14
pjp
return 0;
129
2014-11-14
pjp
}
130
2014-11-14
pjp
131
2014-11-14
pjp
132
2014-11-14
pjp
void
133
2014-11-14
pjp
add_rrlimit(int size, u_int16_t *ip, int sizeip, char *rrlimit_ptr)
134
2014-11-14
pjp
{
135
2014-11-14
pjp
struct rrlimit *rl;
136
2014-11-14
pjp
u_int16_t hash;
137
2014-11-14
pjp
int offset;
138
2014-11-14
pjp
time_t now;
139
2014-11-14
pjp
char *tmp;
140
2014-11-14
pjp
141
2014-11-14
pjp
hash = hash_rrlimit(ip, sizeip);
142
2014-11-14
pjp
143
2014-11-14
pjp
tmp = rrlimit_ptr + (hash * ((size * sizeof(time_t)) + sizeof(u_int8_t)));
144
2014-11-14
pjp
rl = (struct rrlimit *)tmp;
145
2014-11-14
pjp
146
2014-11-14
pjp
offset = rl->pointer;
147
2014-11-14
pjp
148
2014-11-14
pjp
offset--;
149
2014-11-14
pjp
if (offset < 0)
150
2014-11-14
pjp
offset = size - 1;
151
2014-11-14
pjp
152
2014-11-14
pjp
now = time(NULL);
153
2014-11-14
pjp
154
2014-11-14
pjp
rl->times[offset] = now;
155
2014-11-14
pjp
rl->pointer = offset; /* XXX race */
156
2014-11-14
pjp
157
2014-11-14
pjp
}
158
2014-11-14
pjp
159
2014-11-14
pjp
static u_int16_t
160
2014-11-14
pjp
hash_rrlimit(u_int16_t *ip, int size)
161
2014-11-14
pjp
{
162
2014-11-14
pjp
u_int64_t total = 0;
163
2014-11-14
pjp
int i, j;
164
2014-11-14
pjp
165
2014-11-14
pjp
for (i = 0, j = 0; i < size; i += 2) {
166
2014-11-14
pjp
total += (u_int64_t)ip[j++];
167
2014-11-14
pjp
}
168
2014-11-14
pjp
169
2014-11-14
pjp
total %= 0xffff;
170
2014-11-14
pjp
171
2014-11-14
pjp
return ((u_int16_t)total);
172
2014-11-14
pjp
}
repomaster@centroid.eu