15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel_reader.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_listener.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_macros.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelReader::ChannelReader(Listener* listener) : listener_(listener) { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(input_buf_, 0, sizeof(input_buf_)); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChannelReader::~ChannelReader() { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelReader::ProcessIncomingMessages() { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read = 0; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize, 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &bytes_read); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_state == READ_FAILED) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_state == READ_PENDING) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(bytes_read > 0); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!DispatchInputData(input_buf_, bytes_read)) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelReader::AsyncReadComplete(int bytes_read) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DispatchInputData(input_buf_, bytes_read); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChannelReader::IsInternalMessage(const Message& m) { 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return m.routing_id() == MSG_ROUTING_NONE && 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) m.type() >= Channel::CLOSE_FD_MESSAGE_TYPE && 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) m.type() <= Channel::HELLO_MESSAGE_TYPE; 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool ChannelReader::IsHelloMessage(const Message& m) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return m.routing_id() == MSG_ROUTING_NONE && 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) m.type() == Channel::HELLO_MESSAGE_TYPE; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChannelReader::DispatchInputData(const char* input_data, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int input_data_len) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* p; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Possibly combine with the overflow buffer to make a larger buffer. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_overflow_buf_.empty()) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = input_data; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = input_data + input_data_len; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (input_overflow_buf_.size() + input_data_len > 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Channel::kMaximumMessageSize) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_overflow_buf_.clear(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "IPC message is too big"; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_overflow_buf_.append(input_data, input_data_len); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = input_overflow_buf_.data(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = p + input_overflow_buf_.size(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dispatch all complete messages in the data buffer. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (p < end) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* message_tail = Message::FindNext(p, end); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_tail) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = static_cast<int>(message_tail - p); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message m(p, len); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!WillDispatchInputMessage(&m)) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef IPC_MESSAGE_LOG_ENABLED 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Logging* logger = Logging::GetInstance(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string name; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logger->GetMessageText(m.type(), &name, &m, NULL); 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TRACE_EVENT1("ipc,toplevel", "ChannelReader::DispatchInputData", 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "name", name); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) TRACE_EVENT2("ipc,toplevel", "ChannelReader::DispatchInputData", 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "class", IPC_MESSAGE_ID_CLASS(m.type()), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "line", IPC_MESSAGE_ID_LINE(m.type())); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) m.TraceMessageEnd(); 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (IsInternalMessage(m)) 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) HandleInternalMessage(m); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_->OnMessageReceived(m); 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (m.dispatch_error()) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) listener_->OnBadMessageReceived(m); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = message_tail; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Last message is partial. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save any partial data in the overflow buffer. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_overflow_buf_.assign(p, end - p); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace internal 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 118