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