ipc_channel_reader.cc 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ipc/ipc_channel_reader.h"
  5. #include <stddef.h>
  6. #include <algorithm>
  7. #include "base/logging.h"
  8. #include "base/threading/thread_task_runner_handle.h"
  9. #include "ipc/ipc_listener.h"
  10. #include "ipc/ipc_logging.h"
  11. #include "ipc/ipc_message.h"
  12. #include "ipc/ipc_message_attachment_set.h"
  13. #include "ipc/ipc_message_macros.h"
  14. namespace IPC {
  15. namespace internal {
  16. #if BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  17. namespace {
  18. std::string GetMessageText(const Message& message) {
  19. std::string name;
  20. Logging::GetInstance()->GetMessageText(
  21. message.type(), &name, &message, nullptr);
  22. return name;
  23. }
  24. } // namespace
  25. #define EMIT_TRACE_EVENT(message) \
  26. TRACE_EVENT_WITH_FLOW1( \
  27. "ipc,toplevel", "ChannelReader::DispatchInputData", \
  28. (message).flags(), TRACE_EVENT_FLAG_FLOW_IN, "name", \
  29. GetMessageText(message));
  30. #else
  31. #define EMIT_TRACE_EVENT(message) \
  32. TRACE_EVENT_WITH_FLOW2("ipc,toplevel", "ChannelReader::DispatchInputData", \
  33. (message).flags(), TRACE_EVENT_FLAG_FLOW_IN, "class", \
  34. IPC_MESSAGE_ID_CLASS((message).type()), "line", \
  35. IPC_MESSAGE_ID_LINE((message).type()));
  36. #endif // BUILDFLAG(IPC_MESSAGE_LOG_ENABLED)
  37. ChannelReader::ChannelReader(Listener* listener)
  38. : listener_(listener),
  39. max_input_buffer_size_(Channel::kMaximumReadBufferSize) {
  40. memset(input_buf_, 0, sizeof(input_buf_));
  41. }
  42. ChannelReader::~ChannelReader() = default;
  43. ChannelReader::DispatchState ChannelReader::ProcessIncomingMessages() {
  44. while (true) {
  45. int bytes_read = 0;
  46. ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize,
  47. &bytes_read);
  48. if (read_state == READ_FAILED)
  49. return DISPATCH_ERROR;
  50. if (read_state == READ_PENDING)
  51. return DISPATCH_FINISHED;
  52. DCHECK(bytes_read > 0);
  53. if (!TranslateInputData(input_buf_, bytes_read))
  54. return DISPATCH_ERROR;
  55. }
  56. }
  57. ChannelReader::DispatchState ChannelReader::AsyncReadComplete(int bytes_read) {
  58. if (!TranslateInputData(input_buf_, bytes_read))
  59. return DISPATCH_ERROR;
  60. return DISPATCH_FINISHED;
  61. }
  62. bool ChannelReader::IsInternalMessage(const Message& m) {
  63. return m.routing_id() == MSG_ROUTING_NONE &&
  64. m.type() >= Channel::CLOSE_FD_MESSAGE_TYPE &&
  65. m.type() <= Channel::HELLO_MESSAGE_TYPE;
  66. }
  67. bool ChannelReader::IsHelloMessage(const Message& m) {
  68. return m.routing_id() == MSG_ROUTING_NONE &&
  69. m.type() == Channel::HELLO_MESSAGE_TYPE;
  70. }
  71. void ChannelReader::CleanUp() {
  72. }
  73. void ChannelReader::DispatchMessage(Message* m) {
  74. EMIT_TRACE_EVENT(*m);
  75. listener_->OnMessageReceived(*m);
  76. HandleDispatchError(*m);
  77. }
  78. bool ChannelReader::TranslateInputData(const char* input_data,
  79. int input_data_len) {
  80. const char* p;
  81. const char* end;
  82. // Possibly combine with the overflow buffer to make a larger buffer.
  83. if (input_overflow_buf_.empty()) {
  84. p = input_data;
  85. end = input_data + input_data_len;
  86. } else {
  87. if (!CheckMessageSize(input_overflow_buf_.size() + input_data_len))
  88. return false;
  89. input_overflow_buf_.append(input_data, input_data_len);
  90. p = input_overflow_buf_.data();
  91. end = p + input_overflow_buf_.size();
  92. }
  93. size_t next_message_size = 0;
  94. // Dispatch all complete messages in the data buffer.
  95. while (p < end) {
  96. Message::NextMessageInfo info;
  97. Message::FindNext(p, end, &info);
  98. if (info.message_found) {
  99. int pickle_len = static_cast<int>(info.pickle_end - p);
  100. Message translated_message(p, pickle_len);
  101. if (!HandleTranslatedMessage(&translated_message))
  102. return false;
  103. p = info.message_end;
  104. } else {
  105. // Last message is partial.
  106. next_message_size = info.message_size;
  107. if (!CheckMessageSize(next_message_size))
  108. return false;
  109. break;
  110. }
  111. }
  112. // Account for the case where last message's byte is in the next data chunk.
  113. size_t next_message_buffer_size = next_message_size ?
  114. next_message_size + Channel::kReadBufferSize - 1:
  115. 0;
  116. // Save any partial data in the overflow buffer.
  117. if (p != input_overflow_buf_.data())
  118. input_overflow_buf_.assign(p, end - p);
  119. if (!input_overflow_buf_.empty()) {
  120. // We have something in the overflow buffer, which means that we will
  121. // append the next data chunk (instead of parsing it directly). So we
  122. // resize the buffer to fit the next message, to avoid repeatedly
  123. // growing the buffer as we receive all message' data chunks.
  124. if (next_message_buffer_size > input_overflow_buf_.capacity()) {
  125. input_overflow_buf_.reserve(next_message_buffer_size);
  126. }
  127. }
  128. // Trim the buffer if we can
  129. if (next_message_buffer_size < max_input_buffer_size_ &&
  130. input_overflow_buf_.size() < max_input_buffer_size_ &&
  131. input_overflow_buf_.capacity() > max_input_buffer_size_) {
  132. // std::string doesn't really have a method to shrink capacity to
  133. // a specific value, so we have to swap with another string.
  134. std::string trimmed_buf;
  135. trimmed_buf.reserve(max_input_buffer_size_);
  136. if (trimmed_buf.capacity() > max_input_buffer_size_) {
  137. // Since we don't control how much space reserve() actually reserves,
  138. // we have to go other way around and change the max size to avoid
  139. // getting into the outer if() again.
  140. max_input_buffer_size_ = trimmed_buf.capacity();
  141. }
  142. trimmed_buf.assign(input_overflow_buf_.data(),
  143. input_overflow_buf_.size());
  144. input_overflow_buf_.swap(trimmed_buf);
  145. }
  146. if (input_overflow_buf_.empty() && !DidEmptyInputBuffers())
  147. return false;
  148. return true;
  149. }
  150. bool ChannelReader::HandleTranslatedMessage(Message* translated_message) {
  151. // Immediately handle internal messages.
  152. if (IsInternalMessage(*translated_message)) {
  153. EMIT_TRACE_EVENT(*translated_message);
  154. HandleInternalMessage(*translated_message);
  155. HandleDispatchError(*translated_message);
  156. return true;
  157. }
  158. return HandleExternalMessage(translated_message);
  159. }
  160. bool ChannelReader::HandleExternalMessage(Message* external_message) {
  161. if (!GetAttachments(external_message))
  162. return false;
  163. DispatchMessage(external_message);
  164. return true;
  165. }
  166. void ChannelReader::HandleDispatchError(const Message& message) {
  167. if (message.dispatch_error())
  168. listener_->OnBadMessageReceived(message);
  169. }
  170. bool ChannelReader::CheckMessageSize(size_t size) {
  171. if (size <= Channel::kMaximumMessageSize) {
  172. return true;
  173. }
  174. input_overflow_buf_.clear();
  175. LOG(ERROR) << "IPC message is too big: " << size;
  176. return false;
  177. }
  178. } // namespace internal
  179. } // namespace IPC