1 /*
2 MiddleMan filtering proxy server
3 Copyright (C) 2002 Jason McLaughlin
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <time.h>
23 #include "proto.h"
24
limits_load(LIMITS_LIST * limits_list,XML_LIST * xml_list)25 LIMITS_LIST *limits_load(LIMITS_LIST * limits_list, XML_LIST * xml_list)
26 {
27 LIMITS_LIST *tmp_list = limits_list;
28 struct LIMITS_LIST_LIST *ll = NULL;
29 struct tm from, to;
30 int totime, fromtime;
31
32 if (tmp_list == NULL) {
33 tmp_list = xmalloc(sizeof(LIMITS_LIST));
34 tmp_list->limits_list = NULL;
35 tmp_list->enabled = TRUE;
36 tmp_list->id = 0;
37
38 limits_list = tmp_list;
39
40 pthread_rwlock_init(&tmp_list->lock, NULL);
41 } else
42 ll = limits_list->limits_list;
43
44 while ((xml_list = xml_section(xml_list, "<limits>"))) {
45 XML_LIST_LOOP(xml_list, "<limits>") {
46 XML_LIST_CMP(xml_list, "<item>") {
47 ll = limits_ll_new(ll);
48 ll->id = tmp_list->id++;
49
50 if (limits_list->limits_list == NULL)
51 limits_list->limits_list = ll;
52
53 memset(&from, 0, sizeof(struct tm));
54 memset(&to, 0, sizeof(struct tm));
55 fromtime = totime = FALSE;
56
57 XML_LIST_LOOP(xml_list, "<item>") {
58 XML_LIST_CMP(xml_list, "<enabled>") {
59 xml_list = xml_list->next;
60 if (xml_list->type == XML_VALUE) {
61 if (!strcasecmp(xml_list->item, "false"))
62 ll->enabled = FALSE;
63 else
64 ll->enabled = TRUE;
65 }
66 }
67 XML_LIST_CMP(xml_list, "<action>") {
68 xml_list = xml_list->next;
69 if (xml_list->type == XML_VALUE) {
70 if (!strcasecmp(xml_list->item, "allow"))
71 ll->action = POLICY_ALLOW;
72 else
73 ll->action = POLICY_DENY;
74 }
75 }
76 XML_LIST_CMP(xml_list, "<profiles>") {
77 xml_list = xml_list->next;
78 if (xml_list->type == XML_VALUE)
79 limits_ll_insert(ll, xml_list->item, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
80 }
81 XML_LIST_CMP(xml_list, "<comment>") {
82 xml_list = xml_list->next;
83 if (xml_list->type == XML_VALUE)
84 limits_ll_insert(ll, NULL, xml_list->item, NULL, NULL, NULL, NULL, NULL, NULL);
85 }
86 XML_LIST_CMP(xml_list, "<template>") {
87 xml_list = xml_list->next;
88 if (xml_list->type == XML_VALUE)
89 limits_ll_insert(ll, NULL, NULL, xml_list->item, NULL, NULL, NULL, NULL, NULL);
90 }
91 XML_LIST_CMP(xml_list, "<fromhour>") {
92 xml_list = xml_list->next;
93 if (xml_list->type == XML_VALUE) {
94 fromtime = TRUE;
95 from.tm_hour = strtol(xml_list->item, NULL, 10);
96 }
97 }
98 XML_LIST_CMP(xml_list, "<frommin>") {
99 xml_list = xml_list->next;
100 if (xml_list->type == XML_VALUE) {
101 fromtime = TRUE;
102 from.tm_min = strtol(xml_list->item, NULL, 10);
103 }
104 }
105 XML_LIST_CMP(xml_list, "<frommday>") {
106 xml_list = xml_list->next;
107 if (xml_list->type == XML_VALUE) {
108 fromtime = TRUE;
109 from.tm_mday = strtol(xml_list->item, NULL, 10);
110 }
111 }
112 XML_LIST_CMP(xml_list, "<frommon>") {
113 xml_list = xml_list->next;
114 if (xml_list->type == XML_VALUE) {
115 fromtime = TRUE;
116 from.tm_mon = strtol(xml_list->item, NULL, 10);
117 }
118 }
119 XML_LIST_CMP(xml_list, "<fromwday>") {
120 xml_list = xml_list->next;
121 if (xml_list->type == XML_VALUE) {
122 fromtime = TRUE;
123 from.tm_wday = strtol(xml_list->item, NULL, 10);
124 }
125 }
126 XML_LIST_CMP(xml_list, "<tohour>") {
127 xml_list = xml_list->next;
128 if (xml_list->type == XML_VALUE) {
129 totime = TRUE;
130 to.tm_hour = strtol(xml_list->item, NULL, 10);
131 }
132 }
133 XML_LIST_CMP(xml_list, "<tomin>") {
134 xml_list = xml_list->next;
135 if (xml_list->type == XML_VALUE) {
136 totime = TRUE;
137 to.tm_min = strtol(xml_list->item, NULL, 10);
138 }
139 }
140 XML_LIST_CMP(xml_list, "<tomday>") {
141 xml_list = xml_list->next;
142 if (xml_list->type == XML_VALUE) {
143 totime = TRUE;
144 to.tm_mday = strtol(xml_list->item, NULL, 10);
145 }
146 }
147 XML_LIST_CMP(xml_list, "<tomon>") {
148 xml_list = xml_list->next;
149 if (xml_list->type == XML_VALUE) {
150 totime = TRUE;
151 to.tm_mon = strtol(xml_list->item, NULL, 10);
152 }
153 }
154 XML_LIST_CMP(xml_list, "<towday>") {
155 xml_list = xml_list->next;
156 if (xml_list->type == XML_VALUE) {
157 totime = TRUE;
158 to.tm_wday = strtol(xml_list->item, NULL, 10);
159 }
160 }
161 XML_LIST_CMP(xml_list, "<maxbytes>") {
162 xml_list = xml_list->next;
163 if (xml_list->type == XML_VALUE)
164 limits_ll_insert(ll, NULL, NULL, NULL, NULL, NULL, xml_list->item, NULL, NULL);
165 }
166 XML_LIST_CMP(xml_list, "<maxrequests>") {
167 xml_list = xml_list->next;
168 if (xml_list->type == XML_VALUE)
169 limits_ll_insert(ll, NULL, NULL, NULL, NULL, NULL, NULL, xml_list->item, NULL);
170 }
171 XML_LIST_CMP(xml_list, "<flags>") {
172 xml_list = xml_list->next;
173 if (xml_list->type == XML_VALUE)
174 limits_ll_insert(ll, NULL, NULL, NULL, NULL, NULL, NULL, NULL, xml_list->item);
175 }
176 }
177
178 if (fromtime == TRUE)
179 limits_ll_insert(ll, NULL, NULL, NULL, &from, NULL, NULL, NULL, NULL);
180 if (totime == TRUE)
181 limits_ll_insert(ll, NULL, NULL, NULL, NULL, &to, NULL, NULL, NULL);
182 }
183 XML_LIST_CMP(xml_list, "<enabled>") {
184 xml_list = xml_list->next;
185 if (xml_list->type == XML_VALUE) {
186 if (!strcasecmp(xml_list->item, "false"))
187 limits_list->enabled = FALSE;
188 else
189 limits_list->enabled = TRUE;
190 }
191 }
192 }
193 }
194
195
196 return limits_list;
197 }
198
limits_xml(LIMITS_LIST * limits_list,XML_LIST * xml_list)199 XML_LIST *limits_xml(LIMITS_LIST * limits_list, XML_LIST * xml_list)
200 {
201 char *ptr, buf[128];
202 struct LIMITS_LIST_LIST *ll;
203
204 pthread_rwlock_rdlock(&limits_list->lock);
205
206 xml_list = xml_list_add(xml_list, "<limits>", XML_TAG);
207
208 xml_list = xml_list_add(xml_list, "<enabled>", XML_TAG);
209 xml_list = xml_list_add(xml_list, (limits_list->enabled == TRUE) ? "true" : "false", XML_VALUE);
210 xml_list = xml_list_add(xml_list, "</enabled>", XML_TAG);
211
212 for (ll = limits_list->limits_list; ll; ll = ll->next) {
213 xml_list = xml_list_add(xml_list, "<item>", XML_TAG);
214
215 if (ll->comment != NULL) {
216 xml_list = xml_list_add(xml_list, "<comment>", XML_TAG);
217 ptr = string_to_xml(ll->comment);
218 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
219 xfree(ptr);
220 xml_list = xml_list_add(xml_list, "</comment>", XML_TAG);
221 }
222
223 if (ll->profiles != NULL) {
224 xml_list = xml_list_add(xml_list, "<profiles>", XML_TAG);
225 ptr = array_merge(ll->profiles, ',');
226 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
227 xfree(ptr);
228 xml_list = xml_list_add(xml_list, "</profiles>", XML_TAG);
229 }
230
231 xml_list = xml_list_add(xml_list, "<action>", XML_TAG);
232 xml_list = xml_list_add(xml_list, (ll->action == POLICY_ALLOW) ? "allow" : "deny", XML_VALUE);
233 xml_list = xml_list_add(xml_list, "</action>", XML_TAG);
234
235 if (ll->template != NULL) {
236 xml_list = xml_list_add(xml_list, "<template>", XML_TAG);
237 ptr = string_to_xml(ll->template);
238 xml_list = xml_list_add(xml_list, ptr, XML_VALUE);
239 xfree(ptr);
240 xml_list = xml_list_add(xml_list, "</template>", XML_TAG);
241 }
242
243 if (ll->from != NULL) {
244 if (ll->from->tm_hour != 0) {
245 xml_list = xml_list_add(xml_list, "<fromhour>", XML_TAG);
246 snprintf(buf, sizeof(buf), "%d", ll->from->tm_hour);
247 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
248 xml_list = xml_list_add(xml_list, "</fromhour>", XML_TAG);
249 }
250
251 if (ll->from->tm_min != 0) {
252 xml_list = xml_list_add(xml_list, "<frommin>", XML_TAG);
253 snprintf(buf, sizeof(buf), "%d", ll->from->tm_min);
254 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
255 xml_list = xml_list_add(xml_list, "</frommin>", XML_TAG);
256 }
257
258 if (ll->from->tm_mday != 0) {
259 xml_list = xml_list_add(xml_list, "<frommday>", XML_TAG);
260 snprintf(buf, sizeof(buf), "%d", ll->from->tm_mday);
261 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
262 xml_list = xml_list_add(xml_list, "</frommday>", XML_TAG);
263 }
264
265 if (ll->from->tm_mon != 0) {
266 xml_list = xml_list_add(xml_list, "<frommon>", XML_TAG);
267 snprintf(buf, sizeof(buf), "%d", ll->from->tm_mon);
268 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
269 xml_list = xml_list_add(xml_list, "</frommon>", XML_TAG);
270 }
271
272 if (ll->from->tm_wday != 0) {
273 xml_list = xml_list_add(xml_list, "<fromwday>", XML_TAG);
274 snprintf(buf, sizeof(buf), "%d", ll->from->tm_wday);
275 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
276 xml_list = xml_list_add(xml_list, "</fromwday>", XML_TAG);
277 }
278 }
279
280 if (ll->to != NULL) {
281 if (ll->to->tm_hour != 0) {
282 xml_list = xml_list_add(xml_list, "<tohour>", XML_TAG);
283 snprintf(buf, sizeof(buf), "%d", ll->to->tm_hour);
284 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
285 xml_list = xml_list_add(xml_list, "</tohour>", XML_TAG);
286 }
287
288 if (ll->to->tm_min != 0) {
289 xml_list = xml_list_add(xml_list, "<tomin>", XML_TAG);
290 snprintf(buf, sizeof(buf), "%d", ll->to->tm_min);
291 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
292 xml_list = xml_list_add(xml_list, "</tomin>", XML_TAG);
293 }
294
295 if (ll->to->tm_mday != 0) {
296 xml_list = xml_list_add(xml_list, "<tomday>", XML_TAG);
297 snprintf(buf, sizeof(buf), "%d", ll->to->tm_mday);
298 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
299 xml_list = xml_list_add(xml_list, "</tomday>", XML_TAG);
300 }
301
302 if (ll->to->tm_mon != 0) {
303 xml_list = xml_list_add(xml_list, "<tomon>", XML_TAG);
304 snprintf(buf, sizeof(buf), "%d", ll->to->tm_mon);
305 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
306 xml_list = xml_list_add(xml_list, "</tomon>", XML_TAG);
307 }
308
309 if (ll->to->tm_wday != 0) {
310 xml_list = xml_list_add(xml_list, "<towday>", XML_TAG);
311 snprintf(buf, sizeof(buf), "%d", ll->to->tm_wday);
312 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
313 xml_list = xml_list_add(xml_list, "</towday>", XML_TAG);
314 }
315 }
316
317 if (ll->maxbytes != 0) {
318 xml_list = xml_list_add(xml_list, "<maxbytes>", XML_TAG);
319 snprintf(buf, sizeof(buf), "%u", ll->maxbytes);
320 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
321 xml_list = xml_list_add(xml_list, "</maxbytes>", XML_TAG);
322 }
323
324 if (ll->maxrequests != 0) {
325 xml_list = xml_list_add(xml_list, "<maxrequests>", XML_TAG);
326 snprintf(buf, sizeof(buf), "%u", ll->maxrequests);
327 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
328 xml_list = xml_list_add(xml_list, "</maxrequests>", XML_TAG);
329 }
330
331 if (ll->flags != 0) {
332 xml_list = xml_list_add(xml_list, "<flags>", XML_TAG);
333 snprintf(buf, sizeof(buf), "%s,%s,%s", (ll->flags & LIMIT_CACHE) ? "limitcache" : "", (ll->flags & LIMIT_ABSOLUTETIME) ? "absolutetime" : "", (ll->flags & LIMIT_ALLRANGETIME) ? "allrangetime" : "");
334 xml_list = xml_list_add(xml_list, buf, XML_VALUE);
335 xml_list = xml_list_add(xml_list, "</flags>", XML_TAG);
336 }
337
338 xml_list = xml_list_add(xml_list, "</item>", XML_TAG);
339 }
340
341 xml_list = xml_list_add(xml_list, "</limits>", XML_TAG);
342
343 pthread_rwlock_unlock(&limits_list->lock);
344
345 return xml_list;
346 }
347
limits_ll_insert(struct LIMITS_LIST_LIST * x,char * profiles,char * comment,char * template,struct tm * from,struct tm * to,char * maxbytes,char * maxrequests,char * flags)348 void limits_ll_insert(struct LIMITS_LIST_LIST *x, char *profiles, char *comment, char *template, struct tm *from, struct tm *to, char *maxbytes, char *maxrequests, char *flags)
349 {
350 int i;
351 char **args;
352
353 if (profiles != NULL) {
354 if (x->profiles != NULL)
355 array_free(x->profiles);
356
357 if (strcmp(profiles, ""))
358 x->profiles = string_break(profiles, ',');
359 else
360 x->profiles = NULL;
361 }
362
363 if (comment != NULL) {
364 FREE_AND_NULL(x->comment);
365
366 if (strcmp(comment, ""))
367 x->comment = xstrdup(comment);
368 }
369
370 if (template != NULL) {
371 FREE_AND_NULL(x->template);
372
373 if (strcmp(template, ""))
374 x->template = xstrdup(template);
375 }
376
377 if (from != NULL) {
378 FREE_AND_NULL(x->from);
379
380 x->from = xmalloc(sizeof(struct tm));
381 *x->from = *from;
382 }
383
384 if (to != NULL) {
385 FREE_AND_NULL(x->to);
386
387 x->to = xmalloc(sizeof(struct tm));
388 *x->to = *to;
389 }
390
391 if (maxbytes != NULL) {
392 x->maxbytes = 0;
393
394 if (strcmp(maxbytes, ""))
395 x->maxbytes = strtoll(maxbytes, NULL, 10);
396 }
397
398 if (maxrequests != NULL) {
399 x->maxrequests = 0;
400
401 if (strcmp(maxrequests, ""))
402 x->maxrequests = strtoll(maxrequests, NULL, 10);
403 }
404
405 if (flags != NULL) {
406 x->flags = LIMIT_ABSOLUTETIME;;
407
408 if (strcmp(flags, "")) {
409 args = string_break(flags, ',');
410 for (i = 0; args[i]; i++) {
411 if (!strcasecmp(args[i], "limitcache"))
412 x->flags |= LIMIT_CACHE;
413 else if (!strcasecmp(args[i], "absolutetime")) {
414 x->flags &= ~LIMIT_ALLRANGETIME;
415 x->flags |= LIMIT_ABSOLUTETIME;
416 } else if (!strcasecmp(args[i], "allrangetime")) {
417 x->flags &= ~LIMIT_ABSOLUTETIME;
418 x->flags |= LIMIT_ALLRANGETIME;
419 }
420
421 xfree(args[i]);
422 }
423 xfree(args);
424 }
425 }
426
427 }
428
limits_ll_new(struct LIMITS_LIST_LIST * x)429 struct LIMITS_LIST_LIST *limits_ll_new(struct LIMITS_LIST_LIST *x)
430 {
431 if (x == NULL) {
432 x = xmalloc(sizeof(struct LIMITS_LIST_LIST));
433 x->prev = NULL;
434 } else {
435 while (x->next != NULL)
436 x = x->next;
437 x->next = xmalloc(sizeof(struct LIMITS_LIST_LIST));
438 x->next->prev = x;
439 x = x->next;
440 }
441
442 x->next = NULL;
443 x->enabled = TRUE;
444 x->profiles = NULL;
445 x->action = POLICY_ALLOW;
446 x->comment = NULL;
447 x->template = NULL;
448 x->from = NULL;
449 x->to = NULL;
450 x->maxrequests = 0;
451 x->maxbytes = 0;
452 x->n_requests = 0;
453 x->n_bytes = 0;
454 x->flags = LIMIT_ABSOLUTETIME;
455
456 return x;
457 }
458
limits_ll_delete(struct LIMITS_LIST_LIST * x)459 struct LIMITS_LIST_LIST *limits_ll_delete(struct LIMITS_LIST_LIST *x)
460 {
461 struct LIMITS_LIST_LIST *start = x;
462
463 while (start->prev != NULL)
464 start = start->prev;
465
466 if (x->next != NULL)
467 x->next->prev = x->prev;
468 if (x->prev != NULL)
469 x->prev->next = x->next;
470 else
471 start = x->next;
472
473 if (x->profiles != NULL)
474 array_free(x->profiles);
475 FREE_AND_NULL(x->comment);
476 FREE_AND_NULL(x->template);
477 FREE_AND_NULL(x->to);
478 FREE_AND_NULL(x->from);
479
480 xfree(x);
481
482 return start;
483 }
484
limits_ll_free(struct LIMITS_LIST_LIST * x)485 void limits_ll_free(struct LIMITS_LIST_LIST *x)
486 {
487 struct LIMITS_LIST_LIST *tmp;
488
489 while (x != NULL) {
490 tmp = x->next;
491
492 if (x->profiles != NULL)
493 array_free(x->profiles);
494 FREE_AND_NULL(x->comment);
495 FREE_AND_NULL(x->template);
496 FREE_AND_NULL(x->to);
497 FREE_AND_NULL(x->from);
498
499 xfree(x);
500
501 x = tmp;
502 }
503 }
504
limits_free(LIMITS_LIST * limits_list)505 void limits_free(LIMITS_LIST * limits_list)
506 {
507 if (!limits_list)
508 return;
509
510 limits_ll_free(limits_list->limits_list);
511
512 pthread_rwlock_destroy(&limits_list->lock);
513
514 xfree(limits_list);
515 }
516
limits_check(LIMITS_LIST * limits_list,CONNECTION * connection)517 struct LIMITS_LIST_LIST *limits_check(LIMITS_LIST * limits_list, CONNECTION * connection)
518 {
519 struct LIMITS_LIST_LIST *ll, *match = NULL;
520 time_t curtime;
521 struct tm lt;
522
523 /* caller must always unlock this */
524 pthread_rwlock_rdlock(&limits_list->lock);
525
526 if (!limits_list || (connection->bypass & FEATURE_LIMITS))
527 return NULL;
528
529 curtime = time(NULL);
530 localtime_r(&curtime, <);
531
532 if (limits_list->enabled == FALSE)
533 return NULL;
534
535 for (ll = limits_list->limits_list; ll; ll = ll->next) {
536 if (ll->enabled == FALSE)
537 continue;
538
539 if (!profile_find(connection->profiles, ll->profiles))
540 continue;
541
542 if (ll->from != NULL && ll->to != NULL) {
543 if (ll->flags & LIMIT_ABSOLUTETIME) {
544 if (!in_absolutetimerange(<, ll->from, ll->to))
545 continue;
546 } else {
547 if (!in_alltimerange(<, ll->from, ll->to))
548 continue;
549 }
550 }
551
552 match = ll;
553 }
554
555 return match;
556 }
557
limits_update(LIMITS_LIST * limits_list,CONNECTION * connection)558 void limits_update(LIMITS_LIST * limits_list, CONNECTION * connection)
559 {
560 struct LIMITS_LIST_LIST *ll;
561 time_t curtime;
562 struct tm lt;
563
564 if (!limits_list || (connection->bypass & FEATURE_LIMITS))
565 return;
566
567 curtime = time(NULL);
568 localtime_r(&curtime, <);
569
570 pthread_rwlock_rdlock(&limits_list->lock);
571
572 if (limits_list->enabled == FALSE) {
573 pthread_rwlock_unlock(&limits_list->lock);
574
575 return;
576 }
577
578 for (ll = limits_list->limits_list; ll; ll = ll->next) {
579 if (ll->enabled == FALSE)
580 continue;
581
582 if (!profile_find(connection->profiles, ll->profiles))
583 continue;
584
585 if (ll->from != NULL && ll->to != NULL) {
586 if (ll->flags & LIMIT_ABSOLUTETIME) {
587 if (!in_absolutetimerange(<, ll->from, ll->to))
588 continue;
589 } else {
590 if (!in_alltimerange(<, ll->from, ll->to))
591 continue;
592 }
593 }
594
595 if (ll->maxbytes != 0 && (connection->cachemap == NULL || (connection->flags & CONNECTION_CACHING) || (ll->flags & LIMIT_CACHE))) ll->n_bytes += connection->transferred;
596 if (ll->maxrequests != 0) ll->n_requests++;
597 }
598
599 pthread_rwlock_unlock(&limits_list->lock);
600 }
601
602
limits_reset(LIMITS_LIST * limits_list)603 void limits_reset(LIMITS_LIST * limits_list)
604 {
605 struct LIMITS_LIST_LIST *ll;
606 time_t curtime;
607 struct tm lt;
608
609 if (!limits_list)
610 return;
611
612 curtime = time(NULL);
613 localtime_r(&curtime, <);
614
615 pthread_rwlock_rdlock(&limits_list->lock);
616
617 if (limits_list->enabled == FALSE) {
618 pthread_rwlock_unlock(&limits_list->lock);
619
620 return;
621 }
622
623 for (ll = limits_list->limits_list; ll; ll = ll->next) {
624 if (ll->enabled == FALSE)
625 continue;
626
627 if (ll->n_bytes == 0 && ll->n_requests == 0) continue;
628
629 if (ll->from != NULL && ll->to != NULL) {
630 if (ll->flags & LIMIT_ABSOLUTETIME) {
631 if (in_absolutetimerange(<, ll->from, ll->to))
632 continue;
633 } else {
634 if (in_alltimerange(<, ll->from, ll->to))
635 continue;
636 }
637 } else continue;
638
639 /* ok, we are outside the time range this entry applies to, we can reset the
640 byte and request counter */
641 ll->n_bytes = ll->n_requests = 0;
642 }
643
644 pthread_rwlock_unlock(&limits_list->lock);
645 }
646
647
648