summaryrefslogtreecommitdiffstats
path: root/src/types.h
diff options
context:
space:
mode:
authorSimon Rettberg2017-10-17 12:08:55 +0200
committerSimon Rettberg2017-10-17 12:08:55 +0200
commit102705470366b871109d2c3bf182c151ab71eb01 (patch)
treeb174c068ab12967491ff78458523c842b04f7b92 /src/types.h
parent[SERVER] rpc: Support querying storage size + available space (diff)
downloaddnbd3-102705470366b871109d2c3bf182c151ab71eb01.tar.gz
dnbd3-102705470366b871109d2c3bf182c151ab71eb01.tar.xz
dnbd3-102705470366b871109d2c3bf182c151ab71eb01.zip
[*] Support hop-counting in request header, protocol version 3
We steal 8 bits from the request offset to count hops when requests get relayed by proxies. This still leaves plenty of bits for the offset (56 bits, supporting images of up to 72 petabytes). This is used to detect proxy cycles. The algorithm is not perfect but should prevent endless relays of the same request. This is backwards compatible to old clients and servers, as the server only ever sets the hopcount in relayed requests if the upstream server is using protocol version 3 or newer, and clients are automatically upwards compatible as there is practically no image larger than 74PB, so the newly introduced hop count field is always 0 even in requests from old clients.
Diffstat (limited to 'src/types.h')
-rw-r--r--src/types.h33
1 files changed, 27 insertions, 6 deletions
diff --git a/src/types.h b/src/types.h
index 63fe3a6..9f9e744 100644
--- a/src/types.h
+++ b/src/types.h
@@ -37,7 +37,7 @@
#ifdef __GNUC__
#define UNUSED __attribute__ ((unused))
#else
-#define UNUSED dfg dsfg dg
+#error "Please add define for your compiler for UNUSED, or define to nothing for your compiler if not supported"
#endif
#ifdef __linux__
@@ -79,6 +79,9 @@ static const uint16_t dnbd3_packet_magic = (0x73 << 8) | (0x72);
(a).size = net_order_32((a).size); \
} while (0)
#define ENDIAN_MODE "Big Endian"
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN
+#endif
#elif defined(__LITTLE_ENDIAN__) || (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || defined(__i386__) || defined(__i386) || defined(__x86_64)
static const uint16_t dnbd3_packet_magic = (0x73) | (0x72 << 8);
// Make little endian our network byte order as probably 99.999% of machines this will be used on are LE
@@ -88,6 +91,9 @@ static const uint16_t dnbd3_packet_magic = (0x73) | (0x72 << 8);
#define fixup_request(a) while(0)
#define fixup_reply(a) while(0)
#define ENDIAN_MODE "Little Endian"
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN
+#endif
#else
#error "Unknown Endianness"
#endif
@@ -124,17 +130,31 @@ typedef struct
#define CMD_SET_CLIENT_MODE 7
#define CMD_GET_CRC32 8
+#define DNBD3_REQUEST_SIZE 24
#pragma pack(1)
typedef struct
{
- uint16_t magic; // 2byte
- uint16_t cmd; // 2byte
- uint32_t size; // 4byte
- uint64_t offset; // 8byte
- uint64_t handle; // 8byte
+ uint16_t magic; // 2byte
+ uint16_t cmd; // 2byte
+ uint32_t size; // 4byte
+ union {
+ struct {
+#ifdef LITTLE_ENDIAN
+ uint64_t offset_small:56; // 7byte
+ uint8_t hops; // 1byte
+#elif defined(BIG_ENDIAN)
+ uint8_t hops; // 1byte
+ uint64_t offset_small:56; // 7byte
+#endif
+ };
+ uint64_t offset; // 8byte
+ };
+ uint64_t handle; // 8byte
} dnbd3_request_t;
#pragma pack(0)
+_Static_assert( sizeof(dnbd3_request_t) == DNBD3_REQUEST_SIZE, "dnbd3_request_t is messed up" );
+#define DNBD3_REPLY_SIZE 16
#pragma pack(1)
typedef struct
{
@@ -144,6 +164,7 @@ typedef struct
uint64_t handle; // 8byte
} dnbd3_reply_t;
#pragma pack(0)
+_Static_assert( sizeof(dnbd3_reply_t) == DNBD3_REPLY_SIZE, "dnbd3_reply_t is messed up" );
#pragma pack(1)
typedef struct