github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/src/tao/message_channel.cc (about) 1 // File: message_channel.cc 2 // Author: Tom Roeder <tmroeder@google.com> 3 // 4 // Description: A MessageChannel that communicates over Unix file descriptors. 5 // 6 // Copyright (c) 2013, Google Inc. All rights reserved. 7 // 8 // Licensed under the Apache License, Version 2.0 (the "License"); 9 // you may not use this file except in compliance with the License. 10 // You may obtain a copy of the License at 11 // 12 // http://www.apache.org/licenses/LICENSE-2.0 13 // 14 // Unless required by applicable law or agreed to in writing, software 15 // distributed under the License is distributed on an "AS IS" BASIS, 16 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 // See the License for the specific language governing permissions and 18 // limitations under the License. 19 #include "tao/message_channel.h" 20 21 #include <arpa/inet.h> 22 #include <unistd.h> 23 24 #include <list> 25 #include <string> 26 27 #include <glog/logging.h> 28 #include <google/protobuf/message.h> 29 30 #include "tao/util.h" 31 32 namespace tao { 33 constexpr size_t MessageChannel::DefaultMaxMessageSize; 34 35 bool MessageChannel::SendString(const string &s) { 36 uint32_t net_len = htonl(s.size()); 37 return SendData(&net_len, sizeof(net_len)) && SendData(s.c_str(), s.size()); 38 } 39 40 bool MessageChannel::SendMessage(const google::protobuf::Message &m) { 41 string serialized; 42 if (!m.SerializeToString(&serialized)) { 43 LOG(ERROR) << "Could not serialize the Message to a string"; 44 Close(); // Not really necessary, but simplifies semantics. 45 return false; 46 } 47 return SendString(serialized); 48 } 49 50 bool MessageChannel::ReceiveData(void *buffer, size_t buffer_len, bool *eof) { 51 if (IsClosed()) { 52 LOG(ERROR) << "Can't receive data, channel is already closed"; 53 *eof = true; 54 return true; 55 } else { 56 *eof = false; 57 } 58 size_t filled_len = 0; 59 while (filled_len != buffer_len) { 60 size_t recv_len; 61 if (!ReceivePartialData( 62 reinterpret_cast<unsigned char *>(buffer) + filled_len, 63 buffer_len - filled_len, &recv_len, eof)) { 64 LOG(ERROR) << "Failed to read data"; 65 return false; 66 } else if (*eof && filled_len != 0) { 67 LOG(ERROR) << "Failed to read complete data"; 68 return false; 69 } else if (*eof) { 70 return true; 71 } 72 filled_len += recv_len; 73 } 74 return true; 75 } 76 77 bool MessageChannel::ReceiveString(string *s, bool *eof) { 78 uint32_t net_len; 79 if (!ReceiveData(&net_len, sizeof(net_len), eof)) { 80 LOG(ERROR) << "Could not get the length of the data"; 81 return false; 82 } else if (*eof) { 83 return true; 84 } 85 uint32_t len = ntohl(net_len); 86 if (len > MaxMessageSize()) { 87 LOG(ERROR) << "Message exceeded maximum allowable size"; 88 Close(); 89 return false; 90 } 91 unique_ptr<char[]> temp_data(new char[len]); 92 if (!ReceiveData(temp_data.get(), static_cast<size_t>(len), eof) || *eof) { 93 LOG(ERROR) << "Could not get the data"; 94 return false; 95 } 96 s->assign(temp_data.get(), len); 97 return true; 98 } 99 100 bool MessageChannel::ReceiveMessage(google::protobuf::Message *m, bool *eof) { 101 string s; 102 if (!ReceiveString(&s, eof)) { 103 LOG(ERROR) << "Could not receive message"; 104 return false; 105 } else if (*eof) { 106 return true; 107 } 108 if (!m->ParseFromString(s)) { 109 LOG(ERROR) << "Could not parse message"; 110 Close(); 111 return false; 112 } 113 return true; 114 } 115 116 } // namespace tao