122 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (C) 2016 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *      http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| #ifndef _RESOLVER_STATS_H_
 | |
| #define _RESOLVER_STATS_H_
 | |
| 
 | |
| #include <time.h>
 | |
| 
 | |
| namespace android {
 | |
| namespace net {
 | |
| 
 | |
| struct ResolverStats {
 | |
|     // Offsets into the per-server resolver stats as encoded in vector<int32_t> stats of
 | |
|     // getResolverInfo() of Netd's binder interface. The stats are based on data reported by
 | |
|     // android_net_res_stats_get_info_for_net(), the usability is calculated by applying
 | |
|     // android_net_res_stats_get_usable_servers() to this data.
 | |
|     enum ResolverStatsOffsets {
 | |
|         STATS_SUCCESSES = 0,     // # successes counted for this server
 | |
|         STATS_ERRORS,            // # errors
 | |
|         STATS_TIMEOUTS,          // # timeouts
 | |
|         STATS_INTERNAL_ERRORS,   // # internal errors
 | |
|         STATS_RTT_AVG,           // average round-trip-time
 | |
|         STATS_LAST_SAMPLE_TIME,  // time in s when the last sample was recorded
 | |
|         STATS_USABLE,            // whether the server is considered usable
 | |
|         STATS_COUNT              // total count of integers in the per-server data
 | |
|     };
 | |
| 
 | |
|     int successes{-1};
 | |
|     int errors{-1};
 | |
|     int timeouts{-1};
 | |
|     int internal_errors{-1};
 | |
|     int rtt_avg{-1};
 | |
|     time_t last_sample_time{0};
 | |
|     bool usable{false};
 | |
| 
 | |
|     // Serialize the resolver stats to the end of |out|.
 | |
|     void encode(std::vector<int32_t>* out) const;
 | |
| 
 | |
|     // Read the serialized resolverstats starting at |in[ofs]|.
 | |
|     ssize_t decode(const std::vector<int32_t>& in, ssize_t ofs);
 | |
| 
 | |
|     // Serialize the contents of |stats| and append them to the end of |out|. Multiple arrays
 | |
|     // can be written to the same output vector in sequence, however, the corresponding call
 | |
|     // to decodeAll() will return the combined contents in one vector.
 | |
|     static void encodeAll(const std::vector<ResolverStats>& stats, std::vector<int32_t>* out);
 | |
| 
 | |
|     // Decodes the serialized ResolverStats from |in| and appends them to stats.
 | |
|     static bool decodeAll(const std::vector<int32_t>& in, std::vector<ResolverStats>* stats);
 | |
| };
 | |
| 
 | |
| inline void ResolverStats::encode(std::vector<int32_t>* out) const {
 | |
|     size_t ofs = out->size();
 | |
|     out->resize(ofs + STATS_COUNT);
 | |
|     int32_t* cur = &(*out)[ofs];
 | |
|     cur[STATS_SUCCESSES] = successes;
 | |
|     cur[STATS_ERRORS] = errors;
 | |
|     cur[STATS_TIMEOUTS] = timeouts;
 | |
|     cur[STATS_INTERNAL_ERRORS] = internal_errors;
 | |
|     cur[STATS_RTT_AVG] = rtt_avg;
 | |
|     cur[STATS_LAST_SAMPLE_TIME] = last_sample_time;
 | |
|     cur[STATS_USABLE] = usable;
 | |
| }
 | |
| 
 | |
| // Read the serialized resolverstats starting at |in[ofs]|.
 | |
| inline ssize_t ResolverStats::decode(const std::vector<int32_t>& in, ssize_t ofs) {
 | |
|     if (ofs < 0 || static_cast<size_t>(ofs) + STATS_COUNT > in.size()) {
 | |
|         return -1;
 | |
|     }
 | |
|     const int32_t* cur = &in[ofs];
 | |
|     successes = cur[STATS_SUCCESSES];
 | |
|     errors = cur[STATS_ERRORS];
 | |
|     timeouts = cur[STATS_TIMEOUTS];
 | |
|     internal_errors = cur[STATS_INTERNAL_ERRORS];
 | |
|     rtt_avg = cur[STATS_RTT_AVG];
 | |
|     last_sample_time = cur[STATS_LAST_SAMPLE_TIME];
 | |
|     usable = cur[STATS_USABLE];
 | |
|     return ofs + STATS_COUNT;
 | |
| }
 | |
| 
 | |
| inline void ResolverStats::encodeAll(const std::vector<ResolverStats>& stats,
 | |
|                                      std::vector<int32_t>* out) {
 | |
|     for (const auto& s : stats) {
 | |
|         s.encode(out);
 | |
|     }
 | |
| }
 | |
| 
 | |
| // TODO: Replace with a better representation, e.g. a Parcelable.
 | |
| inline bool ResolverStats::decodeAll(const std::vector<int32_t>& in,
 | |
|                                      std::vector<ResolverStats>* stats) {
 | |
|     ssize_t size = in.size();
 | |
|     if (size % STATS_COUNT) {
 | |
|         return false;
 | |
|     }
 | |
|     stats->resize(size / STATS_COUNT);
 | |
|     ssize_t ofs = 0;
 | |
|     for (auto& s : *stats) {
 | |
|         ofs = s.decode(in, ofs);
 | |
|         if (ofs < 0) {
 | |
|             return false;
 | |
|         }
 | |
|     }
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| }  // namespace net
 | |
| }  // namespace android
 | |
| 
 | |
| #endif /* _RESOLVER_STATS_H_ */
 |