Fix 'occurred' typo
[bpdyndnsd] / src / service_ods.cpp
1 /** @file
2  * @brief ODS Service class implementation. This class represents the ODS service.
3  *
4  *
5  *
6  * @copyright Intra2net AG
7  * @license GPLv2
8 */
9
10 #include "service_ods.hpp"
11 #include "net_helper.hpp"
12 #include "util.hpp"
13
14 using namespace std;
15
16
17 /**
18  * Default Constructor, needed for object serialization.
19  */
20 ServiceOds::ServiceOds()
21 {
22 }
23
24
25 /**
26  * Constructor.
27  * @param _hostname The hostname to update
28  * @param _login The login name.
29  * @param _password The corresponding password.
30  */
31 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)
32     : UpdateServer("update.ods.org")
33     , Port("7071")
34 {
35     if ( _update_interval == -1 )        // If _update_interval is default po::option_desc (not specified via config)
36         set_update_interval(15);              // use default protocol value
37     else
38         set_update_interval(_update_interval);
39
40     if ( _max_updates_within_interval == -1 )
41         set_max_updates_within_interval(3);
42     else
43         set_max_updates_within_interval(_max_updates_within_interval);
44
45     if ( _max_equal_updates_in_succession == -1 )
46         set_max_equal_updates_in_succession(2);
47     else
48         set_max_equal_updates_in_succession(_max_equal_updates_in_succession);
49
50     if ( _dns_cache_ttl == -1 )
51         set_dns_cache_ttl(180);
52     else
53         set_dns_cache_ttl(_dns_cache_ttl);
54
55     set_protocol(_protocol);
56     set_hostname(_hostname);
57     set_login(_login);
58     set_password(_password);
59     set_logger(_logger);
60 }
61
62
63 /**
64  * Default destructor.
65  */
66 ServiceOds::~ServiceOds()
67 {
68 }
69
70
71 /**
72  * Performs the Service update.
73  * @param ip IP Address to set.
74  * @return 0 if all is fine, -1 otherwise.
75  */
76 Service::UpdateErrorCode ServiceOds::perform_update(const std::string& ip)
77 {
78     // First of all create a boost shared pointer to the NetHelper.
79     NetHelper::Ptr connection(new NetHelper(get_logger()));
80
81     // Then open the connection to the ODS update server.
82     if (connection->open_connection(UpdateServer,Port) != 0)
83         return GenericError;
84
85     // Receive the server greeting.
86     string server_greeting = connection->receive_data();
87     if ( server_greeting.empty() )
88     {
89         connection->close_connection(); /*lint !e534 */
90         return GenericError;
91     }
92
93     // Send login command
94     ostringstream login;
95     login << "LOGIN " << get_login() << " " << get_password() << endl;
96     if (connection->send_data(login.str()) != 0)
97     {
98         connection->close_connection(); /*lint !e534 */
99         return GenericError;
100     }
101
102     // Receive login reply
103     string login_reply = connection->receive_data();
104     if ( login_reply.empty() )
105     {
106         connection->close_connection(); /*lint !e534 */
107         return GenericError;
108     }
109     else
110     {
111         // Get the return code out of the received data
112         string status_code = Util::parse_status_code(login_reply);
113         if ( status_code == "520" )
114         {
115             // Login failed
116             get_logger()->print_service_not_authorized(UpdateServer,get_login(),get_password());
117             connection->close_connection(); /*lint !e534 */
118             return NotAuth;
119         }
120         else if ( status_code != "225" )
121         {
122             // Undefined protocol error, Log login_reply
123             get_logger()->print_undefined_protocol_error("ODS",login_reply);
124             connection->close_connection(); /*lint !e534 */
125             return GenericError;
126         }
127     }
128
129     // Successfully loged in, status_code should be 225
130
131     // Perform delete operation until there is no RR or we have performed it 10 times.
132     int del_count = 0;
133     string delete_reply, reply_code;
134     ostringstream delete_request;
135     delete_request << "DELRR " << get_hostname() << " A " << endl;
136     do
137     {
138         // Send delete request
139         if (connection->send_data(delete_request.str()) != 0)
140         {
141             connection->close_connection(); /*lint !e534 */
142             return GenericError;
143         }
144         // Get delete reply
145         delete_reply = connection->receive_data();
146         if ( delete_reply.empty() )
147         {
148             connection->close_connection(); /*lint !e534 */
149             return GenericError;
150         }
151         del_count++;
152         reply_code = Util::parse_status_code(delete_reply);
153     }while ( (del_count < 10) && (reply_code != "300") );
154
155
156     // Send update request
157     ostringstream update_request;
158     update_request << "ADDRR " << get_hostname() << " A " << ip << endl;
159     if (connection->send_data(update_request.str()) != 0)
160     {
161         connection->close_connection(); /*lint !e534 */
162         return GenericError;
163     }
164
165     // Receive update request server reply
166     string update_reply = connection->receive_data();
167     if ( update_reply.empty() )
168     {
169         connection->close_connection(); /*lint !e534 */
170         return GenericError;
171     }
172     else
173     {
174         // Get the return code out of the received data
175         string status_code = Util::parse_status_code(update_reply);
176         if ( status_code != "795" )
177         {
178             get_logger()->print_undefined_protocol_error("ODS",update_reply);
179             connection->close_connection(); /*lint !e534 */
180             return UpdateError;
181         }
182     }
183
184     // Successfully updated host
185     connection->close_connection(); /*lint !e534 */
186     return UpdateOk;
187 }