1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
11 #include <anna/core/tracing/Logger.hpp>
13 #include <anna/comm/Network.hpp>
15 #include <anna/comm/Device.hpp>
16 #include <anna/comm/Host.hpp>
17 #include <anna/comm/Server.hpp>
19 #include <anna/xml/Node.hpp>
20 #include <anna/xml/Attribute.hpp>
25 comm::Device* comm::Network::find(const in_addr_t& address)
27 Device* result = NULL;
29 if(a_cacheDevice != NULL && *a_cacheDevice == address)
32 for(device_iterator ii = device_begin(), maxii = device_end(); ii != maxii; ii ++) {
35 if(*result == address)
36 return a_cacheDevice = result;
39 a_devices.push_back(result = new Device(address));
40 return a_cacheDevice = result;
43 comm::Host* comm::Network::find_host(const char* name)
47 if(a_cacheHost != NULL && anna_strcmp(a_cacheHost->getName().c_str(), name) == 0)
50 for(host_iterator ii = host_begin(), maxii = host_end(); ii != maxii; ii ++) {
53 if(anna_strcmp(result->getName().c_str(), name) == 0)
54 return a_cacheHost = result;
57 a_hosts.push_back(result = new Host(name));
58 return a_cacheHost = result;
61 comm::Host* comm::Network::resolve(const char* hostname)
62 throw(RuntimeException) {
63 comm::Host* result = find_host(hostname);
66 if((host = gethostbyname(hostname)) == NULL) {
67 string msg("comm::Network::resolve | Host: ");
70 msg += hstrerror(h_errno);
71 throw RuntimeException(msg, ANNA_FILE_LOCATION);
74 if(host->h_addrtype != AF_INET) {
75 string msg("comm::Network::resolve | Host: ");
77 msg += " | Address type unsupported";
78 throw RuntimeException(msg, ANNA_FILE_LOCATION);
81 for(int i = 0; host->h_addr_list[i] != NULL; i ++) {
82 const in_addr_t& address = *reinterpret_cast <in_addr_t*>(host->h_addr_list[i]);
84 string msg("comm::Network::resolve | Host: ");
87 msg += inet_ntoa(*reinterpret_cast <in_addr*>(host->h_addr_list[i]));
88 Logger::debug(msg, ANNA_FILE_LOCATION);
90 result->assign(find(address));
97 comm::Server* comm::Network::createServer(const char* ip, const int remotePort, const bool autoRecovery, comm::TransportFactory* transportFactory, const Port::_v mode, const DoConnect::_v doConnect)
98 throw(RuntimeException) {
99 comm::Server* result(NULL);
100 comm::Host* host = find_host(ip);
101 Guard guard(host, "comm::Host from comm::Network::createServer");
103 if(mode == Port::Unique) {
105 * Si ya existe una conexión previa con esa (ip, port) la devuelve
107 if((result = host->find_server(remotePort)) != NULL)
111 comm::Device* device = find(comm::Device::asAddress(ip));
112 host->assign(device);
113 string serverName = ip;
114 serverName += functions::asText(":", remotePort);
115 return host->createServer(serverName, remotePort, autoRecovery, transportFactory, false /* ignore incoming messages */, (doConnect == DoConnect::Yes));
118 comm::Server* comm::Network::createServer(const char* ip, const int remotePort, const bool autoRecovery, comm::ReceiverFactory& rrff, comm::TransportFactory* transportFactory, const Port::_v mode, const DoConnect::_v doConnect)
119 throw(RuntimeException) {
120 Server* result = createServer(ip, remotePort, autoRecovery, transportFactory, mode, doConnect);
121 result->setReceiverFactory(rrff);
125 //comm::Server* comm::Network::findServer (const char* ip, const int remotePort)
126 // throw (RuntimeException)
128 // comm::Host* _host (NULL);
130 // for (host_iterator ii = host_begin (), maxii = host_end (); ii != maxii; ii ++) {
131 // if (host (ii)->getName () == ip) {
132 // _host = host (ii);
137 // return (_host == NULL) ? NULL: _host->find_server (remotePort);
141 comm::Server* comm::Network::resolveServer(const char* hostname, const int remotePort, const bool autoRecovery, comm::TransportFactory* transportFactory, const Port::_v mode, const DoConnect::_v doConnect)
142 throw(RuntimeException) {
143 comm::Server* result(NULL);
144 comm::Host* host = resolve(hostname);
145 Guard guard(host, "comm::Host from comm::Network::resolveServer");
147 if(mode == Port::Unique) {
149 * Si ya existe una conexión previa con esa (ip, port) la devuelve
151 if((result = host->find_server(remotePort)) != NULL)
155 string serverName = hostname;
156 serverName += functions::asText(":", remotePort);
157 return host->createServer(serverName, remotePort, autoRecovery, transportFactory, false /* ignore incoming messages */, (doConnect == DoConnect::Yes));
160 comm::Server* comm::Network::resolveServer(const char* hostname, const int remotePort, const bool autoRecovery, comm::ReceiverFactory& rrff, comm::TransportFactory* transportFactory, const Port::_v mode, const DoConnect::_v doConnect)
161 throw(RuntimeException) {
162 Server* result = resolveServer(hostname, remotePort, autoRecovery, transportFactory, mode, doConnect);
163 result->setReceiverFactory(rrff);
167 comm::INetAddress comm::Network::getINetAddress(const char* ip, const int port)
168 throw(RuntimeException) {
169 const Device* device = find(Device::asAddress(ip));
170 return INetAddress(device, port);
173 comm::INetAddress comm::Network::getINetAddress(const std::string& ip, const int port)
174 throw(RuntimeException) {
175 const Device* device = find(Device::asAddress(ip));
176 return INetAddress(device, port);
179 xml::Node* comm::Network::asXML(xml::Node* parent) const
181 xml::Node* result = parent->createChild("comm.Network");
182 xml::Node* node = result->createChild("comm.Devices");
184 for(const_device_iterator ii = device_begin(), maxii = device_end(); ii != maxii; ii ++)
185 device(ii)->asXML(node);
187 node = result->createChild("comm.Hosts");
189 for(const_host_iterator ii = host_begin(), maxii = host_end(); ii != maxii; ii ++)
190 host(ii)->asXML(node);