XRootD
XrdHttpTpcTPC.hh
Go to the documentation of this file.
1 #ifndef XRD_HTTP_TPC_TPC_HH
2 #define XRD_HTTP_TPC_TPC_HH
3 #include <memory>
4 #include <string>
5 #include <vector>
6 #include <sys/time.h>
7 
9 
11 #include "XrdHttp/XrdHttpUtils.hh"
12 
13 #include "XrdTls/XrdTlsTempCA.hh"
15 
16 #include <curl/curl.h>
17 #include <openssl/ssl.h>
18 
19 class XrdOucErrInfo;
20 class XrdOucStream;
21 class XrdSfsFile;
22 class XrdSfsFileSystem;
23 class XrdXrootdTpcMon;
24 typedef void CURL;
25 
26 namespace TPC {
27 class State;
28 
29 enum LogMask {
30  Debug = 0x01,
31  Info = 0x02,
32  Warning = 0x04,
33  Error = 0x08,
34  All = 0xff
35 };
36 
37 enum class TpcType {
38  Pull,
39  Push
40 };
41 
42 struct CurlDeleter {
43  void operator()(CURL *curl);
44 };
45 using ManagedCurlHandle = std::unique_ptr<CURL, CurlDeleter>;
46 
47 
48 class TPCHandler : public XrdHttpExtHandler {
49 public:
50  TPCHandler(XrdSysError *log, const char *config, XrdOucEnv *myEnv);
51  virtual ~TPCHandler();
52 
53  virtual bool MatchesPath(const char *verb, const char *path);
54  virtual int ProcessReq(XrdHttpExtReq &req);
55  // Abstract method in the base class, but does not seem to be used
56  virtual int Init(const char *cfgfile) {return 0;}
57  static constexpr std::string_view OSS_TASK_OPAQUE = "oss.task=httptpc";
58 private:
59 
60  static int sockopt_callback(void * clientp, curl_socket_t curlfd, curlsocktype purpose);
61  static int opensocket_callback(void *clientp,
62  curlsocktype purpose,
63  struct curl_sockaddr *address);
64 
65  static int closesocket_callback(void *clientp, curl_socket_t fd);
66  static int ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *clientp);
67  static int verify_callback(int preverify_ok, X509_STORE_CTX* ctx);
68 
69  struct TPCLogRecord {
70 
71  TPCLogRecord(XrdHttpExtReq &req, const TpcType tpcType)
72  : bytes_transferred(-1), status(-1), tpc_status(-1), streams(1), isIPv6(false),
73  allow_local(false), allow_private(false), mReq(req), pmarkManager(mReq, tpcType), mTpcType(tpcType)
74  {
75  gettimeofday(&begT, 0); // Set effective start time
76  }
77 
78  ~TPCLogRecord();
79 
80  std::string log_prefix;
81  std::string local;
82  std::string remote;
83  std::string name;
84  std::string clID;
85  static XrdXrootdTpcMon* tpcMonitor;
86  timeval begT;
87  off_t bytes_transferred;
88  int status;
89  int tpc_status;
90  unsigned int streams;
91  bool isIPv6;
92  bool allow_local;
93  bool allow_private;
94  XrdHttpExtReq & mReq;
95  XrdHttpTpc::PMarkManager pmarkManager;
96  XrdSysError * m_log;
97  TpcType mTpcType;
98  };
99 
100  int ProcessOptionsReq(XrdHttpExtReq &req);
101 
102  static std::string GetAuthz(XrdHttpExtReq &req);
103 
104  // Configure curl handle's CA settings. The CA files present here should
105  // be valid for the lifetime of the process.
106  void ConfigureCurlCA(CURL *curl);
107 
108  // Redirect the transfer according to the contents of an XrdOucErrInfo object.
109  int RedirectTransfer(CURL *curl, const std::string &redirect_resource, XrdHttpExtReq &req,
110  XrdOucErrInfo &error, TPCLogRecord &);
111 
112  int OpenWaitStall(XrdSfsFile &fh, const std::string &resource, int mode,
113  int openMode, const XrdSecEntity &sec,
114  const std::string &authz);
115 
116  int PerformHEADRequest(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
117  bool &success, TPCLogRecord &rec, bool shouldReturnErrorToClient = true);
118 
119  int GetRemoteFileInfoTPCPull(CURL *curl, XrdHttpExtReq &req, uint64_t & contentLength, std::map<std::string,std::string> & reprDigest, bool & success, TPCLogRecord &rec);
120 
121  // Send a 'performance marker' back to the TPC client, informing it of our
122  // progress. The TPC client will use this information to determine whether
123  // the transfer is making sufficient progress and/or other monitoring info
124  // (such as whether the transfer is happening over IPv4, IPv6, or both).
125  int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, TPC::State &state);
126  int SendPerfMarker(XrdHttpExtReq &req, TPCLogRecord &rec, std::vector<State*> &state,
127  off_t bytes_transferred);
128 
129  // Perform the libcurl transfer, periodically sending back chunked updates.
130  int RunCurlWithUpdates(CURL *curl, XrdHttpExtReq &req, TPC::State &state,
131  TPCLogRecord &rec);
132 
133  // Experimental multi-stream version of RunCurlWithUpdates
134  int RunCurlWithStreams(XrdHttpExtReq &req, TPC::State &state,
135  size_t streams, TPCLogRecord &rec);
136  int RunCurlWithStreamsImpl(XrdHttpExtReq &req, TPC::State &state,
137  size_t streams, std::vector<TPC::State*> &streams_handles,
138  std::vector<ManagedCurlHandle> &curl_handles,
139  TPCLogRecord &rec);
140 
141  int ProcessPushReq(const std::string & resource, XrdHttpExtReq &req);
142  int ProcessPullReq(const std::string &resource, XrdHttpExtReq &req);
143 
144  bool ConfigureFSLib(XrdOucStream &Config, std::string &path1, bool &path1_alt,
145  std::string &path2, bool &path2_alt);
146  bool Configure(const char *configfn, XrdOucEnv *myEnv);
147  bool ConfigureLogger(XrdOucStream &Config);
148 
149  // Generate a consistently-formatted log message.
150  void logTransferEvent(LogMask lvl, const TPCLogRecord &record,
151  const std::string &event, const std::string &message="");
152 
153  std::string generateClientErr(std::stringstream &err_ss, const TPCLogRecord &rec, CURLcode cCode = CURLcode::CURLE_OK);
154 
155  std::string prepareURL(XrdHttpExtReq &req);
156 
168  bool mismatchReprDigest(const std::map<std::string,std::string> & passiveSrvReprDigest, XrdHttpExtReq & req, TPCLogRecord &rec);
169 
170  static int m_marker_period;
171  static size_t m_block_size;
172  static size_t m_small_block_size;
173  bool m_allow_local;
174  bool m_allow_private;
175  bool m_desthttps;
176  bool m_fixed_route; // If 'true' the Destination IP in an HTTP-TPC is forced to be the same as the IP used to contact the server
177  // when 'false' any IP available can be selected
178  int m_timeout; // the 'timeout interval'; if no bytes have been received during this time period, abort the transfer.
179  int m_first_timeout; // the 'first timeout interval'; the amount of time we're willing to wait to get the first byte.
180  // Unless explicitly specified, this is 2x the timeout interval.
181  std::string m_cadir; // The directory to use for CAs.
182  std::string m_cafile; // The file to use for CAs in libcurl
183  static XrdSysMutex m_monid_mutex;
184  static uint64_t m_monid;
185  XrdSysError m_log;
186  XrdSfsFileSystem *m_sfs;
187  std::shared_ptr<XrdTlsTempCA> m_ca_file;
188 
189  // 16 blocks in flight at 16 MB each, meaning that there will be up to 256MB
190  // in flight; this is equal to the bandwidth delay product of a 200ms transcontinental
191  // connection at 10Gbps.
192  static const int m_pipelining_multiplier = 16;
193 
194  bool usingEC; // indicate if XrdEC is used
195 
196  static bool allowMissingCRL;
197 
198  // Time to connect the curl socket to the remote server uses the linux's default value
199  // of 60 seconds
200  static const long CONNECT_TIMEOUT = 60;
201 
202  // hdr2cgimap
203  std::map<std::string,std::string> hdr2cgimap;
204 };
205 }
206 #endif
void CURL
void CURL
Utility functions for XrdHTTP.
TPCHandler(XrdSysError *log, const char *config, XrdOucEnv *myEnv)
virtual int ProcessReq(XrdHttpExtReq &req)
virtual ~TPCHandler()
static constexpr std::string_view OSS_TASK_OPAQUE
virtual int Init(const char *cfgfile)
Initializes the external request handler.
virtual bool MatchesPath(const char *verb, const char *path)
Tells if the incoming path is recognized as one of the paths that have to be processed.
std::unique_ptr< CURL, CurlDeleter > ManagedCurlHandle
@ Warning
XrdCmsConfig Config
void operator()(CURL *curl)