diff options
author | Dennis Shen <dzshen@google.com> | 2024-05-02 13:57:58 +0000 |
---|---|---|
committer | Dennis Shen <dzshen@google.com> | 2024-05-02 18:37:19 +0000 |
commit | 6a2bb3762452fa3c01dd7307c204d3b546bcb0b5 (patch) | |
tree | 2716032c24c5df94652aeb56a0ca77c7357d85cc | |
parent | 8665ba7cf26a201243957449bad9e4d9cd37b015 (diff) | |
download | server_configurable_flags-main.tar.gz |
Before this cl, the bytes sent over this socket is just (proto), now it
will be (proto byte size | proto). So both sender and reciever can
allocate proper buffer without using a fixed size buffer.
Bug: b/312444587
Test: atest aconfigd_test
Flag: enable_aconfig_new_storage
Change-Id: I3737f9ecfaf684610a1c4307ae7b6f0ce1f515bc
-rw-r--r-- | aconfigd/Android.bp | 21 | ||||
-rw-r--r-- | aconfigd/aconfigd.cpp | 6 | ||||
-rw-r--r-- | aconfigd/aconfigd.h | 3 | ||||
-rw-r--r-- | aconfigd/aconfigd.proto | 1 | ||||
-rw-r--r-- | aconfigd/aconfigd_main.cpp | 107 | ||||
-rw-r--r-- | aconfigd/aconfigd_test.cpp | 33 |
6 files changed, 129 insertions, 42 deletions
diff --git a/aconfigd/Android.bp b/aconfigd/Android.bp index c00c099..aa26738 100644 --- a/aconfigd/Android.bp +++ b/aconfigd/Android.bp @@ -35,6 +35,27 @@ cc_aconfig_library { aconfig_declarations: "aconfig_new_storage_flags", } +java_aconfig_library { + name: "aconfig_new_storage_flags_lib", + aconfig_declarations: "aconfig_new_storage_flags", +} + +java_library { + name: "aconfigd_java_proto_lib", + host_supported: true, + srcs: ["aconfigd.proto"], + static_libs: ["libprotobuf-java-lite"], + proto: { + type: "lite", + }, + sdk_version: "current", + min_sdk_version: "UpsideDownCake", + apex_available: [ + "//apex_available:anyapex", + "//apex_available:platform", + ] +} + cc_test { name: "aconfigd_test", srcs: [ diff --git a/aconfigd/aconfigd.cpp b/aconfigd/aconfigd.cpp index c1e5354..2fdbf9f 100644 --- a/aconfigd/aconfigd.cpp +++ b/aconfigd/aconfigd.cpp @@ -535,6 +535,12 @@ void HandleSocketRequest(const StorageRequestMessage& message, *errmsg = "Unknown message type from aconfigd socket"; break; } + + if (return_message.has_error_message()) { + LOG(ERROR) << "Failed to handle socket request: " << return_message.error_message(); + } else { + LOG(INFO) << "Successfully handled socket request"; + } } } // namespace aconfigd diff --git a/aconfigd/aconfigd.h b/aconfigd/aconfigd.h index 3020e28..d4be7e2 100644 --- a/aconfigd/aconfigd.h +++ b/aconfigd/aconfigd.h @@ -26,9 +26,6 @@ namespace android { /// Aconfigd socket name static constexpr char kAconfigdSocket[] = "aconfigd"; - /// Socket message buffer size - static constexpr size_t kBufferSize = 4096; - /// Persistent storage records pb file full path static constexpr char kPersistentStorageRecordsFileName[] = "/metadata/aconfig/persistent_storage_file_records.pb"; diff --git a/aconfigd/aconfigd.proto b/aconfigd/aconfigd.proto index c49c30e..7519d1f 100644 --- a/aconfigd/aconfigd.proto +++ b/aconfigd/aconfigd.proto @@ -15,6 +15,7 @@ */ syntax = "proto2"; +package android.aconfigd; option optimize_for = LITE_RUNTIME; // incoming request to aconfigd diff --git a/aconfigd/aconfigd_main.cpp b/aconfigd/aconfigd_main.cpp index e9109cc..526eeb9 100644 --- a/aconfigd/aconfigd_main.cpp +++ b/aconfigd/aconfigd_main.cpp @@ -24,6 +24,7 @@ #include "aconfigd_util.h" using namespace android::aconfigd; +using namespace android::base; static int aconfigd_init() { auto init_result = InitializeInMemoryStorageRecords(); @@ -57,6 +58,70 @@ static int aconfigd_init() { return 0; } +/// receive storage requests from socket +static Result<StorageRequestMessages> receiveMessage(int client_fd) { + unsigned char size_buffer[4] = {}; + auto num_bytes = TEMP_FAILURE_RETRY( + recv(client_fd, size_buffer, 4, 0)); + if (num_bytes < 0) { + return ErrnoError() << "failed to read number of bytes from aconfigd socket"; + } else if (num_bytes != 4) { + return Error() << "expecting 4 bytes from aconfigd socket, received " << num_bytes; + } + uint32_t payload_size = uint32_t( + size_buffer[0]<<24 | size_buffer[1]<<16 | size_buffer[2]<<8 | size_buffer[3]); + + char payload_buffer[payload_size]; + num_bytes = TEMP_FAILURE_RETRY( + recv(client_fd, payload_buffer, payload_size, 0)); + if (num_bytes < 0) { + return ErrnoError() << "failed to read payload from aconfigd socket"; + } else if (num_bytes != payload_size) { + return Error() << "expecting " << payload_size + << " bytes of payload from aconfigd socket, received " << num_bytes; + } + auto msg = std::string(payload_buffer, num_bytes); + + auto requests = StorageRequestMessages{}; + if (!requests.ParseFromString(msg)) { + return Error() << "Could not parse message from aconfig storage init socket"; + } + return requests; +} + +/// send return acknowledgement +static Result<void> sendMessage(int client_fd, const StorageReturnMessages& msg) { + auto content = std::string(); + if (!msg.SerializeToString(&content)) { + return Error() << "failed to serialize return messages to string"; + } + + unsigned char bytes[4]; + uint32_t msg_size = content.size(); + bytes[0] = (msg_size >> 24) & 0xFF; + bytes[1] = (msg_size >> 16) & 0xFF; + bytes[2] = (msg_size >> 8) & 0xFF; + bytes[3] = (msg_size >> 0) & 0xFF; + + auto num_bytes = TEMP_FAILURE_RETRY(send(client_fd, bytes, 4, 0)); + if (num_bytes < 0) { + return ErrnoError() << "send() failed for return msg size"; + } else if (num_bytes != 4) { + return Error() << "send() failed for return msg size, sent " << num_bytes + << " bytes expect 4 bytes"; + } + + num_bytes = TEMP_FAILURE_RETRY(send(client_fd, content.c_str(), content.size(), 0)); + if (num_bytes < 0) { + return ErrnoError() << "send() failed for return msg"; + } else if (num_bytes != content.size()) { + return Error() << "send() failed for return msg, sent " << num_bytes + << " bytes expect " << content.size() << " bytes"; + } + + return {}; +} + static int aconfigd_start() { auto init_result = InitializeInMemoryStorageRecords(); if (!init_result.ok()) { @@ -88,51 +153,29 @@ static int aconfigd_start() { aconfigd_fd, reinterpret_cast<sockaddr*>(&addr), &addr_len, SOCK_CLOEXEC)); if (client_fd == -1) { PLOG(ERROR) << "failed to establish connection"; - break; - } - LOG(INFO) << "received a client requests"; - - char buffer[kBufferSize] = {}; - auto num_bytes = TEMP_FAILURE_RETRY(recv(client_fd, buffer, sizeof(buffer), 0)); - if (num_bytes < 0) { - PLOG(ERROR) << "failed to read from aconfigd socket"; - break; - } else if (num_bytes == 0) { - LOG(ERROR) << "failed to read from aconfigd socket, empty message"; - break; + continue; } - auto msg = std::string(buffer, num_bytes); + LOG(INFO) << "received client requests"; - auto messages = StorageRequestMessages{}; - if (!messages.ParseFromString(msg)) { - LOG(ERROR) << "Could not parse message from aconfig storage init socket"; + auto requests = receiveMessage(client_fd.get()); + if (!requests.ok()) { + LOG(ERROR) << requests.error(); continue; } auto return_messages = StorageReturnMessages(); - for (auto& msg : messages.msgs()) { + for (auto& request : requests->msgs()) { auto* return_msg = return_messages.add_msgs(); - HandleSocketRequest(msg, *return_msg); - if (!return_msg->has_error_message()) { - LOG(ERROR) << "failed to handle socket request: " << return_msg->error_message(); - } + HandleSocketRequest(request, *return_msg); } - auto return_content = std::string(); - if (!return_messages.SerializeToString(&return_content)) { - LOG(ERROR) << "failed to serialize return messages to string"; - continue; - } - - auto num = TEMP_FAILURE_RETRY( - send(client_fd, return_content.c_str(), return_content.size(), 0)); - if (num != static_cast<long>(return_content.size())) { - PLOG(ERROR) << "failed to send return message"; + auto result = sendMessage(client_fd.get(), return_messages); + if (!result.ok()) { + LOG(ERROR) << result.error(); } } return 1; - } int main(int argc, char** argv) { diff --git a/aconfigd/aconfigd_test.cpp b/aconfigd/aconfigd_test.cpp index 71ecd05..e846ebd 100644 --- a/aconfigd/aconfigd_test.cpp +++ b/aconfigd/aconfigd_test.cpp @@ -76,16 +76,35 @@ class AconfigdTest : public ::testing::Test { return Error() << "failed to serialize pb to string"; } - auto result = TEMP_FAILURE_RETRY( + unsigned char bytes[4]; + uint32_t msg_size = message_string.size(); + bytes[0] = (msg_size >> 24) & 0xFF; + bytes[1] = (msg_size >> 16) & 0xFF; + bytes[2] = (msg_size >> 8) & 0xFF; + bytes[3] = (msg_size >> 0) & 0xFF; + + auto num_bytes = TEMP_FAILURE_RETRY(send(*sock_fd, bytes, 4, 0)); + if (num_bytes != 4) { + return ErrnoError() << "send() failed for msg size"; + } + + num_bytes = TEMP_FAILURE_RETRY( send(*sock_fd, message_string.c_str(), message_string.size(), 0)); - if (result != static_cast<long>(message_string.size())) { - return ErrnoError() << "send() failed"; + if (num_bytes != static_cast<long>(message_string.size())) { + return ErrnoError() << "send() failed for msg"; + } + + num_bytes = TEMP_FAILURE_RETRY(recv(*sock_fd, bytes, 4, 0)); + if (num_bytes != 4) { + return ErrnoError() << "recv() failed for return msg size"; } - char buffer[kBufferSize] = {}; - auto num_bytes = TEMP_FAILURE_RETRY(recv(*sock_fd, buffer, sizeof(buffer), 0)); - if (num_bytes < 0) { - return ErrnoError() << "recv() failed"; + uint32_t payload_size = + uint32_t(bytes[0]<<24 | bytes[1]<<16 | bytes[2]<<8 | bytes[3]); + char buffer[payload_size]; + num_bytes = TEMP_FAILURE_RETRY(recv(*sock_fd, buffer, payload_size, 0)); + if (num_bytes != payload_size) { + return ErrnoError() << "recv() failed for return msg"; } auto return_messages = StorageReturnMessages{}; |