An Overlay-based
Virtual Network Substrate
SpoVNet

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

Last change on this file since 5412 was 5412, checked in by Christoph Mayer, 14 years ago

-logging fix, -sdp fix, -endpoint operator fix, -endpoint aufräumen

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.isUnspecified() ){
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.