source: trunk/FACT++/src/DimSetup.cc@ 18915

Last change on this file since 18915 was 12348, checked in by tbretz, 13 years ago
Use the connection to the DNS as the IP address to get the Local IP.
File size: 5.2 KB
Line 
1// **************************************************************************
2/** @namespace Dim
3
4@brief Namespace to host some global Dim helper functions
5
6*/
7// **************************************************************************
8#include "Dim.h"
9
10/*
11#include <netdb.h>
12#include <sys/types.h>
13#include <sys/socket.h>
14#include <arpa/inet.h>
15*/
16#include <boost/asio.hpp>
17
18#include <iostream>
19
20using namespace std;
21
22// --------------------------------------------------------------------------
23//
24//! Tries to determine the local IP address with which we will connect
25//! to the DIM dns.
26//!
27//! The local IP address is necessary because in some circumstances
28//! Dim needs the IP address of the connecting machine (DIM_HOST_NODE)
29//! for the clients to correctly connect to them. So what we would
30//! need is the IP address over which the machine is reachable from
31//! the client. Unfortunately, we have no access to the client
32//! connection, hence, we have to find the best guess of an address
33//! which is not our own machine and hope it is routed over the
34//! standard ethernet interface over which other clients will connect.
35//!
36//! To not send random packages over the network we use a local
37//! IP address. To make sure it is something which leaves the network
38//! card and is not just our machine, we can use a broadcast address.
39//! Consequently, the deafult has been chosen to be "192.168.0.255"
40//!
41//! @param dns
42//! Address of the Dim-dns
43//!
44//! @returns
45//! The IP Address through which the connection to the DNS will
46//! take place.
47//!
48//! @todo
49//! Implement a --host command line option (just in case)
50//!
51string Dim::GetLocalIp(const string &dns)
52{
53 using namespace boost::asio;
54 using namespace boost::asio::ip;
55
56 cout << "Trying to resolve local IP address..." << endl;
57
58 boost::system::error_code ec;
59
60 boost::asio::io_service io_service;
61
62 udp::socket socket(io_service);
63
64 udp::resolver resolver(io_service);
65 udp::resolver::query query(dns, "0");
66 udp::resolver::iterator iterator = resolver.resolve(query, ec);
67 if (ec)
68 {
69 //cout << "WARNING - Failure in name-resolution of '" << dns << ":0': ";
70 cout << "WARNING - Could not resolve local ip address: ";
71 cout << ec.message() << " (" << ec << ")" << endl;
72 return dns;
73 }
74
75 for (; iterator != udp::resolver::iterator(); ++iterator)
76 {
77 udp::endpoint endpoint = *iterator;
78 socket.connect(endpoint, ec);
79 if (ec)
80 {
81 cout << "WARNING - Could not resolve local ip address: ";
82 cout << ec.message() << " (" << ec << ")" << endl;
83 continue;
84 }
85
86 const string addr = socket.local_endpoint().address().to_v4().to_string();
87 return addr;
88 }
89
90 return "localhost";
91
92/*
93 struct addrinfo hints, *servinfo, *p;
94
95 memset(&hints, 0, sizeof hints);
96 hints.ai_family = AF_INET; //AF_UNSPEC; // use AF_INET6 to force IPv6
97 hints.ai_socktype = SOCK_STREAM;
98
99 int rv;
100 if ((rv = getaddrinfo(dns.c_str(), NULL, &hints, &servinfo)) != 0)
101 {
102 cout << "WARNING - getaddrinfo: " << gai_strerror(rv) << endl;
103 return dns;
104 }
105
106 // loop through all the results and connect to the first we can
107 for (p=servinfo; p; p=p->ai_next)
108 {
109 const int sock = socket(AF_INET, SOCK_DGRAM, 0);
110 if (sock==-1)
111 continue;
112
113 if (connect(sock, p->ai_addr, p->ai_addrlen)==-1)
114 {
115 cout << "WARNING - connect: " << strerror(errno) << endl;
116 close(sock);
117 continue;
118 }
119
120 sockaddr_in name;
121 socklen_t namelen = sizeof(name);
122 if (getsockname(sock, (sockaddr*)&name, &namelen)==-1)
123 {
124 cout << "WARNING - getsockname: " << strerror(errno) << endl;
125 close(sock);
126 continue;
127 }
128
129 char buffer[16];
130 if (!inet_ntop(AF_INET, &name.sin_addr, buffer, 16))
131 {
132 cout << "WARNING - inet_ntop: " << strerror(errno) << endl;
133 close(sock);
134 continue;
135 }
136
137 close(sock);
138
139 freeaddrinfo(servinfo); // all done with this structure
140
141 cout << "DIM_HOST_NODE=" << buffer << endl;
142 return buffer;
143 }
144
145 freeaddrinfo(servinfo); // all done with this structure
146
147 return dns;
148*/
149}
150
151// --------------------------------------------------------------------------
152//
153//! Set the environment variable DIM_DNS_NODE to the given string and
154//! DIM_HOST_NODE to the IP-address through which this machine connects
155//! to the dns.
156//!
157//! @param dns
158//! Address of the Dim-dns
159//!
160void Dim::Setup(const std::string &dns, const std::string &host)
161{
162 if (dns.empty())
163 {
164 setenv("DIM_DNS_NODE", "...", 1);
165 //unsetenv("DIM_DNS_NODE");
166 //unsetenv("DIM_HOST_NODE");
167 return;
168 }
169
170 const string loc = host.empty() ? Dim::GetLocalIp(dns.c_str()) : host;
171
172 setenv("DIM_DNS_NODE", dns.c_str(), 1);
173 setenv("DIM_HOST_NODE", loc.c_str(), 1);
174
175 cout << "Setting DIM_DNS_NODE =" << dns << endl;
176 cout << "Setting DIM_HOST_NODE=" << loc << endl;
177}
178
179extern "C"
180{
181 const char *GetLocalIp()
182 {
183 static string rc;
184 rc = Dim::GetLocalIp();
185 cout << "Setting DIM_HOST_NODE=" << rc << endl;
186 return rc.c_str();
187 }
188}
Note: See TracBrowser for help on using the repository browser.