1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab ft=cpp
/*
* RGW Etag Verifier is an RGW filter which enables the objects copied using
* multisite sync to be verified using their ETag from source i.e. the MD5
* checksum of the object is computed at the destination and is verified to be
* identical to the ETag stored in the object HEAD at source cluster.
*
* For MPU objects, a different filter named RGWMultipartEtagFilter is applied
* which re-computes ETag using RGWObjManifest. This computes the ETag using the
* same algorithm used at the source cluster i.e. MD5 sum of the individual ETag
* on the MPU parts.
*/
#ifndef CEPH_RGW_ETAG_VERIFIER_H
#define CEPH_RGW_ETAG_VERIFIER_H
#include "rgw_putobj.h"
#include "rgw_op.h"
#include "common/static_ptr.h"
namespace rgw::putobj {
class ETagVerifier : public rgw::putobj::Pipe
{
protected:
CephContext* cct;
MD5 hash;
string calculated_etag;
public:
ETagVerifier(CephContext* cct_, rgw::putobj::DataProcessor *next)
: Pipe(next), cct(cct_) {
// Allow use of MD5 digest in FIPS mode for non-cryptographic purposes
hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
}
virtual void calculate_etag() = 0;
string get_calculated_etag() { return calculated_etag;}
}; /* ETagVerifier */
class ETagVerifier_Atomic : public ETagVerifier
{
public:
ETagVerifier_Atomic(CephContext* cct_, rgw::putobj::DataProcessor *next)
: ETagVerifier(cct_, next) {}
int process(bufferlist&& data, uint64_t logical_offset) override;
void calculate_etag() override;
}; /* ETagVerifier_Atomic */
class ETagVerifier_MPU : public ETagVerifier
{
std::vector<uint64_t> part_ofs;
uint64_t cur_part_index{0}, next_part_index{1};
MD5 mpu_etag_hash;
void process_end_of_MPU_part();
public:
ETagVerifier_MPU(CephContext* cct,
std::vector<uint64_t> part_ofs,
rgw::putobj::DataProcessor *next)
: ETagVerifier(cct, next),
part_ofs(std::move(part_ofs))
{
// Allow use of MD5 digest in FIPS mode for non-cryptographic purposes
hash.SetFlags(EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
}
int process(bufferlist&& data, uint64_t logical_offset) override;
void calculate_etag() override;
}; /* ETagVerifier_MPU */
constexpr auto max_etag_verifier_size = std::max(
sizeof(ETagVerifier_Atomic),
sizeof(ETagVerifier_MPU)
);
using etag_verifier_ptr = ceph::static_ptr<ETagVerifier, max_etag_verifier_size>;
int create_etag_verifier(const DoutPrefixProvider *dpp,
CephContext* cct, DataProcessor* next,
const bufferlist& manifest_bl,
const std::optional<RGWCompressionInfo>& compression,
etag_verifier_ptr& verifier);
} // namespace rgw::putobj
#endif /* CEPH_RGW_ETAG_VERIFIER_H */
|