/* * ---------------------------------------------------------------- * Night Light IRC Proxy - Listen I/O Functions * ---------------------------------------------------------------- * Copyright (C) 1997-2007 Jonas Kvinge * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Last modified by: * Jonas Kvinge (15.11.2006) * */ #define LISTEN_IO_C #define NEED_SYS_TYPES_H 1 /* Extra types */ #define NEED_SYS_PARAM_H 1 /* Some systems need this */ #define NEED_LIMITS_H 0 /* Kernel limits */ #define NEED_STDARG_H 1 /* va_list, etc */ #define NEED_ERRNO_H 1 /* errno */ #define NEED_CTYPE_H 1 /* isdigit(), etc */ #define NEED_NETINET_IN_H 1 /* in_addr, sockaddr_in, etc */ #define NEED_ARPA_INET_H 1 /* inet_ntoa(), inet_aton(), etc */ #define NEED_STDIO_H 1 /* Standard C UNIX functions */ #define NEED_STDLIB_H 1 /* malloc(), exit(), atoi(), etc */ #define NEED_TIME_H 1 /* time(), etc */ #define NEED_SYSCTL_H 0 /* sysctl(), etc */ #define NEED_SYS_STAT_H 0 /* chmod(), mkdir(), etc */ #define NEED_SYS_UIO_H 0 /* iovec, etc */ #define NEED_FCNTL_H 1 /* open(), creat(), fcntl(), etc */ #define NEED_SYS_IOCTL_H 1 /* ioctl(), etc */ #define NEED_SYS_FILIO_H 1 /* Solaris need this for ioctl(), etc */ #define NEED_UNISTD_H 1 /* Unix standard functions */ #define NEED_STRING_H 1 /* C string functions */ #define NEED_SIGNAL_H 0 /* Signal functions */ #define NEED_SYS_SOCKET_H 1 /* Socket functions */ #define NEED_NETDB_H 1 /* Network database functions */ #define NEED_ARPA_NAMESER_H 0 /* Nameserver definitions */ #define NEED_GETUSERPW_HEADERS 0 /* Functions to retrive system passwords */ #define NEED_ARES 1 /* Functions needed for ares */ #define NEED_SSL 1 /* Needed for SSL support */ #include "includes.h" #include "conf.h" #include "listen.h" #include "listen_io.h" #include "client.h" #include "client_connection.h" /* VARIABLES - JONAS (06.10.2000) */ extern struct Conf_Struct ConfS; extern struct Listen_Struct *Listen_Head; extern struct Listen_Struct *Listen_Tail; extern struct Client_Struct *Client_Head; #if ARES extern ares_channel Ares_Channel; #endif #if SSL_SUPPORT extern SSL_CTX *IRCPROXY_SSL_SERVER_CTX; extern SSL_CTX *IRCPROXY_SSL_CLIENT_CTX; #endif /* LISTEN_START - JONAS (22.07.2001) */ void listen_start(struct Listen_Struct *ListenS) { signed long int Result = 0; struct sockaddr_in SockAddr = { 0 }; #if IPV6_SUPPORT struct sockaddr_in6 SockAddr6 = { 0 }; #endif unsigned long int Flags = 0; assert(ListenS != NULL); ListenS->Time = NOW; ++ListenS->Tries; DEBUGPRINT(BITMASK_DEBUG_LISTEN, "*** DEBUG *** listen_start(%s)", ListenS->Host); if (!Listen_IsResolved(ListenS)) { #if !ARES struct hostent *HostEnt = NULL; #endif if (ListenS->Host[0] == '*') { #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&ListenS->INAddr6, 0, sizeof(ListenS->INAddr6)); ListenS->INAddr6 = in6addr_any; } else { #endif /* IPV6_SUPPORT */ memset(&ListenS->INAddr, 0, sizeof(ListenS->INAddr)); ListenS->INAddr.s_addr = INADDR_ANY; #if IPV6_SUPPORT } #endif /* IPV6_SUPPORT */ ListenS->HostIPS = strrealloc(ListenS->HostIPS, "ALL"); Listen_SetResolved(ListenS); } else { #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&ListenS->INAddr6, 0, sizeof(ListenS->INAddr6)); Result = inet_pton(AF_INET6, ListenS->Host, &ListenS->INAddr6); } else { memset(&ListenS->INAddr, 0, sizeof(ListenS->INAddr)); Result = inet_pton(AF_INET, ListenS->Host, &ListenS->INAddr); } #else /* IPV6_SUPPORT */ memset(&ListenS->INAddr, 0, sizeof(ListenS->INAddr)); Result = inet_aton(ListenS->Host, &ListenS->INAddr); #endif /* IPV6_SUPPORT */ if (Result <= 0) { Listen_SetResolving(ListenS); #if ARES #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { ares_gethostbyname(Ares_Channel, ListenS->Host, AF_INET6, (ares_host_callback) listen_hosttoip, ListenS); } else { #endif /* IPV6_SUPPORT */ ares_gethostbyname(Ares_Channel, ListenS->Host, AF_INET, (ares_host_callback) listen_hosttoip, ListenS); #if IPV6_SUPPORT } #endif /* IPV6_SUPPORT */ return; #else /* ARES */ #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { HostEnt = gethostbyname2(ListenS->Host, AF_INET6); } else { HostEnt = gethostbyname2(ListenS->Host, AF_INET); } #else /* IPV6_SUPPORT */ HostEnt = gethostbyname(ListenS->Host); #endif /* IPV6_SUPPORT */ listen_hosttoip(ListenS, errno, HostEnt); if (!Listen_IsResolved(ListenS)) { return; } #endif /* ARES */ } else { Listen_SetResolved(ListenS); ListenS->HostIPS = strrealloc(ListenS->HostIPS, ListenS->Host); if (aerrno != AESUCCESS) { listen_init(ListenS); return; } } } } /* CREATE SOCKET */ #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { Result = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); } else { #endif Result = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); #if IPV6_SUPPORT } #endif if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to create socket: [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } ListenS->FD = Result; Listen_SetSocket(ListenS); /* SET SOCKET IN NON-BLOCKING MODE */ #if defined(NBLOCK_SYSV) Flags = 1; Result = ioctl(ListenS->FD, FIONBIO, &Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to set socket in non-blocking mode using ioctl(): [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } #else Result = fcntl(ListenS->FD, F_GETFL, &Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to get socket flags using fcntl(): [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } #if defined(NBLOCK_BSD) Flags |= O_NDELAY; #elif defined(NBLOCK_POSIX) Flags |= O_NONBLOCK; #else #warning "This system does not support non-blocking sockets?" Flags |= O_NONBLOCK; #endif Result = fcntl(ListenS->FD, F_SETFL, Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to set socket in non-blocking mode using fcntl(): [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } #endif if (LISTEN_SOCKKEEPALIVE == TRUE) { unsigned long int OPT = 1; Result = setsockopt(ListenS->FD, SOL_SOCKET, SO_KEEPALIVE, &OPT, sizeof(OPT)); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to set Keep Alive option for socket: [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } } if (LISTEN_SOCKREUSEADDR == TRUE) { unsigned long int OPT = 1; Result = setsockopt(ListenS->FD, SOL_SOCKET, SO_REUSEADDR, &OPT, sizeof(OPT)); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to set Reuse Address option for socket: [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } } /* BIND */ #if !WIN32 if (ListenS->PortH < 1024) { sysseteuid(0); } #endif #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&SockAddr6, 0, sizeof(SockAddr6)); SockAddr6.sin6_family = AF_INET6; SockAddr6.sin6_addr = ListenS->INAddr6; SockAddr6.sin6_port = ListenS->PortN; Result = bind(ListenS->FD, (struct sockaddr *) &SockAddr6, sizeof(SockAddr6)); } else { #endif /* IPV6_SUPPORT */ memset(&SockAddr, 0, sizeof(SockAddr)); SockAddr.sin_family = AF_INET; SockAddr.sin_addr = ListenS->INAddr; SockAddr.sin_port = ListenS->PortN; Result = bind(ListenS->FD, (struct sockaddr *) &SockAddr, sizeof(SockAddr)); #if IPV6_SUPPORT } #endif /* IPV6_SUPPORT */ #if !WIN32 if (ListenS->PortH < 1024) { sysseteuidnormal(); } #endif if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to bind socket to address: [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } /* LISTEN */ Result = listen(ListenS->FD, SOMAXCONN); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s: Unable to listen on address: [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_stop(ListenS); return; } else { sysprint(BITMASK_MAIN, "Listening on %s(%s):%ld%s for incoming connections.", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : "")); Listen_SetListening(ListenS); return; } } /* LISTEN_HOSTTOIP FUNCTION - JONAS (01.03.2000) */ #if HAVE_CARES_CALLBACK_TIMEOUTS void listen_hosttoip(void *ArgPT, int ErrNo, int Timeouts, struct hostent *HostEnt) { #else void listen_hosttoip(void *ArgPT, int ErrNo, struct hostent *HostEnt) { #endif struct Listen_Struct *ListenS = ArgPT; const char *HostIPPT = NULL; #if IPV6_SUPPORT char Host[INET6_ADDRSTRLEN+1] = ""; #endif assert(ListenS != NULL); if ((HostEnt == NULL) || (HostEnt->h_length < 1)) { sysprint(BITMASK_MAIN, "Listener %s:%ld%s: Unable to resolve host %s to IP-address: [%d] %s", ListenS->Host, ListenS->PortH, ListenS->Host, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), ErrNo, res_strerror(ErrNo)); listen_init(ListenS); return; } #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&ListenS->INAddr6, 0, sizeof(ListenS->INAddr6)); memcpy(&ListenS->INAddr6, HostEnt->h_addr, HostEnt->h_length); HostIPPT = inet_ntop(AF_INET6, &ListenS->INAddr6, Host, INET6_ADDRSTRLEN); if (HostIPPT == NULL) { sysprint(BITMASK_MAIN, "Listener %s:%ld%s: inet_ntop() failed: [%d] %s", ListenS->Host, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_init(ListenS); return; } } else { memset(&ListenS->INAddr, 0, sizeof(ListenS->INAddr)); memcpy(&ListenS->INAddr, HostEnt->h_addr, HostEnt->h_length); HostIPPT = inet_ntop(AF_INET, &ListenS->INAddr, Host, INET_ADDRSTRLEN); if (HostIPPT == NULL) { sysprint(BITMASK_MAIN, "Listener %s:%ld%s: inet_ntop() failed: [%d] %s", ListenS->Host, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_init(ListenS); return; } } #else /* IPV6_SUPPORT */ memset(&ListenS->INAddr, 0, sizeof(ListenS->INAddr)); memcpy(&ListenS->INAddr, HostEnt->h_addr, HostEnt->h_length); HostIPPT = inet_ntoa(ListenS->INAddr); if (HostIPPT == NULL) { sysprint(BITMASK_MAIN, "Listener %s:%ld%s: inet_ntoa() failed: [%d] %s", ListenS->Host, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); listen_init(ListenS); return; } #endif ListenS->HostIPS = strrealloc(ListenS->HostIPS, HostIPPT); if (ListenS->HostIPS == NULL) { listen_init(ListenS); return; } Listen_ClearResolving(ListenS); Listen_SetResolved(ListenS); #if ARES listen_start(ListenS); #endif } /* LISTEN_STOP - JONAS (05.10.2000) */ void listen_stop(struct Listen_Struct *ListenS) { assert(ListenS != NULL); if (Listen_IsResolving(ListenS)) { #if HAVE_ARES_CANCELQUERY ares_cancelquery(Ares_Channel, ListenS); #endif return; } if (Listen_IsListening(ListenS)) { sysprint(BITMASK_MAIN, "Listener %s(%s):%ld%s has stopped.", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : "")); } if (Listen_IsSocket(ListenS)) { close(ListenS->FD); ListenS->FD = FD_NONE; } listen_init(ListenS); } /* LISTEN_FDS - JONAS (22.07.2001) */ void listen_fds(fd_set *ReadFDS, fd_set *WriteFDS, unsigned long int *FDS) { struct Listen_Struct *ListenS = NULL; for (ListenS = Listen_Head ; ListenS != NULL ;) { if (Listen_IsRemove(ListenS)) { struct Listen_Struct *ListenS_DEL = NULL; if (Listen_IsResolving(ListenS)) { continue; } listen_stop(ListenS); ListenS_DEL = ListenS; ListenS = ListenS->Next; listen_rem(ListenS_DEL); continue; } if (Listen_IsListening(ListenS)) { FD_SET(ListenS->FD, ReadFDS); } else { if (!Listen_IsResolving(ListenS)) { time_t Duration = (NOW - ListenS->Time); if (Duration >= LISTEN_INTERVAL) { #if SSL_SUPPORT if (ConfS.SSLSupport == TRUE) { listen_start(ListenS); } else if (!Listen_IsSSL(ListenS)) { listen_start(ListenS); } #else if (!Listen_IsSSL(ListenS)) { listen_start(ListenS); } #endif } } } ListenS = ListenS->Next; } } /* LISTEN_IO - JONAS (06.10.2000) */ void listen_io(fd_set *ReadFDS, fd_set *WriteFDS, unsigned long int *FDS) { struct Listen_Struct *ListenS = NULL; for (ListenS = Listen_Head ; ListenS != NULL ; ListenS = ListenS->Next) { unsigned short int Count = 0; assert(*FDS >= 0); if (*FDS <= 0) { return; } if (!Listen_IsListening(ListenS)) { continue; } if (!FD_ISSET(ListenS->FD, ReadFDS)) { continue; } *FDS = *FDS - 1; assert(*FDS >= 0); for (Count = 0 ;; ++Count) { signed long int Result = 0; unsigned long int Flags = 0; struct sockaddr_in SockAddr = { 0 }; accept_addrlen_type SockAddrLen = sizeof(SockAddr); #if IPV6_SUPPORT struct sockaddr_in6 SockAddr6 = { 0 }; accept_addrlen_type SockAddrLen6 = sizeof(SockAddr6); #endif unsigned long int FD = 0; struct in_addr INAddr; #if IPV6_SUPPORT struct in6_addr INAddr6; #endif unsigned long int PortH = 0; unsigned long int PortN = 0; const char *HostIPPT = NULL; struct Client_Struct *ClientS = NULL; char Host[INET6_ADDRSTRLEN+1] = ""; #if SSL_SUPPORT SSL *ClientSSL = NULL; #endif #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { Result = accept(ListenS->FD, (struct sockaddr *) &SockAddr6, &SockAddrLen6); } else { #endif /* IPV6_SUPPORT */ Result = accept(ListenS->FD, (struct sockaddr *) &SockAddr, &SockAddrLen); #if IPV6_SUPPORT } #endif /* IPV6_SUPPORT */ if (Result <= ERROR) { if (Count == 0) { sysprint(BITMASK_MAIN, "Unable to accept incoming connection on address \"%s(%s):%ld\": [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, errno, strerror(errno)); } return; } FD = Result; #if SSL_SUPPORT if ((Listen_IsSSL(ListenS)) && (IRCPROXY_SSL_SERVER_CTX == NULL)) { /* This is fatal and should never happen under normal circumstances */ sysprint(BITMASK_MAIN, "Closing socket to incoming connection on address \"%s(%s):%ld\": Missing SSL_CTX object.", ListenS->Host, ListenS->HostIPS, ListenS->PortH); close(FD); continue; } #endif #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&INAddr6, 0, sizeof(INAddr6)); INAddr6 = SockAddr6.sin6_addr; PortN = SockAddr6.sin6_port; } else { #endif /* IPV6_SUPPORT */ memset(&INAddr, 0, sizeof(INAddr)); INAddr = SockAddr.sin_addr; PortN = SockAddr.sin_port; #if IPV6_SUPPORT } #endif /* IPV6_SUPPORT */ PortH = ntohs(PortN); #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { HostIPPT = inet_ntop(AF_INET6, &INAddr6, Host, INET6_ADDRSTRLEN); if (HostIPPT == NULL) { close(FD); sysprint(BITMASK_MAIN, "Failed inet_ntop() for incoming client connection on \"%s(%s):%ld%s\": [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); continue; } } else { HostIPPT = inet_ntop(AF_INET, &INAddr, Host, INET6_ADDRSTRLEN); if (HostIPPT == NULL) { close(FD); sysprint(BITMASK_MAIN, "Failed inet_ntop() for incoming client connection on \"%s(%s):%ld%s\": [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); continue; } } #else HostIPPT = inet_ntoa(INAddr); if (HostIPPT == NULL) { close(FD); sysprint(BITMASK_MAIN, "Failed inet_ntoa() for incoming client connection on \"%s(%s):%ld%s\": [%d] %s", ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); continue; } #endif sysprint(BITMASK_MAIN, "Incoming client connection from \"%s:%ld\" on \"%s(%s):%ld%s\".", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : "")); /* SET SOCKET IN NON-BLOCKING MODE */ #if defined(NBLOCK_SYSV) Flags = 1; Result = ioctl(FD, FIONBIO, &Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Unable to set socket in non-blocking mode using ioctl() for incoming client \"%s:%ld\" on \"%s(%s):%ld%s\".: [%d] %s", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); close(FD); continue; } #else Result = fcntl(FD, F_GETFL, &Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Unable to get socket flags using fcntl() for incoming client \"%s:%ld\" on \"%s(%s):%ld%s\".: [%d] %s", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); close(FD); continue; } #if defined(NBLOCK_BSD) Flags |= O_NDELAY; #elif defined(NBLOCK_POSIX) Flags |= O_NONBLOCK; #else #warning "This system does not support non-blocking sockets?" Flags |= O_NONBLOCK; #endif Result = fcntl(FD, F_SETFL, Flags); if (Result <= ERROR) { sysprint(BITMASK_MAIN, "Unable to set socket in non-blocking mode using fcntl() for incoming client \"%s:%ld\" on \"%s(%s):%ld%s\".: [%d] %s", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); close(FD); continue; } #endif #if SSL_SUPPORT if (Listen_IsSSL(ListenS)) { assert(IRCPROXY_SSL_SERVER_CTX != NULL); ClientSSL = SSL_new(IRCPROXY_SSL_SERVER_CTX); if (ClientSSL == NULL) { close(FD); sysprint(BITMASK_MAIN, "Failed to create a new SSL structure for incoming client connection from \"%s:%ld\" on \"%s(%s):%ld%s\".: [%d] %s.", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), errno, strerror(errno)); continue; } Result = SSL_set_fd(ClientSSL, FD); if (Result <= 0) { signed long int sslerrno = SSL_get_error(ClientSSL, Result); close(FD); SSL_free(ClientSSL); sysprint(BITMASK_MAIN, "Failed to connect the SSL object with file descriptor for incoming client connection from \"%s:%ld\" on \"%s(%s):%ld%s\".: [%ld] %s.", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : ""), sslerrno, ERR_error_string(sslerrno, NULL)); continue; } SSL_set_accept_state(ClientSSL); } #endif /* SSL_SUPPORT */ ClientS = client_add(ListenS, HostIPPT); if (ClientS == NULL) { close(FD); #if SSL_SUPPORT SSL_free(ClientSSL); #endif sysprint(BITMASK_MAIN, "Failed to allocate client structure for incoming client connection from \"%s:%ld\" on \"%s(%s):%ld%s\".", HostIPPT, PortH, ListenS->Host, ListenS->HostIPS, ListenS->PortH, (Listen_IsSSL(ListenS) ? "(SSL)" : "")); continue; } ClientS->FD = FD; ClientS->HostIPS = strrealloc(ClientS->HostIPS, HostIPPT); ClientS->PortH = PortH; ClientS->PortN = PortN; #if IPV6_SUPPORT if (Listen_IsIPv6(ListenS)) { memset(&ClientS->INAddr6, 0, sizeof(ClientS->INAddr6)); ClientS->INAddr6 = INAddr6; Client_SetIPv6(ClientS); } else { #endif memset(&ClientS->INAddr, 0, sizeof(ClientS->INAddr)); ClientS->INAddr = INAddr; #if IPV6_SUPPORT } #endif #if SSL_SUPPORT if (Listen_IsSSL(ListenS)) { Client_SetSSL(ClientS); ClientS->SSL_H = ClientSSL; } #endif client_resolve(ClientS); } } } /* LISTEN_CLOSEALL FUNCTION - JONAS (09.06.2001) */ unsigned short int listen_closeall(const char *const MessagePT, ...) { struct Listen_Struct *ListenS = NULL; struct Listen_Struct *ListenS_DEL = NULL; unsigned short int Count = 0; for (ListenS = Listen_Head ; ListenS != NULL ;) { if (Listen_IsResolving(ListenS)) { #if HAVE_ARES_CANCELQUERY ares_cancelquery(Ares_Channel, ListenS); #endif ++Count; Listen_SetRemove(ListenS); continue; } listen_stop(ListenS); ListenS_DEL = ListenS; ListenS = ListenS->Next; listen_rem(ListenS_DEL); } return(Count); }