X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=client.cpp;h=5d5c179be0e6df019930fb2924cf22be2e7bcab1;hp=4b7bcb7e0bdb7604551e4d146f3bb1a4689e358d;hb=7c23f706733b12405c0cb8793866b57ba5800c98;hpb=f0621e41fdb96ce1bd58e7561e0aa76345072ba3 diff --git a/client.cpp b/client.cpp index 4b7bcb7..5d5c179 100644 --- a/client.cpp +++ b/client.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include #include +#include #include "client.h" #include "log.h" @@ -20,11 +22,6 @@ Client::Client(int sock) { request.reserve(1024); - if (clock_gettime(CLOCK_MONOTONIC_COARSE, &connect_time) == -1) { - log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)"); - return; - } - // Find the remote address, and convert it to ASCII. sockaddr_in6 addr; socklen_t addr_len = sizeof(addr); @@ -54,22 +51,29 @@ 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()), user_agent(serialized.user_agent()), + x_playback_session_id(serialized.x_playback_session_id()), state(State(serialized.state())), request(serialized.request()), url(serialized.url()), stream(stream), - header_or_short_response(serialized.header_or_short_response()), + close_after_response(serialized.close_after_response()), + http_11(serialized.http_11()), 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()) { + // Set back the close-on-exec flag for the socket. + // (This can't leak into a child, since we haven't been started yet.) + fcntl(sock, F_SETFD, O_CLOEXEC); + 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) { @@ -77,6 +81,16 @@ Client::Client(const ClientProto &serialized, Stream *stream) } } } + + 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(); @@ -105,24 +119,39 @@ Client::Client(const ClientProto &serialized, Stream *stream) } } -ClientProto Client::serialize() const +ClientProto Client::serialize(unordered_map *short_response_pool) const { + // Unset the close-on-exec flag for the socket. + // (This can't leak into a child, since there's only one thread left.) + fcntl(sock, F_SETFD, 0); + ClientProto serialized; serialized.set_sock(sock); serialized.set_remote_addr(remote_addr); serialized.set_referer(referer); serialized.set_user_agent(user_agent); + serialized.set_x_playback_session_id(x_playback_session_id); serialized.set_connect_time_sec(connect_time.tv_sec); serialized.set_connect_time_nsec(connect_time.tv_nsec); serialized.set_state(state); serialized.set_request(request); serialized.set_url(url); - serialized.set_header_or_short_response(header_or_short_response); - serialized.set_header_or_short_response_bytes_sent(serialized.header_or_short_response_bytes_sent()); + + 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(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); + serialized.set_http_11(http_11); + serialized.set_close_after_response(close_after_response); if (tls_context != nullptr) { bool small_version = false; @@ -200,5 +229,6 @@ ClientStats Client::get_stats() const stats.bytes_sent = bytes_sent; stats.bytes_lost = bytes_lost; stats.num_loss_events = num_loss_events; + stats.hls_zombie_key = get_hls_zombie_key(); return stats; }