4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 #include "byte-swapping.h"
44 #include "nbd-protocol.h"
45 #include "protostrings.h"
48 /* Initial bound of client options we allow before giving up.
49 * However, a client that issues NBD_OPT_LIST is permitted to follow
50 * up with another round of options per export listed.
52 #define MAX_NR_OPTIONS 32
54 /* Receive newstyle options. */
56 send_newstyle_option_reply (uint32_t option
, uint32_t reply
)
59 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
61 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
62 fixed_new_option_reply
.option
= htobe32 (option
);
63 fixed_new_option_reply
.reply
= htobe32 (reply
);
64 fixed_new_option_reply
.replylen
= htobe32 (0);
66 debug ("replying to %s with %s", name_of_nbd_opt (option
),
67 name_of_nbd_rep (reply
));
68 if (conn
->send (&fixed_new_option_reply
,
69 sizeof fixed_new_option_reply
, 0) == -1) {
70 /* The protocol document says that the client is allowed to simply
71 * drop the connection after sending NBD_OPT_ABORT, or may read
74 if (option
== NBD_OPT_ABORT
)
75 debug ("write: %s: %m", name_of_nbd_opt (option
));
77 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
84 /* Reply to NBD_OPT_LIST with the plugin's list of export names.
87 send_newstyle_option_reply_exportnames (uint32_t option
, size_t *nr_options
)
90 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
92 CLEANUP_EXPORTS_FREE
struct nbdkit_exports
*exps
= NULL
;
94 exps
= nbdkit_exports_new ();
96 return send_newstyle_option_reply (option
, NBD_REP_ERR_TOO_BIG
);
97 if (backend_list_exports (top
, read_only
, exps
) == -1)
98 return send_newstyle_option_reply (option
, NBD_REP_ERR_PLATFORM
);
100 /* Allow additional per-export NBD_OPT_INFO and friends. */
101 list_len
= nbdkit_exports_count (exps
);
102 *nr_options
+= MAX_NR_OPTIONS
* list_len
;
104 for (i
= 0; i
< list_len
; i
++) {
105 const struct nbdkit_export export
= nbdkit_get_export (exps
, i
);
106 size_t name_len
= strlen (export
.name
);
107 size_t desc_len
= export
.description
? strlen (export
.description
) : 0;
110 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
111 fixed_new_option_reply
.option
= htobe32 (option
);
112 fixed_new_option_reply
.reply
= htobe32 (NBD_REP_SERVER
);
113 fixed_new_option_reply
.replylen
= htobe32 (name_len
+ sizeof (len
) +
116 if (conn
->send (&fixed_new_option_reply
,
117 sizeof fixed_new_option_reply
, SEND_MORE
) == -1) {
118 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
122 len
= htobe32 (name_len
);
123 if (conn
->send (&len
, sizeof len
, SEND_MORE
) == -1) {
124 nbdkit_error ("write: %s: %s: %m",
125 name_of_nbd_opt (option
), "sending length");
128 if (conn
->send (export
.name
, name_len
, SEND_MORE
) == -1) {
129 nbdkit_error ("write: %s: %s: %m",
130 name_of_nbd_opt (option
), "sending export name");
133 if (conn
->send (export
.description
, desc_len
, 0) == -1) {
134 nbdkit_error ("write: %s: %s: %m",
135 name_of_nbd_opt (option
), "sending export description");
140 return send_newstyle_option_reply (option
, NBD_REP_ACK
);
144 send_newstyle_option_reply_info_export (uint32_t option
, uint32_t reply
,
145 uint16_t info
, uint64_t exportsize
)
148 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
149 struct nbd_fixed_new_option_reply_info_export export
;
151 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
152 fixed_new_option_reply
.option
= htobe32 (option
);
153 fixed_new_option_reply
.reply
= htobe32 (reply
);
154 fixed_new_option_reply
.replylen
= htobe32 (sizeof export
);
155 export
.info
= htobe16 (info
);
156 export
.exportsize
= htobe64 (exportsize
);
157 export
.eflags
= htobe16 (conn
->eflags
);
159 if (conn
->send (&fixed_new_option_reply
,
160 sizeof fixed_new_option_reply
, SEND_MORE
) == -1 ||
161 conn
->send (&export
, sizeof export
, 0) == -1) {
162 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
169 /* Can be used for NBD_INFO_NAME and NBD_INFO_DESCRIPTION. */
171 send_newstyle_option_reply_info_str (uint32_t option
, uint32_t reply
,
172 uint16_t info
, const char *str
,
176 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
177 struct nbd_fixed_new_option_reply_info_name_or_desc name
;
181 assert (len
<= NBD_MAX_STRING
);
183 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
184 fixed_new_option_reply
.option
= htobe32 (option
);
185 fixed_new_option_reply
.reply
= htobe32 (reply
);
186 fixed_new_option_reply
.replylen
= htobe32 (sizeof info
+ len
);
187 name
.info
= htobe16 (info
);
189 if (conn
->send (&fixed_new_option_reply
,
190 sizeof fixed_new_option_reply
, SEND_MORE
) == -1 ||
191 conn
->send (&name
, sizeof name
, SEND_MORE
) == -1 ||
192 conn
->send (str
, len
, 0) == -1) {
193 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
200 /* Send reply containing NBD_INFO_BLOCK_SIZE. */
202 send_newstyle_option_reply_info_block_size (uint32_t option
, uint32_t reply
,
209 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
210 struct nbd_fixed_new_option_reply_info_block_size block_size
;
212 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
213 fixed_new_option_reply
.option
= htobe32 (option
);
214 fixed_new_option_reply
.reply
= htobe32 (reply
);
215 fixed_new_option_reply
.replylen
= htobe32 (14);
216 block_size
.info
= htobe16 (info
);
217 block_size
.minimum
= htobe32 (minimum
);
218 block_size
.preferred
= htobe32 (preferred
);
219 block_size
.maximum
= htobe32 (maximum
);
221 if (conn
->send (&fixed_new_option_reply
,
222 sizeof fixed_new_option_reply
, SEND_MORE
) == -1 ||
223 conn
->send (&block_size
,
224 sizeof block_size
, 0) == -1) {
225 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
233 send_newstyle_option_reply_meta_context (uint32_t option
, uint32_t reply
,
238 struct nbd_fixed_new_option_reply fixed_new_option_reply
;
239 struct nbd_fixed_new_option_reply_meta_context context
;
240 const size_t namelen
= strlen (name
);
242 debug ("newstyle negotiation: %s: replying with %s id %d",
243 name_of_nbd_opt (option
), name
, context_id
);
244 fixed_new_option_reply
.magic
= htobe64 (NBD_REP_MAGIC
);
245 fixed_new_option_reply
.option
= htobe32 (option
);
246 fixed_new_option_reply
.reply
= htobe32 (reply
);
247 fixed_new_option_reply
.replylen
= htobe32 (sizeof context
+ namelen
);
248 context
.context_id
= htobe32 (context_id
);
250 if (conn
->send (&fixed_new_option_reply
,
251 sizeof fixed_new_option_reply
, SEND_MORE
) == -1 ||
252 conn
->send (&context
, sizeof context
, SEND_MORE
) == -1 ||
253 conn
->send (name
, namelen
, 0) == -1) {
254 nbdkit_error ("write: %s: %m", name_of_nbd_opt (option
));
261 /* Sub-function during negotiate_handshake_newstyle, to uniformly handle
262 * a client hanging up on a message boundary.
264 static int ATTRIBUTE_FORMAT_PRINTF (3, 4)
265 conn_recv_full (void *buf
, size_t len
, const char *fmt
, ...)
268 int r
= conn
->recv (buf
, len
);
272 va_start (args
, fmt
);
273 nbdkit_verror (fmt
, args
);
278 /* During negotiation, client EOF on message boundary is less
279 * severe than failure in the middle of the buffer. */
280 debug ("client closed input socket, closing connection");
286 /* Sub-function of negotiate_handshake_newstyle_options below. It
287 * must be called on all non-error paths out of the options for-loop
288 * in that function, and must not cause any wire traffic.
291 finish_newstyle_options (uint64_t *exportsize
,
292 const char *exportname_in
, uint32_t exportnamelen
)
296 /* Since the exportname string passed here comes directly out of the
297 * NBD protocol make a temporary copy of the exportname into a
298 * \0-terminated buffer.
300 CLEANUP_FREE
char *exportname
= strndup (exportname_in
, exportnamelen
);
301 if (exportname
== NULL
) {
302 nbdkit_error ("strndup: %m");
306 /* The NBD spec says that if the client later uses NBD_OPT_GO on a
307 * different export, then the context from the earlier
308 * NBD_OPT_SET_META_CONTEXT is not usable so discard it.
310 if (conn
->exportname_from_set_meta_context
&&
311 strcmp (conn
->exportname_from_set_meta_context
, exportname
) != 0) {
312 debug ("newstyle negotiation: NBD_OPT_SET_META_CONTEXT export name \"%s\" "
313 "≠final client exportname \"%s\", "
314 "so discarding the previous context",
315 conn
->exportname_from_set_meta_context
, exportname
);
316 conn
->meta_context_base_allocation
= false;
319 if (protocol_common_open (exportsize
, &conn
->eflags
, exportname
) == -1)
322 debug ("newstyle negotiation: flags: export 0x%x", conn
->eflags
);
326 /* Check that the string sent as part of @option, beginning at @buf,
327 * and with a client-reported length of @len, fits within @maxlen
328 * bytes and is well-formed. If not, report an error mentioning
332 check_string (uint32_t option
, char *buf
, uint32_t len
, uint32_t maxlen
,
335 if (len
> NBD_MAX_STRING
|| len
> maxlen
) {
336 nbdkit_error ("%s: %s too long", name_of_nbd_opt (option
), name
);
339 if (strnlen (buf
, len
) != len
) {
340 nbdkit_error ("%s: %s may not include NUL bytes",
341 name_of_nbd_opt (option
), name
);
344 /* TODO: Check for valid UTF-8? */
348 /* Sub-function of negotiate_handshake_newstyle_options, to grab and
349 * validate an export name.
352 check_export_name (uint32_t option
, char *buf
,
353 uint32_t exportnamelen
, uint32_t maxlen
)
357 if (check_string (option
, buf
, exportnamelen
, maxlen
, "export name") == -1)
360 debug ("newstyle negotiation: %s: client requested export '%.*s'",
361 name_of_nbd_opt (option
), (int) exportnamelen
, buf
);
366 negotiate_handshake_newstyle_options (void)
369 struct nbd_new_option new_option
;
371 bool list_seen
= false;
375 struct nbd_export_name_option_reply handshake_finish
;
380 for (nr_options
= MAX_NR_OPTIONS
; nr_options
> 0; --nr_options
) {
381 CLEANUP_FREE
char *data
= NULL
;
383 if (conn_recv_full (&new_option
, sizeof new_option
,
384 "reading option: conn->recv: %m") == -1)
387 version
= be64toh (new_option
.version
);
388 if (version
!= NBD_NEW_VERSION
) {
389 nbdkit_error ("unknown option version %" PRIx64
390 ", expecting %" PRIx64
,
391 version
, NBD_NEW_VERSION
);
395 /* There is a maximum option length we will accept, regardless
396 * of the option type.
398 optlen
= be32toh (new_option
.optlen
);
399 if (optlen
> MAX_REQUEST_SIZE
) {
400 nbdkit_error ("client option data too long (%" PRIu32
")", optlen
);
403 data
= malloc (optlen
+ 1); /* Allowing a trailing NUL helps some uses */
405 nbdkit_error ("malloc: %m");
409 option
= be32toh (new_option
.option
);
410 optname
= name_of_nbd_opt (option
);
412 /* If the client lacks fixed newstyle support, it should only send
413 * NBD_OPT_EXPORT_NAME.
415 if (!(conn
->cflags
& NBD_FLAG_FIXED_NEWSTYLE
) &&
416 option
!= NBD_OPT_EXPORT_NAME
) {
417 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
))
422 /* In --tls=require / FORCEDTLS mode the only options allowed
423 * before TLS negotiation are NBD_OPT_ABORT and NBD_OPT_STARTTLS.
425 if (tls
== 2 && !conn
->using_tls
&&
426 !(option
== NBD_OPT_ABORT
|| option
== NBD_OPT_STARTTLS
)) {
427 if (option
== NBD_OPT_EXPORT_NAME
) {
428 debug ("newstyle negotiation: can't reply NBD_REP_ERR_TLS_REQD to %s",
429 name_of_nbd_opt (option
));
432 if (send_newstyle_option_reply (option
, NBD_REP_ERR_TLS_REQD
))
434 if (conn_recv_full (data
, optlen
,
435 "waiting for starttls: %m") == -1)
441 case NBD_OPT_EXPORT_NAME
:
442 if (conn_recv_full (data
, optlen
,
443 "read: %s: %m", name_of_nbd_opt (option
)) == -1)
445 if (check_export_name (option
, data
, optlen
, optlen
) == -1)
448 /* We have to finish the handshake by sending handshake_finish.
449 * On failure, we have to disconnect.
451 if (finish_newstyle_options (&exportsize
, data
, optlen
) == -1)
454 memset (&handshake_finish
, 0, sizeof handshake_finish
);
455 handshake_finish
.exportsize
= htobe64 (exportsize
);
456 handshake_finish
.eflags
= htobe16 (conn
->eflags
);
458 if (conn
->send (&handshake_finish
,
459 (conn
->cflags
& NBD_FLAG_NO_ZEROES
)
460 ? offsetof (struct nbd_export_name_option_reply
, zeroes
)
461 : sizeof handshake_finish
, 0) == -1) {
462 nbdkit_error ("write: %s: %m", optname
);
468 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
470 debug ("client sent %s to abort the connection",
471 name_of_nbd_opt (option
));
476 debug ("ignoring request, client sent unexpected payload: %s",
477 name_of_nbd_opt (option
));
478 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
481 if (conn_recv_full (data
, optlen
,
482 "read: %s: %m", name_of_nbd_opt (option
)) == -1)
488 debug ("newstyle negotiation: %s: export list already advertised",
489 name_of_nbd_opt (option
));
490 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
) == -1)
495 /* Send back the exportname list. */
496 debug ("newstyle negotiation: %s: advertising exports",
497 name_of_nbd_opt (option
));
498 if (send_newstyle_option_reply_exportnames (option
, &nr_options
) == -1)
504 case NBD_OPT_STARTTLS
:
506 debug ("ignoring request, client sent unexpected payload: %s",
507 name_of_nbd_opt (option
));
508 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
511 if (conn_recv_full (data
, optlen
,
512 "read: %s: %m", name_of_nbd_opt (option
)) == -1)
517 if (tls
== 0) { /* --tls=off (NOTLS mode). */
519 #define NO_TLS_REPLY NBD_REP_ERR_POLICY
521 #define NO_TLS_REPLY NBD_REP_ERR_UNSUP
523 if (send_newstyle_option_reply (option
, NO_TLS_REPLY
) == -1)
526 else /* --tls=on or --tls=require */ {
527 /* We can't upgrade to TLS twice on the same connection. */
528 if (conn
->using_tls
) {
529 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
) == -1)
534 /* We have to send the (unencrypted) reply before starting
537 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
540 /* Upgrade the connection to TLS. Also performs access control. */
541 if (crypto_negotiate_tls (conn
->sockin
, conn
->sockout
) == -1)
543 conn
->using_tls
= true;
544 debug ("using TLS on this connection");
545 /* Wipe out any cached state. */
546 conn
->structured_replies
= false;
547 free (conn
->exportname_from_set_meta_context
);
548 conn
->exportname_from_set_meta_context
= NULL
;
549 conn
->meta_context_base_allocation
= false;
550 for_each_backend (b
) {
551 free (conn
->default_exportname
[b
->i
]);
552 conn
->default_exportname
[b
->i
] = NULL
;
559 if (conn_recv_full (data
, optlen
, "read: %s: %m", optname
) == -1)
562 if (optlen
< 6) { /* 32 bit export length + 16 bit nr info */
563 debug ("newstyle negotiation: %s option length < 6", optname
);
565 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
572 uint32_t exportnamelen
;
577 /* Validate the name length and number of INFO requests. */
578 memcpy (&exportnamelen
, &data
[0], 4);
579 exportnamelen
= be32toh (exportnamelen
);
580 if (exportnamelen
> optlen
-6 /* NB optlen >= 6, see above */) {
581 debug ("newstyle negotiation: %s: export name too long", optname
);
582 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
587 memcpy (&nrinfos
, &data
[exportnamelen
+4], 2);
588 nrinfos
= be16toh (nrinfos
);
589 if (optlen
!= 4 + exportnamelen
+ 2 + 2*nrinfos
) {
590 debug ("newstyle negotiation: %s: "
591 "number of information requests incorrect", optname
);
592 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
598 /* As with NBD_OPT_EXPORT_NAME we print the export name and
599 * save it in the connection. If an earlier
600 * NBD_OPT_SET_META_CONTEXT used an export name, it must match
601 * or else we drop the support for that context.
603 if (check_export_name (option
, &data
[4], exportnamelen
,
605 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
611 /* The spec is confusing, but it is required that we send back
612 * NBD_INFO_EXPORT, even if the client did not request it!
613 * qemu client in particular does not request this, but will
614 * fail if we don't send it. Note that if .open fails, but we
615 * succeed at .close, then we merely return an error to the
616 * client and let them try another NBD_OPT, rather than
619 if (finish_newstyle_options (&exportsize
,
620 &data
[4], exportnamelen
) == -1) {
621 if (conn
->top_context
) {
622 if (backend_finalize (conn
->top_context
) == -1)
624 backend_close (conn
->top_context
);
625 conn
->top_context
= NULL
;
627 if (send_newstyle_option_reply (option
, NBD_REP_ERR_UNKNOWN
) == -1)
632 assert (conn
->top_context
);
633 if (send_newstyle_option_reply_info_export (option
,
639 /* For now we send NBD_INFO_NAME, NBD_INFO_DESCRIPTION and
640 * NBD_INFO_BLOCK_SIZE if requested, and ignore all other info
641 * requests (including NBD_INFO_EXPORT if it was requested,
642 * because we replied already above).
644 for (i
= 0; i
< nrinfos
; ++i
) {
645 memcpy (&info
, &data
[4 + exportnamelen
+ 2 + i
*2], 2);
646 info
= be16toh (info
);
648 case NBD_INFO_EXPORT
: /* ignore - reply sent above */ break;
651 const char *name
= &data
[4];
652 size_t namelen
= exportnamelen
;
654 if (exportnamelen
== 0) {
655 name
= backend_default_export (top
, read_only
);
657 debug ("newstyle negotiation: %s: "
658 "NBD_INFO_NAME: no name to send", optname
);
663 if (send_newstyle_option_reply_info_str (option
,
666 name
, namelen
) == -1)
670 case NBD_INFO_DESCRIPTION
:
672 const char *desc
= backend_export_description (conn
->top_context
);
675 debug ("newstyle negotiation: %s: "
676 "NBD_INFO_DESCRIPTION: no description to send",
680 if (send_newstyle_option_reply_info_str (option
,
682 NBD_INFO_DESCRIPTION
,
687 case NBD_INFO_BLOCK_SIZE
:
689 uint32_t minimum
, preferred
, maximum
;
691 if (backend_block_size (conn
->top_context
,
692 &minimum
, &preferred
, &maximum
) == -1)
695 debug ("newstyle negotiation: %s: "
696 "NBD_INFO_BLOCK_SIZE: client requested but "
697 "no plugin or filter provided block size information, "
698 "ignoring client request",
702 if (send_newstyle_option_reply_info_block_size
706 minimum
, preferred
, maximum
) == -1)
711 debug ("newstyle negotiation: %s: "
712 "ignoring NBD_INFO_* request %u (%s)",
713 optname
, (unsigned) info
, name_of_nbd_info (info
));
719 /* Unlike NBD_OPT_EXPORT_NAME, NBD_OPT_GO sends back an ACK
720 * or ERROR packet. If this was NBD_OPT_LIST, call .close.
722 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
725 if (option
== NBD_OPT_INFO
) {
726 if (backend_finalize (conn
->top_context
) == -1)
728 backend_close (conn
->top_context
);
729 conn
->top_context
= NULL
;
734 case NBD_OPT_STRUCTURED_REPLY
:
736 debug ("ignoring request, client sent unexpected payload: %s",
737 name_of_nbd_opt (option
));
738 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
741 if (conn_recv_full (data
, optlen
,
742 "read: %s: %m", name_of_nbd_opt (option
)) == -1)
747 debug ("newstyle negotiation: %s: client requested structured replies",
748 name_of_nbd_opt (option
));
751 /* Must fail with ERR_UNSUP for qemu 4.2 to remain happy;
752 * but failing with ERR_POLICY would have been nicer.
754 if (send_newstyle_option_reply (option
, NBD_REP_ERR_UNSUP
) == -1)
756 debug ("newstyle negotiation: %s: structured replies are disabled",
757 name_of_nbd_opt (option
));
761 if (conn
->structured_replies
) {
762 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
) == -1)
764 debug ("newstyle negotiation: %s: structured replies already in use",
765 name_of_nbd_opt (option
));
769 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
772 conn
->structured_replies
= true;
775 case NBD_OPT_LIST_META_CONTEXT
:
776 case NBD_OPT_SET_META_CONTEXT
:
779 uint32_t exportnamelen
;
784 if (conn_recv_full (data
, optlen
, "read: %s: %m", optname
) == -1)
787 /* Note that we support base:allocation whether or not the plugin
788 * supports can_extents.
790 if (option
== NBD_OPT_SET_META_CONTEXT
&& !conn
->structured_replies
) {
791 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
797 /* Minimum length of the option payload is:
798 * 32 bit export name length followed by empty export name
799 * + 32 bit number of queries followed by no queries
804 opt_meta_invalid_option_len
:
805 debug ("newstyle negotiation: %s: invalid option length: %s",
808 if (send_newstyle_option_reply (option
, NBD_REP_ERR_INVALID
)
814 memcpy (&exportnamelen
, &data
[0], 4);
815 exportnamelen
= be32toh (exportnamelen
);
816 what
= "validating export name";
817 if (check_export_name (option
, &data
[4], exportnamelen
,
819 goto opt_meta_invalid_option_len
;
821 /* Remember the export name: the NBD spec says that if the client
822 * later uses NBD_OPT_GO on a different export, then the context
823 * returned here is not usable.
825 if (option
== NBD_OPT_SET_META_CONTEXT
) {
826 conn
->exportname_from_set_meta_context
=
827 strndup (&data
[4], exportnamelen
);
828 if (conn
->exportname_from_set_meta_context
== NULL
) {
829 nbdkit_error ("malloc: %m");
834 opt_index
= 4 + exportnamelen
;
836 /* Read the number of queries. */
837 what
= "reading number of queries";
838 if (opt_index
+4 > optlen
)
839 goto opt_meta_invalid_option_len
;
840 memcpy (&nr_queries
, &data
[opt_index
], 4);
841 nr_queries
= be32toh (nr_queries
);
844 /* for LIST: nr_queries == 0 means return all meta contexts
845 * for SET: nr_queries == 0 means reset all contexts
847 debug ("newstyle negotiation: %s: %s count: %d", optname
,
848 option
== NBD_OPT_LIST_META_CONTEXT
? "query" : "set",
850 if (option
== NBD_OPT_SET_META_CONTEXT
)
851 conn
->meta_context_base_allocation
= false;
852 if (nr_queries
== 0) {
853 if (option
== NBD_OPT_LIST_META_CONTEXT
) {
854 if (send_newstyle_option_reply_meta_context (option
,
855 NBD_REP_META_CONTEXT
,
856 0, "base:allocation")
861 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
865 /* Read and answer each query. */
866 while (nr_queries
> 0) {
867 what
= "reading query string length";
868 if (opt_index
+4 > optlen
)
869 goto opt_meta_invalid_option_len
;
870 memcpy (&querylen
, &data
[opt_index
], 4);
871 querylen
= be32toh (querylen
);
873 what
= "reading query string";
874 if (check_string (option
, &data
[opt_index
], querylen
,
875 optlen
- opt_index
, "meta context query") == -1)
876 goto opt_meta_invalid_option_len
;
878 debug ("newstyle negotiation: %s: %s %.*s",
880 option
== NBD_OPT_LIST_META_CONTEXT
? "query" : "set",
881 (int) querylen
, &data
[opt_index
]);
883 /* For LIST, "base:" returns all supported contexts in the
884 * base namespace. We only support "base:allocation".
886 if (option
== NBD_OPT_LIST_META_CONTEXT
&&
888 strncmp (&data
[opt_index
], "base:", 5) == 0) {
889 if (send_newstyle_option_reply_meta_context
890 (option
, NBD_REP_META_CONTEXT
,
891 0, "base:allocation") == -1)
894 /* "base:allocation" requested by name. */
895 else if (querylen
== 15 &&
896 strncmp (&data
[opt_index
], "base:allocation", 15) == 0) {
897 if (send_newstyle_option_reply_meta_context
898 (option
, NBD_REP_META_CONTEXT
,
899 option
== NBD_OPT_SET_META_CONTEXT
900 ? base_allocation_id
: 0,
901 "base:allocation") == -1)
903 if (option
== NBD_OPT_SET_META_CONTEXT
)
904 conn
->meta_context_base_allocation
= true;
906 /* Every other query must be ignored. */
908 opt_index
+= querylen
;
911 if (send_newstyle_option_reply (option
, NBD_REP_ACK
) == -1)
914 debug ("newstyle negotiation: %s: reply complete", optname
);
919 /* Unknown option. */
920 if (send_newstyle_option_reply (option
, NBD_REP_ERR_UNSUP
) == -1)
922 if (conn_recv_full (data
, optlen
,
923 "reading unknown option data: conn->recv: %m") == -1)
927 /* Note, since it's not very clear from the protocol doc, that the
928 * client must send NBD_OPT_EXPORT_NAME or NBD_OPT_GO last, and
929 * that ends option negotiation.
931 if (option
== NBD_OPT_EXPORT_NAME
|| option
== NBD_OPT_GO
)
935 if (nr_options
== 0) {
936 nbdkit_error ("client spent too much time negotiating without selecting "
941 /* In --tls=require / FORCEDTLS mode, we must have upgraded to TLS
942 * by the time we finish option negotiation. If not, give up.
944 if (tls
== 2 && !conn
->using_tls
) {
945 nbdkit_error ("non-TLS client tried to connect in --tls=require mode");
953 protocol_handshake_newstyle (void)
956 struct nbd_new_handshake handshake
;
959 gflags
= (NBD_FLAG_FIXED_NEWSTYLE
| NBD_FLAG_NO_ZEROES
) & mask_handshake
;
961 debug ("newstyle negotiation: flags: global 0x%x", gflags
);
963 handshake
.nbdmagic
= htobe64 (NBD_MAGIC
);
964 handshake
.version
= htobe64 (NBD_NEW_VERSION
);
965 handshake
.gflags
= htobe16 (gflags
);
967 if (conn
->send (&handshake
, sizeof handshake
, 0) == -1) {
968 nbdkit_error ("write: %s: %m", "sending newstyle handshake");
972 /* Client now sends us its 32 bit flags word ... */
973 if (conn_recv_full (&conn
->cflags
, sizeof conn
->cflags
,
974 "reading initial client flags: conn->recv: %m") == -1)
976 conn
->cflags
= be32toh (conn
->cflags
);
977 /* ... which we check for accuracy. */
978 debug ("newstyle negotiation: client flags: 0x%x", conn
->cflags
);
979 if (conn
->cflags
& ~gflags
) {
980 nbdkit_error ("client requested unexpected flags 0x%x", conn
->cflags
);
984 /* Receive newstyle options. */
985 if (negotiate_handshake_newstyle_options () == -1)