1 /*
2 * ----------------------------------------------------------------
3 * Ident Daemon - Listener Functions
4 * ----------------------------------------------------------------
5 * Copyright (C) 1997-2009 Jonas Kvinge
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * $Id: ident_listen.c 54 2009-03-18 18:23:29Z jonasio $
21 *
22 */
23
24 #define IDENT_LISTEN_C
25
26 #define NEED_SYS_TYPES_H 1 /* Extra types */
27 #define NEED_SYS_PARAM_H 1 /* Some systems need this */
28 #define NEED_LIMITS_H 0 /* Kernel limits */
29 #define NEED_STDARG_H 1 /* va_list, etc */
30 #define NEED_ERRNO_H 1 /* errno */
31 #define NEED_CTYPE_H 1 /* isdigit(), etc */
32 #define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */
33 #define NEED_ARPA_INET_H 1 /* inet_ntoa(), inet_aton(), etc */
34 #define NEED_STDIO_H 1 /* Standard C UNIX functions */
35 #define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */
36 #define NEED_TIME_H 1 /* time(), etc */
37 #define NEED_SYSCTL_H 0 /* sysctl(), etc */
38 #define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */
39 #define NEED_SYS_UIO_H 0 /* iovec, etc */
40 #define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */
41 #define NEED_SYS_IOCTL_H 1 /* ioctl(), etc */
42 #define NEED_SYS_FILIO_H 1 /* Solaris need this for ioctl(), etc */
43 #define NEED_UNISTD_H 1 /* Unix standard functions */
44 #define NEED_STRING_H 1 /* C string functions */
45 #define NEED_SIGNAL_H 0 /* Signal functions */
46 #define NEED_SYS_SOCKET_H 1 /* Socket functions */
47 #define NEED_NETDB_H 1 /* Network database functions */
48 #define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */
49 #define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */
50 #define NEED_ARES 1 /* Functions needed for ares */
51 #define NEED_SSL 0 /* Needed for SSL support */
52
53 #include "includes.h"
54
55 #include "ident_listen.h"
56 #include "ident_conn.h"
57
58 /* VARIABLES - JONAS (03.07.2003) */
59
60 struct IdentListen_Struct *IdentListen_Head = NULL;
61 struct IdentListen_Struct *IdentListen_Tail = NULL;
62 unsigned long int G_Ident_Listens = 0;
63
64 #if ARES
65 extern ares_channel Ares_Channel;
66 #endif
67
68 /* IDENT_LISTEN_ADD FUNCTION - JONAS (03.07.2003) */
69
ident_listen_add(const char * const HostPT,const unsigned long int Port)70 struct IdentListen_Struct *ident_listen_add(const char *const HostPT, const unsigned long int Port) {
71
72 struct IdentListen_Struct *IdentListenS = NULL;
73 struct IdentListen_Struct *IdentListen_NEW = NULL;
74
75 assert(HostPT != NULL);
76
77 IdentListenS = ident_get(HostPT, Port);
78 if (IdentListenS != NULL) {
79 aerrno = AEEXISTS;
80 return(IdentListenS);
81 }
82
83 IdentListen_NEW = malloc(sizeof(struct IdentListen_Struct));
84 if (IdentListen_NEW == NULL) {
85 aerrno = AEMALLOC;
86 return(NULL);
87 }
88
89 memset(IdentListen_NEW, 0, sizeof(struct IdentListen_Struct));
90
91 IdentListen_NEW->Host = strdup(HostPT);
92 if (IdentListen_NEW->Host == NULL) {
93 free(IdentListen_NEW);
94 aerrno = AEMALLOC;
95 return(NULL);
96 }
97
98 IdentListen_NEW->PortH = Port;
99 IdentListen_NEW->PortN = htons(Port);
100
101 if (IdentListen_Head == NULL) {
102 IdentListen_Head = IdentListen_NEW;
103 IdentListen_Tail = IdentListen_NEW;
104 }
105 else {
106 IdentListenS = IdentListen_Tail;
107 IdentListenS->Next = IdentListen_NEW;
108 IdentListen_NEW->Prev = IdentListenS;
109 IdentListen_Tail = IdentListen_NEW;
110 }
111
112 G_Ident_Listens++;
113
114 aerrno = AESUCCESS;
115 return(IdentListen_NEW);
116
117 }
118
119 /* IDENT_LISTEN_REM FUNCTION - JONAS (03.07.2003) */
120
ident_listen_rem(struct IdentListen_Struct * IdentListenS)121 void ident_listen_rem(struct IdentListen_Struct *IdentListenS) {
122
123 assert(IdentListenS != NULL);
124
125 if (IdentListenS->Prev == NULL) { IdentListen_Head = IdentListenS->Next; }
126 else { IdentListenS->Prev->Next = IdentListenS->Next; }
127
128 if (IdentListenS->Next == NULL) { IdentListen_Tail = IdentListenS->Prev; }
129 else { IdentListenS->Next->Prev = IdentListenS->Prev; }
130
131 ident_listen_init(IdentListenS);
132
133 free(IdentListenS->Host);
134 free(IdentListenS);
135
136 G_Ident_Listens--;
137
138 }
139
140 /* IDENT_LISTEN_INIT FUNCTION - JONAS (03.07.2003) */
141
ident_listen_init(struct IdentListen_Struct * IdentListenS)142 void ident_listen_init(struct IdentListen_Struct *IdentListenS) {
143
144 assert(IdentListenS != NULL);
145
146 IdentListenS->Flags = 0;
147 FREE(IdentListenS->HostIPS);
148 memset(&IdentListenS->INAddr, 0, sizeof(IdentListenS->INAddr));
149 #if IPV6_SUPPORT
150 memset(&IdentListenS->INAddr6, 0, sizeof(IdentListenS->INAddr6));
151 #endif
152 IdentListenS->PortH = 0;
153 IdentListenS->PortN = 0;
154 IdentListenS->FD = FD_NONE;
155
156 }
157
158 /* IDENT_LISTEN_GET - JONAS (03.07.2003) */
159
ident_get(const char * const HostPT,const unsigned long int Port)160 struct IdentListen_Struct *ident_get(const char *const HostPT, const unsigned long int Port) {
161
162 struct IdentListen_Struct *IdentListenS = NULL;
163
164 assert(HostPT != NULL);
165
166 for (IdentListenS = IdentListen_Head ; IdentListenS != NULL ; IdentListenS = IdentListenS->Next) {
167 if ((strcasecmp(IdentListenS->Host, HostPT) == FALSE) && (IdentListenS->PortH == Port)) {
168 aerrno = AESUCCESS;
169 return(IdentListenS);
170 }
171 }
172 aerrno = AENOMATCH;
173 return(NULL);
174
175 }
176
177 /* IDENT_LISTEN_START - JONAS (03.07.2003) */
178
ident_listen_start(struct IdentListen_Struct * IdentListenS)179 void ident_listen_start(struct IdentListen_Struct *IdentListenS) {
180
181 signed long int Result = 0;
182 signed long int BindResult = 0;
183
184 struct sockaddr_in SockAddr = { 0 };
185 #if IPV6_SUPPORT
186 struct sockaddr_in6 SockAddr6 = { 0 };
187 #endif
188
189 #if !ARES
190 struct hostent *HostEnt = NULL;
191 #endif
192
193 unsigned long int Flags = 0;
194
195 assert(IdentListenS != NULL);
196
197 IdentListenS->Time = NOW;
198 IdentListenS->Tries++;
199
200 if (!IdentListen_IsResolved(IdentListenS)) {
201
202 if (IdentListenS->Host[0] == '*') {
203 #if IPV6_SUPPORT
204 if (IdentListen_IsIPv6(IdentListenS)) {
205 memset(&IdentListenS->INAddr6, 0, sizeof(IdentListenS->INAddr6));
206 IdentListenS->INAddr6 = in6addr_any;
207 }
208 else {
209 #endif /* IPV6_SUPPORT */
210 memset(&IdentListenS->INAddr, 0, sizeof(IdentListenS->INAddr));
211 IdentListenS->INAddr.s_addr = INADDR_ANY;
212 #if IPV6_SUPPORT
213 }
214 #endif /* IPV6_SUPPORT */
215 IdentListen_SetResolved(IdentListenS);
216 }
217 else {
218 memset(&IdentListenS->INAddr, 0, sizeof(IdentListenS->INAddr));
219 Result = inet_aton(IdentListenS->Host, &IdentListenS->INAddr);
220 if (Result <= 0) {
221 IdentListen_SetResolving(IdentListenS);
222 #if ARES
223 #if IPV6_SUPPORT
224 if (IdentListen_IsIPv6(IdentListenS)) {
225 ares_gethostbyname(Ares_Channel, IdentListenS->Host, AF_INET6, (ares_host_callback) ident_listen_hosttoip, IdentListenS);
226 return;
227 }
228 else {
229 #endif /* IPV6_SUPPORT */
230 ares_gethostbyname(Ares_Channel, IdentListenS->Host, AF_INET, (ares_host_callback) ident_listen_hosttoip, IdentListenS);
231 #if IPV6_SUPPORT
232 }
233 #endif /* IPV6_SUPPORT */
234 return;
235 #else /* ARES */
236
237
238 #if IPV6_SUPPORT
239 if (IdentListen_IsIPv6(IdentListenS)) { HostEnt = gethostbyname2(IdentListenS->Host, AF_INET6); }
240 else { HostEnt = gethostbyname2(IdentListenS->Host, AF_INET); }
241 #else /* IPV6_SUPPORT */
242 HostEnt = gethostbyname(IdentListenS->Host);
243 #endif /* IPV6_SUPPORT */
244 ident_listen_hosttoip(IdentListenS, errno, HostEnt);
245 if (!Listen_IsResolved(IdentListenS)) { return; }
246 #endif /* ARES */
247 }
248 else {
249 IdentListen_SetResolved(IdentListenS);
250 IdentListenS->HostIPS = strrealloc(IdentListenS->HostIPS, IdentListenS->Host);
251 if (aerrno != AESUCCESS) { ident_listen_init(IdentListenS); return; }
252 }
253 }
254
255 }
256
257 /* CREATE SOCKET */
258
259 #if IPV6_SUPPORT
260 if (IdentListen_IsIPv6(IdentListenS)) {
261 Result = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
262 }
263 else {
264 #endif /* IPV6_SUPPORT */
265 Result = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
266 #if IPV6_SUPPORT
267 }
268 #endif /* IPV6_SUPPORT */
269 if (Result <= ERROR) {
270 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to create socket: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
271 ident_listen_stop(IdentListenS);
272 return;
273 }
274 IdentListenS->FD = Result;
275
276 IdentListen_SetSocket(IdentListenS);
277
278 /* SET SOCKET IN NON-BLOCKING MODE */
279
280 #if defined(NBLOCK_SYSV)
281 Flags = 1;
282 Result = ioctl(IdentListenS->FD, FIONBIO, &Flags);
283 if (Result <= ERROR) {
284 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to set socket in non-blocking mode using ioctl(): [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
285 ident_listen_stop(IdentListenS);
286 return;
287 }
288 #else
289 Result = fcntl(IdentListenS->FD, F_GETFL, &Flags);
290 if (Result <= ERROR) {
291 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to get socket flags using fcntl(): [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
292 ident_listen_stop(IdentListenS);
293 return;
294 }
295 #if defined(NBLOCK_BSD)
296 Flags |= O_NDELAY;
297 #elif defined(NBLOCK_POSIX)
298 Flags |= O_NONBLOCK;
299 #else
300 #warning "This system does not support non-blocking sockets?"
301 Flags |= O_NONBLOCK;
302 #endif
303 Result = fcntl(IdentListenS->FD, F_SETFL, Flags);
304 if (Result <= ERROR) {
305 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to set socket in non-blocking mode using fcntl(): [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
306 ident_listen_stop(IdentListenS);
307 return;
308 }
309 #endif
310
311
312 if (IDENTLISTEN_SOCKKEEPALIVE == TRUE) {
313
314 unsigned long int OPT = 1;
315
316 Result = setsockopt(IdentListenS->FD, SOL_SOCKET, SO_KEEPALIVE, &OPT, sizeof(OPT));
317 if (Result <= ERROR) {
318 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to set Keep Alive option for socket: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
319 ident_listen_stop(IdentListenS);
320 return;
321 }
322
323 }
324
325 if (IDENTLISTEN_SOCKREUSEADDR == TRUE) {
326
327 unsigned long int OPT = 1;
328
329 Result = setsockopt(IdentListenS->FD, SOL_SOCKET, SO_REUSEADDR, &OPT, sizeof(OPT));
330 if (Result <= ERROR) {
331 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to set Reuse Address option for socket: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
332 ident_listen_stop(IdentListenS);
333 return;
334 }
335
336 }
337
338 /* BIND */
339
340 #if !WIN32
341 if (IdentListenS->PortH < 1024) { sysseteuid(0); }
342 #endif
343
344 #if IPV6_SUPPORT
345 if (IdentListen_IsIPv6(IdentListenS)) {
346 memset(&SockAddr6, 0, sizeof(SockAddr6));
347 SockAddr6.sin6_family = AF_INET6;
348 SockAddr6.sin6_addr = IdentListenS->INAddr6;
349 SockAddr6.sin6_port = IdentListenS->PortN;
350 BindResult = bind(IdentListenS->FD, (struct sockaddr *) &SockAddr6, sizeof(SockAddr6));
351 }
352 else {
353 #endif /* IPV6_SUPPORT */
354 memset(&SockAddr, 0, sizeof(SockAddr));
355 SockAddr.sin_family = AF_INET;
356 SockAddr.sin_addr = IdentListenS->INAddr;
357 SockAddr.sin_port = IdentListenS->PortN;
358 BindResult = bind(IdentListenS->FD, (struct sockaddr *) &SockAddr, sizeof(SockAddr));
359 #if IPV6_SUPPORT
360 }
361 #endif /* IPV6_SUPPORT */
362
363 #if !WIN32
364 if (IdentListenS->PortH < 1024) { sysseteuidnormal(); }
365 #endif
366
367 if (BindResult <= ERROR) {
368 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to bind socket to address: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
369 ident_listen_stop(IdentListenS);
370 return;
371 }
372
373 /* IDENT */
374
375 Result = listen(IdentListenS->FD, SOMAXCONN);
376 if (Result <= ERROR) {
377 sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to listen on address: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
378 ident_listen_stop(IdentListenS);
379 return;
380 }
381 else {
382 DEBUGPRINT(BITMASK_DEBUG_IDENT, "Ident daemon %s(%s):%ld started.", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH);
383 IdentListen_SetListening(IdentListenS);
384 return;
385 }
386
387 }
388
389 /* IDENT_LISTEN_HOSTTOIP FUNCTION - JONAS (03.07.2003) */
390
391 #if HAVE_CARES_CALLBACK_TIMEOUTS
ident_listen_hosttoip(void * ArgPT,unsigned short int ErrNo,int Timeouts,struct hostent * HostEnt)392 void ident_listen_hosttoip(void *ArgPT, unsigned short int ErrNo, int Timeouts, struct hostent *HostEnt) {
393 #else
394 void ident_listen_hosttoip(void *ArgPT, unsigned short int ErrNo, struct hostent *HostEnt) {
395 #endif
396
397 struct IdentListen_Struct *IdentListenS = ArgPT;
398 const char *HostIPPT = NULL;
399 #if IPV6_SUPPORT
400 char Host[INET6_ADDRSTRLEN+1] = "";
401 #endif
402
403 assert(IdentListenS != NULL);
404
405 if ((HostEnt == NULL) || (HostEnt->h_length < 1)) {
406 sysprint(BITMASK_MAIN, "Ident daemon %s:%ld: Unable to resolve host %s to IP-address: [%d] %s", IdentListenS->Host, IdentListenS->PortH, IdentListenS->Host, ErrNo, res_strerror(ErrNo));
407 ident_listen_init(IdentListenS);
408 return;
409 }
410
411 #if IPV6_SUPPORT
412 if (IdentListen_IsIPv6(IdentListenS)) {
413 memset(&IdentListenS->INAddr6, 0, sizeof(IdentListenS->INAddr6));
414 memcpy(&IdentListenS->INAddr6, HostEnt->h_addr, HostEnt->h_length);
415 HostIPPT = inet_ntop(AF_INET6, &IdentListenS->INAddr6, Host, INET6_ADDRSTRLEN);
416 if (HostIPPT == NULL) {
417 sysprint(BITMASK_MAIN, "Ident daemon %s:%ld: inet_ntop() failed: [%d] %s", IdentListenS->Host, IdentListenS->PortH, errno, strerror(errno));
418 ident_listen_init(IdentListenS);
419 return;
420 }
421 }
422 else {
423 memset(&IdentListenS->INAddr, 0, sizeof(IdentListenS->INAddr));
424 memcpy(&IdentListenS->INAddr, HostEnt->h_addr, HostEnt->h_length);
425 HostIPPT = inet_ntop(AF_INET, &IdentListenS->INAddr, Host, INET6_ADDRSTRLEN);
426 if (HostIPPT == NULL) {
427 sysprint(BITMASK_MAIN, "Ident daemon %s:%ld: inet_ntop() failed: [%d] %s", IdentListenS->Host, IdentListenS->PortH, errno, strerror(errno));
428 ident_listen_init(IdentListenS);
429 return;
430 }
431 }
432 #else /* IPV6_SUPPORT */
433 memset(&IdentListenS->INAddr, 0, sizeof(IdentListenS->INAddr));
434 memcpy(&IdentListenS->INAddr, HostEnt->h_addr, HostEnt->h_length);
435 HostIPPT = inet_ntoa(IdentListenS->INAddr);
436 if (HostIPPT == NULL) {
437 sysprint(BITMASK_MAIN, "Ident daemon %s:%ld: inet_ntoa() failed: [%d] %s", IdentListenS->Host, IdentListenS->PortH, errno, strerror(errno));
438 ident_listen_init(IdentListenS);
439 return;
440 }
441 #endif
442 IdentListenS->HostIPS = strrealloc(IdentListenS->HostIPS, HostIPPT);
443
444 IdentListen_ClearResolving(IdentListenS);
445 IdentListen_SetResolved(IdentListenS);
446
447 #if ARES
448 ident_listen_start(IdentListenS);
449 #endif /* ARES */
450
451 }
452
453 /* IDENT_LISTEN_STOP - JONAS (03.07.2003) */
454
455 void ident_listen_stop(struct IdentListen_Struct *IdentListenS) {
456
457 assert(IdentListenS != NULL);
458
459 if (IdentListen_IsResolving(IdentListenS)) {
460 #if HAVE_ARES_CANCELQUERY
461 ares_cancelquery(Ares_Channel, IdentListenS);
462 #endif
463 return;
464 }
465 if (IdentListen_IsListening(IdentListenS)) { DEBUGPRINT(BITMASK_DEBUG_IDENT, "Ident daemon %s(%s):%ld stopped.", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH); }
466 if (IdentListen_IsSocket(IdentListenS)) {
467 close(IdentListenS->FD);
468 IdentListenS->FD = FD_NONE;
469 }
470 ident_listen_init(IdentListenS);
471
472 }
473
474 /* IDENT_LISTEN_FDS - JONAS (03.07.2003) */
475
476 void ident_listen_fds(fd_set *ReadFDS, fd_set *WriteFDS, unsigned long int *FDS) {
477
478 struct IdentListen_Struct *IdentListenS = NULL;
479
480 for (IdentListenS = IdentListen_Head ; IdentListenS != NULL ;) {
481 if (IdentListen_IsRemove(IdentListenS)) {
482 struct IdentListen_Struct *IdentListenS_DEL = NULL;
483 if (IdentListen_IsResolving(IdentListenS)) { continue; }
484 ident_listen_stop(IdentListenS);
485 IdentListenS_DEL = IdentListenS;
486 IdentListenS = IdentListenS->Next;
487 ident_listen_rem(IdentListenS_DEL);
488 continue;
489 }
490 if (IdentListen_IsListening(IdentListenS)) { FD_SET(IdentListenS->FD, ReadFDS); }
491 else {
492 if (!IdentListen_IsResolving(IdentListenS)) {
493 unsigned long int Duration = (NOW - IdentListenS->Time);
494 if (Duration >= IDENTLISTEN_INTERVAL) { ident_listen_start(IdentListenS); }
495 }
496 }
497 IdentListenS = IdentListenS->Next;
498 }
499
500 }
501
502 /* IDENT_LISTEN_IO - JONAS (03.07.2003) */
503
504 void ident_listen_io(fd_set *ReadFDS, fd_set *WriteFDS, unsigned long int *FDS) {
505
506 struct IdentListen_Struct *IdentListenS = NULL;
507 struct IdentConn_Struct *IdentConnS = NULL;
508 signed long int Result = 0;
509 unsigned long int FD = 0;
510 struct in_addr INAddr;
511 struct sockaddr_in SockAddr = { 0 };
512 accept_addrlen_type SockAddrLen = sizeof(SockAddr);
513 #if IPV6_SUPPORT
514 struct in6_addr INAddr6;
515 struct sockaddr_in6 SockAddr6 = { 0 };
516 accept_addrlen_type SockAddrLen6 = sizeof(SockAddr6);
517 char Host[INET6_ADDRSTRLEN+1] = "";
518 #endif
519 const char *HostIPPT = NULL;
520 unsigned long int PortH;
521 unsigned long int PortN;
522 unsigned short int Count = 0;
523
524 for (IdentListenS = IdentListen_Head ; IdentListenS != NULL ; IdentListenS = IdentListenS->Next) {
525
526 assert(*FDS >= 0);
527 if (*FDS <= 0) { return; }
528
529 if (!IdentListen_IsListening(IdentListenS)) { continue; }
530
531 if (!FD_ISSET(IdentListenS->FD, ReadFDS)) { continue; }
532 *FDS = *FDS - 1;
533
534 for (Count = 0 ;; ++Count) {
535 #if IPV6_SUPPORT
536 if (IdentListen_IsIPv6(IdentListenS)) {
537 Result = accept(IdentListenS->FD, (struct sockaddr *) &SockAddr6, &SockAddrLen6);
538 }
539 else {
540 #endif /* IPV6_SUPPORT */
541 Result = accept(IdentListenS->FD, (struct sockaddr *) &SockAddr, &SockAddrLen);
542 #if IPV6_SUPPORT
543 }
544 #endif /* IPV6_SUPPORT */
545 if (Result <= ERROR) {
546 if (Count == 0) { sysprint(BITMASK_MAIN, "Ident daemon %s(%s):%ld: Unable to accept new incoming connection: [%d] %s", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno)); }
547 break;
548 }
549 FD = Result;
550
551 #if IPV6_SUPPORT
552 if (IdentListen_IsIPv6(IdentListenS)) {
553 memset(&INAddr6, 0, sizeof(INAddr6));
554 INAddr6 = SockAddr6.sin6_addr;
555 PortN = SockAddr6.sin6_port;
556 }
557 else {
558 #endif /* IPV6_SUPPORT */
559 memset(&INAddr, 0, sizeof(INAddr));
560 INAddr = SockAddr.sin_addr;
561 PortN = SockAddr.sin_port;
562 #if IPV6_SUPPORT
563 }
564 #endif /* IPV6_SUPPORT */
565
566 PortH = ntohs(PortN);
567
568 #if IPV6_SUPPORT
569 if (IdentListen_IsIPv6(IdentListenS)) {
570 HostIPPT = inet_ntop(AF_INET6, &INAddr6, Host, INET6_ADDRSTRLEN);
571 if (HostIPPT == NULL) {
572 close(FD);
573 sysprint(BITMASK_ERROR, "Ident daemon %s(%s):%ld: Failed inet_ntop() for incoming client: %d [%s].", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
574 continue;
575 }
576 }
577 else {
578 HostIPPT = inet_ntop(AF_INET, &INAddr, Host, INET6_ADDRSTRLEN);
579 if (HostIPPT == NULL) {
580 close(FD);
581 sysprint(BITMASK_ERROR, "Ident daemon %s(%s):%ld: Failed inet_ntop() for incoming client: %d [%s].", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
582 continue;
583 }
584 }
585 #else
586 HostIPPT = inet_ntoa(INAddr);
587 if (HostIPPT == NULL) {
588 close(FD);
589 sysprint(BITMASK_ERROR, "Ident daemon %s(%s):%ld: Failed inet_ntoa() for incoming client: %d [%s].", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, errno, strerror(errno));
590 continue;
591 }
592 #endif
593
594 IdentConnS = ident_conn_add(HostIPPT, FD);
595 if (IdentConnS == NULL) {
596 close(FD);
597 continue;
598 }
599 IdentConnS->PortH = PortH;
600 IdentConnS->PortN = PortN;
601
602 #if IPV6_SUPPORT
603 if (IdentListen_IsIPv6(IdentListenS)) {
604 IdentConnS->INAddr6 = INAddr6;
605 }
606 else {
607 #endif
608 IdentConnS->INAddr = INAddr;
609 #if IPV6_SUPPORT
610 }
611 #endif
612
613 DEBUGPRINT(BITMASK_DEBUG_IDENT, "Ident daemon %s(%s):%ld: Successfully accepted new incoming connection from \"%s\".", IdentListenS->Host, IdentListenS->HostIPS, IdentListenS->PortH, HostIPPT);
614
615 }
616 }
617 }
618
619 /* IDENT_LISTEN_CLOSEALL FUNCTION - JONAS (03.07.2003) */
620
621 unsigned short int ident_listen_closeall(const char *const MessagePT, ...) {
622
623 struct IdentListen_Struct *IdentListenS = NULL;
624 struct IdentListen_Struct *IdentListenS_DEL = NULL;
625 unsigned short int Count = 0;
626
627 for (IdentListenS = IdentListen_Head ; IdentListenS != NULL ;) {
628 if (IdentListen_IsResolving(IdentListenS)) {
629 #if HAVE_ARES_CANCELQUERY
630 ares_cancelquery(Ares_Channel, IdentListenS);
631 #endif
632 ++Count;
633 IdentListen_SetRemove(IdentListenS);
634 continue;
635 }
636 ident_listen_stop(IdentListenS);
637 IdentListenS_DEL = IdentListenS;
638 IdentListenS = IdentListenS->Next;
639 ident_listen_rem(IdentListenS_DEL);
640 }
641
642 return(Count);
643
644 }
645
646