Bugfix: Don't check for private IP-Address if we get the actual IP of the host to...
[bpdyndnsd] / src / serviceholder.cpp
CommitLineData
6beab33f 1/** @file
e0080b78 2 * @brief Serviceholder class implementation. This class holds Service and OldService lists.
6beab33f
BS
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4de6a9b8 10#include "serviceholder.hpp"
6beab33f 11
ca5d6889 12#include <fstream>
e0080b78 13
ca5d6889 14#include <boost/foreach.hpp>
e0080b78 15#include <boost/filesystem.hpp>
ca5d6889 16
04e3d681 17#define OBJECT_FILE "/var/state/bpdyndnsd/bpdyndnsd.state"
88a594e8 18
6beab33f
BS
19using namespace std;
20
ca5d6889
BS
21namespace fs = boost::filesystem;
22
6beab33f
BS
23
24/**
31af6a2e
BS
25 * Default constructor.
26 */
27Serviceholder::Serviceholder()
28 :Log(new Logger)
29 ,IPAddrHelp()
30{
31}
32
33
34/**
35 * Constructor with Logger object.
6beab33f 36 */
e0080b78 37Serviceholder::Serviceholder(Logger::Ptr _log)
9a0aff44 38 :Log(_log)
20399847 39 ,IPAddrHelp()
6beab33f
BS
40{
41}
42
43
44/**
45 * Default destructor. While serializing and deserializing we use boost/shared_ptr, the resources are managed correctly.
46 */
47Serviceholder::~Serviceholder()
48{
49}
50
51
52/**
e0080b78
BS
53 * This function serializes all Service objects in Services and OldServices (where the update Timeout isn't expired) into a specified file.
54 * @return 0 if all is fine, -1 if output file could not be opened for reading or error while serializing.
6beab33f 55 */
c730deea 56int Serviceholder::serialize_services() const
6beab33f 57{
e0080b78
BS
58 // Put Services and OldServices into Serviceholder.
59 SerializeServiceContainer::Ptr service_container(new SerializeServiceContainer);
60
c730deea 61 BOOST_FOREACH(const Service::Ptr &service, Services)
e0080b78
BS
62 {
63 service_container->add_service(service);
64 }
65
62df5f33 66 time_t current_time = time(NULL);
e0080b78 67
c730deea 68 BOOST_FOREACH(const Service::Ptr &service, OldServices)
e0080b78 69 {
08a5a621 70 if ( ( service->get_last_updates().front() + ((time_t)service->get_update_interval()*60) ) >= current_time ) /*lint !e1793 */ // UpdateInterval timeout of service isn't expired.
e0080b78
BS
71 service_container->add_service(service);
72 }
73
20399847 74 // Serialize SerializeServiceContainer and IPAddrHelper into file.
e0080b78
BS
75 ofstream ofs(OBJECT_FILE);
76 if ( ofs.is_open() )
77 {
78 SerializeServiceContainer* _service_container = service_container.get();
20399847 79 IPAddrHelper* _ip_addr_helper = IPAddrHelp.get();
e0080b78
BS
80 try
81 {
82 boost::archive::text_oarchive oa(ofs);
20399847 83 oa << _service_container << _ip_addr_helper;
e0080b78 84 }
08a5a621 85 catch( const boost::archive::archive_exception& e )
e0080b78
BS
86 {
87 Log->print_exception_serialize(e.what());
88 ofs.close();
89 return -1;
90 }
91
92 ofs.close();
93 }
94 else
95 {
96 Log->print_error_opening_rw(OBJECT_FILE);
97 return -1;
98 }
99
100 Log->print_serialized_objects_success();
101
102 return 0;
6beab33f
BS
103}
104
105
106/**
e0080b78
BS
107 * This function de-serializes the SerializeServiceContainer (containing Services) from the object file.
108 * @return 0 if all is fine, -1 if object file couldn't be opened for reading or error while de-serializing.
109 */
110int Serviceholder::deserialize_services()
111{
112 // test if OBJECT_FILE exists
113 fs::path object_file = fs::system_complete(fs::path(OBJECT_FILE));
114 if ( !fs::exists(object_file) )
115 {
116 // There is no object file, possibly first program start, continue without recovering old Services' state.
117 Log->print_no_object_file(OBJECT_FILE);
118 return 0;
119 }
120
121 ifstream ifs(OBJECT_FILE);
122 if ( ifs.is_open() )
123 {
124 // deserialize SerializeServiceContainer
125 SerializeServiceContainer* _service_container;
20399847 126 IPAddrHelper* _ip_addr_helper;
e0080b78
BS
127 try
128 {
129 boost::archive::text_iarchive ia(ifs);
20399847 130 ia >> _service_container >> _ip_addr_helper;
e0080b78 131 }
08a5a621 132 catch( const boost::archive::archive_exception& e )
e0080b78
BS
133 {
134 Log->print_exception_deserialize(e.what());
135 ifs.close();
136 return -1;
137 }
138 SerializeServiceContainer::Ptr service_container(_service_container);
c3c84086 139 IPAddrHelp = IPAddrHelper::Ptr(_ip_addr_helper);
e0080b78
BS
140 ifs.close();
141
142 // Get the list of old Services from de-serialized SerializeServiceContainer object.
143 list<Service::Ptr> _old_services = service_container->get_containing_services();
144
145 // Put all de-serialized Services into OldServices member and
146 // compare new Services (generated from config file and cmd) with old Services (de-serialized from object file)
147 // if identical Service was found, adopt the value from old Service to recover Services' state.
148 BOOST_FOREACH(Service::Ptr &old_service, _old_services)
149 {
150 OldServices.push_back(old_service);
d5a516ba 151 Log->print_service_object("Deserialized following Service object:", old_service->get_protocol(), old_service->get_hostname(), old_service->get_login() ,old_service->get_password(), old_service->get_update_interval(), old_service->get_max_updates_within_interval(), old_service->get_dns_cache_ttl() , old_service->get_actual_ip(), old_service->get_last_updates());
e0080b78
BS
152 BOOST_FOREACH(Service::Ptr &service, Services)
153 {
154 if ( *service == *old_service )
155 {
156 service->set_last_updates(old_service->get_last_updates());
157 service->set_actual_ip(old_service->get_actual_ip());
d5a516ba 158 Log->print_service_object("New Service object with adopted values:", service->get_protocol(), service->get_hostname(), service->get_login() ,service->get_password(), service->get_update_interval(), service->get_max_updates_within_interval(), service->get_dns_cache_ttl() , service->get_actual_ip(), service->get_last_updates());
e0080b78
BS
159 // We have adopted the values of the old_service. Just set lastupdated and timeout to 0, so this old_service wont be serialized.
160 old_service->set_update_interval(0);
161 }
162 }
163 }
164 Log->print_deserialized_objects_success();
165 }
166 else
167 {
168 Log->print_error_opening_r(OBJECT_FILE);
169 return -1;
170 }
171
172 return 0;
173}
174
175
176/**
177 * Add service to internal service list.
178 * @param service Shared pointer to service object.
6beab33f 179 */
88a594e8 180void Serviceholder::add_service(Service::Ptr service)
6beab33f 181{
e0080b78
BS
182 Services.push_back(service);
183}
184
185
186/**
187 * Resets all shared Service pointers and clears the Services list.
188 */
189void Serviceholder::delete_services()
190{
191 BOOST_FOREACH( Service::Ptr &service, Services )
192 {
193 service.reset();
194 }
195 Services.clear();
196
197 BOOST_FOREACH( Service::Ptr &service, OldServices )
198 {
199 service.reset();
200 }
201 OldServices.clear();
20399847
BS
202
203 IPAddrHelp.reset();
6beab33f
BS
204}
205
206
207/**
e0080b78
BS
208 * Getter for member Services
209 * @return List with shared Service pointers.
6beab33f 210 */
e0080b78 211std::list<Service::Ptr> Serviceholder::get_services() const
6beab33f 212{
e0080b78 213 return Services;
6beab33f 214}
20399847
BS
215
216
217/**
218 * Set member IPAddrHelp
219 * @param _ip_addr_helper The IPAddrHelper.
220 */
221void Serviceholder::set_ip_addr_helper(IPAddrHelper::Ptr _ip_addr_helper)
222{
223 IPAddrHelp = _ip_addr_helper;
224}
225
226
227/**
228 * Get member IPAddrHelp
229 * @return IPAddrHelp
230 */
231IPAddrHelper::Ptr Serviceholder::get_ip_addr_helper() const
232{
233 return IPAddrHelp;
234}