diff --git a/src/FatController.cpp b/src/FatController.cpp index fbff15d..ba028d8 100644 --- a/src/FatController.cpp +++ b/src/FatController.cpp @@ -477,7 +477,7 @@ int handle_connections(UDSocket &pipe) toldparentready = false; // now check the connection is actually good - if (peersock->getFD() < 0 || peersockip.length() < 7) { + if (peersock->getFD() < 0) { if (o.logconerror) syslog(LOG_INFO, "Error accepting. (Ignorable)"); continue; @@ -1677,19 +1677,6 @@ int fc_controlit() serversocketcount = o.filter_ip.size(); serversockets.reset(serversocketcount); - int *serversockfds = serversockets.getFDAll(); - - for (int i = 0; i < serversocketcount; i++) { - // if the socket fd is not +ve then the socket creation failed - if (serversockfds[i] < 0) { - if (!is_daemonised) { - std::cerr << "Error creating server socket " << i << std::endl; - } - syslog(LOG_ERR, "Error creating server socket %d", i); - return 1; - } - } - if (o.no_logger) { loggersock.close(); @@ -1754,7 +1741,7 @@ int fc_controlit() // we expect to find a valid filter ip 0 specified in conf if multiple IPs are in use. // if we don't find one, bind to any, as per old behaviour. - if (o.filter_ip[0].length() > 6) { + if (o.filter_ip[0].length() > 0) { if (serversockets.bindAll(o.filter_ip, o.filter_port)) { if (!is_daemonised) { std::cerr << "Error binding server socket (is something else running on the filter port and ip?" << std::endl; @@ -1768,7 +1755,7 @@ int fc_controlit() if (!is_daemonised) { std::cerr << "Error binding server socket: [" << o.filter_port << "] (" << strerror(errno) << ")" << std::endl; } - syslog(LOG_ERR, "Error binding server socket: [%d] (%s)", o.filter_port, strerror(errno)); + syslog(LOG_ERR, "Error binding server socket: [%s] (%s)", o.filter_port.c_str(), strerror(errno)); return 1; } } @@ -1903,7 +1890,6 @@ int fc_controlit() if (loggerpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it - delete[] serversockfds; urllistsock.close(); // we don't need our copy of this so close it log_listener(o.log_location, o.logconerror, o.log_syslog); #ifdef DGDEBUG @@ -1918,7 +1904,6 @@ int fc_controlit() urllistpid = fork(); if (urllistpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it - delete[] serversockfds; if (!o.no_logger) { loggersock.close(); // we don't need our copy of this so close it } @@ -1935,7 +1920,6 @@ int fc_controlit() iplistpid = fork(); if (iplistpid == 0) { // ma ma! i am the child serversockets.deleteAll(); // we don't need our copy of this so close it - delete[] serversockfds; if (!o.no_logger) { loggersock.close(); // we don't need our copy of this so close it } @@ -2041,6 +2025,19 @@ int fc_controlit() } // ...and server fds + int *serversockfds = serversockets.getFDAll(); + + for (int i = 0; i < serversocketcount; i++) { + // if the socket fd is not +ve then the socket creation failed + if (serversockfds[i] < 0) { + if (!is_daemonised) { + std::cerr << "Error creating server socket " << i << std::endl; + } + syslog(LOG_ERR, "Error creating server socket %d", i); + return 1; + } + } + for (i = o.max_children; i < fds; i++) { pids[i].fd = serversockfds[i - o.max_children]; pids[i].events = POLLIN; diff --git a/src/OptionContainer.cpp b/src/OptionContainer.cpp index 14cbf62..3815fc1 100644 --- a/src/OptionContainer.cpp +++ b/src/OptionContainer.cpp @@ -351,14 +351,8 @@ bool OptionContainer::read(const char *filename, int type) custom_banned_image_file = findoptionS("custombannedimagefile"); banned_image.read(custom_banned_image_file.c_str()); - filter_port = findoptionI("filterport"); - if (!realitycheck(filter_port, 1, 65535, "filterport")) { - return false; - } // check its a reasonable value - proxy_port = findoptionI("proxyport"); - if (!realitycheck(proxy_port, 1, 65535, "proxyport")) { - return false; - } // etc + filter_port = findoptionS("filterport"); + proxy_port = findoptionS("proxyport"); proxy_ip = findoptionS("proxyip"); // multiple listen IP support diff --git a/src/OptionContainer.hpp b/src/OptionContainer.hpp index dd79390..ac274de 100644 --- a/src/OptionContainer.hpp +++ b/src/OptionContainer.hpp @@ -68,8 +68,8 @@ public: int preserve_case; bool hex_decode_content; bool force_quick_search; - int filter_port; - int proxy_port; + std::string filter_port; + std::string proxy_port; std::string proxy_ip; std::deque filter_ip; #ifdef ENABLE_ORIG_IP diff --git a/src/Socket.cpp b/src/Socket.cpp index a154bac..8dd0478 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -1,4 +1,5 @@ // Socket class - implements BaseSocket for INET domain sockets +// IPv6 support added by Sascha Hlusiak, 2011. //Please refer to http://dansguardian.org/?page=copyright2 //for the license for this code. @@ -34,6 +35,8 @@ #include #include #include +#include +#include // IMPLEMENTATION @@ -41,12 +44,11 @@ // constructor - create an INET socket & clear address structs Socket::Socket() { - sck = socket(AF_INET, SOCK_STREAM, 0); + sck = -1; memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); - my_adr.sin_family = AF_INET; - peer_adr.sin_family = AF_INET; - peer_adr_length = sizeof(struct sockaddr_in); + my_adr_length = 0; + peer_adr_length = 0; int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } @@ -56,23 +58,21 @@ Socket::Socket(int fd):BaseSocket(fd) { memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); - my_adr.sin_family = AF_INET; - peer_adr.sin_family = AF_INET; - peer_adr_length = sizeof(struct sockaddr_in); + peer_adr_length = 0; + my_adr_length = 0; int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } // create socket from pre-existing FD, storing local & remote IPs -Socket::Socket(int newfd, struct sockaddr_in myip, struct sockaddr_in peerip):BaseSocket(newfd) +Socket::Socket(int newfd, struct sockaddr_storage myip, socklen_t myiplen, struct sockaddr_storage peerip, socklen_t peeriplen):BaseSocket(newfd) { memset(&my_adr, 0, sizeof my_adr); // *** memset(&peer_adr, 0, sizeof peer_adr); // *** - my_adr.sin_family = AF_INET; // *** Fix suggested by - peer_adr.sin_family = AF_INET; // *** Christopher Weimann my_adr = myip; peer_adr = peerip; - peer_adr_length = sizeof(struct sockaddr_in); + my_adr_length = myiplen; + peer_adr_length = peeriplen; int f = 1; setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, &f, sizeof(int)); } @@ -80,73 +80,159 @@ Socket::Socket(int newfd, struct sockaddr_in myip, struct sockaddr_in peerip):Ba // find the ip to which the client has connected std::string Socket::getLocalIP() { - return inet_ntoa(my_adr.sin_addr); + char buf[INET6_ADDRSTRLEN]; + + getnameinfo((struct sockaddr*)&my_adr, + my_adr_length, + buf, + sizeof(buf), + NULL, + 0, + NI_NUMERICHOST); + + return buf; } // find the ip of the client connecting to us std::string Socket::getPeerIP() { - return inet_ntoa(peer_adr.sin_addr); + char buf[INET6_ADDRSTRLEN]; + + getnameinfo((struct sockaddr*)&peer_adr, + peer_adr_length, + buf, + sizeof(buf), + NULL, + 0, + NI_NUMERICHOST); + + return buf; } // find the port of the client connecting to us int Socket::getPeerSourcePort() { - return ntohs(peer_adr.sin_port); -} - -// return the address of the client connecting to us -unsigned long int Socket::getPeerSourceAddr() -{ - return (unsigned long int)ntohl(peer_adr.sin_addr.s_addr); + char buf[INET6_ADDRSTRLEN]; + + getnameinfo((struct sockaddr*)&peer_adr, + peer_adr_length, + NULL, + 0, + buf, + sizeof(buf), + NI_NUMERICSERV); + + return atoi(buf); } // close connection & wipe address structs void Socket::reset() { this->baseReset(); - sck = socket(AF_INET, SOCK_STREAM, 0); + sck = -1; memset(&my_adr, 0, sizeof my_adr); memset(&peer_adr, 0, sizeof peer_adr); - my_adr.sin_family = AF_INET; - peer_adr.sin_family = AF_INET; - peer_adr_length = sizeof(struct sockaddr_in); + peer_adr_length = 0; + my_adr_length = 0; } // connect to given IP & port (following default constructor) -int Socket::connect(const std::string &ip, int port) +int Socket::connect(const std::string &ip, const std::string& port) { - int len = sizeof my_adr; - peer_adr.sin_port = htons(port); - inet_aton(ip.c_str(), &peer_adr.sin_addr); - return ::connect(sck, (struct sockaddr *) &peer_adr, len); -} -// bind socket to given port -int Socket::bind(int port) -{ - int len = sizeof my_adr; - int i = 1; - setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); - my_adr.sin_port = htons(port); - return ::bind(sck, (struct sockaddr *) &my_adr, len); + struct addrinfo *addr_info, *p, hints; + int ret, s; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = 0; + + ret = getaddrinfo(ip.c_str(), port.c_str(), &hints, &addr_info); + if (ret) + return -1; + + p = addr_info; + while (p) + { + /* Create socket for found family */ + s = socket(p->ai_family, p->ai_socktype, 0); + + + /* Try to connect */ + if (::connect(s, p->ai_addr, p->ai_addrlen) == 0) + { + memcpy(&peer_adr, p->ai_addr, p->ai_addrlen); + peer_adr_length = p->ai_addrlen; + freeaddrinfo(addr_info); + sck = s; + return 0; + } + ::close(s); + + p = p->ai_next; + } + + freeaddrinfo(addr_info); + return -1; } // bind socket to given port & IP -int Socket::bind(const std::string &ip, int port) +int Socket::bind(const std::string &ip, const std::string &port) { - int len = sizeof my_adr; - int i = 1; - setsockopt(sck, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); - my_adr.sin_port = htons(port); - my_adr.sin_addr.s_addr = inet_addr(ip.c_str()); - return ::bind(sck, (struct sockaddr *) &my_adr, len); -} + struct addrinfo *addr_info, *p, hints; + int ret, s; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = AI_PASSIVE | AI_V4MAPPED; + + ret = getaddrinfo(ip.c_str(), port.c_str(), &hints, &addr_info); + if (ret) + return -1; + + p = addr_info; + while (p) + { + int on = 1; + + /* Create socket for found family */ + s = socket(p->ai_family, p->ai_socktype, 0); + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { + /* maybe not so fatal, continue */ + } + if (p->ai_family == AF_INET6) { + if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) { + /* maybe not so fatal, continue */ + } + } + + /* Try to bind socket */ + if (::bind(s, p->ai_addr, p->ai_addrlen) == 0) { + memcpy(&my_adr, p->ai_addr, p->ai_addrlen); + my_adr_length = p->ai_addrlen; + freeaddrinfo(addr_info); + sck = s; + return 0; + } else { + ::close(s); + } + + p = p->ai_next; + } + + freeaddrinfo(addr_info); + return -1; + } // accept incoming connections & return new Socket Socket* Socket::accept() { - peer_adr_length = sizeof(struct sockaddr_in); + peer_adr_length = sizeof(peer_adr); int newfd = this->baseAccept((struct sockaddr*) &peer_adr, &peer_adr_length); - Socket* s = new Socket(newfd, my_adr, peer_adr); + Socket* s = new Socket(newfd, my_adr, my_adr_length, peer_adr, peer_adr_length); return s; } diff --git a/src/Socket.hpp b/src/Socket.hpp index d109a67..54f0372 100644 --- a/src/Socket.hpp +++ b/src/Socket.hpp @@ -37,15 +37,13 @@ public: // create socket using pre-existing FD (address structs will be empty!) Socket(int fd); // create socket from pre-existing FD, storing given local & remote IPs - Socket(int newfd, struct sockaddr_in myip, struct sockaddr_in peerip); + Socket(int newfd, struct sockaddr_storage myip, socklen_t myiplen, struct sockaddr_storage peerip, socklen_t peeriplen); // connect to given IP & port (following default constructor) - int connect(const std::string& ip, int port); + int connect(const std::string& ip, const std::string& port); - // bind to given port - int bind(int port); // bind to given IP & port, for machines with multiple NICs - int bind(const std::string& ip, int port); + int bind(const std::string& ip, const std::string& port); // accept incoming connections & return new Socket Socket* accept(); @@ -56,15 +54,15 @@ public: // get remote IP/port std::string getPeerIP(); int getPeerSourcePort(); - unsigned long int getPeerSourceAddr(); // get local IP std::string getLocalIP(); private: // local & remote addresses - struct sockaddr_in my_adr; - struct sockaddr_in peer_adr; + struct sockaddr_storage my_adr; + socklen_t my_adr_length; + struct sockaddr_storage peer_adr; }; #endif diff --git a/src/SocketArray.cpp b/src/SocketArray.cpp index fdd9fe6..bf39aad 100644 --- a/src/SocketArray.cpp +++ b/src/SocketArray.cpp @@ -58,12 +58,12 @@ void SocketArray::reset(int sockcount) } // bind our first socket to any IP -int SocketArray::bindSingle(int port) +int SocketArray::bindSingle(const std::string &port) { if (socknum < 1) { return -1; } - return drawer[0].bind(port); + return drawer[0].bind("0.0.0.0", port); } // return an array of our socket FDs @@ -95,7 +95,7 @@ int SocketArray::listenAll(int queue) } // bind all sockets to given IP list -int SocketArray::bindAll(std::deque &ips, int port) +int SocketArray::bindAll(std::deque &ips, const std::string &port) { if (ips.size() > socknum) { return -1; @@ -109,7 +109,7 @@ int SocketArray::bindAll(std::deque &ips, int port) std::cerr << "Error binding server socket: [" << port << " " << ips[i] << " " << i << "] (" << strerror(errno) << ")" << std::endl; } - syslog(LOG_ERR, "Error binding socket: [%d %s %d] (%s)", port, ips[i].toCharArray(), i, strerror(errno)); + syslog(LOG_ERR, "Error binding socket: [%d %s %d] (%s)", port.c_str(), ips[i].toCharArray(), i, strerror(errno)); return -1; } } diff --git a/src/SocketArray.hpp b/src/SocketArray.hpp index a0dd92b..cb8c3ad 100644 --- a/src/SocketArray.hpp +++ b/src/SocketArray.hpp @@ -1,67 +1,67 @@ -// SocketArray - wrapper for clean handling of an array of Sockets - -//Please refer to http://dansguardian.org/?page=copyright2 -//for the license for this code. - -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -#ifndef __HPP_SOCKETARRAY -#define __HPP_SOCKETARRAY - - -// INCLUDES -#include "Socket.hpp" -#include "String.hpp" - -#include - - -// DECLARATIONS - -class SocketArray -{ -public: - // set sensible defaults - SocketArray():drawer(NULL),socknum(0) {}; - // delete all sockets - ~SocketArray(); - - // close all old socks & create specified amount of new ones - void reset(int sockcount); - - // just delete the lot of 'em - void deleteAll(); - - // bind our sockets to the given IPs - int bindAll(std::deque &ips, int port); +// SocketArray - wrapper for clean handling of an array of Sockets + +//Please refer to http://dansguardian.org/?page=copyright2 +//for the license for this code. + +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef __HPP_SOCKETARRAY +#define __HPP_SOCKETARRAY + + +// INCLUDES +#include "Socket.hpp" +#include "String.hpp" + +#include + + +// DECLARATIONS + +class SocketArray +{ +public: + // set sensible defaults + SocketArray():drawer(NULL),socknum(0) {}; + // delete all sockets + ~SocketArray(); + + // close all old socks & create specified amount of new ones + void reset(int sockcount); + + // just delete the lot of 'em + void deleteAll(); + + // bind our sockets to the given IPs + int bindAll(std::deque &ips, const std::string &port); // bind just the one, to all available IPs - int bindSingle(int port); + int bindSingle(const std::string &port); // set all sockets listening with given kernel queue length - int listenAll(int queue); - - // shove all socket FDs into the given array (pass in unallocated) - int* getFDAll(); - - // array dereference operator - Socket* operator[] (int i) { return &(drawer[i]); }; - -private: - // our sock collection container - Socket* drawer; - // how many sockets we have - unsigned int socknum; -}; - -#endif + int listenAll(int queue); + + // shove all socket FDs into the given array (pass in unallocated) + int* getFDAll(); + + // array dereference operator + Socket* operator[] (int i) { return &(drawer[i]); }; + +private: + // our sock collection container + Socket* drawer; + // how many sockets we have + unsigned int socknum; +}; + +#endif diff --git a/src/authplugins/ident.cpp b/src/authplugins/ident.cpp index 6d5ce02..787eac2 100644 --- a/src/authplugins/ident.cpp +++ b/src/authplugins/ident.cpp @@ -77,7 +77,7 @@ int identinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, st #endif Socket iq; iq.setTimeout(5); - int rc = iq.connect(clientip.c_str(), 113); // ident port + int rc = iq.connect(clientip.c_str(), "113"); // ident port if (rc) { #ifdef DGDEBUG std::cerr << "Error connecting to obtain ident from: " << clientip << std::endl; diff --git a/src/contentscanners/icapscan.cpp b/src/contentscanners/icapscan.cpp index 9b4b6c7..1af959a 100644 --- a/src/contentscanners/icapscan.cpp +++ b/src/contentscanners/icapscan.cpp @@ -70,7 +70,7 @@ private: // ICAP server hostname, IP and port String icaphost; String icapip; - unsigned int icapport; + String icapport; // URL for the AV service String icapurl; // whether or not to send ICAP message previews, and the preview object size @@ -115,9 +115,9 @@ int icapinstance::init(void* args) // it would be far better to do a test connection } icaphost = icapurl.after("//"); - icapport = icaphost.after(":").before("/").toInteger(); - if (icapport == 0) { - icapport = 1344; + icapport = icaphost.after(":").before("/"); + if (icapport == "") { + icapport = "1344"; } icaphost = icaphost.before("/"); if (icaphost.contains(":")) {