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