ze-filter  (ze-filter-0.8.0-develop-180218)
ze-connopen.c
Go to the documentation of this file.
1 
2 /*
3  *
4  * ze-filter - Mail Server Filter for sendmail
5  *
6  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
7  *
8  * Auteur : Jose Marcio Martins da Cruz
9  * jose.marcio.mc@gmail.org
10  *
11  * Historique :
12  * Creation : janvier 2002
13  *
14  * This program is free software, but with restricted license :
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * More details about ze-filter license can be found at ze-filter
22  * web site : http://foss.jose-marcio.org
23  */
24 
25 #include <ze-sys.h>
26 
27 #include "ze-filter.h"
28 
29 
30 /* ****************************************************************************
31  * *
32  * *
33  **************************************************************************** */
34 
35 #define SZ_NAME 64
36 
37 #ifndef DTCLEANUP
38 #define DTCLEANUP 600
39 #endif
40 
41 
42 typedef struct OpenConn_T {
43 #if 0
44  JSOCKADDR_T addr;
45 #endif
46  char ip[SZ_IP];
47  char name[SZ_NAME];
48  int nb;
49  time_t update;
50 } OpenConn_T;
51 
52 
53 /* ****************************************************************************
54  * *
55  * *
56  **************************************************************************** */
57 
58 static struct {
59  bool ok;
60  time_t last;
61  int nb;
62 
63  pthread_mutex_t mutex;
64 
66 
67 } hdata = {
68 FALSE, (time_t) 0, 0, PTHREAD_MUTEX_INITIALIZER, JBT_INITIALIZER};
69 
70 #define DATA_LOCK() \
71  if (pthread_mutex_lock(&hdata.mutex) != 0) { \
72  ZE_LogSysError("pthread_mutex_lock"); \
73  }
74 
75 #define DATA_UNLOCK() \
76  if (pthread_mutex_unlock(&hdata.mutex) != 0) { \
77  ZE_LogSysError("pthread_mutex_unlock"); \
78  }
79 
80 
81 
82 /* ****************************************************************************
83  * *
84  * *
85  **************************************************************************** */
86 static int
87 connopen_cmp(a, b)
88  void *a;
89  void *b;
90 {
91  OpenConn_T *ta = (OpenConn_T *) a;
92  OpenConn_T *tb = (OpenConn_T *) b;
93 
94  if ((ta == NULL) || (tb == NULL)) {
95  if (ta == tb)
96  return 0;
97  if (ta == NULL)
98  return -1;
99  else
100  return 1;
101  }
102 
103  return (strcmp(ta->ip, tb->ip));
104 }
105 
106 /* ****************************************************************************
107  * *
108  * *
109  **************************************************************************** */
110 static bool
111 connopen_init()
112 {
113  if (hdata.ok)
114  return TRUE;
115 
116  DATA_LOCK();
117 
118  if (!hdata.ok) {
119  if (zeBTree_Init(&hdata.db_open, sizeof (OpenConn_T), connopen_cmp)) {
120  hdata.ok = TRUE;
121  hdata.last = time(NULL);
122  } else
123  ZE_LogMsgError(0, "Can't initialize db_open");
124  }
125 
126  DATA_UNLOCK();
127 
128  return hdata.ok;
129 }
130 
131 /* ****************************************************************************
132  * *
133  * *
134  **************************************************************************** */
135 void
137 {
138  DATA_LOCK();
139 
140  zeBTree_Destroy(&hdata.db_open);
141  hdata.nb = 0;
142 
143  DATA_UNLOCK();
144 }
145 
146 /* ****************************************************************************
147  * *
148  * *
149  **************************************************************************** */
150 int
152  char *ip;
153  char *name;
154  int nb;
155 {
156  OpenConn_T p;
157  OpenConn_T *ptr = NULL;
158  int res = 0;
159  time_t now = time(NULL);
160 
161 #if 0 && defined(OS_FREEBSD)
162  return 0;
163 #endif
164 
165  if ((ip == NULL) || (strlen(ip) == 0))
166  return res;
167 
168  if (!connopen_init())
169  return res;
170 
171  DATA_LOCK();
172 
173  name = STRNULL(name, "NONAME");
174  if (strlen(name) == 0)
175  name = "NONAME";
176 
177  /*
178  * update open connections table...
179  */
180  memset(&p, 0, sizeof (p));
181  strlcpy(p.ip, ip, sizeof (p.ip));
182 
183  ptr = zeBTree_Get(&hdata.db_open, &p);
184 
185  if (ptr != NULL) {
186  if (nb != 0) {
187  ptr->nb += nb;
188  ptr->update = now;
189  hdata.nb += nb;
190  }
191  res = ptr->nb;
192  } else {
193  if (nb > 0) {
194  strlcpy(p.ip, ip, sizeof (p.ip));
195  strlcpy(p.name, name, sizeof (p.name));
196 
197  p.nb = nb;
198  p.update = now;
199  if (zeBTree_Add(&hdata.db_open, &p)) {
200  res = p.nb;
201  hdata.nb += nb;
202  } else
203  ZE_LogMsgError(0, "Error adding new leaf to db");
204  }
205  }
206 
207  DATA_UNLOCK();
208 
209  if ((hdata.last + DTCLEANUP / 2 < now) &&
210  ((hdata.last + DTCLEANUP < now)
211  || (zeBTree_Count(&hdata.db_open) > NB_BTCLEANUP)))
213 
214  return res;
215 }
216 
217 
218 /* ****************************************************************************
219  * *
220  * *
221  **************************************************************************** */
222 static time_t tcleanup = (time_t) 0;
223 
224 static bool
225 select_function(vp, arg)
226  void *vp;
227  void *arg;
228 {
229  OpenConn_T *p = (OpenConn_T *) vp;
230  time_t now;
231 
232 #if 1
233  now = tcleanup;
234 #else
235  now = time(NULL);
236 #endif
237 
238  if (p == NULL)
239  return FALSE;
240 
241  if ((p->nb > 0) || (p->update + DTCLEANUP > now))
242  return TRUE;
243  return FALSE;
244 }
245 
246 bool
248 {
249  time_t now = time(NULL);
250 
251  if (!connopen_init())
252  return FALSE;
253 
254  DATA_LOCK();
255 
256  tcleanup = now;
257 
258  if ((hdata.last + DTCLEANUP / 2 < now) &&
259  ((hdata.last + DTCLEANUP < now)
260  || (zeBTree_Count(&hdata.db_open) > NB_BTCLEANUP))) {
261 
262 #if 1
263  ZEBT_T tmp = JBT_INITIALIZER;
264 
265  ZE_MessageInfo(19, "connopen_clean_table : before : %d nodes",
266  zeBTree_Count(&hdata.db_open));
267 
268  if (zeBTree_Init(&tmp, sizeof (OpenConn_T), connopen_cmp)) {
269  if (zeBTree_Cpy(&tmp, &hdata.db_open, select_function, NULL)) {
270  zeBTree_Destroy(&hdata.db_open);
271  hdata.db_open = tmp;
272  } else
273  ZE_LogMsgError(0, "Can't copy btrees...");
274  } else
275 #else
276  if (!zeBTree_Cleanup(&hdata.db_open, connopen_cmp, NULL))
277 #endif
278  ZE_LogMsgError(0, "Can't initialize temporary btree");
279 
280  ZE_MessageInfo(19, "connopen_clean_table : after : %d nodes",
281  zeBTree_Count(&hdata.db_open));
282 
283  hdata.last = now;
284  }
285 
286  DATA_UNLOCK();
287 
288  return TRUE;
289 }
290 
291 /* ****************************************************************************
292  * *
293  * *
294  **************************************************************************** */
295 int logfd = -1;
296 
297 static int
298 log_rec(void *data, void *param)
299 {
300  OpenConn_T *p = (OpenConn_T *) data;
301 
302  if (p->nb > 0) {
303  if (logfd < 0)
304  ZE_MessageInfo(10, " %-17s : %3d : %s", p->ip, p->nb, p->name);
305  else
306  FD_PRINTF(logfd, " %-17s : %3d : %s\n", p->ip, p->nb, p->name);
307  return 1;
308  }
309  return 0;
310 }
311 
312 void
314  int fd;
315 {
316  int nb = 0;
317 
318  if (!connopen_init())
319  return;
320 
321  DATA_LOCK();
322 
323  logfd = fd;
324  if (logfd < 0)
325  ZE_MessageInfo(10, "*** Open connections :");
326  else
327  FD_PRINTF(logfd, "*** Open connections :\n");
328 
329  nb = zeBTree_Browse(&hdata.db_open, log_rec, NULL);
330 
331  if (logfd < 0)
332  ZE_MessageInfo(10, " %d entries on database", nb);
333  else
334  FD_PRINTF(logfd, " %d entries on database\n", nb);
335  fd = -1;
336 
337  DATA_UNLOCK();
338 }
#define DTCLEANUP
Definition: ze-connopen.c:38
#define DATA_UNLOCK()
Definition: ze-connopen.c:75
void * zeBTree_Get(ZEBT_T *, void *)
Definition: zeBTree.c:281
#define JBT_INITIALIZER
Definition: zeBTree.h:85
bool zeBTree_Init(ZEBT_T *, size_t, ZEBT_CMP_F)
Definition: zeBTree.c:96
int logfd
Definition: ze-connopen.c:295
#define NB_BTCLEANUP
Definition: zeBTree.h:70
#define STRNULL(x, r)
Definition: macros.h:81
bool ok
Definition: ze-connopen.c:59
bool zeBTree_Add(ZEBT_T *, void *)
Definition: zeBTree.c:309
pthread_mutex_t mutex
Definition: ze-connopen.c:63
char ip[SZ_IP]
Definition: ze-connopen.c:46
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
bool zeBTree_Destroy(ZEBT_T *)
Definition: zeBTree.c:192
#define FD_PRINTF(fdp,...)
Definition: macros.h:45
bool connopen_clean_table()
Definition: ze-connopen.c:247
#define SZ_IP
Definition: ze-libjc.h:77
time_t update
Definition: ze-connopen.c:49
ZEBT_T db_open
Definition: ze-connopen.c:65
int zeBTree_Count(ZEBT_T *)
Definition: zeBTree.c:245
bool zeBTree_Cpy(ZEBT_T *, ZEBT_T *, ZEBT_SEL_F, void *)
Definition: zeBTree.c:515
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define DATA_LOCK()
Definition: ze-connopen.c:70
#define TRUE
Definition: macros.h:157
char name[SZ_NAME]
Definition: ze-connopen.c:47
void connopen_reset()
Definition: ze-connopen.c:136
time_t last
Definition: ze-connopen.c:60
int connopen_check_host(char *ip, char *name, int nb)
Definition: ze-connopen.c:151
struct OpenConn_T OpenConn_T
void connopen_print_table(int fd)
Definition: ze-connopen.c:313
#define SZ_NAME
Definition: ze-connopen.c:35
bool zeBTree_Cleanup(ZEBT_T *, ZEBT_SEL_F, void *)
Definition: zeBTree.c:564
int zeBTree_Browse(ZEBT_T *, ZEBT_BROWSE_F, void *)
Definition: zeBTree.c:262
Definition: zeBTree.h:73