summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client/client.c17
-rw-r--r--src/kernel/blk.c24
-rw-r--r--src/kernel/core.c2
-rw-r--r--src/kernel/net.c24
-rw-r--r--src/serialize.c7
-rw-r--r--src/server/net.c7
-rw-r--r--src/server/server.c1
-rw-r--r--src/types.h2
8 files changed, 62 insertions, 22 deletions
diff --git a/src/client/client.c b/src/client/client.c
index a48cab9..86b7cb9 100644
--- a/src/client/client.c
+++ b/src/client/client.c
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
break;
case 'h':
dnbd3_get_ip(optarg, msg.addr, &msg.addrtype);
- printf("Host set to %s (type %d)\n", optarg, (int)msg.addrtype);
+ printf("Host set to %s (type %d)\n", inet_ntoa(*(struct in_addr*)msg.addr), (int)msg.addrtype);
break;
case 'i':
msg.imgname = strdup(optarg);
@@ -166,9 +166,10 @@ int main(int argc, char *argv[])
fd = open(dev, O_WRONLY);
printf("INFO: Closing device %s\n", dev);
- if (ioctl(fd, IOCTL_CLOSE, &msg) < 0)
+ const int ret = ioctl(fd, IOCTL_OPEN, &msg);
+ if (ret < 0)
{
- printf("ERROR: ioctl not successful (close)\n");
+ printf("ERROR: ioctl not successful (close, errcode: %d)\n", ret);
exit(EXIT_FAILURE);
}
@@ -199,9 +200,10 @@ int main(int argc, char *argv[])
fd = open(dev, O_WRONLY);
printf("INFO: Connecting %s to %s (%s rid:%i)\n", dev, "<fixme>", msg.imgname, msg.rid);
- if (ioctl(fd, IOCTL_OPEN, &msg) < 0)
+ const int ret = ioctl(fd, IOCTL_OPEN, &msg);
+ if (ret < 0)
{
- printf("ERROR: ioctl not successful (connect)\n");
+ printf("ERROR: ioctl not successful (connect, errcode: %d)\n", ret);
exit(EXIT_FAILURE);
}
@@ -235,9 +237,10 @@ int main(int argc, char *argv[])
fd = open(dev, O_WRONLY);
printf("INFO: Connecting %s to %s (%s rid:%i)\n", dev, "<fixme>", msg.imgname, msg.rid);
- if (ioctl(fd, IOCTL_OPEN, &msg) < 0)
+ const int ret = ioctl(fd, IOCTL_OPEN, &msg);
+ if (ret < 0)
{
- printf("ERROR: ioctl not successful (connect)\n");
+ printf("ERROR: ioctl not successful (config file, errcode: %d)\n", ret);
exit(EXIT_FAILURE);
}
diff --git a/src/kernel/blk.c b/src/kernel/blk.c
index 1177f3a..b0b0912 100644
--- a/src/kernel/blk.c
+++ b/src/kernel/blk.c
@@ -123,12 +123,17 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
}
copy_from_user(imgname, msg->imgname, msg->imgnamelen);
imgname[msg->imgnamelen] = '\0';
+ //printk("IOCTL Image name of len %d is %s\n", (int)msg->imgnamelen, imgname);
}
switch (cmd)
{
case IOCTL_OPEN:
- if (imgname == NULL)
+ if (dev->imgname != NULL)
+ {
+ result = -EBUSY;
+ }
+ else if (imgname == NULL)
{
result = -EINVAL;
}
@@ -138,10 +143,18 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
dev->cur_server.port = msg->port;
dev->cur_server.hostaddrtype = msg->addrtype;
dev->imgname = imgname;
- imgname = NULL;
dev->rid = msg->rid;
blk_queue->backing_dev_info.ra_pages = (msg->read_ahead_kb * 1024) / PAGE_CACHE_SIZE;
- result = dnbd3_net_connect(dev);
+ if (dnbd3_net_connect(dev) == 0)
+ {
+ result = 0;
+ imgname = NULL; // Prevent kfree at the end
+ }
+ else
+ {
+ result = -ENOENT;
+ dev->imgname = NULL;
+ }
}
break;
@@ -149,6 +162,11 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u
set_capacity(dev->disk, 0);
result = dnbd3_net_disconnect(dev);
dnbd3_blk_fail_all_requests(dev);
+ if (dev->imgname)
+ {
+ kfree(dev->imgname);
+ dev->imgname = NULL;
+ }
break;
case IOCTL_SWITCH:
diff --git a/src/kernel/core.c b/src/kernel/core.c
index d87bccf..63d71d1 100644
--- a/src/kernel/core.c
+++ b/src/kernel/core.c
@@ -40,6 +40,8 @@ static int __init dnbd3_init(void)
return -EIO;
}
+ printk("DNBD3 kernel module loaded. Machine type: " ENDIAN_MODE "\n");
+
// add MAX_NUMBER_DEVICES devices
for (i = 0; i < max_devs; i++)
{
diff --git a/src/kernel/net.c b/src/kernel/net.c
index 4d33842..41f3e5f 100644
--- a/src/kernel/net.c
+++ b/src/kernel/net.c
@@ -87,7 +87,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev)
sin.sin_family = AF_INET;
memcpy(&(sin.sin_addr.s_addr), dev->cur_server.hostaddr, 4);
sin.sin_port = dev->cur_server.port;
- if (kernel_connect(dev->sock, (struct sockaddr *) &sin, sizeof(sin), 0) < 0)
+ if (kernel_connect(dev->sock, (struct sockaddr *) &sin, sizeof(sin), 0) != 0)
{
printk("ERROR: Couldn't connect to host %pI4 : %d\n", dev->cur_server.hostaddr, (int)ntohs(dev->cur_server.port));
goto error;
@@ -105,14 +105,23 @@ int dnbd3_net_connect(dnbd3_device_t *dev)
serializer_put_uint16(&dev->payload_buffer, dev->rid);
iov[1].iov_base = &dev->payload_buffer;
iov[1].iov_len = serializer_get_written_length(&dev->payload_buffer);
- if (kernel_sendmsg(dev->sock, &msg, iov, 2, sizeof(dnbd3_request) + iov[1].iov_len) <= 0)
+ if (kernel_sendmsg(dev->sock, &msg, iov, 2, sizeof(dnbd3_request) + iov[1].iov_len) != sizeof(dnbd3_request) + iov[1].iov_len)
+ {
+ printk("ERROR: Couldn't send CMD_SIZE_REQUEST to %pI4 : %d\n", dev->cur_server.hostaddr, (int)ntohs(dev->cur_server.port));
goto error;
+ }
// receive reply header
iov[0].iov_base = &dnbd3_reply;
iov[0].iov_len = sizeof(dnbd3_reply);
- if (kernel_recvmsg(dev->sock, &msg, iov, 1, sizeof(dnbd3_reply), msg.msg_flags) != sizeof(dnbd3_reply) || dnbd3_reply.cmd != CMD_GET_SIZE || dnbd3_reply.size < 3 || dnbd3_reply.size > MAX_PAYLOAD || dnbd3_reply.magic != dnbd3_packet_magic)
+ if (kernel_recvmsg(dev->sock, &msg, iov, 1, sizeof(dnbd3_reply), msg.msg_flags) != sizeof(dnbd3_reply))
+ {
+ printk("FATAL: Received corrupted reply header after CMD_SIZE_REQUEST.\n");
+ goto error;
+ }
+ fixup_reply(dnbd3_reply);
+ if (dnbd3_reply.cmd != CMD_GET_SIZE || dnbd3_reply.size < 3 || dnbd3_reply.size > MAX_PAYLOAD || dnbd3_reply.magic != dnbd3_packet_magic)
{
- printk("FATAL: Requested image does not exist on server.\n");
+ printk("FATAL: Received invalid reply to CMD_SIZE_REQUEST, image doesn't exist on server.\n");
goto error;
}
// receive reply payload
@@ -123,6 +132,7 @@ int dnbd3_net_connect(dnbd3_device_t *dev)
printk("FATAL: Cold not read CMD_GET_SIZE payload on handshake.\n");
goto error;
}
+ serializer_reset_read(&dev->payload_buffer, dnbd3_reply.size);
// read reply payload
dev->cur_server.protocol_version = serializer_get_uint16(&dev->payload_buffer);
if (dev->cur_server.protocol_version < MIN_SUPPORTED_SERVER)
@@ -393,7 +403,6 @@ int dnbd3_net_discover(void *data)
// Request filesize
dnbd3_request.cmd = CMD_GET_SIZE;
- dnbd3_request.size = strlen(dev->imgname) + 1 + 2 + 2; // str+\0, version, rid
fixup_request(dnbd3_request);
iov[0].iov_base = &dnbd3_request;
iov[0].iov_len = sizeof(dnbd3_request);
@@ -402,7 +411,7 @@ int dnbd3_net_discover(void *data)
serializer_put_string(payload, dev->imgname);
serializer_put_uint16(payload, dev->rid);
iov[1].iov_base = payload;
- iov[1].iov_len = serializer_get_written_length(payload);
+ dnbd3_request.size = iov[1].iov_len = serializer_get_written_length(payload);
if (kernel_sendmsg(sock, &msg, iov, 2, sizeof(dnbd3_request) + iov[1].iov_len) != sizeof(dnbd3_request) + iov[1].iov_len)
{
printk("ERROR: Requesting image size failed (%pI4 : %d, discover)\n", dev->alt_servers[i].hostaddr, (int)ntohs(dev->alt_servers[i].port));
@@ -481,7 +490,8 @@ int dnbd3_net_discover(void *data)
return 0;
}
- do_gettimeofday(&start); // start rtt measurement
+ // start rtt measurement
+ do_gettimeofday(&start);
// Request block
dnbd3_request.cmd = CMD_GET_BLOCK;
diff --git a/src/serialize.c b/src/serialize.c
index 7961cfe..fa1e878 100644
--- a/src/serialize.c
+++ b/src/serialize.c
@@ -22,7 +22,7 @@ uint16_t serializer_get_uint16(serialized_buffer_t *buffer)
uint16_t ret;
if (buffer->buffer_pointer + 2 > buffer->buffer_end) return 0;
memcpy(&ret, buffer->buffer_pointer, 2);
- *buffer->buffer_pointer += 2;
+ buffer->buffer_pointer += 2;
return net_order_16(ret);
}
@@ -31,13 +31,14 @@ uint64_t serializer_get_uint64(serialized_buffer_t *buffer)
uint64_t ret;
if (buffer->buffer_pointer + 8 > buffer->buffer_end) return 0;
memcpy(&ret, buffer->buffer_pointer, 8);
- *buffer->buffer_pointer += 8;
+ buffer->buffer_pointer += 8;
return net_order_64(ret);
}
char* serializer_get_string(serialized_buffer_t *buffer)
{
char *ptr = buffer->buffer_pointer, *start = buffer->buffer_pointer;
+ if (ptr >= buffer->buffer_end) return NULL;
while (ptr < buffer->buffer_end && *ptr) ++ptr;
if (*ptr) return NULL; // String did not terminate within buffer (possibly corrupted/malicious packet)
buffer->buffer_pointer = ptr + 1;
@@ -62,7 +63,7 @@ void serializer_put_uint64(serialized_buffer_t *buffer, uint64_t value)
void serializer_put_string(serialized_buffer_t *buffer, char *value)
{
- size_t len = strlen(value) + 1;
+ const size_t len = strlen(value) + 1;
if (buffer->buffer_pointer + len > buffer->buffer_end) return;
memcpy(buffer->buffer_pointer, value, len);
buffer->buffer_pointer += len;
diff --git a/src/server/net.c b/src/server/net.c
index 9ae168a..bf680a3 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -42,7 +42,7 @@
static char recv_request_header(int sock, dnbd3_request_t *request)
{
// Read request heade from socket
- if (recv(sock, request, sizeof(dnbd3_request_t), MSG_WAITALL) != sizeof(dnbd3_request_t))
+ if (recv(sock, request, sizeof(*request), MSG_WAITALL) != sizeof(*request))
{
printf("[DEBUG] Error receiving request: Could not read message header\n");
return 0;
@@ -152,6 +152,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
}
else
{
+ printf("Payload len: %d\n", (int)request.size);
if (recv_request_payload(client->sock, request.size, &payload))
{
client_version = serializer_get_uint16(&payload);
@@ -174,7 +175,7 @@ void *dnbd3_handle_query(void *dnbd3_client)
image = dnbd3_get_image(image_name, rid, 0);
if (!image)
{
- printf("[DEBUG] Client requested non-existent image '%s'\n", image_name);
+ printf("[DEBUG] Client requested non-existent image '%s' (rid:%d, protocol:%d)\n", image_name, (int)rid, (int)client_version);
}
else
{
@@ -384,6 +385,8 @@ int dnbd3_setup_socket()
memlogf("ERROR: Socket setup failure\n");
return -1;
}
+ const int opt = 1;
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
memset(&server, 0, sizeof(server));
server.sin_family = AF_INET; // IPv4
diff --git a/src/server/server.c b/src/server/server.c
index 0a206d1..b2a36a5 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -173,6 +173,7 @@ int main(int argc, char* argv[])
pthread_spin_init(&_spinlock, PTHREAD_PROCESS_PRIVATE);
initmemlog();
+ memlogf("DNBD3 server starting.... Machine type: " ENDIAN_MODE);
// load config file
dnbd3_load_config(_config_file_name);
diff --git a/src/types.h b/src/types.h
index 5332dc4..6ba7629 100644
--- a/src/types.h
+++ b/src/types.h
@@ -44,6 +44,7 @@ const uint16_t dnbd3_packet_magic = (0x73 << 8) | (0x72);
(a).cmd = net_order_16((a).cmd); \
(a).size = net_order_32((a).size); \
} while (0)
+#define ENDIAN_MODE "Big Endian"
#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__)
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
@@ -52,6 +53,7 @@ static const uint16_t dnbd3_packet_magic = (0x73) | (0x72 << 8);
#define net_order_16(a) (a)
#define fixup_request(a) while(0)
#define fixup_reply(a) while(0)
+#define ENDIAN_MODE "Little Endian"
#else
#error "Unknown Endianness"
#endif