1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Pawel Jakub Dawidek under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h>
|
31__FBSDID("$FreeBSD: head/sbin/hastd/hast_proto.c 209175 2010-06-14 21:01:13Z pjd $");
| 31__FBSDID("$FreeBSD: head/sbin/hastd/hast_proto.c 212033 2010-08-30 22:26:42Z pjd $");
|
32 33#include <sys/endian.h> 34 35#include <assert.h> 36#include <errno.h> 37#include <string.h> 38#include <strings.h> 39 40#ifdef HAVE_CRYPTO 41#include <openssl/sha.h> 42#endif 43 44#include <hast.h> 45#include <ebuf.h> 46#include <nv.h> 47#include <pjdlog.h> 48#include <proto.h> 49 50#include "hast_proto.h" 51 52struct hast_main_header { 53 /* Protocol version. */ 54 uint8_t version; 55 /* Size of nv headers. */ 56 uint32_t size; 57} __packed; 58
| 32 33#include <sys/endian.h> 34 35#include <assert.h> 36#include <errno.h> 37#include <string.h> 38#include <strings.h> 39 40#ifdef HAVE_CRYPTO 41#include <openssl/sha.h> 42#endif 43 44#include <hast.h> 45#include <ebuf.h> 46#include <nv.h> 47#include <pjdlog.h> 48#include <proto.h> 49 50#include "hast_proto.h" 51 52struct hast_main_header { 53 /* Protocol version. */ 54 uint8_t version; 55 /* Size of nv headers. */ 56 uint32_t size; 57} __packed; 58
|
59typedef int hps_send_t(struct hast_resource *, struct nv *nv, void **, size_t *, bool *); 60typedef int hps_recv_t(struct hast_resource *, struct nv *nv, void **, size_t *, bool *);
| 59typedef int hps_send_t(const struct hast_resource *, struct nv *nv, void **, 60 size_t *, bool *); 61typedef int hps_recv_t(const struct hast_resource *, struct nv *nv, void **, 62 size_t *, bool *);
|
61 62struct hast_pipe_stage { 63 const char *hps_name; 64 hps_send_t *hps_send; 65 hps_recv_t *hps_recv; 66}; 67
| 63 64struct hast_pipe_stage { 65 const char *hps_name; 66 hps_send_t *hps_send; 67 hps_recv_t *hps_recv; 68}; 69
|
68static int compression_send(struct hast_resource *res, struct nv *nv,
| 70static int compression_send(const struct hast_resource *res, struct nv *nv,
|
69 void **datap, size_t *sizep, bool *freedatap);
| 71 void **datap, size_t *sizep, bool *freedatap);
|
70static int compression_recv(struct hast_resource *res, struct nv *nv,
| 72static int compression_recv(const struct hast_resource *res, struct nv *nv,
|
71 void **datap, size_t *sizep, bool *freedatap); 72#ifdef HAVE_CRYPTO
| 73 void **datap, size_t *sizep, bool *freedatap); 74#ifdef HAVE_CRYPTO
|
73static int checksum_send(struct hast_resource *res, struct nv *nv,
| 75static int checksum_send(const struct hast_resource *res, struct nv *nv,
|
74 void **datap, size_t *sizep, bool *freedatap);
| 76 void **datap, size_t *sizep, bool *freedatap);
|
75static int checksum_recv(struct hast_resource *res, struct nv *nv,
| 77static int checksum_recv(const struct hast_resource *res, struct nv *nv,
|
76 void **datap, size_t *sizep, bool *freedatap); 77#endif 78 79static struct hast_pipe_stage pipeline[] = { 80 { "compression", compression_send, compression_recv }, 81#ifdef HAVE_CRYPTO 82 { "checksum", checksum_send, checksum_recv } 83#endif 84}; 85 86static int
| 78 void **datap, size_t *sizep, bool *freedatap); 79#endif 80 81static struct hast_pipe_stage pipeline[] = { 82 { "compression", compression_send, compression_recv }, 83#ifdef HAVE_CRYPTO 84 { "checksum", checksum_send, checksum_recv } 85#endif 86}; 87 88static int
|
87compression_send(struct hast_resource *res, struct nv *nv, void **datap,
| 89compression_send(const struct hast_resource *res, struct nv *nv, void **datap,
|
88 size_t *sizep, bool *freedatap) 89{ 90 unsigned char *newbuf; 91 92 res = res; /* TODO */ 93 94 /* 95 * TODO: For now we emulate compression. 96 * At 80% probability we succeed to compress data, which means we 97 * allocate new buffer, copy the data over set *freedatap to true. 98 */ 99 100 if (arc4random_uniform(100) < 80) { 101 uint32_t *origsize; 102 103 /* 104 * Compression succeeded (but we will grow by 4 bytes, not 105 * shrink for now). 106 */ 107 newbuf = malloc(sizeof(uint32_t) + *sizep); 108 if (newbuf == NULL) 109 return (-1); 110 origsize = (void *)newbuf; 111 *origsize = htole32((uint32_t)*sizep); 112 nv_add_string(nv, "null", "compression"); 113 if (nv_error(nv) != 0) { 114 free(newbuf); 115 errno = nv_error(nv); 116 return (-1); 117 } 118 bcopy(*datap, newbuf + sizeof(uint32_t), *sizep); 119 if (*freedatap) 120 free(*datap); 121 *freedatap = true; 122 *datap = newbuf; 123 *sizep = sizeof(uint32_t) + *sizep; 124 } else { 125 /* 126 * Compression failed, so we leave everything as it was. 127 * It is not critical for compression to succeed. 128 */ 129 } 130 131 return (0); 132} 133 134static int
| 90 size_t *sizep, bool *freedatap) 91{ 92 unsigned char *newbuf; 93 94 res = res; /* TODO */ 95 96 /* 97 * TODO: For now we emulate compression. 98 * At 80% probability we succeed to compress data, which means we 99 * allocate new buffer, copy the data over set *freedatap to true. 100 */ 101 102 if (arc4random_uniform(100) < 80) { 103 uint32_t *origsize; 104 105 /* 106 * Compression succeeded (but we will grow by 4 bytes, not 107 * shrink for now). 108 */ 109 newbuf = malloc(sizeof(uint32_t) + *sizep); 110 if (newbuf == NULL) 111 return (-1); 112 origsize = (void *)newbuf; 113 *origsize = htole32((uint32_t)*sizep); 114 nv_add_string(nv, "null", "compression"); 115 if (nv_error(nv) != 0) { 116 free(newbuf); 117 errno = nv_error(nv); 118 return (-1); 119 } 120 bcopy(*datap, newbuf + sizeof(uint32_t), *sizep); 121 if (*freedatap) 122 free(*datap); 123 *freedatap = true; 124 *datap = newbuf; 125 *sizep = sizeof(uint32_t) + *sizep; 126 } else { 127 /* 128 * Compression failed, so we leave everything as it was. 129 * It is not critical for compression to succeed. 130 */ 131 } 132 133 return (0); 134} 135 136static int
|
135compression_recv(struct hast_resource *res, struct nv *nv, void **datap,
| 137compression_recv(const struct hast_resource *res, struct nv *nv, void **datap,
|
136 size_t *sizep, bool *freedatap) 137{ 138 unsigned char *newbuf; 139 const char *algo; 140 size_t origsize; 141 142 res = res; /* TODO */ 143 144 /* 145 * TODO: For now we emulate compression. 146 */ 147 148 algo = nv_get_string(nv, "compression"); 149 if (algo == NULL) 150 return (0); /* No compression. */ 151 if (strcmp(algo, "null") != 0) { 152 pjdlog_error("Unknown compression algorithm '%s'.", algo); 153 return (-1); /* Unknown compression algorithm. */ 154 } 155 156 origsize = le32toh(*(uint32_t *)*datap); 157 newbuf = malloc(origsize); 158 if (newbuf == NULL) 159 return (-1); 160 bcopy((unsigned char *)*datap + sizeof(uint32_t), newbuf, origsize); 161 if (*freedatap) 162 free(*datap); 163 *freedatap = true; 164 *datap = newbuf; 165 *sizep = origsize; 166 167 return (0); 168} 169 170#ifdef HAVE_CRYPTO 171static int
| 138 size_t *sizep, bool *freedatap) 139{ 140 unsigned char *newbuf; 141 const char *algo; 142 size_t origsize; 143 144 res = res; /* TODO */ 145 146 /* 147 * TODO: For now we emulate compression. 148 */ 149 150 algo = nv_get_string(nv, "compression"); 151 if (algo == NULL) 152 return (0); /* No compression. */ 153 if (strcmp(algo, "null") != 0) { 154 pjdlog_error("Unknown compression algorithm '%s'.", algo); 155 return (-1); /* Unknown compression algorithm. */ 156 } 157 158 origsize = le32toh(*(uint32_t *)*datap); 159 newbuf = malloc(origsize); 160 if (newbuf == NULL) 161 return (-1); 162 bcopy((unsigned char *)*datap + sizeof(uint32_t), newbuf, origsize); 163 if (*freedatap) 164 free(*datap); 165 *freedatap = true; 166 *datap = newbuf; 167 *sizep = origsize; 168 169 return (0); 170} 171 172#ifdef HAVE_CRYPTO 173static int
|
172checksum_send(struct hast_resource *res, struct nv *nv, void **datap,
| 174checksum_send(const struct hast_resource *res, struct nv *nv, void **datap,
|
173 size_t *sizep, bool *freedatap __unused) 174{ 175 unsigned char hash[SHA256_DIGEST_LENGTH]; 176 SHA256_CTX ctx; 177 178 res = res; /* TODO */ 179 180 SHA256_Init(&ctx); 181 SHA256_Update(&ctx, *datap, *sizep); 182 SHA256_Final(hash, &ctx); 183 184 nv_add_string(nv, "sha256", "checksum"); 185 nv_add_uint8_array(nv, hash, sizeof(hash), "hash"); 186 187 return (0); 188} 189 190static int
| 175 size_t *sizep, bool *freedatap __unused) 176{ 177 unsigned char hash[SHA256_DIGEST_LENGTH]; 178 SHA256_CTX ctx; 179 180 res = res; /* TODO */ 181 182 SHA256_Init(&ctx); 183 SHA256_Update(&ctx, *datap, *sizep); 184 SHA256_Final(hash, &ctx); 185 186 nv_add_string(nv, "sha256", "checksum"); 187 nv_add_uint8_array(nv, hash, sizeof(hash), "hash"); 188 189 return (0); 190} 191 192static int
|
191checksum_recv(struct hast_resource *res, struct nv *nv, void **datap,
| 193checksum_recv(const struct hast_resource *res, struct nv *nv, void **datap,
|
192 size_t *sizep, bool *freedatap __unused) 193{ 194 unsigned char chash[SHA256_DIGEST_LENGTH]; 195 const unsigned char *rhash; 196 SHA256_CTX ctx; 197 const char *algo; 198 size_t size; 199 200 res = res; /* TODO */ 201 202 algo = nv_get_string(nv, "checksum"); 203 if (algo == NULL) 204 return (0); /* No checksum. */ 205 if (strcmp(algo, "sha256") != 0) { 206 pjdlog_error("Unknown checksum algorithm '%s'.", algo); 207 return (-1); /* Unknown checksum algorithm. */ 208 } 209 rhash = nv_get_uint8_array(nv, &size, "hash"); 210 if (rhash == NULL) { 211 pjdlog_error("Checksum algorithm is present, but hash is missing."); 212 return (-1); /* Hash not found. */ 213 } 214 if (size != sizeof(chash)) { 215 pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", 216 size, algo, sizeof(chash)); 217 return (-1); /* Different hash size. */ 218 } 219 220 SHA256_Init(&ctx); 221 SHA256_Update(&ctx, *datap, *sizep); 222 SHA256_Final(chash, &ctx); 223 224 if (bcmp(rhash, chash, sizeof(chash)) != 0) { 225 pjdlog_error("Hash mismatch."); 226 return (-1); /* Hash mismatch. */ 227 } 228 229 return (0); 230} 231#endif /* HAVE_CRYPTO */ 232 233/* 234 * Send the given nv structure via conn. 235 * We keep headers in nv structure and pass data in separate argument. 236 * There can be no data at all (data is NULL then). 237 */ 238int
| 194 size_t *sizep, bool *freedatap __unused) 195{ 196 unsigned char chash[SHA256_DIGEST_LENGTH]; 197 const unsigned char *rhash; 198 SHA256_CTX ctx; 199 const char *algo; 200 size_t size; 201 202 res = res; /* TODO */ 203 204 algo = nv_get_string(nv, "checksum"); 205 if (algo == NULL) 206 return (0); /* No checksum. */ 207 if (strcmp(algo, "sha256") != 0) { 208 pjdlog_error("Unknown checksum algorithm '%s'.", algo); 209 return (-1); /* Unknown checksum algorithm. */ 210 } 211 rhash = nv_get_uint8_array(nv, &size, "hash"); 212 if (rhash == NULL) { 213 pjdlog_error("Checksum algorithm is present, but hash is missing."); 214 return (-1); /* Hash not found. */ 215 } 216 if (size != sizeof(chash)) { 217 pjdlog_error("Invalid hash size (%zu) for %s, should be %zu.", 218 size, algo, sizeof(chash)); 219 return (-1); /* Different hash size. */ 220 } 221 222 SHA256_Init(&ctx); 223 SHA256_Update(&ctx, *datap, *sizep); 224 SHA256_Final(chash, &ctx); 225 226 if (bcmp(rhash, chash, sizeof(chash)) != 0) { 227 pjdlog_error("Hash mismatch."); 228 return (-1); /* Hash mismatch. */ 229 } 230 231 return (0); 232} 233#endif /* HAVE_CRYPTO */ 234 235/* 236 * Send the given nv structure via conn. 237 * We keep headers in nv structure and pass data in separate argument. 238 * There can be no data at all (data is NULL then). 239 */ 240int
|
239hast_proto_send(struct hast_resource *res, struct proto_conn *conn,
| 241hast_proto_send(const struct hast_resource *res, struct proto_conn *conn,
|
240 struct nv *nv, const void *data, size_t size) 241{ 242 struct hast_main_header hdr; 243 struct ebuf *eb; 244 bool freedata; 245 void *dptr, *hptr; 246 size_t hsize; 247 int ret; 248 249 dptr = (void *)(uintptr_t)data; 250 freedata = false; 251 ret = -1; 252 253 if (data != NULL) { 254if (false) { 255 unsigned int ii; 256 257 for (ii = 0; ii < sizeof(pipeline) / sizeof(pipeline[0]); 258 ii++) { 259 ret = pipeline[ii].hps_send(res, nv, &dptr, &size, 260 &freedata); 261 if (ret == -1) 262 goto end; 263 } 264 ret = -1; 265} 266 nv_add_uint32(nv, size, "size"); 267 if (nv_error(nv) != 0) { 268 errno = nv_error(nv); 269 goto end; 270 } 271 } 272 273 eb = nv_hton(nv); 274 if (eb == NULL) 275 goto end; 276 277 hdr.version = HAST_PROTO_VERSION; 278 hdr.size = htole32((uint32_t)ebuf_size(eb)); 279 if (ebuf_add_head(eb, &hdr, sizeof(hdr)) < 0) 280 goto end; 281 282 hptr = ebuf_data(eb, &hsize); 283 if (proto_send(conn, hptr, hsize) < 0) 284 goto end; 285 if (data != NULL && proto_send(conn, dptr, size) < 0) 286 goto end; 287 288 ret = 0; 289end: 290 if (freedata) 291 free(dptr); 292 return (ret); 293} 294 295int
| 242 struct nv *nv, const void *data, size_t size) 243{ 244 struct hast_main_header hdr; 245 struct ebuf *eb; 246 bool freedata; 247 void *dptr, *hptr; 248 size_t hsize; 249 int ret; 250 251 dptr = (void *)(uintptr_t)data; 252 freedata = false; 253 ret = -1; 254 255 if (data != NULL) { 256if (false) { 257 unsigned int ii; 258 259 for (ii = 0; ii < sizeof(pipeline) / sizeof(pipeline[0]); 260 ii++) { 261 ret = pipeline[ii].hps_send(res, nv, &dptr, &size, 262 &freedata); 263 if (ret == -1) 264 goto end; 265 } 266 ret = -1; 267} 268 nv_add_uint32(nv, size, "size"); 269 if (nv_error(nv) != 0) { 270 errno = nv_error(nv); 271 goto end; 272 } 273 } 274 275 eb = nv_hton(nv); 276 if (eb == NULL) 277 goto end; 278 279 hdr.version = HAST_PROTO_VERSION; 280 hdr.size = htole32((uint32_t)ebuf_size(eb)); 281 if (ebuf_add_head(eb, &hdr, sizeof(hdr)) < 0) 282 goto end; 283 284 hptr = ebuf_data(eb, &hsize); 285 if (proto_send(conn, hptr, hsize) < 0) 286 goto end; 287 if (data != NULL && proto_send(conn, dptr, size) < 0) 288 goto end; 289 290 ret = 0; 291end: 292 if (freedata) 293 free(dptr); 294 return (ret); 295} 296 297int
|
296hast_proto_recv_hdr(struct proto_conn *conn, struct nv **nvp)
| 298hast_proto_recv_hdr(const struct proto_conn *conn, struct nv **nvp)
|
297{ 298 struct hast_main_header hdr; 299 struct nv *nv; 300 struct ebuf *eb; 301 void *hptr; 302 303 eb = NULL; 304 nv = NULL; 305 306 if (proto_recv(conn, &hdr, sizeof(hdr)) < 0) 307 goto fail; 308 309 if (hdr.version != HAST_PROTO_VERSION) { 310 errno = ERPCMISMATCH; 311 goto fail; 312 } 313 314 hdr.size = le32toh(hdr.size); 315 316 eb = ebuf_alloc(hdr.size); 317 if (eb == NULL) 318 goto fail; 319 if (ebuf_add_tail(eb, NULL, hdr.size) < 0) 320 goto fail; 321 hptr = ebuf_data(eb, NULL); 322 assert(hptr != NULL); 323 if (proto_recv(conn, hptr, hdr.size) < 0) 324 goto fail; 325 nv = nv_ntoh(eb); 326 if (nv == NULL) 327 goto fail; 328 329 *nvp = nv; 330 return (0); 331fail: 332 if (eb != NULL) 333 ebuf_free(eb); 334 return (-1); 335} 336 337int
| 299{ 300 struct hast_main_header hdr; 301 struct nv *nv; 302 struct ebuf *eb; 303 void *hptr; 304 305 eb = NULL; 306 nv = NULL; 307 308 if (proto_recv(conn, &hdr, sizeof(hdr)) < 0) 309 goto fail; 310 311 if (hdr.version != HAST_PROTO_VERSION) { 312 errno = ERPCMISMATCH; 313 goto fail; 314 } 315 316 hdr.size = le32toh(hdr.size); 317 318 eb = ebuf_alloc(hdr.size); 319 if (eb == NULL) 320 goto fail; 321 if (ebuf_add_tail(eb, NULL, hdr.size) < 0) 322 goto fail; 323 hptr = ebuf_data(eb, NULL); 324 assert(hptr != NULL); 325 if (proto_recv(conn, hptr, hdr.size) < 0) 326 goto fail; 327 nv = nv_ntoh(eb); 328 if (nv == NULL) 329 goto fail; 330 331 *nvp = nv; 332 return (0); 333fail: 334 if (eb != NULL) 335 ebuf_free(eb); 336 return (-1); 337} 338 339int
|
338hast_proto_recv_data(struct hast_resource *res, struct proto_conn *conn,
| 340hast_proto_recv_data(const struct hast_resource *res, struct proto_conn *conn,
|
339 struct nv *nv, void *data, size_t size) 340{ 341 unsigned int ii; 342 bool freedata; 343 size_t dsize; 344 void *dptr; 345 int ret; 346 347 assert(data != NULL); 348 assert(size > 0); 349 350 ret = -1; 351 freedata = false; 352 dptr = data; 353 354 dsize = nv_get_uint32(nv, "size"); 355 if (dsize == 0) 356 (void)nv_set_error(nv, 0); 357 else { 358 if (proto_recv(conn, data, dsize) < 0) 359 goto end; 360if (false) { 361 for (ii = sizeof(pipeline) / sizeof(pipeline[0]); ii > 0; 362 ii--) { 363 assert(!"to be verified"); 364 ret = pipeline[ii - 1].hps_recv(res, nv, &dptr, 365 &dsize, &freedata); 366 if (ret == -1) 367 goto end; 368 } 369 ret = -1; 370 if (dsize < size) 371 goto end; 372 /* TODO: 'size' doesn't seem right here. It is maximum data size. */ 373 if (dptr != data) 374 bcopy(dptr, data, dsize); 375} 376 } 377 378 ret = 0; 379end: 380if (ret < 0) printf("%s:%u %s\n", __func__, __LINE__, strerror(errno)); 381 if (freedata) 382 free(dptr); 383 return (ret); 384} 385 386int
| 341 struct nv *nv, void *data, size_t size) 342{ 343 unsigned int ii; 344 bool freedata; 345 size_t dsize; 346 void *dptr; 347 int ret; 348 349 assert(data != NULL); 350 assert(size > 0); 351 352 ret = -1; 353 freedata = false; 354 dptr = data; 355 356 dsize = nv_get_uint32(nv, "size"); 357 if (dsize == 0) 358 (void)nv_set_error(nv, 0); 359 else { 360 if (proto_recv(conn, data, dsize) < 0) 361 goto end; 362if (false) { 363 for (ii = sizeof(pipeline) / sizeof(pipeline[0]); ii > 0; 364 ii--) { 365 assert(!"to be verified"); 366 ret = pipeline[ii - 1].hps_recv(res, nv, &dptr, 367 &dsize, &freedata); 368 if (ret == -1) 369 goto end; 370 } 371 ret = -1; 372 if (dsize < size) 373 goto end; 374 /* TODO: 'size' doesn't seem right here. It is maximum data size. */ 375 if (dptr != data) 376 bcopy(dptr, data, dsize); 377} 378 } 379 380 ret = 0; 381end: 382if (ret < 0) printf("%s:%u %s\n", __func__, __LINE__, strerror(errno)); 383 if (freedata) 384 free(dptr); 385 return (ret); 386} 387 388int
|
387hast_proto_recv(struct hast_resource *res, struct proto_conn *conn,
| 389hast_proto_recv(const struct hast_resource *res, struct proto_conn *conn,
|
388 struct nv **nvp, void *data, size_t size) 389{ 390 struct nv *nv; 391 size_t dsize; 392 int ret; 393 394 ret = hast_proto_recv_hdr(conn, &nv); 395 if (ret < 0) 396 return (ret); 397 dsize = nv_get_uint32(nv, "size"); 398 if (dsize == 0) 399 (void)nv_set_error(nv, 0); 400 else 401 ret = hast_proto_recv_data(res, conn, nv, data, size); 402 if (ret < 0) 403 nv_free(nv); 404 else 405 *nvp = nv; 406 return (ret); 407}
| 390 struct nv **nvp, void *data, size_t size) 391{ 392 struct nv *nv; 393 size_t dsize; 394 int ret; 395 396 ret = hast_proto_recv_hdr(conn, &nv); 397 if (ret < 0) 398 return (ret); 399 dsize = nv_get_uint32(nv, "size"); 400 if (dsize == 0) 401 (void)nv_set_error(nv, 0); 402 else 403 ret = hast_proto_recv_data(res, conn, nv, data, size); 404 if (ret < 0) 405 nv_free(nv); 406 else 407 *nvp = nv; 408 return (ret); 409}
|