+bool RADIUS::reconnect()
+{
+ if (!m_conns.empty())
+ {
+ std::deque<STG::Conn *>::const_iterator it;
+ for (it = m_conns.begin(); it != m_conns.end(); ++it)
+ delete(*it);
+ m_conns.clear();
+ }
+ if (m_listenSocket != 0)
+ {
+ shutdown(m_listenSocket, SHUT_RDWR);
+ close(m_listenSocket);
+ }
+ if (m_config.connectionType == Config::UNIX)
+ m_listenSocket = createUNIX();
+ else
+ m_listenSocket = createTCP();
+ if (m_listenSocket == 0)
+ return false;
+ if (listen(m_listenSocket, 100) == -1)
+ {
+ m_error = std::string("Error starting to listen socket: ") + strerror(errno);
+ m_logger(m_error);
+ return false;
+ }
+ return true;
+}
+
+int RADIUS::createUNIX() const
+{
+ int fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ m_error = std::string("Error creating UNIX socket: ") + strerror(errno);
+ m_logger(m_error);
+ return 0;
+ }
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, m_config.bindAddress.c_str(), m_config.bindAddress.length());
+ unlink(m_config.bindAddress.c_str());
+ if (bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) == -1)
+ {
+ shutdown(fd, SHUT_RDWR);
+ close(fd);
+ m_error = std::string("Error binding UNIX socket: ") + strerror(errno);
+ m_logger(m_error);
+ return 0;
+ }
+ chown(m_config.bindAddress.c_str(), m_config.sockUID, m_config.sockGID);
+ if (m_config.sockMode != static_cast<mode_t>(-1))
+ chmod(m_config.bindAddress.c_str(), m_config.sockMode);
+ return fd;
+}
+
+int RADIUS::createTCP() const
+{
+ addrinfo hints;
+ memset(&hints, 0, sizeof(addrinfo));
+
+ hints.ai_family = AF_INET; /* Allow IPv4 */
+ hints.ai_socktype = SOCK_STREAM; /* Stream socket */
+ hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
+ hints.ai_protocol = 0; /* Any protocol */
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+
+ addrinfo* ais = NULL;
+ int res = getaddrinfo(m_config.bindAddress.c_str(), m_config.portStr.c_str(), &hints, &ais);
+ if (res != 0)
+ {
+ m_error = "Error resolving address '" + m_config.bindAddress + "': " + gai_strerror(res);
+ m_logger(m_error);
+ return 0;
+ }
+
+ for (addrinfo* ai = ais; ai != NULL; ai = ai->ai_next)
+ {
+ int fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ m_error = std::string("Error creating TCP socket: ") + strerror(errno);
+ m_logger(m_error);
+ freeaddrinfo(ais);
+ return 0;
+ }
+ if (bind(fd, ai->ai_addr, ai->ai_addrlen) == -1)
+ {
+ shutdown(fd, SHUT_RDWR);
+ close(fd);
+ m_error = std::string("Error binding TCP socket: ") + strerror(errno);
+ m_logger(m_error);
+ continue;
+ }
+ freeaddrinfo(ais);
+ return fd;
+ }
+
+ m_error = "Failed to resolve '" + m_config.bindAddress;
+ m_logger(m_error);
+
+ freeaddrinfo(ais);
+ return 0;
+}
+