Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CURA-11103 Fail sending a message that is too big to be parsed #157

Merged
merged 4 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conandata.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version: "5.4.0-alpha.0"
version: "5.4.1"
3 changes: 3 additions & 0 deletions include/Arcus/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ enum class ErrorCode
BindFailedError, ///< Bind to IP and port failed.
AcceptFailedError, ///< Accepting an incoming connection failed.
SendFailedError, ///< Sending a message failed.
MessageTooBigError, ///< Sending a message failed because it was too big.
ReceiveFailedError, ///< Receiving a message failed.
UnknownMessageTypeError, ///< Received a message with an unknown message type.
ParseFailedError, ///< Parsing the received message failed.
Expand All @@ -27,6 +28,8 @@ enum class ErrorCode
InvalidStateError, ///< Socket is in an invalid state.
InvalidMessageError, ///< Message being handled is a nullptr or otherwise invalid.
Debug, // Debug messages

// When changing this list, don't forget to apply the same changes on pyArcus/python/Error.sip
};

/**
Expand Down
2 changes: 1 addition & 1 deletion include/Arcus/Socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Socket
/**
* Send a message across the socket.
*/
virtual void sendMessage(MessagePtr message);
virtual bool sendMessage(MessagePtr message);

/**
* Remove and return the next pending message from the queue with condition blocking.
Expand Down
12 changes: 10 additions & 2 deletions src/Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,21 +203,29 @@ void Socket::close()
delete d->thread;
d->thread = nullptr;
}

// Notify all in case of closing because the waiting threads need to know
// that this socket has been closed and they should not wait any more.
d->message_received_condition_variable.notify_all();
}

void Socket::sendMessage(MessagePtr message)
bool Socket::sendMessage(MessagePtr message)
{
if (! message)
{
d->error(ErrorCode::InvalidMessageError, "Message cannot be nullptr");
return;
return false;
}

if (message->ByteSizeLong() > Private::message_size_maximum)
{
d->error(ErrorCode::MessageTooBigError, "Message is too big to be sent");
return false;
}

std::lock_guard<std::mutex> lock(d->sendQueueMutex);
d->sendQueue.push_back(message);
return true;
}

MessagePtr Socket::takeNextMessage()
Expand Down
16 changes: 9 additions & 7 deletions src/Socket_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
#define VERSION_MINOR 0

#define ARCUS_SIGNATURE 0x2BAD
#define SIG(n) (((n)&0xffff0000) >> 16)
#define SIG(n) (((n) & 0xffff0000) >> 16)

#define SOCKET_CLOSE 0xf0f0f0f0

Expand Down Expand Up @@ -338,33 +338,35 @@ void Socket::Private::run()
// Send a message to the connected socket.
void Socket::Private::sendMessage(const MessagePtr& message)
{
uint32_t header = (ARCUS_SIGNATURE << 16) | (VERSION_MAJOR << 8) | (VERSION_MINOR);
const uint32_t header = (ARCUS_SIGNATURE << 16) | (VERSION_MAJOR << 8) | (VERSION_MINOR);
if (platform_socket.writeUInt32(header) == -1)
{
error(ErrorCode::SendFailedError, "Could not send message header");
return;
}

uint32_t message_size = message->ByteSizeLong();
const uint32_t message_size = message->ByteSizeLong();
if (platform_socket.writeUInt32(message_size) == -1)
{
error(ErrorCode::SendFailedError, "Could not send message size");
return;
}

uint32_t type_id = message_types.getMessageTypeId(message);
const uint32_t type_id = message_types.getMessageTypeId(message);
if (platform_socket.writeUInt32(type_id) == -1)
{
error(ErrorCode::SendFailedError, "Could not send message type");
return;
}

std::string data = message->SerializeAsString();
const std::string data = message->SerializeAsString();
if (platform_socket.writeBytes(data.size(), data.data()) == -1)
{
error(ErrorCode::SendFailedError, "Could not send message data");
return;
}
DEBUG(std::string("Sending message of type ") + std::to_string(type_id) + " and size " + std::to_string(message_size));

DEBUG(std::string("Sent message of type ") + std::to_string(type_id) + " and size " + std::to_string(message_size));
}

// Handle receiving data until we have a proper message.
Expand Down Expand Up @@ -571,4 +573,4 @@ void Socket::Private::checkConnectionState()
}
} // namespace Arcus

#endif // SOCKET_P_H
#endif // SOCKET_P_H
Loading