| 107 | } |
| 108 | |
| 109 | int RelayHandler::handle_input(ACE_HANDLE handle) |
| 110 | { |
| 111 | OpenDDS::DCPS::ThreadStatusManager::Event ev(TheServiceParticipant->get_thread_status_manager(), READ_MASK, handle_to_int(handle)); |
| 112 | |
| 113 | const auto now = OpenDDS::DCPS::MonotonicTimePoint::now(); |
| 114 | |
| 115 | ACE_INET_Addr remote; |
| 116 | int inlen = 65536; // Default to maximum datagram size. |
| 117 | |
| 118 | #ifdef FIONREAD |
| 119 | if (ACE_OS::ioctl (handle, |
| 120 | FIONREAD, |
| 121 | &inlen) == -1) { |
| 122 | HANDLER_ERROR((LM_ERROR, "(%P|%t) ERROR: RelayHandler::handle_input %C failed to get available byte count: %m\n", name_.c_str())); |
| 123 | return 0; |
| 124 | } |
| 125 | #else |
| 126 | ACE_UNUSED_ARG(handle); |
| 127 | #endif |
| 128 | |
| 129 | if (inlen < 0) { |
| 130 | HANDLER_ERROR((LM_ERROR, "(%P|%t) ERROR: RelayHandler::handle_input %C available byte count is negative\n", name_.c_str())); |
| 131 | return 0; |
| 132 | } |
| 133 | |
| 134 | // Allocate at least one byte so that recv cannot return early. |
| 135 | const auto n = static_cast<size_t>(std::max(inlen, 1)); |
| 136 | OpenDDS::DCPS::Lockable_Message_Block_Ptr buffer(new ACE_Message_Block(n), message_block_locking_); |
| 137 | |
| 138 | const auto bytes = socket_.recv(buffer->wr_ptr(), buffer->space(), remote); |
| 139 | |
| 140 | if (bytes < 0) { |
| 141 | if (errno == ECONNRESET) { |
| 142 | // Sending to a non-existent client may result in an ICMP message that is delievered as connection reset. |
| 143 | return 0; |
| 144 | } |
| 145 | |
| 146 | HANDLER_ERROR((LM_ERROR, "(%P|%t) ERROR: RelayHandler::handle_input %C failed to recv: %m\n", name_.c_str())); |
| 147 | return 0; |
| 148 | } else if (bytes == 0) { |
| 149 | // Okay. Empty datagram. |
| 150 | HANDLER_WARNING((LM_WARNING, "(%P|%t) WARNING: RelayHandler::handle_input %C received an empty datagram from %C\n", |
| 151 | name_.c_str(), OpenDDS::DCPS::LogAddr(remote).c_str())); |
| 152 | return 0; |
| 153 | } |
| 154 | |
| 155 | buffer->length(static_cast<size_t>(bytes)); |
| 156 | MessageType type = MessageType::Unknown; |
| 157 | const CORBA::ULong generated_messages = process_message(remote, now, buffer, type); |
| 158 | stats_reporter_.max_gain(generated_messages, now); |
| 159 | stats_reporter_.input_message(static_cast<size_t>(bytes), |
| 160 | OpenDDS::DCPS::MonotonicTimePoint::now() - now, now, type); |
| 161 | |
| 162 | return 0; |
| 163 | } |
| 164 | |
| 165 | int RelayHandler::handle_output(ACE_HANDLE handle) |
| 166 | { |
nothing calls this directly
no test coverage detected