示例#1
0
文件: SSLContext.cpp 项目: 1Hgm/folly
bool SSLContext::setRandomizedAdvertisedNextProtocols(
    const std::list<NextProtocolsItem>& items, NextProtocolType protocolType) {
  unsetNextProtocols();
  if (items.size() == 0) {
    return false;
  }
  int total_weight = 0;
  for (const auto &item : items) {
    if (item.protocols.size() == 0) {
      continue;
    }
    AdvertisedNextProtocolsItem advertised_item;
    advertised_item.length = 0;
    for (const auto& proto : item.protocols) {
      ++advertised_item.length;
      unsigned protoLength = proto.length();
      if (protoLength >= 256) {
        deleteNextProtocolsStrings();
        return false;
      }
      advertised_item.length += protoLength;
    }
    advertised_item.protocols = new unsigned char[advertised_item.length];
    if (!advertised_item.protocols) {
      throw std::runtime_error("alloc failure");
    }
    unsigned char* dst = advertised_item.protocols;
    for (auto& proto : item.protocols) {
      unsigned protoLength = proto.length();
      *dst++ = (unsigned char)protoLength;
      memcpy(dst, proto.data(), protoLength);
      dst += protoLength;
    }
    total_weight += item.weight;
    advertisedNextProtocols_.push_back(advertised_item);
    advertisedNextProtocolWeights_.push_back(item.weight);
  }
  if (total_weight == 0) {
    deleteNextProtocolsStrings();
    return false;
  }
  nextProtocolDistribution_ =
      std::discrete_distribution<>(advertisedNextProtocolWeights_.begin(),
                                   advertisedNextProtocolWeights_.end());
  if ((uint8_t)protocolType & (uint8_t)NextProtocolType::NPN) {
    SSL_CTX_set_next_protos_advertised_cb(
        ctx_, advertisedNextProtocolCallback, this);
    SSL_CTX_set_next_proto_select_cb(ctx_, selectNextProtocolCallback, this);
  }
#if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
  if ((uint8_t)protocolType & (uint8_t)NextProtocolType::ALPN) {
    SSL_CTX_set_alpn_select_cb(ctx_, alpnSelectCallback, this);
    // Client cannot really use randomized alpn
    SSL_CTX_set_alpn_protos(ctx_,
                            advertisedNextProtocols_[0].protocols,
                            advertisedNextProtocols_[0].length);
  }
#endif
  return true;
}
示例#2
0
bool SSLContext::setRandomizedAdvertisedNextProtocols(
    const std::list<NextProtocolsItem>& items) {
  unsetNextProtocols();
  if (items.size() == 0) {
    return false;
  }
  int total_weight = 0;
  for (const auto &item : items) {
    if (item.protocols.size() == 0) {
      continue;
    }
    AdvertisedNextProtocolsItem advertised_item;
    advertised_item.length = 0;
    for (const auto& proto : item.protocols) {
      ++advertised_item.length;
      unsigned protoLength = proto.length();
      if (protoLength >= 256) {
        deleteNextProtocolsStrings();
        return false;
      }
      advertised_item.length += protoLength;
    }
    advertised_item.protocols = new unsigned char[advertised_item.length];
    if (!advertised_item.protocols) {
      throw std::runtime_error("alloc failure");
    }
    unsigned char* dst = advertised_item.protocols;
    for (auto& proto : item.protocols) {
      unsigned protoLength = proto.length();
      *dst++ = (unsigned char)protoLength;
      memcpy(dst, proto.data(), protoLength);
      dst += protoLength;
    }
    total_weight += item.weight;
    advertised_item.probability = item.weight;
    advertisedNextProtocols_.push_back(advertised_item);
  }
  if (total_weight == 0) {
    deleteNextProtocolsStrings();
    return false;
  }
  for (auto &advertised_item : advertisedNextProtocols_) {
    advertised_item.probability /= total_weight;
  }
  SSL_CTX_set_next_protos_advertised_cb(
    ctx_, advertisedNextProtocolCallback, this);
  SSL_CTX_set_next_proto_select_cb(
    ctx_, selectNextProtocolCallback, this);
  return true;
}