| // Copyright 2014 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/quic/crypto/quic_server_info.h" |
| |
| #include <limits> |
| |
| #include "base/pickle.h" |
| |
| using std::string; |
| |
| namespace { |
| |
| const int kQuicCryptoConfigVersion = 1; |
| |
| } // namespace |
| |
| namespace net { |
| |
| QuicServerInfo::State::State() {} |
| |
| QuicServerInfo::State::~State() {} |
| |
| void QuicServerInfo::State::Clear() { |
| server_config.clear(); |
| source_address_token.clear(); |
| server_config_sig.clear(); |
| certs.clear(); |
| } |
| |
| QuicServerInfo::QuicServerInfo(const QuicServerId& server_id) |
| : server_id_(server_id) { |
| } |
| |
| QuicServerInfo::~QuicServerInfo() { |
| } |
| |
| const QuicServerInfo::State& QuicServerInfo::state() const { |
| return state_; |
| } |
| |
| QuicServerInfo::State* QuicServerInfo::mutable_state() { |
| return &state_; |
| } |
| |
| bool QuicServerInfo::Parse(const string& data) { |
| State* state = mutable_state(); |
| |
| state->Clear(); |
| |
| bool r = ParseInner(data); |
| if (!r) |
| state->Clear(); |
| return r; |
| } |
| |
| bool QuicServerInfo::ParseInner(const string& data) { |
| State* state = mutable_state(); |
| |
| // No data was read from the disk cache. |
| if (data.empty()) { |
| return false; |
| } |
| |
| Pickle p(data.data(), data.size()); |
| PickleIterator iter(p); |
| |
| int version = -1; |
| if (!p.ReadInt(&iter, &version)) { |
| DVLOG(1) << "Missing version"; |
| return false; |
| } |
| |
| if (version != kQuicCryptoConfigVersion) { |
| DVLOG(1) << "Unsupported version"; |
| return false; |
| } |
| |
| if (!p.ReadString(&iter, &state->server_config)) { |
| DVLOG(1) << "Malformed server_config"; |
| return false; |
| } |
| if (!p.ReadString(&iter, &state->source_address_token)) { |
| DVLOG(1) << "Malformed source_address_token"; |
| return false; |
| } |
| if (!p.ReadString(&iter, &state->server_config_sig)) { |
| DVLOG(1) << "Malformed server_config_sig"; |
| return false; |
| } |
| |
| // Read certs. |
| uint32 num_certs; |
| if (!p.ReadUInt32(&iter, &num_certs)) { |
| DVLOG(1) << "Malformed num_certs"; |
| return false; |
| } |
| |
| for (uint32 i = 0; i < num_certs; i++) { |
| string cert; |
| if (!p.ReadString(&iter, &cert)) { |
| DVLOG(1) << "Malformed cert"; |
| return false; |
| } |
| state->certs.push_back(cert); |
| } |
| |
| return true; |
| } |
| |
| string QuicServerInfo::Serialize() { |
| string pickled_data = SerializeInner(); |
| state_.Clear(); |
| return pickled_data; |
| } |
| |
| string QuicServerInfo::SerializeInner() const { |
| Pickle p(sizeof(Pickle::Header)); |
| |
| if (!p.WriteInt(kQuicCryptoConfigVersion) || |
| !p.WriteString(state_.server_config) || |
| !p.WriteString(state_.source_address_token) || |
| !p.WriteString(state_.server_config_sig) || |
| state_.certs.size() > std::numeric_limits<uint32>::max() || |
| !p.WriteUInt32(state_.certs.size())) { |
| return string(); |
| } |
| |
| for (size_t i = 0; i < state_.certs.size(); i++) { |
| if (!p.WriteString(state_.certs[i])) { |
| return string(); |
| } |
| } |
| |
| return string(reinterpret_cast<const char *>(p.data()), p.size()); |
| } |
| |
| QuicServerInfoFactory::~QuicServerInfoFactory() {} |
| |
| } // namespace net |