summaryrefslogtreecommitdiffstats
path: root/src/server/protocol.h
diff options
context:
space:
mode:
authorSimon Rettberg2013-08-23 18:44:57 +0200
committerSimon Rettberg2013-08-23 18:44:57 +0200
commit8f020a152a80853780db2998daf797e3ae842606 (patch)
treec48e49e9462b8c9f6421d739fa73c38a14928caf /src/server/protocol.h
parent[CLIENT] Fix daemon-kill command (diff)
downloaddnbd3-8f020a152a80853780db2998daf797e3ae842606.tar.gz
dnbd3-8f020a152a80853780db2998daf797e3ae842606.tar.xz
dnbd3-8f020a152a80853780db2998daf797e3ae842606.zip
[SERVER] WIP: On-the-fly image cloning
Diffstat (limited to 'src/server/protocol.h')
-rw-r--r--src/server/protocol.h102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/server/protocol.h b/src/server/protocol.h
new file mode 100644
index 0000000..96856f8
--- /dev/null
+++ b/src/server/protocol.h
@@ -0,0 +1,102 @@
+#ifndef _PROTOCOL_H_
+#define _PROTOCOL_H_
+
+#include "../types.h"
+#include "../serialize.h"
+
+#define FLAGS8_SERVER 1
+
+static inline int dnbd3_get_reply(int sock, dnbd3_reply_t *reply)
+{
+ if ( recv( sock, reply, sizeof(*reply), MSG_WAITALL ) != sizeof(*reply) ) {
+ return FALSE;
+ }
+ fixup_reply( *reply );
+ if ( reply->magic != dnbd3_packet_magic ) return FALSE;
+ return TRUE;
+}
+
+static inline int dnbd3_select_image(int sock, char *lower_name, uint16_t rid, uint8_t flags8)
+{
+ serialized_buffer_t serialized;
+ dnbd3_request_t request;
+ struct iovec iov[2];
+ serializer_reset_write( &serialized );
+ serializer_put_uint16( &serialized, PROTOCOL_VERSION );
+ serializer_put_string( &serialized, lower_name );
+ serializer_put_uint16( &serialized, rid );
+ serializer_put_uint8( &serialized, flags8 );
+ const ssize_t len = serializer_get_written_length( &serialized );
+ request.magic = dnbd3_packet_magic;
+ request.cmd = CMD_SELECT_IMAGE;
+ request.size = len;
+#ifdef _DEBUG
+ request.handle = 0;
+ request.offset = 0;
+#endif
+ fixup_request( request );
+ iov[0].iov_base = &request;
+ iov[0].iov_len = sizeof(request);
+ iov[1].iov_base = &serialized;
+ iov[1].iov_len = len;
+ return writev( sock, iov, 2 ) == len + sizeof(request);
+}
+
+static inline int dnbd3_get_block(int sock, uint64_t offset, uint32_t size)
+{
+ dnbd3_request_t request;
+ request.magic = dnbd3_packet_magic;
+ request.handle = 0;
+ request.cmd = CMD_GET_BLOCK;
+ request.offset = offset;
+ request.size = size;
+ fixup_request( request );
+ return send( sock, &request, sizeof(request), 0 ) == sizeof(request);
+}
+
+static inline int dnbd3_get_crc32(int sock, uint8_t *buffer, size_t *bufferLen)
+{
+ dnbd3_request_t request;
+ dnbd3_reply_t reply;
+ request.magic = dnbd3_packet_magic;
+ request.handle = 0;
+ request.cmd = CMD_GET_CRC32;
+ request.offset = 0;
+ request.size = 0;
+ fixup_request( request );
+ if ( send( sock, &request, sizeof(request), 0 ) != sizeof(request) ) return FALSE;
+ if ( !dnbd3_get_reply( sock, &reply ) ) return FALSE;
+ if ( reply.cmd != CMD_GET_CRC32 || reply.size > *bufferLen ) return FALSE;
+ *bufferLen = reply.size;
+ if ( reply.size == 0 ) return TRUE;
+ return recv( sock, buffer, reply.size, 0 ) == (int)reply.size;
+}
+
+/**
+ * Pass a full serialized_buffer_t and a socket fd. Parsed data will be returned in further arguments.
+ * Note that all strings will point into the passed buffer, so there's no need to free them.
+ */
+static inline int dnbd3_select_image_reply(serialized_buffer_t *buffer, int sock, uint16_t *protocol_version, char **name, uint16_t *rid,
+ uint64_t *imageSize)
+{
+ dnbd3_reply_t reply;
+ if ( !dnbd3_get_reply( sock, &reply ) ) {
+ return FALSE;
+ }
+ if ( reply.cmd != CMD_SELECT_IMAGE || reply.size < 3 || reply.size > MAX_PAYLOAD ) {
+ return FALSE;
+ }
+// receive reply payload
+ if ( recv( sock, buffer, reply.size, MSG_WAITALL ) != reply.size ) {
+ return FALSE;
+ }
+// handle/check reply payload
+ serializer_reset_read( buffer, reply.size );
+ *protocol_version = serializer_get_uint16( buffer );
+ *name = serializer_get_string( buffer );
+ *rid = serializer_get_uint16( buffer );
+ *imageSize = serializer_get_uint64( buffer );
+ return TRUE;
+}
+
+#endif