]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_torrent.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / rgw / rgw_torrent.cc
CommitLineData
11fdf7f2 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
11fdf7f2 3
7c673cae
FG
4#include <errno.h>
5#include <stdlib.h>
6
7#include <sstream>
8
9#include "rgw_torrent.h"
9f95a23c 10#include "rgw_sal.h"
f67539c2 11#include "rgw_sal_rados.h"
7c673cae
FG
12#include "include/str_list.h"
13#include "include/rados/librados.hpp"
14
11fdf7f2
TL
15#include "services/svc_sys_obj.h"
16
7c673cae
FG
17#define dout_subsys ceph_subsys_rgw
18
20effc67 19using namespace std;
7c673cae
FG
20using namespace librados;
21using namespace boost;
22using ceph::crypto::SHA1;
23
24seed::seed()
25{
26 seed::info.piece_length = 0;
27 seed::info.len = 0;
28 sha_len = 0;
29 is_torrent = false;
30}
31
32seed::~seed()
33{
34 seed::info.sha1_bl.clear();
35 bl.clear();
7c673cae 36 s = NULL;
1e59de90 37 driver = NULL;
7c673cae
FG
38}
39
1e59de90 40void seed::init(req_state *_req, rgw::sal::Driver* _driver)
7c673cae 41{
1e59de90
TL
42 s = _req;
43 driver = _driver;
7c673cae
FG
44}
45
20effc67 46int seed::get_torrent_file(rgw::sal::Object* object,
3efd9988
FG
47 uint64_t &total_len,
48 ceph::bufferlist &bl_data,
49 rgw_obj &obj)
7c673cae
FG
50{
51 /* add other field if config is set */
52 dencode.bencode_dict(bl);
53 set_announce();
54 if (!comment.empty())
55 {
56 dencode.bencode(COMMENT, comment, bl);
57 }
58 if (!create_by.empty())
59 {
60 dencode.bencode(CREATED_BY, create_by, bl);
61 }
62 if (!encoding.empty())
63 {
64 dencode.bencode(ENCODING, encoding, bl);
65 }
66
67 string oid, key;
7c673cae 68 get_obj_bucket_and_oid_loc(obj, oid, key);
b3b6e05e 69 ldpp_dout(s, 20) << "NOTICE: head obj oid= " << oid << dendl;
7c673cae 70
28e407b8
AA
71 const set<string> obj_key{RGW_OBJ_TORRENT};
72 map<string, bufferlist> m;
b3b6e05e 73 const int r = object->omap_get_vals_by_keys(s, oid, obj_key, &m);
28e407b8 74 if (r < 0) {
b3b6e05e 75 ldpp_dout(s, 0) << "ERROR: omap_get_vals_by_keys failed: " << r << dendl;
28e407b8 76 return r;
7c673cae 77 }
28e407b8 78 if (m.size() != 1) {
b3b6e05e 79 ldpp_dout(s, 0) << "ERROR: omap key " RGW_OBJ_TORRENT " not found" << dendl;
28e407b8 80 return -EINVAL;
7c673cae 81 }
28e407b8 82 bl.append(std::move(m.begin()->second));
7c673cae
FG
83 dencode.bencode_end(bl);
84
85 bl_data = bl;
86 total_len = bl.length();
3efd9988 87 return 0;
7c673cae
FG
88}
89
90bool seed::get_flag()
91{
92 return is_torrent;
93}
94
31f18b77 95void seed::update(bufferlist &bl)
7c673cae
FG
96{
97 if (!is_torrent)
98 {
99 return;
100 }
7c673cae 101 info.len += bl.length();
31f18b77
FG
102 sha1(&h, bl, bl.length());
103}
104
f67539c2 105int seed::complete(optional_yield y)
31f18b77
FG
106{
107 uint64_t remain = info.len%info.piece_length;
108 uint8_t remain_len = ((remain > 0)? 1 : 0);
109 sha_len = (info.len/info.piece_length + remain_len)*CEPH_CRYPTO_SHA1_DIGESTSIZE;
110
111 int ret = 0;
112 /* produce torrent data */
113 do_encode();
114
115 /* save torrent data into OMAP */
f67539c2 116 ret = save_torrent_file(y);
31f18b77
FG
117 if (0 != ret)
118 {
b3b6e05e 119 ldpp_dout(s, 0) << "ERROR: failed to save_torrent_file() ret= "<< ret << dendl;
31f18b77
FG
120 return ret;
121 }
122
123 return 0;
7c673cae
FG
124}
125
126off_t seed::get_data_len()
127{
128 return info.len;
129}
130
131void seed::set_create_date(ceph::real_time& value)
132{
133 utime_t date = ceph::real_clock::to_timespec(value);
134 create_date = date.sec();
135}
136
137void seed::set_info_pieces(char *buff)
138{
139 info.sha1_bl.append(buff, CEPH_CRYPTO_SHA1_DIGESTSIZE);
140}
141
142void seed::set_info_name(const string& value)
143{
144 info.name = value;
145}
146
147void seed::sha1(SHA1 *h, bufferlist &bl, off_t bl_len)
148{
149 off_t num = bl_len/info.piece_length;
150 off_t remain = 0;
151 remain = bl_len%info.piece_length;
152
153 char *pstr = bl.c_str();
154 char sha[25];
155
156 /* get sha1 */
157 for (off_t i = 0; i < num; i++)
158 {
92f5a8d4
TL
159 // FIPS zeroization audit 20191116: this memset is not intended to
160 // wipe out a secret after use.
7c673cae 161 memset(sha, 0x00, sizeof(sha));
11fdf7f2
TL
162 h->Update((unsigned char *)pstr, info.piece_length);
163 h->Final((unsigned char *)sha);
7c673cae
FG
164 set_info_pieces(sha);
165 pstr += info.piece_length;
166 }
167
168 /* process remain */
169 if (0 != remain)
170 {
92f5a8d4
TL
171 // FIPS zeroization audit 20191116: this memset is not intended to
172 // wipe out a secret after use.
7c673cae 173 memset(sha, 0x00, sizeof(sha));
11fdf7f2
TL
174 h->Update((unsigned char *)pstr, remain);
175 h->Final((unsigned char *)sha);
7c673cae
FG
176 set_info_pieces(sha);
177 }
92f5a8d4 178 ::ceph::crypto::zeroize_for_security(sha, sizeof(sha));
7c673cae
FG
179}
180
7c673cae
FG
181int seed::get_params()
182{
183 is_torrent = true;
11fdf7f2
TL
184 info.piece_length = g_conf()->rgw_torrent_sha_unit;
185 create_by = g_conf()->rgw_torrent_createby;
186 encoding = g_conf()->rgw_torrent_encoding;
187 origin = g_conf()->rgw_torrent_origin;
188 comment = g_conf()->rgw_torrent_comment;
189 announce = g_conf()->rgw_torrent_tracker;
7c673cae
FG
190
191 /* tracker and tracker list is empty, set announce to origin */
192 if (announce.empty() && !origin.empty())
193 {
194 announce = origin;
195 }
196
197 return 0;
198}
199
200void seed::set_announce()
201{
202 list<string> announce_list; // used to get announce list from conf
203 get_str_list(announce, ",", announce_list);
204
205 if (announce_list.empty())
206 {
b3b6e05e 207 ldpp_dout(s, 5) << "NOTICE: announce_list is empty " << dendl;
7c673cae
FG
208 return;
209 }
210
211 list<string>::iterator iter = announce_list.begin();
212 dencode.bencode_key(ANNOUNCE, bl);
213 dencode.bencode_key((*iter), bl);
214
215 dencode.bencode_key(ANNOUNCE_LIST, bl);
216 dencode.bencode_list(bl);
217 for (; iter != announce_list.end(); ++iter)
218 {
219 dencode.bencode_list(bl);
220 dencode.bencode_key((*iter), bl);
221 dencode.bencode_end(bl);
222 }
223 dencode.bencode_end(bl);
224}
225
226void seed::do_encode()
227{
228 /*Only encode create_date and sha1 info*/
229 /*Other field will be added if confi is set when run get torrent*/
230 dencode.bencode(CREATION_DATE, create_date, bl);
231
232 dencode.bencode_key(INFO_PIECES, bl);
233 dencode.bencode_dict(bl);
234 dencode.bencode(LENGTH, info.len, bl);
235 dencode.bencode(NAME, info.name, bl);
236 dencode.bencode(PIECE_LENGTH, info.piece_length, bl);
237
238 char info_sha[100] = { 0 };
239 sprintf(info_sha, "%" PRIu64, sha_len);
240 string sha_len_str = info_sha;
241 dencode.bencode_key(PIECES, bl);
242 bl.append(sha_len_str.c_str(), sha_len_str.length());
243 bl.append(':');
244 bl.append(info.sha1_bl.c_str(), sha_len);
245 dencode.bencode_end(bl);
246}
247
f67539c2 248int seed::save_torrent_file(optional_yield y)
7c673cae
FG
249{
250 int op_ret = 0;
251 string key = RGW_OBJ_TORRENT;
7c673cae 252
20effc67 253 op_ret = s->object->omap_set_val_by_key(s, key, bl, false, y);
7c673cae
FG
254 if (op_ret < 0)
255 {
b3b6e05e 256 ldpp_dout(s, 0) << "ERROR: failed to omap_set() op_ret = " << op_ret << dendl;
7c673cae
FG
257 return op_ret;
258 }
259
260 return op_ret;
261}