mirror of
https://github.com/akuker/RASCSI.git
synced 2024-12-21 08:29:59 +00:00
Improved remote connection error handling (#376)
* Improved remote connection error handling * Improved error handling by adding a magic string to each message * Interface comment update * Interface comment update * Improve error messages * Clients send the magic word to authenticate Co-authored-by: Daniel Markstedt <markstedt@gmail.com>
This commit is contained in:
parent
f0a7deb361
commit
cc1783c1cd
@ -235,6 +235,8 @@ def send_over_socket(s, payload):
|
||||
Reads data from socket in 2048 bytes chunks until all data is received.
|
||||
"""
|
||||
|
||||
# Sending the magic word "RASCSI" to authenticate with the server
|
||||
s.send(b"RASCSI")
|
||||
# Prepending a little endian 32bit header with the message size
|
||||
s.send(pack("<i", len(payload)))
|
||||
s.send(payload)
|
||||
@ -250,16 +252,17 @@ def send_over_socket(s, payload):
|
||||
while bytes_recvd < response_length:
|
||||
chunk = s.recv(min(response_length - bytes_recvd, 2048))
|
||||
if chunk == b'':
|
||||
exit("Read an empty chunk from the socket. \
|
||||
Socket connection has dropped unexpectedly. \
|
||||
RaSCSI may have has crashed.")
|
||||
exit("Socket connection has dropped unexpectedly. "
|
||||
"RaSCSI may have crashed."
|
||||
)
|
||||
chunks.append(chunk)
|
||||
bytes_recvd = bytes_recvd + len(chunk)
|
||||
response_message = b''.join(chunks)
|
||||
return response_message
|
||||
else:
|
||||
exit("The response from RaSCSI did not contain a protobuf header. \
|
||||
RaSCSI may have crashed.")
|
||||
exit("The response from RaSCSI did not contain a protobuf header. "
|
||||
"RaSCSI may have crashed."
|
||||
)
|
||||
|
||||
|
||||
def formatted_output():
|
||||
|
@ -70,12 +70,12 @@ void protobuf_util::SerializeMessage(int fd, const google::protobuf::Message& me
|
||||
// Write the size of the protobuf data as a header
|
||||
int32_t size = data.length();
|
||||
if (write(fd, &size, sizeof(size)) != sizeof(size)) {
|
||||
throw io_exception("Can't write protobuf header");
|
||||
throw io_exception("Can't write protobuf message header");
|
||||
}
|
||||
|
||||
// Write the actual protobuf data
|
||||
if (write(fd, data.data(), size) != size) {
|
||||
throw io_exception("Can't write protobuf data");
|
||||
throw io_exception("Can't write protobuf message data");
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,17 +83,20 @@ void protobuf_util::DeserializeMessage(int fd, google::protobuf::Message& messag
|
||||
{
|
||||
// Read the header with the size of the protobuf data
|
||||
uint8_t header_buf[4];
|
||||
int bytes_read = ReadNBytes(fd, header_buf, 4);
|
||||
if (bytes_read < 4) {
|
||||
int bytes_read = ReadNBytes(fd, header_buf, sizeof(header_buf));
|
||||
if (bytes_read < (int)sizeof(header_buf)) {
|
||||
return;
|
||||
}
|
||||
int32_t size = (header_buf[3] << 24) + (header_buf[2] << 16) + (header_buf[1] << 8) + header_buf[0];
|
||||
if (size <= 0) {
|
||||
throw io_exception("Broken protobuf message header");
|
||||
}
|
||||
|
||||
// Read the binary protobuf data
|
||||
uint8_t data_buf[size];
|
||||
bytes_read = ReadNBytes(fd, data_buf, size);
|
||||
if (bytes_read < size) {
|
||||
throw io_exception("Missing protobuf data");
|
||||
throw io_exception("Missing protobuf message data");
|
||||
}
|
||||
|
||||
// Create protobuf message
|
||||
|
@ -1291,6 +1291,16 @@ static void *MonThread(void *param)
|
||||
throw io_exception("accept() failed");
|
||||
}
|
||||
|
||||
// Read magic string
|
||||
char magic[6];
|
||||
int bytes_read = ReadNBytes(fd, (uint8_t *)magic, sizeof(magic));
|
||||
if (!bytes_read) {
|
||||
continue;
|
||||
}
|
||||
if (bytes_read != sizeof(magic) || strncmp(magic, "RASCSI", sizeof(magic))) {
|
||||
throw io_exception("Invalid magic");
|
||||
}
|
||||
|
||||
// Fetch the command
|
||||
PbCommand command;
|
||||
DeserializeMessage(fd, command);
|
||||
|
@ -1,6 +1,6 @@
|
||||
//
|
||||
// Each rascsi remote interface message is preceded by a little endian 32 bit header,
|
||||
// which contains the protobuf message size.
|
||||
// Each rascsi message sent to the rascsi server is preceded by the magic string "RASCSI".
|
||||
// A message starts with a little endian 32 bit header which contains the protobuf message size.
|
||||
// Unless explicitly specified the order of repeated data returned is undefined.
|
||||
//
|
||||
|
||||
|
@ -60,7 +60,11 @@ void RasctlCommands::SendCommand()
|
||||
throw io_exception(error.str());
|
||||
}
|
||||
|
||||
SerializeMessage(fd, command);
|
||||
if (write(fd, "RASCSI", 6) != 6) {
|
||||
throw io_exception("Can't write magic");
|
||||
}
|
||||
|
||||
SerializeMessage(fd, command);
|
||||
}
|
||||
catch(const io_exception& e) {
|
||||
cerr << "Error: " << e.getmsg() << endl;
|
||||
|
@ -409,6 +409,8 @@ def send_over_socket(s, payload):
|
||||
"""
|
||||
from struct import pack, unpack
|
||||
|
||||
# Sending the magic word "RASCSI" to authenticate with the server
|
||||
s.send(b"RASCSI")
|
||||
# Prepending a little endian 32bit header with the message size
|
||||
s.send(pack("<i", len(payload)))
|
||||
s.send(payload)
|
||||
|
Loading…
Reference in New Issue
Block a user