-
Notifications
You must be signed in to change notification settings - Fork 174
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
feature/server-client-protocol-version-2 #1072
feature/server-client-protocol-version-2 #1072
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
ecal/core/src/service/asio_server.h
Outdated
std::string request_; | ||
std::string response_; | ||
std::vector<char> packed_response_; | ||
|
||
enum { max_length = 64 * 1024 }; | ||
char data_[max_length]; | ||
char data_[max_length]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays]
char data_[max_length];
^
ecal/core/src/service/asio_server.h
Outdated
std::string request_; | ||
std::string response_; | ||
std::vector<char> packed_response_; | ||
|
||
enum { max_length = 64 * 1024 }; | ||
char data_[max_length]; | ||
char data_[max_length]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: use default member initializer for 'data_' [modernize-use-default-member-init]
ecal/core/src/service/asio_server.h:44:
- : socket_(io_service), data_{}
+ : socket_(io_service),
char data_[max_length]; | |
char data_[max_length]{}; |
ecal/core/src/service/asio_server.h
Outdated
@@ -236,7 +357,7 @@ class CAsioServer | |||
delete new_session; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead [cppcoreguidelines-owning-memory]
delete new_session;
^
Additional context
ecal/core/src/service/asio_server.h:338: variable declared here
void handle_accept(CAsioSession* new_session, unsigned int version,
^
return true; | ||
} | ||
|
||
std::vector<char> CTcpClient::PackRequest(const std::string& request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: method 'PackRequest' can be made static [readability-convert-member-functions-to-static]
ecal/core/src/service/ecal_tcpclient.h:106:
- std::vector<char> PackRequest(const std::string &request);
+ static std::vector<char> PackRequest(const std::string &request);
…with protocol v0 and protocol v1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
@@ -43,7 +43,7 @@ namespace eCAL | |||
{ | |||
public: | |||
CMonitoringImpl(); | |||
~CMonitoringImpl(); | |||
~CMonitoringImpl() = default; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: annotate this function with 'override' or (rarely) 'final' [cppcoreguidelines-explicit-virtual-functions]
~CMonitoringImpl() = default; | |
~CMonitoringImpl() override = default; |
ecal/core/src/service/asio_server.h
Outdated
std::string request_; | ||
std::string response_; | ||
std::vector<char> packed_response_; | ||
|
||
enum { max_length = 64 * 1024 }; | ||
char data_[max_length]; | ||
char data_[max_length]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: use default member initializer for 'data_' [modernize-use-default-member-init]
ecal/core/src/service/asio_server.h:45:
- : socket_(io_service), data_{}
+ : socket_(io_service),
char data_[max_length]; | |
char data_[max_length]{}; |
ecal/core/src/service/asio_server.h
Outdated
@@ -236,7 +358,7 @@ class CAsioServer | |||
delete new_session; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead [cppcoreguidelines-owning-memory]
delete new_session;
^
Additional context
ecal/core/src/service/asio_server.h:339: variable declared here
void handle_accept(CAsioSession* new_session, unsigned int version,
^
ecal/core/src/service/asio_server.h
Outdated
{ | ||
request_ += data.substr(bytes_used, bytes_transferred - bytes_used); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider a relatively rare case, suppose pack_1 and pack_2 are sent in rapid succession on the tcpclient side. If pack_1 is internally split for some reason, and then resend part of the internally split packets (tcp automatic retransmission), then the new packet actually contains the second half of pack_1 and the first half of pack_2, the current code implementation does not do anything to the first half of pack_2.
Of course, due to the nodelay socket option enabled on the sender side, this makes it difficult to reproduce the situation, but there is still a low probability of this problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume by pack_1 and pack_2 you mean two separate requests sent by the same client using the same TCP connection. I guess you are right it could happen, but I think only when you start two requests in parallel using two threads. I think if you send two requests from the same thread using the same client it would be processed sequentially. The first client call would block until it received the response from the server.
I think a more likely problem could be that for some reason not all data comes through and the server will wait forever to receive a complete payload. Then a new request might complete the payload receiving and corrupt the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, thank you for your review - GREAT. I will check all in detail later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, I'll try it out in the next few days.
ecal/core/src/service/asio_server.h
Outdated
{ | ||
request_ += data.substr(bytes_used, bytes_transferred - bytes_used); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume by pack_1 and pack_2 you mean two separate requests sent by the same client using the same TCP connection. I guess you are right it could happen, but I think only when you start two requests in parallel using two threads. I think if you send two requests from the same thread using the same client it would be processed sequentially. The first client call would block until it received the response from the server.
I think a more likely problem could be that for some reason not all data comes through and the server will wait forever to receive a complete payload. Then a new request might complete the payload receiving and corrupt the data.
ecal/core/src/service/asio_server.h
Outdated
if (header_.size() == sizeof(eCAL::STcpHeader) && header_request_size_ == 0) | ||
{ | ||
eCAL::STcpHeader tcp_header; | ||
memcpy(&tcp_header, header_.data(), sizeof(eCAL::STcpHeader)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should add a method to decode and check if the header is valid. e.g. version field in the header and maybe a checksum. If it's not valid cancel here and restart. The is a possibility that we can receive a rubbish header resulting in a wrong or very large payload size.
ecal/core/src/service/asio_server.h
Outdated
} | ||
else | ||
{ | ||
if ((ec == asio::error::eof) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I couldn't get working successfully was adding timeouts to asio. As far as I understand this just handles connection loss, but not timeouts. Theoretically the server could hang there forever trying to receive a full payload. CTcpClient::ReceiveResponse has a timeout handler though I haven't tested it.
@@ -241,7 +316,7 @@ namespace eCAL | |||
// read stream header (sync) | |||
else | |||
{ | |||
size_t bytes_read = m_socket->read_some(asio::buffer(&tcp_header, sizeof(tcp_header))); | |||
size_t const bytes_read = m_socket->read_some(asio::buffer(&tcp_header, sizeof(tcp_header))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe same thing here. Validate header and check if psize_n makes sense.
return true; | ||
} | ||
|
||
std::vector<char> CTcpClient::PackRequest(const std::string& request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if PackRequest and PackResponse should live in core/src/service/ecal_tcpheader.h. Maybe one PackHeader() function would be enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
I've been running this branch for the last week on some of our devices and I haven't found any issues so far. I haven't tested the protocol backwards compatibility. |
2 info logs changed to severity level debug2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
ecal/core/src/service/asio_server.h
Outdated
std::string request_; | ||
std::string response_; | ||
std::vector<char> packed_response_; | ||
|
||
enum { max_length = 64 * 1024 }; | ||
char data_[max_length]; | ||
char data_[max_length]{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: do not declare C-style arrays, use std::array<> instead [cppcoreguidelines-avoid-c-arrays]
char data_[max_length]{};
^
ecal/core/src/service/asio_server.h
Outdated
@@ -236,7 +359,7 @@ class CAsioServer | |||
delete new_session; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead [cppcoreguidelines-owning-memory]
delete new_session;
^
Additional context
ecal/core/src/service/asio_server.h:340: variable declared here
void handle_accept(CAsioSession* new_session, unsigned int version,
^
…ature/server-client-protocol-version-2
The new implementation can already communicate with both V1 and V0 protocol clients
… introduces messages for v1 handshake
…eed on fast machines
…ature/server-client-protocol-version-2
…ature/server-client-protocol-version-2
I am finally handing this over to anybody who would like to review the changes 😉 |
…ature/server-client-protocol-version-2
Pull request type
Please check the type of change your PR introduces:
What is the current behavior?
See issue #907 and pull request #918.
Fixes #905
Fixes #907
What is the new behavior?
Different client/server protocol versions introduced based on the work of @floroeske.
Does this introduce a breaking change?
Public API changed /include/ecal/ecal_callback.h.