CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
download.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_NETWORK_DOWNLOAD_H_
6 #define CVMFS_NETWORK_DOWNLOAD_H_
7 
8 #include <poll.h>
9 #include <pthread.h>
10 #include <stdint.h>
11 #include <unistd.h>
12 
13 #include <cstdio>
14 #include <map>
15 #include <set>
16 #include <string>
17 #include <vector>
18 
19 #include "gtest/gtest_prod.h"
20 
21 #include "compression.h"
22 #include "crypto/hash.h"
23 #include "duplex_curl.h"
24 #include "network/dns.h"
25 #include "network/health_check.h"
26 #include "network/jobinfo.h"
27 #include "network/network_errors.h"
29 #include "network/sink.h"
30 #include "ssl.h"
31 #include "statistics.h"
32 #include "util/atomic.h"
33 #include "util/pipe.h"
34 #include "util/pointer.h"
35 #include "util/prng.h"
36 #include "util/shared_ptr.h"
37 
38 class InterruptCue;
39 
40 namespace download {
41 
42 struct Counters {
44  perf::Counter *sz_transfer_time; // measured in milliseconds
49 
50  explicit Counters(perf::StatisticsTemplate statistics) {
51  sz_transferred_bytes = statistics.RegisterTemplated("sz_transferred_bytes",
52  "Number of transferred bytes");
53  sz_transfer_time = statistics.RegisterTemplated("sz_transfer_time",
54  "Transfer time (milliseconds)");
55  n_requests = statistics.RegisterTemplated("n_requests",
56  "Number of requests");
57  n_retries = statistics.RegisterTemplated("n_retries", "Number of retries");
58  n_proxy_failover = statistics.RegisterTemplated("n_proxy_failover",
59  "Number of proxy failovers");
60  n_host_failover = statistics.RegisterTemplated("n_host_failover",
61  "Number of host failovers");
62  }
63 }; // Counters
64 
74 class HeaderLists {
75  FRIEND_TEST(T_HeaderLists, Intrinsics);
76  public:
77  ~HeaderLists();
78  curl_slist *GetList(const char *header);
79  curl_slist *DuplicateList(curl_slist *slist);
80  void AppendHeader(curl_slist *slist, const char *header);
81  void CutHeader(const char *header, curl_slist **slist);
82  void PutList(curl_slist *slist);
83  std::string Print(curl_slist *slist);
84 
85  private:
86  static const unsigned kBlockSize = 4096/sizeof(curl_slist);
87 
88  bool IsUsed(curl_slist *slist) { return slist->data != NULL; }
89  curl_slist *Get(const char *header);
90  void Put(curl_slist *slist);
91  void AddBlock();
92 
93  std::vector<curl_slist *> blocks_; // List of curl_slist blocks
94 };
95 
96 
103  public:
105  virtual bool ConfigureCurlHandle(CURL *curl_handle,
106  pid_t pid,
107  void **info_data) = 0;
108  virtual void ReleaseCurlHandle(CURL *curl_handle, void *info_data) = 0;
109 };
110 
111 
116 class DownloadManager { // NOLINT(clang-analyzer-optin.performance.Padding)
117  FRIEND_TEST(T_Download, ValidateGeoReply);
118  FRIEND_TEST(T_Download, StripDirect);
119  FRIEND_TEST(T_Download, EscapeUrl);
120 
121  public:
122  struct ProxyInfo {
123  ProxyInfo() { }
124  explicit ProxyInfo(const std::string &url) : url(url) { }
125  ProxyInfo(const dns::Host &host, const std::string &url)
126  : host(host)
127  , url(url)
128  { }
129  std::string Print();
131  std::string url;
132  };
133 
138  };
139 
143  static const int kProbeUnprobed;
148  static const int kProbeDown;
152  static const int kProbeGeo;
153 
154  static const unsigned kDnsDefaultRetries = 1;
155  static const unsigned kDnsDefaultTimeoutMs = 3000;
156  static const unsigned kProxyMapScale = 16;
157 
158  DownloadManager(const unsigned max_pool_handles,
159  const perf::StatisticsTemplate &statistics,
160  const std::string &name = "standard");
162 
163  static int ParseHttpCode(const char digits[3]);
164 
165  void Spawn();
167  const std::string &cloned_name);
168  Failures Fetch(JobInfo *info);
169 
171  std::string GetDnsServer() const;
172  void SetDnsServer(const std::string &address);
173  void SetDnsParameters(const unsigned retries, const unsigned timeout_ms);
174  void SetDnsTtlLimits(const unsigned min_seconds, const unsigned max_seconds);
175  void SetIpPreference(const dns::IpPreference preference);
176  void SetTimeout(const unsigned seconds_proxy, const unsigned seconds_direct);
177  void GetTimeout(unsigned *seconds_proxy, unsigned *seconds_direct);
178  void SetLowSpeedLimit(const unsigned low_speed_limit);
179  void SetHostChain(const std::string &host_list);
180  void SetHostChain(const std::vector<std::string> &host_list);
181  void GetHostInfo(std::vector<std::string> *host_chain,
182  std::vector<int> *rtt, unsigned *current_host);
183  void ProbeHosts();
184  bool ProbeGeo();
185  // Sort list of servers using the Geo API. If the output_order
186  // vector is NULL, then the servers vector input is itself sorted.
187  // If it is non-NULL, then servers is left unchanged and the zero-based
188  // ordering is stored into output_order.
189  bool GeoSortServers(std::vector<std::string> *servers,
190  std::vector<uint64_t> *output_order = NULL);
191  void SwitchHost();
192  void SetProxyChain(const std::string &proxy_list,
193  const std::string &fallback_proxy_list,
194  const ProxySetModes set_mode);
195  void GetProxyInfo(std::vector< std::vector<ProxyInfo> > *proxy_chain,
196  unsigned *current_group,
197  unsigned *fallback_group);
198  std::string GetProxyList();
199  std::string GetFallbackProxyList();
200  void ShardProxies();
201  void RebalanceProxies();
202  void SwitchProxyGroup();
203  void SetProxyGroupResetDelay(const unsigned seconds);
204  void SetHostResetDelay(const unsigned seconds);
205  void SetRetryParameters(const unsigned max_retries,
206  const unsigned backoff_init_ms,
207  const unsigned backoff_max_ms);
208  void SetMaxIpaddrPerProxy(unsigned limit);
209  void SetProxyTemplates(const std::string &direct, const std::string &forced);
210  void EnableInfoHeader();
211  void EnableRedirects();
213  void EnableHTTPTracing();
214  void AddHTTPTracingHeader(const std::string &header);
216 
219  void SetFqrn(const std::string &fqrn) { fqrn_ = fqrn; }
220 
221  unsigned num_hosts() {
222  if (opt_host_chain_) return opt_host_chain_->size();
223  return 0;
224  }
225 
227  return opt_ip_preference_;
228  }
229 
230  private:
231  static int CallbackCurlSocket(CURL *easy, curl_socket_t s, int action,
232  void *userp, void *socketp);
233  static void *MainDownload(void *data);
234 
235  bool StripDirect(const std::string &proxy_list, std::string *cleaned_list);
236  bool ValidateGeoReply(const std::string &reply_order,
237  const unsigned expected_size,
238  std::vector<uint64_t> *reply_vals);
239  void SwitchHost(JobInfo *info);
240  void SwitchProxy(JobInfo *info);
241  ProxyInfo *ChooseProxyUnlocked(const shash::Any *hash);
242  void UpdateProxiesUnlocked(const std::string &reason);
243  void RebalanceProxiesUnlocked(const std::string &reason);
244  CURL *AcquireCurlHandle();
245  void ReleaseCurlHandle(CURL *handle);
246  void ReleaseCredential(JobInfo *info);
247  void InitializeRequest(JobInfo *info, CURL *handle);
248  void SetUrlOptions(JobInfo *info);
249  bool ValidateProxyIpsUnlocked(const std::string &url, const dns::Host &host);
250  void UpdateStatistics(CURL *handle);
251  bool CanRetry(const JobInfo *info);
252  void Backoff(JobInfo *info);
253  void SetNocache(JobInfo *info);
254  void SetRegularCache(JobInfo *info);
255  bool VerifyAndFinalize(const int curl_error, JobInfo *info);
256  void InitHeaders();
257  void CloneProxyConfig(DownloadManager *clone);
258 
259  bool EscapeUrlChar(unsigned char input, char output[3]);
260  std::string EscapeUrl(const int64_t jobinfo_id, const std::string &url);
261  unsigned EscapeHeader(const std::string &header, char *escaped_buf,
262  size_t buf_size);
263 
264  inline std::vector<ProxyInfo> *current_proxy_group() const {
265  return (opt_proxy_groups_ ?
267  }
268 
270  std::set<CURL *> *pool_handles_idle_;
271  std::set<CURL *> *pool_handles_inuse_;
273  CURLM *curl_multi_;
275  curl_slist *default_headers_;
276  char *user_agent_;
277 
278  pthread_t thread_download_;
281 
283  struct pollfd *watch_fds_;
284  uint32_t watch_fds_size_;
286  uint32_t watch_fds_max_;
287 
288  pthread_mutex_t *lock_options_;
289  pthread_mutex_t *lock_synchronous_mode_;
290  std::string opt_dns_server_;
300 
306 
308  std::vector<std::string> http_tracing_headers_;
309 
310  // Host list
311  std::vector<std::string> *opt_host_chain_;
316  std::vector<int> *opt_host_chain_rtt_;
318 
319  // Proxy list
320  std::vector< std::vector<ProxyInfo> > *opt_proxy_groups_;
342  std::string opt_proxy_list_;
350  std::map<uint32_t, ProxyInfo *> opt_proxy_map_;
354  std::vector<std::string> opt_proxy_urls_;
359 
385  std::string fqrn_;
386 
390  std::string name_;
391 
396 
401 
414 
422  time_t opt_timestamp_failover_proxies_; // failover within the same group
424 
432 
434 
440 
445 }; // DownloadManager
446 
447 } // namespace download
448 
449 #endif // CVMFS_NETWORK_DOWNLOAD_H_
unsigned opt_timeout_direct_
Definition: download.h:292
std::vector< std::string > http_tracing_headers_
Definition: download.h:308
bool StripDirect(const std::string &proxy_list, std::string *cleaned_list)
Definition: download.cc:2553
unsigned opt_low_speed_limit_
Definition: download.h:293
Definition: prng.h:28
static const unsigned kDnsDefaultTimeoutMs
Definition: download.h:155
unsigned opt_backoff_init_ms_
Definition: download.h:295
curl_slist * Get(const char *header)
Definition: download.cc:818
bool EscapeUrlChar(unsigned char input, char output[3])
Definition: download.cc:388
std::string Print(curl_slist *slist)
Definition: download.cc:808
unsigned opt_proxy_groups_current_burned_
Definition: download.h:329
unsigned opt_proxy_groups_reset_after_
Definition: download.h:423
void SetUrlOptions(JobInfo *info)
Definition: download.cc:1010
void ReleaseCredential(JobInfo *info)
Definition: download.cc:1358
SharedPtr< ShardingPolicy > sharding_policy_
Definition: download.h:368
bool IsUsed(curl_slist *slist)
Definition: download.h:88
std::string opt_proxy_fallback_list_
Definition: download.h:346
void SetHostChain(const std::string &host_list)
void SetNocache(JobInfo *info)
Definition: download.cc:1331
unsigned opt_host_reset_after_
Definition: download.h:431
void SetLowSpeedLimit(const unsigned low_speed_limit)
Definition: download.cc:2057
DownloadManager(const unsigned max_pool_handles, const perf::StatisticsTemplate &statistics, const std::string &name="standard")
Definition: download.cc:1753
std::string proxy_template_direct_
Definition: download.h:407
static int ParseHttpCode(const char digits[3])
Definition: download.cc:469
FRIEND_TEST(T_Download, ValidateGeoReply)
static const int kProbeGeo
Definition: download.h:152
static const unsigned kBlockSize
Definition: download.h:86
unsigned opt_proxy_groups_current_
Definition: download.h:324
bool ValidateGeoReply(const std::string &reply_order, const unsigned expected_size, std::vector< uint64_t > *reply_vals)
Definition: download.cc:2513
std::vector< ProxyInfo > * current_proxy_group() const
Definition: download.h:264
time_t opt_timestamp_backup_proxies_
Definition: download.h:421
void SetProxyChain(const std::string &proxy_list, const std::string &fallback_proxy_list, const ProxySetModes set_mode)
Definition: download.cc:2593
std::string GetProxyList()
Definition: download.cc:2775
std::set< CURL * > * pool_handles_inuse_
Definition: download.h:271
pthread_mutex_t * lock_options_
Definition: download.h:288
ProxyInfo * ChooseProxyUnlocked(const shash::Any *hash)
Definition: download.cc:2787
pthread_t thread_download_
Definition: download.h:278
ProxyInfo(const dns::Host &host, const std::string &url)
Definition: download.h:125
std::string opt_proxy_list_
Definition: download.h:342
perf::Counter * sz_transfer_time
Definition: download.h:44
std::vector< std::vector< ProxyInfo > > * opt_proxy_groups_
Definition: download.h:320
unsigned opt_proxy_groups_fallback_
Definition: download.h:334
curl_slist * default_headers_
Definition: download.h:275
curl_slist * GetList(const char *header)
Definition: download.cc:742
void ReleaseCurlHandle(CURL *handle)
Definition: download.cc:904
void SetDnsServer(const std::string &address)
Definition: download.cc:1985
DownloadManager * Clone(const perf::StatisticsTemplate &statistics, const std::string &cloned_name)
Definition: download.cc:2991
FRIEND_TEST(T_HeaderLists, Intrinsics)
static void * MainDownload(void *data)
Definition: download.cc:565
void SetTimeout(const unsigned seconds_proxy, const unsigned seconds_direct)
Definition: download.cc:2043
perf::Counter * n_retries
Definition: download.h:46
std::string opt_dns_server_
Definition: download.h:290
void Backoff(JobInfo *info)
Definition: download.cc:1305
perf::Counter * sz_transferred_bytes
Definition: download.h:43
void SetFqrn(const std::string &fqrn)
Definition: download.h:219
std::string EscapeUrl(const int64_t jobinfo_id, const std::string &url)
Definition: download.cc:415
int32_t atomic_int32
Definition: atomic.h:17
Counter * RegisterTemplated(const std::string &name_minor, const std::string &desc)
Definition: statistics.h:111
void UpdateStatistics(CURL *handle)
Definition: download.cc:1271
void SetDnsTtlLimits(const unsigned min_seconds, const unsigned max_seconds)
Definition: download.cc:2022
std::vector< std::string > opt_proxy_urls_
Definition: download.h:354
void GetProxyInfo(std::vector< std::vector< ProxyInfo > > *proxy_chain, unsigned *current_group, unsigned *fallback_group)
Definition: download.cc:2750
void SetProxyGroupResetDelay(const unsigned seconds)
Definition: download.cc:2901
atomic_int32 multi_threaded_
Definition: download.h:279
dns::NormalResolver * resolver_
Definition: download.h:395
std::vector< curl_slist * > blocks_
Definition: download.h:93
ProxyInfo(const std::string &url)
Definition: download.h:124
dns::IpPreference opt_ip_preference_
Definition: download.h:400
Definition: dns.h:90
bool SetShardingPolicy(const ShardingPolicySelector type)
Definition: download.cc:2972
perf::Counter * n_host_failover
Definition: download.h:48
void UpdateProxiesUnlocked(const std::string &reason)
Definition: download.cc:2801
void AppendHeader(curl_slist *slist, const char *header)
Definition: download.cc:764
void SetIpPreference(const dns::IpPreference preference)
Definition: download.cc:2032
perf::Counter * n_requests
Definition: download.h:45
void SetRetryParameters(const unsigned max_retries, const unsigned backoff_init_ms, const unsigned backoff_max_ms)
Definition: download.cc:2920
void SetRegularCache(JobInfo *info)
Definition: download.cc:1345
void CloneProxyConfig(DownloadManager *clone)
Definition: download.cc:3037
void PutList(curl_slist *slist)
Definition: download.cc:799
void SetMaxIpaddrPerProxy(unsigned limit)
Definition: download.cc:2931
void EnableIgnoreSignatureFailures()
Definition: download.cc:2956
std::vector< int > * opt_host_chain_rtt_
Definition: download.h:316
dns::IpPreference opt_ip_preference() const
Definition: download.h:226
SslCertificateStore ssl_certificate_store_
Definition: download.h:444
time_t opt_timestamp_backup_host_
Definition: download.h:430
std::string GetFallbackProxyList()
Definition: download.cc:2779
void SetProxyTemplates(const std::string &direct, const std::string &forced)
Definition: download.cc:2937
IpPreference
Definition: dns.h:46
unsigned opt_backoff_max_ms_
Definition: download.h:296
std::string GetDnsServer() const
Definition: download.cc:1977
unsigned opt_host_chain_current_
Definition: download.h:317
CredentialsAttachment * credentials_attachment_
Definition: download.h:433
std::vector< std::string > * opt_host_chain_
Definition: download.h:311
struct pollfd * watch_fds_
Definition: download.h:283
std::map< uint32_t, ProxyInfo * > opt_proxy_map_
Definition: download.h:350
curl_slist * DuplicateList(curl_slist *slist)
Definition: download.cc:747
UniquePtr< Pipe< kPipeDownloadJobs > > pipe_jobs_
Definition: download.h:282
Failures Fetch(JobInfo *info)
Definition: download.cc:1860
bool CanRetry(const JobInfo *info)
Definition: download.cc:1289
perf::Counter * n_proxy_failover
Definition: download.h:47
void GetTimeout(unsigned *seconds_proxy, unsigned *seconds_direct)
Definition: download.cc:2066
std::string proxy_template_forced_
Definition: download.h:413
time_t opt_timestamp_failover_proxies_
Definition: download.h:422
void SetDnsParameters(const unsigned retries, const unsigned timeout_ms)
Definition: download.cc:2004
unsigned EscapeHeader(const std::string &header, char *escaped_buf, size_t buf_size)
Definition: download.cc:437
UniquePtr< Pipe< kPipeThreadTerminator > > pipe_terminate_
Definition: download.h:280
static const int kProbeUnprobed
Definition: download.h:143
virtual void ReleaseCurlHandle(CURL *curl_handle, void *info_data)=0
static const unsigned kDnsDefaultRetries
Definition: download.h:154
bool GeoSortServers(std::vector< std::string > *servers, std::vector< uint64_t > *output_order=NULL)
Definition: download.cc:2306
static const int kProbeDown
Definition: download.h:148
Counters(perf::StatisticsTemplate statistics)
Definition: download.h:50
static const unsigned kProxyMapScale
Definition: download.h:156
void GetHostInfo(std::vector< std::string > *host_chain, std::vector< int > *rtt, unsigned *current_host)
Definition: download.cc:2110
bool ValidateProxyIpsUnlocked(const std::string &url, const dns::Host &host)
Definition: download.cc:1204
bool VerifyAndFinalize(const int curl_error, JobInfo *info)
Definition: download.cc:1374
void CutHeader(const char *header, curl_slist **slist)
Definition: download.cc:780
SharedPtr< HealthCheck > health_check_
Definition: download.h:376
void SwitchProxy(JobInfo *info)
Definition: download.cc:2130
void AddHTTPTracingHeader(const std::string &header)
Definition: download.cc:2964
void SetCredentialsAttachment(CredentialsAttachment *ca)
Definition: download.cc:1969
std::set< CURL * > * pool_handles_idle_
Definition: download.h:270
void RebalanceProxiesUnlocked(const std::string &reason)
Definition: download.cc:2865
pthread_mutex_t * lock_synchronous_mode_
Definition: download.h:289
virtual bool ConfigureCurlHandle(CURL *curl_handle, pid_t pid, void **info_data)=0
void InitializeRequest(JobInfo *info, CURL *handle)
Definition: download.cc:922
static int CallbackCurlSocket(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp)
Definition: download.cc:485
HeaderLists * header_lists_
Definition: download.h:274
void SetHostResetDelay(const unsigned seconds)
Definition: download.cc:2911
void Put(curl_slist *slist)
Definition: download.cc:835