Add NTP inspired latency tracking and time sync
parent
8847511596
commit
19172140ba
|
@ -45,6 +45,7 @@ enum rfb_client_to_server_msg_type {
|
||||||
RFB_CLIENT_TO_SERVER_KEY_EVENT = 4,
|
RFB_CLIENT_TO_SERVER_KEY_EVENT = 4,
|
||||||
RFB_CLIENT_TO_SERVER_POINTER_EVENT = 5,
|
RFB_CLIENT_TO_SERVER_POINTER_EVENT = 5,
|
||||||
RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT = 6,
|
RFB_CLIENT_TO_SERVER_CLIENT_CUT_TEXT = 6,
|
||||||
|
RFB_CLIENT_TO_SERVER_NTP = 160,
|
||||||
RFB_CLIENT_TO_SERVER_SET_DESKTOP_SIZE = 251,
|
RFB_CLIENT_TO_SERVER_SET_DESKTOP_SIZE = 251,
|
||||||
RFB_CLIENT_TO_SERVER_QEMU = 255,
|
RFB_CLIENT_TO_SERVER_QEMU = 255,
|
||||||
};
|
};
|
||||||
|
@ -67,6 +68,7 @@ enum rfb_encodings {
|
||||||
RFB_ENCODING_QEMU_EXT_KEY_EVENT = -258,
|
RFB_ENCODING_QEMU_EXT_KEY_EVENT = -258,
|
||||||
RFB_ENCODING_EXTENDEDDESKTOPSIZE = -308,
|
RFB_ENCODING_EXTENDEDDESKTOPSIZE = -308,
|
||||||
RFB_ENCODING_PTS = -1000,
|
RFB_ENCODING_PTS = -1000,
|
||||||
|
RFB_ENCODING_NTP = -1001,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RFB_ENCODING_JPEG_HIGHQ -23
|
#define RFB_ENCODING_JPEG_HIGHQ -23
|
||||||
|
@ -77,6 +79,7 @@ enum rfb_server_to_client_msg_type {
|
||||||
RFB_SERVER_TO_CLIENT_SET_COLOUR_MAP_ENTRIES = 1,
|
RFB_SERVER_TO_CLIENT_SET_COLOUR_MAP_ENTRIES = 1,
|
||||||
RFB_SERVER_TO_CLIENT_BELL = 2,
|
RFB_SERVER_TO_CLIENT_BELL = 2,
|
||||||
RFB_SERVER_TO_CLIENT_SERVER_CUT_TEXT = 3,
|
RFB_SERVER_TO_CLIENT_SERVER_CUT_TEXT = 3,
|
||||||
|
RFB_SERVER_TO_CLIENT_NTP = 160,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum rfb_vencrypt_subtype {
|
enum rfb_vencrypt_subtype {
|
||||||
|
@ -228,3 +231,9 @@ struct rfb_vencrypt_plain_auth_msg {
|
||||||
uint32_t password_len;
|
uint32_t password_len;
|
||||||
char text[0];
|
char text[0];
|
||||||
} RFB_PACKED;
|
} RFB_PACKED;
|
||||||
|
|
||||||
|
struct rfb_ntp_msg {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t padding[3];
|
||||||
|
uint32_t t0, t1, t2, t3;
|
||||||
|
} RFB_PACKED;
|
||||||
|
|
48
src/server.c
48
src/server.c
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
@ -93,6 +94,13 @@ static uint64_t nvnc__htonll(uint64_t x)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint64_t gettime_us(clockid_t clock)
|
||||||
|
{
|
||||||
|
struct timespec ts = { 0 };
|
||||||
|
clock_gettime(clock, &ts);
|
||||||
|
return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void client_close(struct nvnc_client* client)
|
static void client_close(struct nvnc_client* client)
|
||||||
{
|
{
|
||||||
nvnc_log(NVNC_LOG_INFO, "Closing client connection %p: ref %d", client,
|
nvnc_log(NVNC_LOG_INFO, "Closing client connection %p: ref %d", client,
|
||||||
|
@ -512,6 +520,7 @@ static int on_client_set_encodings(struct nvnc_client* client)
|
||||||
case RFB_ENCODING_EXTENDEDDESKTOPSIZE:
|
case RFB_ENCODING_EXTENDEDDESKTOPSIZE:
|
||||||
case RFB_ENCODING_QEMU_EXT_KEY_EVENT:
|
case RFB_ENCODING_QEMU_EXT_KEY_EVENT:
|
||||||
case RFB_ENCODING_PTS:
|
case RFB_ENCODING_PTS:
|
||||||
|
case RFB_ENCODING_NTP:
|
||||||
client->encodings[n++] = encoding;
|
client->encodings[n++] = encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,6 +1043,43 @@ static int on_client_set_desktop_size_event(struct nvnc_client* client)
|
||||||
return sizeof(*msg) + msg->number_of_screens * sizeof(struct rfb_screen);
|
return sizeof(*msg) + msg->number_of_screens * sizeof(struct rfb_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void print_ntp_stats(const struct rfb_ntp_msg *msg)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int32_t t0 = ntohl(msg->t0);
|
||||||
|
int32_t t1 = ntohl(msg->t1);
|
||||||
|
int32_t t2 = ntohl(msg->t2);
|
||||||
|
int32_t t3 = ntohl(msg->t3);
|
||||||
|
|
||||||
|
int32_t round_trip_time = (t3 - t0) - (t2 - t1);
|
||||||
|
int32_t time_difference = ((t1 - t0) + (t2 - t3)) / 2;
|
||||||
|
|
||||||
|
nvnc_log(NVNC_LOG_DEBUG, "NTP: rtt: %.2f ms, time-difference: %.2f ms",
|
||||||
|
round_trip_time / 1e3, time_difference / 1e3);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int on_client_ntp(struct nvnc_client* client)
|
||||||
|
{
|
||||||
|
struct rfb_ntp_msg msg;
|
||||||
|
|
||||||
|
if (client->buffer_len - client->buffer_index < sizeof(msg))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memcpy(&msg, client->msg_buffer + client->buffer_index, sizeof(msg));
|
||||||
|
|
||||||
|
if (msg.t3 != 0) {
|
||||||
|
print_ntp_stats(&msg);
|
||||||
|
return sizeof(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.t1 = htonl(gettime_us(CLOCK_MONOTONIC));
|
||||||
|
msg.t2 = msg.t1; // TODO: Update this when the message is dequeued.
|
||||||
|
|
||||||
|
stream_write(client->net_stream, &msg, sizeof(msg), NULL, NULL);
|
||||||
|
return sizeof(msg);
|
||||||
|
}
|
||||||
|
|
||||||
static int on_client_message(struct nvnc_client* client)
|
static int on_client_message(struct nvnc_client* client)
|
||||||
{
|
{
|
||||||
if (client->buffer_len - client->buffer_index < 1)
|
if (client->buffer_len - client->buffer_index < 1)
|
||||||
|
@ -1059,6 +1105,8 @@ static int on_client_message(struct nvnc_client* client)
|
||||||
return on_client_qemu_event(client);
|
return on_client_qemu_event(client);
|
||||||
case RFB_CLIENT_TO_SERVER_SET_DESKTOP_SIZE:
|
case RFB_CLIENT_TO_SERVER_SET_DESKTOP_SIZE:
|
||||||
return on_client_set_desktop_size_event(client);
|
return on_client_set_desktop_size_event(client);
|
||||||
|
case RFB_CLIENT_TO_SERVER_NTP:
|
||||||
|
return on_client_ntp(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
nvnc_log(NVNC_LOG_WARNING, "Got uninterpretable message from client: %p (ref %d)",
|
nvnc_log(NVNC_LOG_WARNING, "Got uninterpretable message from client: %p (ref %d)",
|
||||||
|
|
Loading…
Reference in New Issue