X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=client.cpp;h=05b8e7d88fcd0b622e2386e84b83abedf0687a24;hp=7c58d515485b03d27e9e26650dacb4c36116781f;hb=1d285bcbfd1aa3f7911cfb98a947a37f68154428;hpb=16a03b9858752fae9e81af261821a2a22855fde3 diff --git a/client.cpp b/client.cpp index 7c58d51..05b8e7d 100644 --- a/client.cpp +++ b/client.cpp @@ -16,18 +16,7 @@ using namespace std; Client::Client(int sock) - : sock(sock), - state(Client::READING_REQUEST), - stream(NULL), - header_or_short_response_bytes_sent(0), - stream_pos(0), - bytes_sent(0), - bytes_lost(0), - num_loss_events(0), - tls_context(NULL), - tls_data_to_send(NULL), - tls_data_left_to_send(0), - in_ktls_mode(false) + : sock(sock) { request.reserve(1024); @@ -49,14 +38,14 @@ Client::Client(int sock) char buf[INET6_ADDRSTRLEN]; if (IN6_IS_ADDR_V4MAPPED(&addr.sin6_addr)) { // IPv4 address, really. - if (inet_ntop(AF_INET, &addr.sin6_addr.s6_addr32[3], buf, sizeof(buf)) == NULL) { + if (inet_ntop(AF_INET, &addr.sin6_addr.s6_addr32[3], buf, sizeof(buf)) == nullptr) { log_perror("inet_ntop"); remote_addr = ""; } else { remote_addr = buf; } } else { - if (inet_ntop(addr.sin6_family, &addr.sin6_addr, buf, sizeof(buf)) == NULL) { + if (inet_ntop(addr.sin6_family, &addr.sin6_addr, buf, sizeof(buf)) == nullptr) { log_perror("inet_ntop"); remote_addr = ""; } else { @@ -65,7 +54,7 @@ Client::Client(int sock) } } -Client::Client(const ClientProto &serialized, Stream *stream) +Client::Client(const ClientProto &serialized, const vector> &short_responses, Stream *stream) : sock(serialized.sock()), remote_addr(serialized.remote_addr()), referer(serialized.referer()), @@ -74,20 +63,30 @@ Client::Client(const ClientProto &serialized, Stream *stream) request(serialized.request()), url(serialized.url()), stream(stream), - header_or_short_response(serialized.header_or_short_response()), header_or_short_response_bytes_sent(serialized.header_or_short_response_bytes_sent()), stream_pos(serialized.stream_pos()), + stream_pos_end(serialized.stream_pos_end()), bytes_sent(serialized.bytes_sent()), bytes_lost(serialized.bytes_lost()), num_loss_events(serialized.num_loss_events()) { - if (stream != NULL) { + if (stream != nullptr) { if (setsockopt(sock, SOL_SOCKET, SO_MAX_PACING_RATE, &stream->pacing_rate, sizeof(stream->pacing_rate)) == -1) { if (stream->pacing_rate != ~0U) { log_perror("setsockopt(SO_MAX_PACING_RATE)"); } } } + + if (serialized.has_header_or_short_response_old()) { + // Pre-1.4.0. + header_or_short_response_holder = serialized.header_or_short_response_old(); + header_or_short_response = &header_or_short_response_holder; + } else if (serialized.has_header_or_short_response_index()) { + assert(size_t(serialized.header_or_short_response_index()) < short_responses.size()); + header_or_short_response_ref = short_responses[serialized.header_or_short_response_index()]; + header_or_short_response = header_or_short_response_ref.get(); + } connect_time.tv_sec = serialized.connect_time_sec(); connect_time.tv_nsec = serialized.connect_time_nsec(); @@ -96,7 +95,7 @@ Client::Client(const ClientProto &serialized, Stream *stream) tls_context = tls_import_context( reinterpret_cast(serialized.tls_context().data()), serialized.tls_context().size()); - if (tls_context == NULL) { + if (tls_context == nullptr) { log(WARNING, "tls_import_context() failed, TLS client might not survive across restart"); } else { tls_data_to_send = tls_get_write_buffer(tls_context, &tls_data_left_to_send); @@ -104,7 +103,7 @@ Client::Client(const ClientProto &serialized, Stream *stream) assert(serialized.tls_output_bytes_already_consumed() <= tls_data_left_to_send); if (serialized.tls_output_bytes_already_consumed() >= tls_data_left_to_send) { tls_buffer_clear(tls_context); - tls_data_to_send = NULL; + tls_data_to_send = nullptr; } else { tls_data_to_send += serialized.tls_output_bytes_already_consumed(); tls_data_left_to_send -= serialized.tls_output_bytes_already_consumed(); @@ -112,11 +111,11 @@ Client::Client(const ClientProto &serialized, Stream *stream) in_ktls_mode = serialized.in_ktls_mode(); } } else { - tls_context = NULL; + tls_context = nullptr; } } -ClientProto Client::serialize() const +ClientProto Client::serialize(unordered_map *short_response_pool) const { ClientProto serialized; serialized.set_sock(sock); @@ -128,16 +127,24 @@ ClientProto Client::serialize() const serialized.set_state(state); serialized.set_request(request); serialized.set_url(url); - serialized.set_header_or_short_response(header_or_short_response); + + if (header_or_short_response != nullptr) { + // See if this string is already in the pool (deduplicated by the pointer); if not, insert it. + auto iterator_and_inserted = short_response_pool->emplace( + header_or_short_response, short_response_pool->size()); + serialized.set_header_or_short_response_index(iterator_and_inserted.first->second); + } + serialized.set_header_or_short_response_bytes_sent(serialized.header_or_short_response_bytes_sent()); serialized.set_stream_pos(stream_pos); + serialized.set_stream_pos_end(stream_pos_end); serialized.set_bytes_sent(bytes_sent); serialized.set_bytes_lost(bytes_lost); serialized.set_num_loss_events(num_loss_events); - if (tls_context != NULL) { + if (tls_context != nullptr) { bool small_version = false; - int required_size = tls_export_context(tls_context, NULL, 0, small_version); + int required_size = tls_export_context(tls_context, nullptr, 0, small_version); if (required_size <= 0) { // Can happen if we're in the middle of the key exchange, unfortunately. // We'll get an error fairly fast, and this client hasn't started playing @@ -164,8 +171,8 @@ ClientProto Client::serialize() const // currently serialize in-progress key exchanges. unsigned base_tls_data_left_to_send; const unsigned char *base_tls_data_to_send = tls_get_write_buffer(tls_context, &base_tls_data_left_to_send); - if (base_tls_data_to_send == NULL) { - assert(tls_data_to_send == NULL); + if (base_tls_data_to_send == nullptr) { + assert(tls_data_to_send == nullptr); } else { assert(tls_data_to_send + tls_data_left_to_send == base_tls_data_to_send + base_tls_data_left_to_send); }