OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ipc/ipc_channel_posix.h" | 5 #include "ipc/ipc_channel_posix.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <sys/types.h> | 10 #include <sys/types.h> |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 MessageLoopForIO::WATCH_READ, | 472 MessageLoopForIO::WATCH_READ, |
473 &server_listen_connection_watcher_, | 473 &server_listen_connection_watcher_, |
474 this); | 474 this); |
475 } else { | 475 } else { |
476 did_connect = AcceptConnection(); | 476 did_connect = AcceptConnection(); |
477 } | 477 } |
478 return did_connect; | 478 return did_connect; |
479 } | 479 } |
480 | 480 |
481 bool Channel::ChannelImpl::ProcessIncomingMessages() { | 481 bool Channel::ChannelImpl::ProcessIncomingMessages() { |
482 for (;;) { | 482 while (true) { |
483 if (pipe_ == -1) | 483 int bytes_read = 0; |
brettw
2012/03/01 06:43:23
This check moved to ReadData
| |
484 ReadState read_state = ReadData(input_buf_, Channel::kReadBufferSize, | |
485 &bytes_read); | |
486 if (read_state == READ_FAILED) | |
484 return false; | 487 return false; |
488 if (read_state == READ_PENDING) | |
489 return true; | |
485 | 490 |
486 const char* p = NULL; | 491 DCHECK(bytes_read > 0); |
487 const char* end = NULL; | 492 if (!DispatchInputData(input_buf_, bytes_read)) |
488 if (!ReadDataFromPipe(&p, &end)) | |
489 return false; // Pipe error. | |
490 if (!p) | |
491 return true; // No data waiting. | |
492 | |
493 // Dispatch all complete messages in the data buffer. | |
494 while (p < end) { | |
brettw
2012/03/01 06:43:23
This block moved to DispatchInputData.
| |
495 const char* message_tail = Message::FindNext(p, end); | |
496 if (message_tail) { | |
497 int len = static_cast<int>(message_tail - p); | |
498 Message m(p, len); | |
499 if (!PopulateMessageFileDescriptors(&m)) | |
brettw
2012/03/01 06:43:23
This was renamed to WillDispatchInputMessage (sinc
| |
500 return false; | |
501 | |
502 DVLOG(2) << "received message on channel @" << this | |
503 << " with type " << m.type() << " on fd " << pipe_; | |
504 if (IsHelloMessage(&m)) | |
505 HandleHelloMessage(m); | |
506 else | |
507 listener_->OnMessageReceived(m); | |
508 p = message_tail; | |
509 } else { | |
510 // Last message is partial. | |
511 break; | |
512 } | |
513 } | |
514 input_overflow_buf_.assign(p, end - p); | |
515 | |
516 // When the input data buffer is empty, the fds should be too. If this is | |
517 // not the case, we probably have a rogue renderer which is trying to fill | |
518 // our descriptor table. | |
519 if (input_overflow_buf_.empty() && !input_fds_.empty()) { | |
brettw
2012/03/01 06:43:23
This check moved to DidEmptyInputBuffers.
| |
520 // We close these descriptors in Close() | |
521 return false; | 493 return false; |
522 } | |
523 } | 494 } |
524 } | 495 } |
525 | 496 |
497 bool Channel::ChannelImpl::DispatchInputData(const char* input_data, | |
498 int input_data_len) { | |
499 const char* p; | |
500 const char* end; | |
501 | |
502 // Possibly combine with the overflow buffer to make a larger buffer. | |
503 if (input_overflow_buf_.empty()) { | |
504 p = input_data; | |
505 end = input_data + input_data_len; | |
506 } else { | |
507 if (input_overflow_buf_.size() > | |
508 kMaximumMessageSize - input_data_len) { | |
509 input_overflow_buf_.clear(); | |
510 LOG(ERROR) << "IPC message is too big"; | |
511 return false; | |
512 } | |
513 input_overflow_buf_.append(input_data, input_data_len); | |
514 p = input_overflow_buf_.data(); | |
515 end = p + input_overflow_buf_.size(); | |
516 } | |
517 | |
518 // Dispatch all complete messages in the data buffer. | |
519 while (p < end) { | |
520 const char* message_tail = Message::FindNext(p, end); | |
521 if (message_tail) { | |
522 int len = static_cast<int>(message_tail - p); | |
523 Message m(p, len); | |
524 if (!WillDispatchInputMessage(&m)) | |
525 return false; | |
526 | |
527 if (IsHelloMessage(&m)) | |
528 HandleHelloMessage(m); | |
529 else | |
530 listener_->OnMessageReceived(m); | |
531 p = message_tail; | |
532 } else { | |
533 // Last message is partial. | |
534 break; | |
535 } | |
536 } | |
537 | |
538 // Save any partial data in the overflow buffer. | |
539 input_overflow_buf_.assign(p, end - p); | |
540 | |
541 if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) | |
542 return false; | |
543 return true; | |
544 } | |
545 | |
526 bool Channel::ChannelImpl::ProcessOutgoingMessages() { | 546 bool Channel::ChannelImpl::ProcessOutgoingMessages() { |
527 DCHECK(!waiting_connect_); // Why are we trying to send messages if there's | 547 DCHECK(!waiting_connect_); // Why are we trying to send messages if there's |
528 // no connection? | 548 // no connection? |
529 if (output_queue_.empty()) | 549 if (output_queue_.empty()) |
530 return true; | 550 return true; |
531 | 551 |
532 if (pipe_ == -1) | 552 if (pipe_ == -1) |
533 return false; | 553 return false; |
534 | 554 |
535 // Write out all the messages we can till the write blocks or there are no | 555 // Write out all the messages we can till the write blocks or there are no |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
930 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); | 950 DCHECK_EQ(msg->file_descriptor_set()->size(), 1U); |
931 } | 951 } |
932 #endif // IPC_USES_READWRITE | 952 #endif // IPC_USES_READWRITE |
933 output_queue_.push(msg.release()); | 953 output_queue_.push(msg.release()); |
934 } | 954 } |
935 | 955 |
936 bool Channel::ChannelImpl::IsHelloMessage(const Message* m) const { | 956 bool Channel::ChannelImpl::IsHelloMessage(const Message* m) const { |
937 return m->routing_id() == MSG_ROUTING_NONE && m->type() == HELLO_MESSAGE_TYPE; | 957 return m->routing_id() == MSG_ROUTING_NONE && m->type() == HELLO_MESSAGE_TYPE; |
938 } | 958 } |
939 | 959 |
940 bool Channel::ChannelImpl::ReadDataFromPipe(const char** buffer_begin, | 960 Channel::ChannelImpl::ReadState Channel::ChannelImpl::ReadData( |
941 const char** buffer_end) { | 961 char* buffer, |
962 int buffer_len, | |
963 int* bytes_read) { | |
964 if (pipe_ == -1) | |
965 return READ_FAILED; | |
966 | |
942 struct msghdr msg = {0}; | 967 struct msghdr msg = {0}; |
943 | 968 |
944 struct iovec iov = {input_buf_, Channel::kReadBufferSize}; | 969 struct iovec iov = {buffer, buffer_len}; |
945 msg.msg_iov = &iov; | 970 msg.msg_iov = &iov; |
946 msg.msg_iovlen = 1; | 971 msg.msg_iovlen = 1; |
947 | 972 |
948 msg.msg_control = input_cmsg_buf_; | 973 msg.msg_control = input_cmsg_buf_; |
949 | 974 |
950 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data | 975 // recvmsg() returns 0 if the connection has closed or EAGAIN if no data |
951 // is waiting on the pipe. | 976 // is waiting on the pipe. |
952 ssize_t bytes_read = 0; | |
953 #if defined(IPC_USES_READWRITE) | 977 #if defined(IPC_USES_READWRITE) |
954 if (fd_pipe_ >= 0) { | 978 if (fd_pipe_ >= 0) { |
955 bytes_read = HANDLE_EINTR(read(pipe_, input_buf_, | 979 *bytes_read = HANDLE_EINTR(read(pipe_, buffer, buffer_len)); |
956 Channel::kReadBufferSize)); | |
957 msg.msg_controllen = 0; | 980 msg.msg_controllen = 0; |
958 } else | 981 } else |
959 #endif // IPC_USES_READWRITE | 982 #endif // IPC_USES_READWRITE |
960 { | 983 { |
961 msg.msg_controllen = sizeof(input_cmsg_buf_); | 984 msg.msg_controllen = sizeof(input_cmsg_buf_); |
962 bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT)); | 985 *bytes_read = HANDLE_EINTR(recvmsg(pipe_, &msg, MSG_DONTWAIT)); |
963 } | 986 } |
964 if (bytes_read < 0) { | 987 if (*bytes_read < 0) { |
965 if (errno == EAGAIN) { | 988 if (errno == EAGAIN) { |
966 *buffer_begin = *buffer_end = NULL; // Signal no data was read. | 989 return READ_PENDING; |
967 return true; | |
968 #if defined(OS_MACOSX) | 990 #if defined(OS_MACOSX) |
969 } else if (errno == EPERM) { | 991 } else if (errno == EPERM) { |
970 // On OSX, reading from a pipe with no listener returns EPERM | 992 // On OSX, reading from a pipe with no listener returns EPERM |
971 // treat this as a special case to prevent spurious error messages | 993 // treat this as a special case to prevent spurious error messages |
972 // to the console. | 994 // to the console. |
973 return false; | 995 return READ_FAILED; |
974 #endif // OS_MACOSX | 996 #endif // OS_MACOSX |
975 } else if (errno == ECONNRESET || errno == EPIPE) { | 997 } else if (errno == ECONNRESET || errno == EPIPE) { |
976 return false; | 998 return READ_FAILED; |
977 } else { | 999 } else { |
978 PLOG(ERROR) << "pipe error (" << pipe_ << ")"; | 1000 PLOG(ERROR) << "pipe error (" << pipe_ << ")"; |
979 return false; | 1001 return READ_FAILED; |
980 } | 1002 } |
981 } else if (bytes_read == 0) { | 1003 } else if (*bytes_read == 0) { |
982 // The pipe has closed... | 1004 // The pipe has closed... |
983 return false; | 1005 return READ_FAILED; |
984 } | 1006 } |
985 DCHECK(bytes_read); | 1007 DCHECK(*bytes_read); |
986 | 1008 |
987 CloseClientFileDescriptor(); | 1009 CloseClientFileDescriptor(); |
988 | 1010 |
989 // Read any file descriptors from the message. | 1011 // Read any file descriptors from the message. |
990 if (!ExtractFileDescriptorsFromMsghdr(&msg)) | 1012 if (!ExtractFileDescriptorsFromMsghdr(&msg)) |
991 return false; | 1013 return READ_FAILED; |
992 | 1014 return READ_SUCCEEDED; |
993 // Possibly combine with the overflow buffer to make a larger buffer. | |
brettw
2012/03/01 06:43:23
This moved to DispatchInputData.
| |
994 if (input_overflow_buf_.empty()) { | |
995 *buffer_begin = input_buf_; | |
996 *buffer_end = *buffer_begin + bytes_read; | |
997 } else { | |
998 if (input_overflow_buf_.size() > (kMaximumMessageSize - bytes_read)) { | |
999 input_overflow_buf_.clear(); | |
1000 LOG(ERROR) << "IPC message is too big"; | |
1001 return false; | |
1002 } | |
1003 input_overflow_buf_.append(input_buf_, bytes_read); | |
1004 *buffer_begin = input_overflow_buf_.data(); | |
1005 *buffer_end = *buffer_begin + input_overflow_buf_.size(); | |
1006 } | |
1007 return true; | |
1008 } | 1015 } |
1009 | 1016 |
1010 #if defined(IPC_USES_READWRITE) | 1017 #if defined(IPC_USES_READWRITE) |
1011 bool Channel::ChannelImpl::ReadFileDescriptorsFromFDPipe() { | 1018 bool Channel::ChannelImpl::ReadFileDescriptorsFromFDPipe() { |
1012 char dummy; | 1019 char dummy; |
1013 struct iovec fd_pipe_iov = { &dummy, 1 }; | 1020 struct iovec fd_pipe_iov = { &dummy, 1 }; |
1014 | 1021 |
1015 struct msghdr msg = { 0 }; | 1022 struct msghdr msg = { 0 }; |
1016 msg.msg_iov = &fd_pipe_iov; | 1023 msg.msg_iov = &fd_pipe_iov; |
1017 msg.msg_iovlen = 1; | 1024 msg.msg_iovlen = 1; |
1018 msg.msg_control = input_cmsg_buf_; | 1025 msg.msg_control = input_cmsg_buf_; |
1019 msg.msg_controllen = sizeof(input_cmsg_buf_); | 1026 msg.msg_controllen = sizeof(input_cmsg_buf_); |
1020 ssize_t bytes_received = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT)); | 1027 ssize_t bytes_received = HANDLE_EINTR(recvmsg(fd_pipe_, &msg, MSG_DONTWAIT)); |
1021 | 1028 |
1022 if (bytes_received != 1) | 1029 if (bytes_received != 1) |
1023 return true; // No message waiting. | 1030 return true; // No message waiting. |
1024 | 1031 |
1025 if (!ExtractFileDescriptorsFromMsghdr(&msg)) | 1032 if (!ExtractFileDescriptorsFromMsghdr(&msg)) |
1026 return false; | 1033 return false; |
1027 return true; | 1034 return true; |
1028 } | 1035 } |
1029 #endif | 1036 #endif |
1030 | 1037 |
1031 bool Channel::ChannelImpl::PopulateMessageFileDescriptors(Message* msg) { | 1038 bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) { |
1032 uint16 header_fds = msg->header()->num_fds; | 1039 uint16 header_fds = msg->header()->num_fds; |
1033 if (!header_fds) | 1040 if (!header_fds) |
1034 return true; // Nothing to do. | 1041 return true; // Nothing to do. |
1035 | 1042 |
1036 // The message has file descriptors. | 1043 // The message has file descriptors. |
1037 const char* error = NULL; | 1044 const char* error = NULL; |
1038 if (header_fds > input_fds_.size()) { | 1045 if (header_fds > input_fds_.size()) { |
1039 // The message has been completely received, but we didn't get | 1046 // The message has been completely received, but we didn't get |
1040 // enough file descriptors. | 1047 // enough file descriptors. |
1041 #if defined(IPC_USES_READWRITE) | 1048 #if defined(IPC_USES_READWRITE) |
(...skipping 21 matching lines...) Expand all Loading... | |
1063 ClearInputFDs(); | 1070 ClearInputFDs(); |
1064 return false; | 1071 return false; |
1065 } | 1072 } |
1066 | 1073 |
1067 msg->file_descriptor_set()->SetDescriptors(&input_fds_.front(), | 1074 msg->file_descriptor_set()->SetDescriptors(&input_fds_.front(), |
1068 header_fds); | 1075 header_fds); |
1069 input_fds_.erase(input_fds_.begin(), input_fds_.begin() + header_fds); | 1076 input_fds_.erase(input_fds_.begin(), input_fds_.begin() + header_fds); |
1070 return true; | 1077 return true; |
1071 } | 1078 } |
1072 | 1079 |
1080 bool Channel::ChannelImpl::DidEmptyInputBuffers() { | |
1081 // When the input data buffer is empty, the fds should be too. If this is | |
1082 // not the case, we probably have a rogue renderer which is trying to fill | |
1083 // our descriptor table. | |
1084 return input_fds_.empty(); | |
1085 } | |
1086 | |
1073 bool Channel::ChannelImpl::ExtractFileDescriptorsFromMsghdr(msghdr* msg) { | 1087 bool Channel::ChannelImpl::ExtractFileDescriptorsFromMsghdr(msghdr* msg) { |
1074 // Check that there are any control messages. On OSX, CMSG_FIRSTHDR will | 1088 // Check that there are any control messages. On OSX, CMSG_FIRSTHDR will |
1075 // return an invalid non-NULL pointer in the case that controllen == 0. | 1089 // return an invalid non-NULL pointer in the case that controllen == 0. |
1076 if (msg->msg_controllen == 0) | 1090 if (msg->msg_controllen == 0) |
1077 return true; | 1091 return true; |
1078 | 1092 |
1079 for (cmsghdr* cmsg = CMSG_FIRSTHDR(msg); | 1093 for (cmsghdr* cmsg = CMSG_FIRSTHDR(msg); |
1080 cmsg; | 1094 cmsg; |
1081 cmsg = CMSG_NXTHDR(msg, cmsg)) { | 1095 cmsg = CMSG_NXTHDR(msg, cmsg)) { |
1082 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { | 1096 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1212 } | 1226 } |
1213 | 1227 |
1214 #if defined(OS_LINUX) | 1228 #if defined(OS_LINUX) |
1215 // static | 1229 // static |
1216 void Channel::SetGlobalPid(int pid) { | 1230 void Channel::SetGlobalPid(int pid) { |
1217 ChannelImpl::SetGlobalPid(pid); | 1231 ChannelImpl::SetGlobalPid(pid); |
1218 } | 1232 } |
1219 #endif // OS_LINUX | 1233 #endif // OS_LINUX |
1220 | 1234 |
1221 } // namespace IPC | 1235 } // namespace IPC |
OLD | NEW |