void check_maxfiles() { int sock = -1, sock1 = -1 , bogus = 0, failed_close = 0; #ifdef USE_IPV6 sock1 = getsock(0, AF_INET); /* fill up any lower avail */ sock = getsock(0, AF_INET); #else sock1 = getsock(0); sock = getsock(0); #endif if (sock1 != -1) killsock(sock1); if (sock == -1) { return; } else killsock(sock); bogus = sock - socks_total - 4; //4 for stdin/stdout/stderr/dns if (bogus >= 50) { /* Attempt to close them */ sdprintf("SOCK: %d BOGUS: %d SOCKS_TOTAL: %d", sock, bogus, socks_total); for (int i = 10; i < sock; i++) /* dont close lower sockets, they're probably legit */ if (!findanysnum(i)) { if ((close(i)) == -1) /* try to close the BOGUS fd (likely a KQUEUE) */ failed_close++; else bogus--; } if (bogus >= 150 || failed_close >= 50) { if (tands > 0) { botnet_send_chat(-1, conf.bot->nick, "Max FD reached, restarting..."); botnet_send_bye("Max FD reached, restarting..."); } nuke_server("brb"); cycle_time = 0; restart(-1); } else if (bogus >= 100 && (bogus % 10) == 0) { putlog(LOG_WARN, "*", "* WARNING: $b%d$b bogus file descriptors detected, auto restart at 150", bogus); } } }
int socket_create(const char *dest_ip, int dest_port, const char *src_ip, int src_port, int flags) { char *passive[] = {"::", "0.0.0.0"}; int sock = -1, pfamily, try_ok; sockname_t dest_name, src_name; /* If no source ip address is given, try :: and 0.0.0.0 (passive). */ for (try_ok = 0; try_ok < 2; try_ok++) { /* Resolve the ip addresses. */ socket_name(&dest_name, dest_ip ? dest_ip : passive[try_ok], dest_port); socket_name(&src_name, src_ip ? src_ip : passive[try_ok], src_port); if (src_ip || src_port) flags |= SOCKET_BIND; if (flags & SOCKET_CLIENT) pfamily = dest_name.family; else if (flags & SOCKET_SERVER) pfamily = src_name.family; else { errno = EADDRNOTAVAIL; return(-1); } /* Create the socket. */ if (flags & SOCKET_UDP) sock = socket(pfamily, SOCK_DGRAM, 0); else sock = socket(pfamily, SOCK_STREAM, 0); if (sock >= 0) break; } if (sock < 0) return(-2); allocsock(sock, 0); if (flags & SOCKET_NONBLOCK) socket_set_nonblock(sock, 1); /* Do the bind if necessary. */ if (flags & (SOCKET_SERVER|SOCKET_BIND)) { int yes = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if (bind(sock, &src_name.u.addr, src_name.len) != 0) { killsock(sock); return(-3); } if (flags & SOCKET_SERVER) listen(sock, 50); } if (flags & SOCKET_CLIENT) { int i = -1; if ((i = findanysnum(sock)) != -1) { socklist[i].flags = (socklist[i].flags & ~SOCK_VIRTUAL) | SOCK_CONNECT | SOCK_PASS; socklist[i].host = strdup(dest_ip); socklist[i].port = dest_port; } if (connect(sock, &dest_name.u.addr, dest_name.len) != 0) { if (errno != EINPROGRESS) { killsock(sock); return(-4); } } } errno = 0; /* Yay, we're done. */ return(sock); }