source: source/ariba/utility/measurement/PathloadMeasurement.cpp@ 3712

Last change on this file since 3712 was 3690, checked in by mies, 15 years ago

Merged 20090512-mies-connectors changes r3472:r3689 into trunk.

File size: 5.7 KB
Line 
1// [License]
2// The Ariba-Underlay Copyright
3//
4// Copyright (c) 2008-2009, Institute of Telematics, UniversitÀt Karlsruhe (TH)
5//
6// Institute of Telematics
7// UniversitÀt Karlsruhe (TH)
8// Zirkel 2, 76128 Karlsruhe
9// Germany
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
22// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ARIBA PROJECT OR
25// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33// The views and conclusions contained in the software and documentation
34// are those of the authors and should not be interpreted as representing
35// official policies, either expressed or implied, of the Institute of
36// Telematics.
37// [License]
38
39#include "PathloadMeasurement.h"
40
41namespace ariba {
42namespace utility {
43
44use_logging_cpp(PathloadMeasurement);
45
46PathloadMeasurement::PathloadMeasurement(BaseOverlay* _overlay)
47 : running( false ), resultNode( NodeID::UNSPECIFIED ),
48 listener( NULL), serverpid( -1 ) {
49
50 if( _overlay != NULL ) // this is important due to the singleton interface!
51 baseoverlay = _overlay;
52
53 //
54 // start the pathload sender which acts as server
55 // the server is started in the child process
56 // if an instance is already running, the second
57 // will just fail starting up ...
58 //
59
60 const char* argv[4];
61 argv[0] = "pathload_snd";
62 argv[1] = "-q";
63 argv[2] = "-i";
64 argv[3] = 0;
65
66 if( (serverpid = vfork()) == 0 ){
67
68 // execute in child process
69 execvp( "pathload_snd", (char* const*)argv );
70
71 // if we reach here, the exec failed
72 // and we quit the child process
73 logging_warn( "no bandwidth measurement module found " <<
74 "(executing pathload_snd for bandwidth measurement server failed)" );
75 }
76}
77
78PathloadMeasurement::~PathloadMeasurement(){
79
80 // quit the pathload server
81 if( serverpid != -1 )
82 kill( serverpid, SIGQUIT );
83}
84
85void PathloadMeasurement::measure(const NodeID& destnode, PathloadMeasurementListener* _listener){
86
87 if( running ){
88 logging_warn( "measurement already running" );
89 return;
90 }
91
92 logging_info( "starting new measurement for " << destnode.toString() );
93
94 listener = _listener;
95 resultNode = destnode;
96 resultMbps = -1;
97
98 runBlockingMethod();
99}
100
101void PathloadMeasurement::dispatchFunction(){
102 if( listener != NULL )
103 listener->onMeasurement( resultNode, resultMbps );
104}
105
106void PathloadMeasurement::blockingFunction(){
107
108 // get the endpoint for this node
109 const EndpointDescriptor& endp = baseoverlay->getEndpointDescriptor( resultNode );
110 if( endp == EndpointDescriptor::UNSPECIFIED ){
111 logging_warn( "can not measure node " << resultNode.toString() << ": can't resolve endpoint" );
112 return;
113 }
114
115 // if this is our local endpoint don't perform measurement
116 if( endp == baseoverlay->getEndpointDescriptor() ){
117 logging_debug( "don't perform measurement on local machine" );
118 resultMbps = -1;
119 dispatch();
120 return;
121 }
122
123 // currently we can be sure that this is
124 // an IPv4 and port format, or only IPv4
125 string endpoint = endp.toString();
126 string::size_type p = endpoint.find(':');
127 if( p != string::npos ) endpoint = endpoint.substr( 0, p );
128
129 logging_info( "measuring node " << resultNode.toString() <<
130 " on endpoint " << endpoint );
131
132 string cmdline = "pathload_rcv -s " + endpoint;
133
134 // execute the binary and open a stream to the executables output (stdout)
135 FILE* stream = popen( cmdline.c_str(), "r" );
136 if( stream == NULL || stream <= 0){
137 logging_warn( "no bandwidth measurement module found " <<
138 "(executing pathload_rvc for bandwidth measurement failed)" );
139 return;
140 }
141
142 char buf[128];
143 string content = "";
144 bool failed = true;
145
146 while( fgets(buf, 100, stream) != NULL ){
147 content += buf;
148 }
149
150 logging_debug("pathload measurment output:\n" << content );
151
152 //
153 // evaluate the output
154 //
155
156 if( content.find("Connection refused") != string::npos ){
157 logging_warn( "bandwidth measurement failed due to connection error" );
158 return;
159 }
160
161 if( content.find("Measurements terminated") != string::npos ){
162 logging_warn( "bandwidth measurement failed" );
163 return;
164 }
165
166 if( content.find("Measurements finished") == string::npos ){
167 logging_warn( "bandwidth measurement failed" );
168 return;
169 }
170
171 try {
172 content = content.substr( content.find("Available bandwidth range") );
173 content = content.substr( content.find("-")+2 );
174 content = content.erase( content.find("(")-1, string::npos );
175
176 resultMbps = strtod(content.c_str(), NULL);
177 logging_info( "measurement for node " << resultNode.toString() <<
178 " on endpoint " << endp.toString() << " ended with: " << resultMbps );
179 } catch(...) {
180 logging_warn( "bandwidth measurement failed" );
181 }
182
183 // dispatch into the main thread and async jump into
184 // void PathloadMeasurement::dispatchFunction()
185 dispatch();
186}
187
188}} // namespace ariba, utility
Note: See TracBrowser for help on using the repository browser.