Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / ipsec-tools / src / racoon / throttle.c
1 /* $Id: throttle.c,v 1.2 2004/11/30 07:40:13 manubsd Exp $ */
2
3 /*
4  * Copyright (C) 2004 Emmanuel Dreyfus
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include "config.h"
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #if TIME_WITH_SYS_TIME
38 # include <sys/time.h>
39 # include <time.h> 
40 #else 
41 # if HAVE_SYS_TIME_H
42 #  include <sys/time.h>
43 # else
44 #  include <time.h>
45 # endif 
46 #endif
47 #include <sys/param.h>
48 #include <sys/queue.h>
49 #include <sys/socket.h>
50
51 #include <netinet/in.h>
52
53 #include "vmbuf.h"
54 #include "misc.h"
55 #include "plog.h"
56 #include "throttle.h"
57 #include "sockmisc.h"
58 #include "libpfkey.h"
59 #include "isakmp_var.h"
60 #include "isakmp.h"
61 #include "isakmp_xauth.h"
62 #include "isakmp_cfg.h"
63 #include "gcmalloc.h"
64
65 struct throttle_list throttle_list = TAILQ_HEAD_INITIALIZER(throttle_list);
66
67
68 struct throttle_entry *
69 throttle_add(addr)
70         struct sockaddr *addr;
71 {
72         struct throttle_entry *te;
73         size_t len;
74
75         len = sizeof(*te) 
76             - sizeof(struct sockaddr_storage) 
77             + sysdep_sa_len(addr);
78
79         if ((te = racoon_malloc(len)) == NULL)
80                 return NULL;
81
82         te->penalty = time(NULL) + isakmp_cfg_config.auth_throttle;
83         memcpy(&te->host, addr, sysdep_sa_len(addr));
84         TAILQ_INSERT_HEAD(&throttle_list, te, next);
85
86         return te;
87 }
88
89 int
90 throttle_host(addr, authfail) 
91         struct sockaddr *addr;
92         int authfail;
93 {
94         struct throttle_entry *te;
95         int found = 0;
96         time_t now;
97
98         if (isakmp_cfg_config.auth_throttle == 0)
99                 return 0;
100
101         now = time(NULL);
102
103         TAILQ_FOREACH_REVERSE(te, &throttle_list, throttle_list, next) {
104                 /* 
105                  * Remove outdated entries 
106                  */
107                 if (te->penalty < now) {
108                         TAILQ_REMOVE(&throttle_list, te, next);
109                         racoon_free(te);
110                         continue;
111                 }
112                         
113                 if (cmpsaddrwop(addr, (struct sockaddr *)&te->host) == 0) {
114                         found = 1;
115                         break;
116                 }
117         }
118
119         /* 
120          * No match, if auth failed, allocate a new throttle entry
121          * give no penalty even on error: this is the first time
122          * and we are indulgent.
123          */
124         if (!found) {
125                 if (authfail) {
126                         if ((te = throttle_add(addr)) == NULL) {
127                                 plog(LLV_ERROR, LOCATION, NULL, 
128                                     "Throttle insertion failed\n");
129                                 return (time(NULL) 
130                                     + isakmp_cfg_config.auth_throttle);
131                         }
132                 }
133                 return 0;
134         } else {
135                 /*
136                  * We had a match and auth failed, increase penalty.
137                  */
138                 if (authfail) {
139                         time_t remaining;
140                         time_t new;
141
142                         remaining = te->penalty - now;
143                         new = remaining + isakmp_cfg_config.auth_throttle;
144
145                         if (new > THROTTLE_PENALTY_MAX)
146                                 new = THROTTLE_PENALTY_MAX;
147
148                         te->penalty = now + new;
149                 }
150         }
151         
152         return te->penalty;
153 }
154