/** @file * @brief ODS Service class implementation. This class represents the ODS service. * * * * @copyright Intra2net AG * @license GPLv2 */ #include "service_ods.hpp" #include "net_helper.hpp" #include "util.hpp" using namespace std; /** * Default Constructor, needed for object serialization. */ ServiceOds::ServiceOds() { } /** * Constructor. * @param _hostname The hostname to update * @param _login The login name. * @param _password The corresponding password. */ ServiceOds::ServiceOds(const string& _protocol, const string& _hostname, const string& _login, const string& _password, const Logger::Ptr& _logger, const int _update_interval, const int _max_updates_within_interval, const int _max_equal_updates_in_succession, const int _dns_cache_ttl) : UpdateServer("update.ods.org") , Port("7071") { if ( _update_interval == -1 ) // If _update_interval is default po::option_desc (not specified via config) set_update_interval(15); // use default protocol value else set_update_interval(_update_interval); if ( _max_updates_within_interval == -1 ) set_max_updates_within_interval(3); else set_max_updates_within_interval(_max_updates_within_interval); if ( _max_equal_updates_in_succession == -1 ) set_max_equal_updates_in_succession(2); else set_max_equal_updates_in_succession(_max_equal_updates_in_succession); if ( _dns_cache_ttl == -1 ) set_dns_cache_ttl(180); else set_dns_cache_ttl(_dns_cache_ttl); set_protocol(_protocol); set_hostname(_hostname); set_login(_login); set_password(_password); set_logger(_logger); } /** * Default destructor. */ ServiceOds::~ServiceOds() { } /** * Performs the Service update. * @param ip IP Address to set. * @return 0 if all is fine, -1 otherwise. */ Service::UpdateErrorCode ServiceOds::perform_update(const std::string& ip) { // First of all create a boost shared pointer to the NetHelper. NetHelper::Ptr connection(new NetHelper(get_logger())); // Then open the connection to the ODS update server. if (connection->open_connection(UpdateServer,Port) != 0) return GenericError; // Receive the server greeting. string server_greeting = connection->receive_data(); if ( server_greeting.empty() ) { connection->close_connection(); /*lint !e534 */ return GenericError; } // Send login command ostringstream login; login << "LOGIN " << get_login() << " " << get_password() << endl; if (connection->send_data(login.str()) != 0) { connection->close_connection(); /*lint !e534 */ return GenericError; } // Receive login reply string login_reply = connection->receive_data(); if ( login_reply.empty() ) { connection->close_connection(); /*lint !e534 */ return GenericError; } else { // Get the return code out of the received data string status_code = Util::parse_status_code(login_reply); if ( status_code == "520" ) { // Login failed get_logger()->print_service_not_authorized(UpdateServer,get_login(),get_password()); connection->close_connection(); /*lint !e534 */ return GenericError; } else if ( status_code != "225" ) { // Undefined protocol error, Log login_reply get_logger()->print_undefined_protocol_error("ODS",login_reply); connection->close_connection(); /*lint !e534 */ return GenericError; } } // Successfully loged in, status_code should be 225 // Perform delete operation until there is no RR or we have performed it 10 times. int del_count = 0; string delete_reply, reply_code; ostringstream delete_request; delete_request << "DELRR " << get_hostname() << " A " << endl; do { // Send delete request if (connection->send_data(delete_request.str()) != 0) { connection->close_connection(); /*lint !e534 */ return GenericError; } // Get delete reply delete_reply = connection->receive_data(); if ( delete_reply.empty() ) { connection->close_connection(); /*lint !e534 */ return GenericError; } del_count++; reply_code = Util::parse_status_code(delete_reply); }while ( (del_count < 10) && (reply_code != "300") ); // Send update request ostringstream update_request; update_request << "ADDRR " << get_hostname() << " A " << ip << endl; if (connection->send_data(update_request.str()) != 0) { connection->close_connection(); /*lint !e534 */ return GenericError; } // Receive update request server reply string update_reply = connection->receive_data(); if ( update_reply.empty() ) { connection->close_connection(); /*lint !e534 */ return GenericError; } else { // Get the return code out of the received data string status_code = Util::parse_status_code(update_reply); if ( status_code != "795" ) { get_logger()->print_undefined_protocol_error("ODS",update_reply); connection->close_connection(); /*lint !e534 */ return GenericError; } } // Successfully updated host connection->close_connection(); /*lint !e534 */ return UpdateOk; }