Esempio n. 1
0
mc_fbtrace_info_t* mc_fbtrace_info_deep_copy(const mc_fbtrace_info_t* orig) {
  mc_fbtrace_info_t* new_copy = new_mc_fbtrace_info(1);
  memcpy(new_copy, orig, sizeof(mc_fbtrace_info_t));
  if (orig->fbtrace) {
    mc_fbtrace_incref(orig->fbtrace);
  }
  return new_copy;
}
Esempio n. 2
0
static int _fill_msg_strs(mc_msg_t* msg, entry_list_t* elist,
                          const uint8_t* body, _parse_info_t* parse_info) {
  if (parse_info->key_idx >= 0) {
    _set_str(&msg->key, body, &elist->entries[parse_info->key_idx]);
  }
  if (parse_info->value_idx >= 0) {
    _set_str(&msg->value, body, &elist->entries[parse_info->value_idx]);
    if (msg->op == mc_op_metaget) {
      int af = AF_INET;
      if (strchr(msg->value.str, ':') != NULL) {
        af = AF_INET6;
      }
      if (inet_pton(af, msg->value.str, &msg->ip_addr) > 0) {
        msg->ipv = af == AF_INET ? 4 : 6;
      }
      msg->value.str = NULL;
      msg->value.len = 0;
    }
  }

#ifndef LIBMC_FBTRACE_DISABLE

  if (parse_info->fbtrace_idx >= 0) {
    if (msg->fbtrace_info == NULL) {
      msg->fbtrace_info = new_mc_fbtrace_info(0);
      if (msg->fbtrace_info == NULL || msg->fbtrace_info->fbtrace == NULL) {
        return -1;
      }
    } else {
      dbg_error("msg->fbtrace_info was already initialized");
    }
    if (_cpy_fbtrace_meta(msg->fbtrace_info->metadata, body,
             &elist->entries[parse_info->fbtrace_idx])) {
      return -1;
    }
  }

#endif

  return 0;
}
McRequest umbrellaParseRequest(const folly::IOBuf& source,
                               const uint8_t* header, size_t nheader,
                               const uint8_t* body, size_t nbody,
                               mc_op_t& opOut, uint64_t& reqidOut) {
  McRequest req;
  opOut = mc_op_unknown;
  reqidOut = 0;

  auto msg = reinterpret_cast<const entry_list_msg_t*>(header);
  size_t nentries = folly::Endian::big((uint16_t)msg->nentries);
  if (reinterpret_cast<const uint8_t*>(&msg->entries[nentries])
      != header + nheader) {
    throw std::runtime_error("Invalid number of entries");
  }
  for (size_t i = 0; i < nentries; ++i) {
    auto& entry = msg->entries[i];
    size_t tag = folly::Endian::big((uint16_t)entry.tag);
    size_t val = folly::Endian::big((uint64_t)entry.data.val);
    switch (tag) {
      case msg_op:
        if (val >= UM_NOPS) {
          throw std::runtime_error("op out of range");
        }
        opOut = static_cast<mc_op_t>(umbrella_op_to_mc[val]);
        break;

      case msg_reqid:
        if (val == 0) {
          throw std::runtime_error("invalid reqid");
        }
        reqidOut = val;
        break;

      case msg_flags:
        req.setFlags(val);
        break;

      case msg_exptime:
        req.setExptime(val);
        break;

      case msg_delta:
        req.setDelta(val);
        break;

      case msg_cas:
        req.setCas(val);
        break;

      case msg_lease_id:
        req.setLeaseToken(val);
        break;

      case msg_key:
        if (!req.setKeyFrom(
              source, body +
              folly::Endian::big((uint32_t)entry.data.str.offset),
              folly::Endian::big((uint32_t)entry.data.str.len) - 1)) {
          throw std::runtime_error("Key: invalid offset/length");
        }
        break;

      case msg_value:
        if (!req.setValueFrom(
              source, body +
              folly::Endian::big((uint32_t)entry.data.str.offset),
              folly::Endian::big((uint32_t)entry.data.str.len) - 1)) {
          throw std::runtime_error("Value: invalid offset/length");
        }
        break;

#ifndef LIBMC_FBTRACE_DISABLE
      case msg_fbtrace:
      {
        auto off = folly::Endian::big((uint32_t)entry.data.str.offset);
        auto len = folly::Endian::big((uint32_t)entry.data.str.len) - 1;

        if (len > FBTRACE_METADATA_SZ) {
          throw std::runtime_error("Fbtrace metadata too large");
        }
        if (off + len > nbody || off + len < off) {
          throw std::runtime_error("Fbtrace metadata field invalid");
        }
        auto fbtraceInfo = new_mc_fbtrace_info(0);
        memcpy(fbtraceInfo->metadata, body + off, len);
        req.setFbtraceInfo(fbtraceInfo);
        break;
      }
#endif

      default:
        /* Ignore unknown tags silently */
        break;
    }
  }

  if (opOut == mc_op_unknown) {
    throw std::runtime_error("Request missing operation");
  }

  if (!reqidOut) {
    throw std::runtime_error("Request missing reqid");
  }

  return req;
}