listener.c (302408) | listener.c (64562) |
---|---|
1/* | 1/* |
2 * Copyright (c) 1999-2007 Proofpoint, Inc. and its suppliers. | 2 * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. |
3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 | 3 * All rights reserved. 4 * 5 * By using this file, you agree to the terms and conditions set 6 * forth in the LICENSE file which can be found at the top level of 7 * the sendmail distribution. 8 * 9 */ 10 |
11#include <sm/gen.h> 12SM_RCSID("@(#)$Id: listener.c,v 8.127 2013-11-22 20:51:36 ca Exp $") | 11#ifndef lint 12static char id[] = "@(#)$Id: listener.c,v 8.38.2.1.2.7 2000/05/25 21:44:26 gshapiro Exp $"; 13#endif /* ! lint */ |
13 | 14 |
15#if _FFR_MILTER |
|
14/* 15** listener.c -- threaded network listener 16*/ 17 18#include "libmilter.h" | 16/* 17** listener.c -- threaded network listener 18*/ 19 20#include "libmilter.h" |
19#include <sm/errstring.h> | |
20 | 21 |
21#include <sys/types.h> 22#include <sys/stat.h> | |
23 | 22 |
24 | |
25# if NETINET || NETINET6 26# include <arpa/inet.h> 27# endif /* NETINET || NETINET6 */ | 23# if NETINET || NETINET6 24# include <arpa/inet.h> 25# endif /* NETINET || NETINET6 */ |
28# if SM_CONF_POLL 29# undef SM_FD_OK_SELECT 30# define SM_FD_OK_SELECT(fd) true 31# endif /* SM_CONF_POLL */ 32 33static smutex_t L_Mutex; 34static int L_family; 35static SOCKADDR_LEN_T L_socksize; 36static socket_t listenfd = INVALID_SOCKET; 37 38static socket_t mi_milteropen __P((char *, int, bool, char *)); 39#if !_FFR_WORKERS_POOL 40static void *mi_thread_handle_wrapper __P((void *)); 41#endif /* !_FFR_WORKERS_POOL */ 42 43/* 44** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet 45** 46** Parameters: 47** conn -- connection description 48** backlog -- listen backlog 49** dbg -- debug level 50** rmsocket -- if true, try to unlink() the socket first 51** (UNIX domain sockets only) 52** smfi -- filter structure to use 53** 54** Return value: 55** MI_SUCCESS/MI_FAILURE 56*/ 57 58int 59mi_opensocket(conn, backlog, dbg, rmsocket, smfi) 60 char *conn; 61 int backlog; 62 int dbg; 63 bool rmsocket; 64 smfiDesc_ptr smfi; 65{ 66 if (smfi == NULL || conn == NULL) 67 return MI_FAILURE; 68 69 if (ValidSocket(listenfd)) 70 return MI_SUCCESS; 71 72 if (dbg > 0) 73 { 74 smi_log(SMI_LOG_DEBUG, 75 "%s: Opening listen socket on conn %s", 76 smfi->xxfi_name, conn); 77 } 78 (void) smutex_init(&L_Mutex); 79 (void) smutex_lock(&L_Mutex); 80 listenfd = mi_milteropen(conn, backlog, rmsocket, smfi->xxfi_name); 81 if (!ValidSocket(listenfd)) 82 { 83 smi_log(SMI_LOG_FATAL, 84 "%s: Unable to create listening socket on conn %s", 85 smfi->xxfi_name, conn); 86 (void) smutex_unlock(&L_Mutex); 87 return MI_FAILURE; 88 } 89 if (!SM_FD_OK_SELECT(listenfd)) 90 { 91 smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d", 92 smfi->xxfi_name, listenfd, FD_SETSIZE); 93 (void) smutex_unlock(&L_Mutex); 94 return MI_FAILURE; 95 } 96 (void) smutex_unlock(&L_Mutex); 97 return MI_SUCCESS; 98} 99 100/* | 26/* |
101** MI_MILTEROPEN -- setup socket to listen on 102** 103** Parameters: 104** conn -- connection description 105** backlog -- listen backlog | 27** MI_MILTEROPEN -- setup socket to listen on 28** 29** Parameters: 30** conn -- connection description 31** backlog -- listen backlog |
106** rmsocket -- if true, try to unlink() the socket first 107** (UNIX domain sockets only) 108** name -- name for logging | 32** socksize -- socksize of created socket |
109** 110** Returns: 111** socket upon success, error code otherwise. | 33** 34** Returns: 35** socket upon success, error code otherwise. |
112** 113** Side effect: 114** sets sockpath if UNIX socket. | |
115*/ 116 | 36*/ 37 |
117#if NETUNIX 118static char *sockpath = NULL; 119#endif /* NETUNIX */ 120 121static socket_t 122mi_milteropen(conn, backlog, rmsocket, name) | 38static int 39mi_milteropen(conn, backlog, socksize, name) |
123 char *conn; 124 int backlog; | 40 char *conn; 41 int backlog; |
125 bool rmsocket; | 42 SOCKADDR_LEN_T *socksize; |
126 char *name; 127{ | 43 char *name; 44{ |
128 socket_t sock; | 45 int sock = 0; |
129 int sockopt = 1; | 46 int sockopt = 1; |
130 int fdflags; 131 size_t len = 0; | |
132 char *p; 133 char *colon; 134 char *at; | 47 char *p; 48 char *colon; 49 char *at; |
50 struct hostent *hp = NULL; |
|
135 SOCKADDR addr; 136 137 if (conn == NULL || conn[0] == '\0') 138 { 139 smi_log(SMI_LOG_ERR, "%s: empty or missing socket information", 140 name); | 51 SOCKADDR addr; 52 53 if (conn == NULL || conn[0] == '\0') 54 { 55 smi_log(SMI_LOG_ERR, "%s: empty or missing socket information", 56 name); |
141 return INVALID_SOCKET; | 57 return MI_INVALID_SOCKET; |
142 } 143 (void) memset(&addr, '\0', sizeof addr); 144 145 /* protocol:filename or protocol:port@host */ 146 p = conn; 147 colon = strchr(p, ':'); 148 if (colon != NULL) 149 { 150 *colon = '\0'; 151 | 58 } 59 (void) memset(&addr, '\0', sizeof addr); 60 61 /* protocol:filename or protocol:port@host */ 62 p = conn; 63 colon = strchr(p, ':'); 64 if (colon != NULL) 65 { 66 *colon = '\0'; 67 |
152 if (*p == '\0') | 68 if (*p == '\0') |
153 { 154#if NETUNIX 155 /* default to AF_UNIX */ | 69 { 70#if NETUNIX 71 /* default to AF_UNIX */ |
156 addr.sa.sa_family = AF_UNIX; 157 L_socksize = sizeof (struct sockaddr_un); | 72 addr.sa.sa_family = AF_UNIX; 73 *socksize = sizeof (struct sockaddr_un); |
158#else /* NETUNIX */ 159# if NETINET 160 /* default to AF_INET */ 161 addr.sa.sa_family = AF_INET; | 74#else /* NETUNIX */ 75# if NETINET 76 /* default to AF_INET */ 77 addr.sa.sa_family = AF_INET; |
162 L_socksize = sizeof addr.sin; | 78 *socksize = sizeof addr.sin; |
163# else /* NETINET */ 164# if NETINET6 165 /* default to AF_INET6 */ 166 addr.sa.sa_family = AF_INET6; | 79# else /* NETINET */ 80# if NETINET6 81 /* default to AF_INET6 */ 82 addr.sa.sa_family = AF_INET6; |
167 L_socksize = sizeof addr.sin6; | 83 *socksize = sizeof addr.sin6; |
168# else /* NETINET6 */ 169 /* no protocols available */ 170 smi_log(SMI_LOG_ERR, 171 "%s: no valid socket protocols available", 172 name); | 84# else /* NETINET6 */ 85 /* no protocols available */ 86 smi_log(SMI_LOG_ERR, 87 "%s: no valid socket protocols available", 88 name); |
173 return INVALID_SOCKET; | 89 return MI_INVALID_SOCKET; |
174# endif /* NETINET6 */ 175# endif /* NETINET */ 176#endif /* NETUNIX */ 177 } 178#if NETUNIX 179 else if (strcasecmp(p, "unix") == 0 || 180 strcasecmp(p, "local") == 0) 181 { 182 addr.sa.sa_family = AF_UNIX; | 90# endif /* NETINET6 */ 91# endif /* NETINET */ 92#endif /* NETUNIX */ 93 } 94#if NETUNIX 95 else if (strcasecmp(p, "unix") == 0 || 96 strcasecmp(p, "local") == 0) 97 { 98 addr.sa.sa_family = AF_UNIX; |
183 L_socksize = sizeof (struct sockaddr_un); | 99 *socksize = sizeof (struct sockaddr_un); |
184 } 185#endif /* NETUNIX */ 186#if NETINET 187 else if (strcasecmp(p, "inet") == 0) 188 { 189 addr.sa.sa_family = AF_INET; | 100 } 101#endif /* NETUNIX */ 102#if NETINET 103 else if (strcasecmp(p, "inet") == 0) 104 { 105 addr.sa.sa_family = AF_INET; |
190 L_socksize = sizeof addr.sin; | 106 *socksize = sizeof addr.sin; |
191 } 192#endif /* NETINET */ 193#if NETINET6 194 else if (strcasecmp(p, "inet6") == 0) 195 { 196 addr.sa.sa_family = AF_INET6; | 107 } 108#endif /* NETINET */ 109#if NETINET6 110 else if (strcasecmp(p, "inet6") == 0) 111 { 112 addr.sa.sa_family = AF_INET6; |
197 L_socksize = sizeof addr.sin6; | 113 *socksize = sizeof addr.sin6; |
198 } 199#endif /* NETINET6 */ 200 else 201 { 202 smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", 203 name, p); | 114 } 115#endif /* NETINET6 */ 116 else 117 { 118 smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", 119 name, p); |
204 return INVALID_SOCKET; | 120 return MI_INVALID_SOCKET; |
205 } 206 *colon++ = ':'; 207 } 208 else 209 { 210 colon = p; 211#if NETUNIX 212 /* default to AF_UNIX */ | 121 } 122 *colon++ = ':'; 123 } 124 else 125 { 126 colon = p; 127#if NETUNIX 128 /* default to AF_UNIX */ |
213 addr.sa.sa_family = AF_UNIX; 214 L_socksize = sizeof (struct sockaddr_un); | 129 addr.sa.sa_family = AF_UNIX; 130 *socksize = sizeof (struct sockaddr_un); |
215#else /* NETUNIX */ 216# if NETINET 217 /* default to AF_INET */ 218 addr.sa.sa_family = AF_INET; | 131#else /* NETUNIX */ 132# if NETINET 133 /* default to AF_INET */ 134 addr.sa.sa_family = AF_INET; |
219 L_socksize = sizeof addr.sin; | 135 *socksize = sizeof addr.sin; |
220# else /* NETINET */ 221# if NETINET6 222 /* default to AF_INET6 */ 223 addr.sa.sa_family = AF_INET6; | 136# else /* NETINET */ 137# if NETINET6 138 /* default to AF_INET6 */ 139 addr.sa.sa_family = AF_INET6; |
224 L_socksize = sizeof addr.sin6; | 140 *socksize = sizeof addr.sin6; |
225# else /* NETINET6 */ 226 smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", 227 name, p); | 141# else /* NETINET6 */ 142 smi_log(SMI_LOG_ERR, "%s: unknown socket type %s", 143 name, p); |
228 return INVALID_SOCKET; | 144 return MI_INVALID_SOCKET; |
229# endif /* NETINET6 */ 230# endif /* NETINET */ 231#endif /* NETUNIX */ 232 } 233 234#if NETUNIX 235 if (addr.sa.sa_family == AF_UNIX) 236 { 237# if 0 238 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN; 239# endif /* 0 */ 240 241 at = colon; | 145# endif /* NETINET6 */ 146# endif /* NETINET */ 147#endif /* NETUNIX */ 148 } 149 150#if NETUNIX 151 if (addr.sa.sa_family == AF_UNIX) 152 { 153# if 0 154 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_CREAT|SFF_MUSTOWN; 155# endif /* 0 */ 156 157 at = colon; |
242 len = strlen(colon) + 1; 243 if (len >= sizeof addr.sunix.sun_path) | 158 if (strlcpy(addr.sunix.sun_path, colon, 159 sizeof addr.sunix.sun_path) >= 160 sizeof addr.sunix.sun_path) |
244 { 245 errno = EINVAL; 246 smi_log(SMI_LOG_ERR, "%s: UNIX socket name %s too long", 247 name, colon); | 161 { 162 errno = EINVAL; 163 smi_log(SMI_LOG_ERR, "%s: UNIX socket name %s too long", 164 name, colon); |
248 return INVALID_SOCKET; | 165 return MI_INVALID_SOCKET; |
249 } | 166 } |
250 (void) sm_strlcpy(addr.sunix.sun_path, colon, 251 sizeof addr.sunix.sun_path); | |
252# if 0 253 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 254 S_IRUSR|S_IWUSR, NULL); 255 256 /* if not safe, don't create */ 257 if (errno != 0) 258 { 259 smi_log(SMI_LOG_ERR, 260 "%s: UNIX socket name %s unsafe", 261 name, colon); | 167# if 0 168 errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, 169 S_IRUSR|S_IWUSR, NULL); 170 171 /* if not safe, don't create */ 172 if (errno != 0) 173 { 174 smi_log(SMI_LOG_ERR, 175 "%s: UNIX socket name %s unsafe", 176 name, colon); |
262 return INVALID_SOCKET; | 177 return MI_INVALID_SOCKET; |
263 } 264# endif /* 0 */ | 178 } 179# endif /* 0 */ |
180 |
|
265 } 266#endif /* NETUNIX */ 267 268#if NETINET || NETINET6 269 if ( 270# if NETINET 271 addr.sa.sa_family == AF_INET 272# endif /* NETINET */ 273# if NETINET && NETINET6 274 || 275# endif /* NETINET && NETINET6 */ 276# if NETINET6 277 addr.sa.sa_family == AF_INET6 278# endif /* NETINET6 */ 279 ) 280 { | 181 } 182#endif /* NETUNIX */ 183 184#if NETINET || NETINET6 185 if ( 186# if NETINET 187 addr.sa.sa_family == AF_INET 188# endif /* NETINET */ 189# if NETINET && NETINET6 190 || 191# endif /* NETINET && NETINET6 */ 192# if NETINET6 193 addr.sa.sa_family == AF_INET6 194# endif /* NETINET6 */ 195 ) 196 { |
281 unsigned short port; | 197 u_short port; |
282 283 /* Parse port@host */ 284 at = strchr(colon, '@'); 285 if (at == NULL) 286 { 287 switch (addr.sa.sa_family) 288 { 289# if NETINET --- 8 unchanged lines hidden (view full) --- 298 break; 299# endif /* NETINET6 */ 300 } 301 } 302 else 303 *at = '\0'; 304 305 if (isascii(*colon) && isdigit(*colon)) | 198 199 /* Parse port@host */ 200 at = strchr(colon, '@'); 201 if (at == NULL) 202 { 203 switch (addr.sa.sa_family) 204 { 205# if NETINET --- 8 unchanged lines hidden (view full) --- 214 break; 215# endif /* NETINET6 */ 216 } 217 } 218 else 219 *at = '\0'; 220 221 if (isascii(*colon) && isdigit(*colon)) |
306 port = htons((unsigned short) atoi(colon)); | 222 port = htons((u_short) atoi(colon)); |
307 else 308 { 309# ifdef NO_GETSERVBYNAME 310 smi_log(SMI_LOG_ERR, "%s: invalid port number %s", 311 name, colon); | 223 else 224 { 225# ifdef NO_GETSERVBYNAME 226 smi_log(SMI_LOG_ERR, "%s: invalid port number %s", 227 name, colon); |
312 return INVALID_SOCKET; | 228 return MI_INVALID_SOCKET; |
313# else /* NO_GETSERVBYNAME */ 314 register struct servent *sp; 315 316 sp = getservbyname(colon, "tcp"); 317 if (sp == NULL) 318 { 319 smi_log(SMI_LOG_ERR, 320 "%s: unknown port name %s", 321 name, colon); | 229# else /* NO_GETSERVBYNAME */ 230 register struct servent *sp; 231 232 sp = getservbyname(colon, "tcp"); 233 if (sp == NULL) 234 { 235 smi_log(SMI_LOG_ERR, 236 "%s: unknown port name %s", 237 name, colon); |
322 return INVALID_SOCKET; | 238 return MI_INVALID_SOCKET; |
323 } 324 port = sp->s_port; 325# endif /* NO_GETSERVBYNAME */ 326 } 327 if (at != NULL) 328 { 329 *at++ = '@'; 330 if (*at == '[') 331 { 332 char *end; 333 334 end = strchr(at, ']'); 335 if (end != NULL) 336 { | 239 } 240 port = sp->s_port; 241# endif /* NO_GETSERVBYNAME */ 242 } 243 if (at != NULL) 244 { 245 *at++ = '@'; 246 if (*at == '[') 247 { 248 char *end; 249 250 end = strchr(at, ']'); 251 if (end != NULL) 252 { |
337 bool found = false; | 253 bool found = FALSE; |
338# if NETINET 339 unsigned long hid = INADDR_NONE; 340# endif /* NETINET */ 341# if NETINET6 342 struct sockaddr_in6 hid6; 343# endif /* NETINET6 */ 344 345 *end = '\0'; 346# if NETINET 347 if (addr.sa.sa_family == AF_INET && | 254# if NETINET 255 unsigned long hid = INADDR_NONE; 256# endif /* NETINET */ 257# if NETINET6 258 struct sockaddr_in6 hid6; 259# endif /* NETINET6 */ 260 261 *end = '\0'; 262# if NETINET 263 if (addr.sa.sa_family == AF_INET && |
348 (hid = inet_addr(&at[1])) != INADDR_NONE) | 264 (hid = inet_addr(&at[1])) != 265 INADDR_NONE) |
349 { 350 addr.sin.sin_addr.s_addr = hid; 351 addr.sin.sin_port = port; | 266 { 267 addr.sin.sin_addr.s_addr = hid; 268 addr.sin.sin_port = port; |
352 found = true; | 269 found = TRUE; |
353 } 354# endif /* NETINET */ 355# if NETINET6 356 (void) memset(&hid6, '\0', sizeof hid6); 357 if (addr.sa.sa_family == AF_INET6 && | 270 } 271# endif /* NETINET */ 272# if NETINET6 273 (void) memset(&hid6, '\0', sizeof hid6); 274 if (addr.sa.sa_family == AF_INET6 && |
358 mi_inet_pton(AF_INET6, &at[1], 359 &hid6.sin6_addr) == 1) | 275 inet_pton(AF_INET6, &at[1], 276 &hid6.sin6_addr) == 1) |
360 { 361 addr.sin6.sin6_addr = hid6.sin6_addr; 362 addr.sin6.sin6_port = port; | 277 { 278 addr.sin6.sin6_addr = hid6.sin6_addr; 279 addr.sin6.sin6_port = port; |
363 found = true; | 280 found = TRUE; |
364 } 365# endif /* NETINET6 */ 366 *end = ']'; 367 if (!found) 368 { 369 smi_log(SMI_LOG_ERR, 370 "%s: Invalid numeric domain spec \"%s\"", 371 name, at); | 281 } 282# endif /* NETINET6 */ 283 *end = ']'; 284 if (!found) 285 { 286 smi_log(SMI_LOG_ERR, 287 "%s: Invalid numeric domain spec \"%s\"", 288 name, at); |
372 return INVALID_SOCKET; | 289 return MI_INVALID_SOCKET; |
373 } 374 } 375 else 376 { 377 smi_log(SMI_LOG_ERR, 378 "%s: Invalid numeric domain spec \"%s\"", 379 name, at); | 290 } 291 } 292 else 293 { 294 smi_log(SMI_LOG_ERR, 295 "%s: Invalid numeric domain spec \"%s\"", 296 name, at); |
380 return INVALID_SOCKET; | 297 return MI_INVALID_SOCKET; |
381 } 382 } 383 else 384 { | 298 } 299 } 300 else 301 { |
385 struct hostent *hp = NULL; 386 | |
387 hp = mi_gethostbyname(at, addr.sa.sa_family); 388 if (hp == NULL) 389 { 390 smi_log(SMI_LOG_ERR, 391 "%s: Unknown host name %s", 392 name, at); | 302 hp = mi_gethostbyname(at, addr.sa.sa_family); 303 if (hp == NULL) 304 { 305 smi_log(SMI_LOG_ERR, 306 "%s: Unknown host name %s", 307 name, at); |
393 return INVALID_SOCKET; | 308 return MI_INVALID_SOCKET; |
394 } 395 addr.sa.sa_family = hp->h_addrtype; 396 switch (hp->h_addrtype) 397 { 398# if NETINET 399 case AF_INET: | 309 } 310 addr.sa.sa_family = hp->h_addrtype; 311 switch (hp->h_addrtype) 312 { 313# if NETINET 314 case AF_INET: |
400 (void) memmove(&addr.sin.sin_addr, 401 hp->h_addr, 402 INADDRSZ); | 315 memmove(&addr.sin.sin_addr, 316 hp->h_addr, 317 INADDRSZ); |
403 addr.sin.sin_port = port; 404 break; 405# endif /* NETINET */ 406 407# if NETINET6 408 case AF_INET6: | 318 addr.sin.sin_port = port; 319 break; 320# endif /* NETINET */ 321 322# if NETINET6 323 case AF_INET6: |
409 (void) memmove(&addr.sin6.sin6_addr, 410 hp->h_addr, 411 IN6ADDRSZ); | 324 memmove(&addr.sin6.sin6_addr, 325 hp->h_addr, 326 IN6ADDRSZ); |
412 addr.sin6.sin6_port = port; 413 break; 414# endif /* NETINET6 */ 415 416 default: 417 smi_log(SMI_LOG_ERR, 418 "%s: Unknown protocol for %s (%d)", 419 name, at, hp->h_addrtype); | 327 addr.sin6.sin6_port = port; 328 break; 329# endif /* NETINET6 */ 330 331 default: 332 smi_log(SMI_LOG_ERR, 333 "%s: Unknown protocol for %s (%d)", 334 name, at, hp->h_addrtype); |
420 return INVALID_SOCKET; | 335 return MI_INVALID_SOCKET; |
421 } | 336 } |
422# if NETINET6 423 freehostent(hp); 424# endif /* NETINET6 */ | |
425 } 426 } 427 else 428 { 429 switch (addr.sa.sa_family) 430 { 431# if NETINET 432 case AF_INET: --- 10 unchanged lines hidden (view full) --- 443 } 444#endif /* NETINET || NETINET6 */ 445 446 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 447 if (!ValidSocket(sock)) 448 { 449 smi_log(SMI_LOG_ERR, 450 "%s: Unable to create new socket: %s", | 337 } 338 } 339 else 340 { 341 switch (addr.sa.sa_family) 342 { 343# if NETINET 344 case AF_INET: --- 10 unchanged lines hidden (view full) --- 355 } 356#endif /* NETINET || NETINET6 */ 357 358 sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); 359 if (!ValidSocket(sock)) 360 { 361 smi_log(SMI_LOG_ERR, 362 "%s: Unable to create new socket: %s", |
451 name, sm_errstring(errno)); 452 return INVALID_SOCKET; | 363 name, strerror(errno)); 364 return MI_INVALID_SOCKET; |
453 } 454 | 365 } 366 |
455 if ((fdflags = fcntl(sock, F_GETFD, 0)) == -1 || 456 fcntl(sock, F_SETFD, fdflags | FD_CLOEXEC) == -1) 457 { 458 smi_log(SMI_LOG_ERR, 459 "%s: Unable to set close-on-exec: %s", name, 460 sm_errstring(errno)); 461 (void) closesocket(sock); 462 return INVALID_SOCKET; 463 } 464 465 if ( 466#if NETUNIX 467 addr.sa.sa_family != AF_UNIX && 468#endif /* NETUNIX */ 469 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt, | 367 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt, |
470 sizeof(sockopt)) == -1) 471 { 472 smi_log(SMI_LOG_ERR, | 368 sizeof(sockopt)) == -1) 369 { 370 smi_log(SMI_LOG_ERR, |
473 "%s: set reuseaddr failed (%s)", name, 474 sm_errstring(errno)); 475 (void) closesocket(sock); 476 return INVALID_SOCKET; | 371 "%s: Unable to setsockopt: %s", name, strerror(errno)); 372 (void) close(sock); 373 return MI_INVALID_SOCKET; |
477 } 478 | 374 } 375 |
479#if NETUNIX 480 if (addr.sa.sa_family == AF_UNIX && rmsocket) | 376 if (bind(sock, &addr.sa, *socksize) < 0) |
481 { | 377 { |
482 struct stat s; 483 484 if (stat(colon, &s) != 0) 485 { 486 if (errno != ENOENT) 487 { 488 smi_log(SMI_LOG_ERR, 489 "%s: Unable to stat() %s: %s", 490 name, colon, sm_errstring(errno)); 491 (void) closesocket(sock); 492 return INVALID_SOCKET; 493 } 494 } 495 else if (!S_ISSOCK(s.st_mode)) 496 { 497 smi_log(SMI_LOG_ERR, 498 "%s: %s is not a UNIX domain socket", 499 name, colon); 500 (void) closesocket(sock); 501 return INVALID_SOCKET; 502 } 503 else if (unlink(colon) != 0) 504 { 505 smi_log(SMI_LOG_ERR, 506 "%s: Unable to remove %s: %s", 507 name, colon, sm_errstring(errno)); 508 (void) closesocket(sock); 509 return INVALID_SOCKET; 510 } 511 } 512#endif /* NETUNIX */ 513 514 if (bind(sock, &addr.sa, L_socksize) < 0) 515 { | |
516 smi_log(SMI_LOG_ERR, 517 "%s: Unable to bind to port %s: %s", | 378 smi_log(SMI_LOG_ERR, 379 "%s: Unable to bind to port %s: %s", |
518 name, conn, sm_errstring(errno)); 519 (void) closesocket(sock); 520 return INVALID_SOCKET; | 380 name, conn, strerror(errno)); 381 (void) close(sock); 382 return MI_INVALID_SOCKET; |
521 } 522 523 if (listen(sock, backlog) < 0) 524 { 525 smi_log(SMI_LOG_ERR, | 383 } 384 385 if (listen(sock, backlog) < 0) 386 { 387 smi_log(SMI_LOG_ERR, |
526 "%s: listen call failed: %s", name, 527 sm_errstring(errno)); 528 (void) closesocket(sock); 529 return INVALID_SOCKET; | 388 "%s: listen call failed: %s", name, strerror(errno)); 389 (void) close(sock); 390 return MI_INVALID_SOCKET; |
530 } 531 | 391 } 392 |
532#if NETUNIX 533 if (addr.sa.sa_family == AF_UNIX && len > 0) 534 { 535 /* 536 ** Set global variable sockpath so the UNIX socket can be 537 ** unlink()ed at exit. 538 */ 539 540 sockpath = (char *) malloc(len); 541 if (sockpath != NULL) 542 (void) sm_strlcpy(sockpath, colon, len); 543 else 544 { 545 smi_log(SMI_LOG_ERR, 546 "%s: can't malloc(%d) for sockpath: %s", 547 name, (int) len, sm_errstring(errno)); 548 (void) closesocket(sock); 549 return INVALID_SOCKET; 550 } 551 } 552#endif /* NETUNIX */ 553 L_family = addr.sa.sa_family; | |
554 return sock; 555} | 393 return sock; 394} |
556 557#if !_FFR_WORKERS_POOL 558/* | 395/* |
559** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session 560** 561** Parameters: 562** arg -- argument to pass to mi_handle_session() 563** 564** Returns: 565** results from mi_handle_session() 566*/ 567 | 396** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session 397** 398** Parameters: 399** arg -- argument to pass to mi_handle_session() 400** 401** Returns: 402** results from mi_handle_session() 403*/ 404 |
568static void * | 405void * |
569mi_thread_handle_wrapper(arg) 570 void *arg; 571{ | 406mi_thread_handle_wrapper(arg) 407 void *arg; 408{ |
572 /* 573 ** Note: on some systems this generates a compiler warning: 574 ** cast to pointer from integer of different size 575 ** You can safely ignore this warning as the result of this function 576 ** is not used anywhere. 577 */ 578 | |
579 return (void *) mi_handle_session(arg); 580} | 409 return (void *) mi_handle_session(arg); 410} |
581#endif /* _FFR_WORKERS_POOL */ | |
582 | 411 |
583/* 584** MI_CLOSENER -- close listen socket | 412/* 413** MI_MILTER_LISTENER -- Generic listener harness |
585** | 414** |
586** Parameters: 587** none. 588** 589** Returns: 590** none. 591*/ 592 593void 594mi_closener() 595{ 596 (void) smutex_lock(&L_Mutex); 597 if (ValidSocket(listenfd)) 598 { 599#if NETUNIX 600 bool removable; 601 struct stat sockinfo; 602 struct stat fileinfo; 603 604 removable = sockpath != NULL && 605 geteuid() != 0 && 606 fstat(listenfd, &sockinfo) == 0 && 607 (S_ISFIFO(sockinfo.st_mode) 608# ifdef S_ISSOCK 609 || S_ISSOCK(sockinfo.st_mode) 610# endif /* S_ISSOCK */ 611 ); 612#endif /* NETUNIX */ 613 614 (void) closesocket(listenfd); 615 listenfd = INVALID_SOCKET; 616 617#if NETUNIX 618 /* XXX sleep() some time before doing this? */ 619 if (sockpath != NULL) 620 { 621 if (removable && 622 stat(sockpath, &fileinfo) == 0 && 623 ((fileinfo.st_dev == sockinfo.st_dev && 624 fileinfo.st_ino == sockinfo.st_ino) 625# ifdef S_ISSOCK 626 || S_ISSOCK(fileinfo.st_mode) 627# endif /* S_ISSOCK */ 628 ) 629 && 630 (S_ISFIFO(fileinfo.st_mode) 631# ifdef S_ISSOCK 632 || S_ISSOCK(fileinfo.st_mode) 633# endif /* S_ISSOCK */ 634 )) 635 (void) unlink(sockpath); 636 free(sockpath); 637 sockpath = NULL; 638 } 639#endif /* NETUNIX */ 640 } 641 (void) smutex_unlock(&L_Mutex); 642} 643 644/* 645** MI_LISTENER -- Generic listener harness 646** | |
647** Open up listen port 648** Wait for connections 649** 650** Parameters: 651** conn -- connection description 652** dbg -- debug level 653** smfi -- filter structure to use 654** timeout -- timeout for reads/writes | 415** Open up listen port 416** Wait for connections 417** 418** Parameters: 419** conn -- connection description 420** dbg -- debug level 421** smfi -- filter structure to use 422** timeout -- timeout for reads/writes |
655** backlog -- listen queue backlog size | |
656** 657** Returns: 658** MI_SUCCESS -- Exited normally 659** (session finished or we were told to exit) 660** MI_FAILURE -- Network initialization failed. 661*/ 662 | 423** 424** Returns: 425** MI_SUCCESS -- Exited normally 426** (session finished or we were told to exit) 427** MI_FAILURE -- Network initialization failed. 428*/ 429 |
663#if BROKEN_PTHREAD_SLEEP 664 665/* 666** Solaris 2.6, perhaps others, gets an internal threads library panic 667** when sleep() is used: 668** 669** thread_create() failed, returned 11 (EINVAL) 670** co_enable, thr_create() returned error = 24 671** libthread panic: co_enable failed (PID: 17793 LWP 1) 672** stacktrace: 673** ef526b10 674** ef52646c 675** ef534cbc 676** 156a4 677** 14644 678** 1413c 679** 135e0 680** 0 681*/ 682 683# define MI_SLEEP(s) \ 684{ \ 685 int rs = 0; \ 686 struct timeval st; \ 687 \ 688 st.tv_sec = (s); \ 689 st.tv_usec = 0; \ 690 if (st.tv_sec > 0) \ 691 { \ 692 for (;;) \ 693 { \ 694 rs = select(0, NULL, NULL, NULL, &st); \ 695 if (rs < 0 && errno == EINTR) \ 696 continue; \ 697 if (rs != 0) \ 698 { \ 699 smi_log(SMI_LOG_ERR, \ 700 "MI_SLEEP(): select() returned non-zero result %d, errno = %d", \ 701 rs, errno); \ 702 } \ 703 break; \ 704 } \ 705 } \ 706} 707#else /* BROKEN_PTHREAD_SLEEP */ 708# define MI_SLEEP(s) sleep((s)) 709#endif /* BROKEN_PTHREAD_SLEEP */ 710 | |
711int | 430int |
712mi_listener(conn, dbg, smfi, timeout, backlog) | 431mi_listener(conn, dbg, smfi, timeout) |
713 char *conn; 714 int dbg; 715 smfiDesc_ptr smfi; 716 time_t timeout; | 432 char *conn; 433 int dbg; 434 smfiDesc_ptr smfi; 435 time_t timeout; |
717 int backlog; | |
718{ | 436{ |
719 socket_t connfd = INVALID_SOCKET; 720#if _FFR_DUP_FD 721 socket_t dupfd = INVALID_SOCKET; 722#endif /* _FFR_DUP_FD */ | 437 int connfd = -1; 438 int listenfd = -1; |
723 int sockopt = 1; | 439 int sockopt = 1; |
724 int r, mistop; | 440 int r; |
725 int ret = MI_SUCCESS; | 441 int ret = MI_SUCCESS; |
726 int mcnt = 0; /* error count for malloc() failures */ 727 int tcnt = 0; /* error count for thread_create() failures */ 728 int acnt = 0; /* error count for accept() failures */ 729 int scnt = 0; /* error count for select() failures */ 730 int save_errno = 0; 731 int fdflags; 732#if !_FFR_WORKERS_POOL | 442 int cnt_m = 0; 443 int cnt_t = 0; |
733 sthread_t thread_id; | 444 sthread_t thread_id; |
734#endif /* !_FFR_WORKERS_POOL */ | |
735 _SOCK_ADDR cliaddr; | 445 _SOCK_ADDR cliaddr; |
446 SOCKADDR_LEN_T socksize; |
|
736 SOCKADDR_LEN_T clilen; 737 SMFICTX_PTR ctx; | 447 SOCKADDR_LEN_T clilen; 448 SMFICTX_PTR ctx; |
738 FD_RD_VAR(rds, excs); | 449 fd_set readset, excset; |
739 struct timeval chktime; 740 | 450 struct timeval chktime; 451 |
741 if (mi_opensocket(conn, backlog, dbg, false, smfi) == MI_FAILURE) | 452 if (dbg > 0) 453 smi_log(SMI_LOG_DEBUG, 454 "%s: Opening listen socket on conn %s", 455 smfi->xxfi_name, conn); 456 if ((listenfd = mi_milteropen(conn, SOMAXCONN, &socksize, 457 smfi->xxfi_name)) < 0) 458 { 459 smi_log(SMI_LOG_FATAL, 460 "%s: Unable to create listening socket on conn %s", 461 smfi->xxfi_name, conn); |
742 return MI_FAILURE; | 462 return MI_FAILURE; |
743 744#if _FFR_WORKERS_POOL 745 if (mi_pool_controller_init() == MI_FAILURE) | 463 } 464 clilen = socksize; 465 if (listenfd >= FD_SETSIZE) 466 { 467 smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d", 468 smfi->xxfi_name, listenfd, FD_SETSIZE); |
746 return MI_FAILURE; | 469 return MI_FAILURE; |
747#endif /* _FFR_WORKERS_POOL */ | 470 } |
748 | 471 |
749 clilen = L_socksize; 750 while ((mistop = mi_stop()) == MILTER_CONT) | 472 while (mi_stop() == MILTER_CONT) |
751 { | 473 { |
752 (void) smutex_lock(&L_Mutex); 753 if (!ValidSocket(listenfd)) 754 { 755 ret = MI_FAILURE; 756 smi_log(SMI_LOG_ERR, 757 "%s: listenfd=%d corrupted, terminating, errno=%d", 758 smfi->xxfi_name, listenfd, errno); 759 (void) smutex_unlock(&L_Mutex); 760 break; 761 } 762 | |
763 /* select on interface ports */ | 474 /* select on interface ports */ |
764 FD_RD_INIT(listenfd, rds, excs); | 475 FD_ZERO(&readset); 476 FD_SET((u_int) listenfd, &readset); 477 FD_ZERO(&excset); 478 FD_SET((u_int) listenfd, &excset); |
765 chktime.tv_sec = MI_CHK_TIME; 766 chktime.tv_usec = 0; | 479 chktime.tv_sec = MI_CHK_TIME; 480 chktime.tv_usec = 0; |
767 r = FD_RD_READY(listenfd, rds, excs, &chktime); | 481 r = select(listenfd + 1, &readset, NULL, &excset, &chktime); |
768 if (r == 0) /* timeout */ | 482 if (r == 0) /* timeout */ |
769 { 770 (void) smutex_unlock(&L_Mutex); | |
771 continue; /* just check mi_stop() */ | 483 continue; /* just check mi_stop() */ |
772 } | |
773 if (r < 0) 774 { | 484 if (r < 0) 485 { |
775 save_errno = errno; 776 (void) smutex_unlock(&L_Mutex); 777 if (save_errno == EINTR) | 486 if (errno == EINTR) |
778 continue; | 487 continue; |
779 scnt++; 780 smi_log(SMI_LOG_ERR, 781 "%s: %s() failed (%s), %s", 782 smfi->xxfi_name, MI_POLLSELECT, 783 sm_errstring(save_errno), 784 scnt >= MAX_FAILS_S ? "abort" : "try again"); 785 MI_SLEEP(scnt); 786 if (scnt >= MAX_FAILS_S) 787 { 788 ret = MI_FAILURE; 789 break; 790 } 791 continue; | 488 ret = MI_FAILURE; 489 break; |
792 } | 490 } |
793 if (!FD_IS_RD_RDY(listenfd, rds, excs)) | 491 if (!FD_ISSET(listenfd, &readset)) |
794 { 795 /* some error: just stop for now... */ 796 ret = MI_FAILURE; | 492 { 493 /* some error: just stop for now... */ 494 ret = MI_FAILURE; |
797 (void) smutex_unlock(&L_Mutex); 798 smi_log(SMI_LOG_ERR, 799 "%s: %s() returned exception for socket, abort", 800 smfi->xxfi_name, MI_POLLSELECT); | |
801 break; 802 } | 495 break; 496 } |
803 scnt = 0; /* reset error counter for select() */ | |
804 | 497 |
805 (void) memset(&cliaddr, '\0', sizeof cliaddr); | |
806 connfd = accept(listenfd, (struct sockaddr *) &cliaddr, 807 &clilen); | 498 connfd = accept(listenfd, (struct sockaddr *) &cliaddr, 499 &clilen); |
808 save_errno = errno; 809 (void) smutex_unlock(&L_Mutex); | |
810 | 500 |
811 /* 812 ** If remote side closes before accept() finishes, 813 ** sockaddr might not be fully filled in. 814 */ 815 816 if (ValidSocket(connfd) && 817 (clilen == 0 || 818# ifdef BSD4_4_SOCKADDR 819 cliaddr.sa.sa_len == 0 || 820# endif /* BSD4_4_SOCKADDR */ 821 cliaddr.sa.sa_family != L_family)) | 501 if (connfd < 0) |
822 { | 502 { |
823 (void) closesocket(connfd); 824 connfd = INVALID_SOCKET; 825 save_errno = EINVAL; 826 } 827 828 /* check if acceptable for select() */ 829 if (ValidSocket(connfd) && !SM_FD_OK_SELECT(connfd)) 830 { 831 (void) closesocket(connfd); 832 connfd = INVALID_SOCKET; 833 save_errno = ERANGE; 834 } 835 836 if (!ValidSocket(connfd)) 837 { 838 if (save_errno == EINTR 839#ifdef EAGAIN 840 || save_errno == EAGAIN 841#endif /* EAGAIN */ 842#ifdef ECONNABORTED 843 || save_errno == ECONNABORTED 844#endif /* ECONNABORTED */ 845#ifdef EMFILE 846 || save_errno == EMFILE 847#endif /* EMFILE */ 848#ifdef ENFILE 849 || save_errno == ENFILE 850#endif /* ENFILE */ 851#ifdef ENOBUFS 852 || save_errno == ENOBUFS 853#endif /* ENOBUFS */ 854#ifdef ENOMEM 855 || save_errno == ENOMEM 856#endif /* ENOMEM */ 857#ifdef ENOSR 858 || save_errno == ENOSR 859#endif /* ENOSR */ 860#ifdef EWOULDBLOCK 861 || save_errno == EWOULDBLOCK 862#endif /* EWOULDBLOCK */ 863 ) 864 continue; 865 acnt++; | |
866 smi_log(SMI_LOG_ERR, | 503 smi_log(SMI_LOG_ERR, |
867 "%s: accept() returned invalid socket (%s), %s", 868 smfi->xxfi_name, sm_errstring(save_errno), 869 acnt >= MAX_FAILS_A ? "abort" : "try again"); 870 MI_SLEEP(acnt); 871 if (acnt >= MAX_FAILS_A) 872 { 873 ret = MI_FAILURE; 874 break; 875 } | 504 "%s: accept() returned invalid socket", 505 smfi->xxfi_name); |
876 continue; 877 } | 506 continue; 507 } |
878 acnt = 0; /* reset error counter for accept() */ 879#if _FFR_DUP_FD 880 dupfd = fcntl(connfd, F_DUPFD, 256); 881 if (ValidSocket(dupfd) && SM_FD_OK_SELECT(dupfd)) 882 { 883 close(connfd); 884 connfd = dupfd; 885 dupfd = INVALID_SOCKET; 886 } 887#endif /* _FFR_DUP_FD */ | |
888 | 508 |
889 /* 890 ** Need to set close-on-exec for connfd in case a user's 891 ** filter starts other applications. 892 ** Note: errors will not stop processing (for now). 893 */ 894 895 if ((fdflags = fcntl(connfd, F_GETFD, 0)) == -1 || 896 fcntl(connfd, F_SETFD, fdflags | FD_CLOEXEC) == -1) 897 { 898 smi_log(SMI_LOG_ERR, 899 "%s: Unable to set close-on-exec: %s", 900 smfi->xxfi_name, sm_errstring(errno)); 901 } 902 | |
903 if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, 904 (void *) &sockopt, sizeof sockopt) < 0) 905 { | 509 if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, 510 (void *) &sockopt, sizeof sockopt) < 0) 511 { |
906 smi_log(SMI_LOG_WARN, 907 "%s: set keepalive failed (%s)", 908 smfi->xxfi_name, sm_errstring(errno)); | 512 smi_log(SMI_LOG_WARN, "%s: setsockopt() failed", 513 smfi->xxfi_name); |
909 /* XXX: continue? */ 910 } 911 if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) 912 { | 514 /* XXX: continue? */ 515 } 516 if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) 517 { |
913 (void) closesocket(connfd); 914 mcnt++; 915 smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed (%s), %s", 916 smfi->xxfi_name, sm_errstring(save_errno), 917 mcnt >= MAX_FAILS_M ? "abort" : "try again"); 918 MI_SLEEP(mcnt); 919 if (mcnt >= MAX_FAILS_M) | 518 (void) close(connfd); 519 smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed", 520 smfi->xxfi_name); 521 sleep(++cnt_m); 522 if (cnt_m >= MAX_FAILS_M) |
920 { 921 ret = MI_FAILURE; 922 break; 923 } 924 continue; 925 } | 523 { 524 ret = MI_FAILURE; 525 break; 526 } 527 continue; 528 } |
926 mcnt = 0; /* reset error counter for malloc() */ 927 (void) memset(ctx, '\0', sizeof *ctx); | 529 cnt_m = 0; 530 memset(ctx, '\0', sizeof *ctx); |
928 ctx->ctx_sd = connfd; 929 ctx->ctx_dbg = dbg; 930 ctx->ctx_timeout = timeout; 931 ctx->ctx_smfi = smfi; | 531 ctx->ctx_sd = connfd; 532 ctx->ctx_dbg = dbg; 533 ctx->ctx_timeout = timeout; 534 ctx->ctx_smfi = smfi; |
535#if 0 536 if (smfi->xxfi_eoh == NULL) 537 if (smfi->xxfi_eom == NULL) 538 if (smfi->xxfi_abort == NULL) 539 if (smfi->xxfi_close == NULL) 540#endif /* 0 */ |
|
932 if (smfi->xxfi_connect == NULL) 933 ctx->ctx_pflags |= SMFIP_NOCONNECT; 934 if (smfi->xxfi_helo == NULL) 935 ctx->ctx_pflags |= SMFIP_NOHELO; 936 if (smfi->xxfi_envfrom == NULL) 937 ctx->ctx_pflags |= SMFIP_NOMAIL; 938 if (smfi->xxfi_envrcpt == NULL) 939 ctx->ctx_pflags |= SMFIP_NORCPT; 940 if (smfi->xxfi_header == NULL) 941 ctx->ctx_pflags |= SMFIP_NOHDRS; 942 if (smfi->xxfi_eoh == NULL) 943 ctx->ctx_pflags |= SMFIP_NOEOH; 944 if (smfi->xxfi_body == NULL) 945 ctx->ctx_pflags |= SMFIP_NOBODY; | 541 if (smfi->xxfi_connect == NULL) 542 ctx->ctx_pflags |= SMFIP_NOCONNECT; 543 if (smfi->xxfi_helo == NULL) 544 ctx->ctx_pflags |= SMFIP_NOHELO; 545 if (smfi->xxfi_envfrom == NULL) 546 ctx->ctx_pflags |= SMFIP_NOMAIL; 547 if (smfi->xxfi_envrcpt == NULL) 548 ctx->ctx_pflags |= SMFIP_NORCPT; 549 if (smfi->xxfi_header == NULL) 550 ctx->ctx_pflags |= SMFIP_NOHDRS; 551 if (smfi->xxfi_eoh == NULL) 552 ctx->ctx_pflags |= SMFIP_NOEOH; 553 if (smfi->xxfi_body == NULL) 554 ctx->ctx_pflags |= SMFIP_NOBODY; |
946 if (smfi->xxfi_version <= 3 || smfi->xxfi_data == NULL) 947 ctx->ctx_pflags |= SMFIP_NODATA; 948 if (smfi->xxfi_version <= 2 || smfi->xxfi_unknown == NULL) 949 ctx->ctx_pflags |= SMFIP_NOUNKNOWN; | |
950 | 555 |
951#if _FFR_WORKERS_POOL 952# define LOG_CRT_FAIL "%s: mi_start_session() failed: %d, %s" 953 if ((r = mi_start_session(ctx)) != MI_SUCCESS) 954#else /* _FFR_WORKERS_POOL */ 955# define LOG_CRT_FAIL "%s: thread_create() failed: %d, %s" | |
956 if ((r = thread_create(&thread_id, 957 mi_thread_handle_wrapper, | 556 if ((r = thread_create(&thread_id, 557 mi_thread_handle_wrapper, |
958 (void *) ctx)) != 0) 959#endif /* _FFR_WORKERS_POOL */ | 558 (void *) ctx)) != MI_SUCCESS) |
960 { | 559 { |
961 tcnt++; | |
962 smi_log(SMI_LOG_ERR, | 560 smi_log(SMI_LOG_ERR, |
963 LOG_CRT_FAIL, 964 smfi->xxfi_name, r, 965 tcnt >= MAX_FAILS_T ? "abort" : "try again"); 966 MI_SLEEP(tcnt); 967 (void) closesocket(connfd); | 561 "%s: thread_create() failed: %d", 562 smfi->xxfi_name, r); 563 sleep(++cnt_t); 564 (void) close(connfd); |
968 free(ctx); | 565 free(ctx); |
969 if (tcnt >= MAX_FAILS_T) | 566 if (cnt_t >= MAX_FAILS_T) |
970 { 971 ret = MI_FAILURE; 972 break; 973 } 974 continue; 975 } | 567 { 568 ret = MI_FAILURE; 569 break; 570 } 571 continue; 572 } |
976 tcnt = 0; | 573 cnt_t = 0; |
977 } 978 if (ret != MI_SUCCESS) 979 mi_stop_milters(MILTER_ABRT); | 574 } 575 if (ret != MI_SUCCESS) 576 mi_stop_milters(MILTER_ABRT); |
980 else 981 { 982 if (mistop != MILTER_CONT) 983 smi_log(SMI_LOG_INFO, "%s: mi_stop=%d", 984 smfi->xxfi_name, mistop); 985 mi_closener(); 986 } 987 (void) smutex_destroy(&L_Mutex); | 577 if (listenfd >= 0) 578 (void) close(listenfd); |
988 return ret; 989} | 579 return ret; 580} |
581#endif /* _FFR_MILTER */ |
|