]> git.sesse.net Git - cubemap/blobdiff - client.cpp
Change the connected time from time_t to timespec.
[cubemap] / client.cpp
index f2d60a62653ea13abad4ff9366e8a2e5fa55ca97..e7a12f6c8ef395691f3dfa86efc12d2fda228efe 100644 (file)
@@ -1,37 +1,58 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
-#include <stdio.h>
+#include <stdint.h>
 #include <sys/socket.h>
 
 #include "client.h"
-#include "markpool.h"
+#include "log.h"
 #include "state.pb.h"
 #include "stream.h"
 
+#ifndef SO_MAX_PACING_RATE
+#define SO_MAX_PACING_RATE 47
+#endif
+
 using namespace std;
 
 Client::Client(int sock)
        : sock(sock),
-         fwmark(0),
-         connect_time(time(NULL)),
          state(Client::READING_REQUEST),
          stream(NULL),
          header_or_error_bytes_sent(0),
-         stream_pos(0)
+         stream_pos(0),
+         bytes_sent(0),
+         bytes_lost(0),
+         num_loss_events(0)
 {
        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);
 
        if (getpeername(sock, reinterpret_cast<sockaddr *>(&addr), &addr_len) == -1) {
-               perror("getpeername");
+               log_perror("getpeername");
                remote_addr = "";
+               return;
+       }
+
+       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) {
+                       log_perror("inet_ntop");
+                       remote_addr = "";
+               } else {
+                       remote_addr = buf;
+               }
        } else {
-               char buf[INET6_ADDRSTRLEN];
                if (inet_ntop(addr.sin6_family, &addr.sin6_addr, buf, sizeof(buf)) == NULL) {
-                       perror("inet_ntop");
+                       log_perror("inet_ntop");
                        remote_addr = "";
                } else {
                        remote_addr = buf;
@@ -42,24 +63,34 @@ Client::Client(int sock)
 Client::Client(const ClientProto &serialized, Stream *stream)
        : sock(serialized.sock()),
          remote_addr(serialized.remote_addr()),
-         connect_time(serialized.connect_time()),
          state(State(serialized.state())),
          request(serialized.request()),
-         stream_id(serialized.stream_id()),
+         url(serialized.url()),
          stream(stream),
          header_or_error(serialized.header_or_error()),
          header_or_error_bytes_sent(serialized.header_or_error_bytes_sent()),
-         stream_pos(serialized.stream_pos())
+         stream_pos(serialized.stream_pos()),
+         bytes_sent(serialized.bytes_sent()),
+         bytes_lost(serialized.bytes_lost()),
+         num_loss_events(serialized.num_loss_events())
 {
-       if (stream != NULL && stream->mark_pool != NULL) {
-               fwmark = stream->mark_pool->get_mark();
-       } else {
-               fwmark = 0;  // No mark.
+       if (stream != NULL) {
+               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 (setsockopt(sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1) {
-               if (fwmark != 0) {
-                       perror("setsockopt(SO_MARK)");
+       if (serialized.has_connect_time_old()) {
+               // Do a rough conversion from time() to monotonic time.
+               if (clock_gettime(CLOCK_MONOTONIC_COARSE, &connect_time) == -1) {
+                       log_perror("clock_gettime(CLOCK_MONOTONIC_COARSE)");
+                       return;
                }
+               connect_time.tv_sec += serialized.connect_time_old() - time(NULL);
+       } else {
+               connect_time.tv_sec = serialized.connect_time_sec();
+               connect_time.tv_nsec = serialized.connect_time_nsec();
        }
 }
 
@@ -68,22 +99,33 @@ ClientProto Client::serialize() const
        ClientProto serialized;
        serialized.set_sock(sock);
        serialized.set_remote_addr(remote_addr);
-       serialized.set_connect_time(connect_time);
+       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_stream_id(stream_id);
+       serialized.set_url(url);
        serialized.set_header_or_error(header_or_error);
        serialized.set_header_or_error_bytes_sent(serialized.header_or_error_bytes_sent());
        serialized.set_stream_pos(stream_pos);
+       serialized.set_bytes_sent(bytes_sent);
+       serialized.set_bytes_lost(bytes_lost);
+       serialized.set_num_loss_events(num_loss_events);
        return serialized;
 }
        
 ClientStats Client::get_stats() const
 {
        ClientStats stats;
-       stats.stream_id = stream_id;
+       if (url.empty()) {
+               stats.url = "-";
+       } else {
+               stats.url = url;
+       }
+       stats.sock = sock;
        stats.remote_addr = remote_addr;
        stats.connect_time = connect_time;
-       stats.bytes_sent = stream_pos;
+       stats.bytes_sent = bytes_sent;
+       stats.bytes_lost = bytes_lost;
+       stats.num_loss_events = num_loss_events;
        return stats;
 }