From 102705470366b871109d2c3bf182c151ab71eb01 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 17 Oct 2017 12:08:55 +0200 Subject: [*] Support hop-counting in request header, protocol version 3 We steal 8 bits from the request offset to count hops when requests get relayed by proxies. This still leaves plenty of bits for the offset (56 bits, supporting images of up to 72 petabytes). This is used to detect proxy cycles. The algorithm is not perfect but should prevent endless relays of the same request. This is backwards compatible to old clients and servers, as the server only ever sets the hopcount in relayed requests if the upstream server is using protocol version 3 or newer, and clients are automatically upwards compatible as there is practically no image larger than 74PB, so the newly introduced hop count field is always 0 even in requests from old clients. --- src/server/globals.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/server/globals.h') diff --git a/src/server/globals.h b/src/server/globals.h index 379fb8d..b1740f4 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -21,7 +21,7 @@ typedef struct _dnbd3_client dnbd3_client_t; // Must only be set in uplink_request() #define ULR_NEW 1 // Slot is occupied, reply has not yet been received, matching request can safely rely on reuse. -// Must only be set in uplink_mainloop() +// Must only be set in uplink_mainloop() or uplink_request() #define ULR_PENDING 2 // Slot is being processed, do not consider for hop on. // Must only be set in uplink_handle_receive() @@ -34,6 +34,7 @@ typedef struct dnbd3_client_t * client; // Client to send reply to int status; // status of this entry: ULR_* time_t entered; // When this request entered the queue (for debugging) + uint8_t hopCount; // How many hops this request has already taken across proxies } dnbd3_queued_request_t; #define RTT_IDLE 0 // Not in progress @@ -44,16 +45,16 @@ typedef struct struct _dnbd3_connection { int fd; // socket fd to remote server + int version; // remote server protocol version dnbd3_signal_t* signal; // used to wake up the process pthread_t thread; // thread holding the connection pthread_spinlock_t queueLock; // lock for synchronization on request queue etc. - dnbd3_queued_request_t queue[SERVER_MAX_UPLINK_QUEUE]; - int queueLen; // length of queue dnbd3_image_t *image; // image that this uplink is used for; do not call get/release for this pointer dnbd3_host_t currentServer; // Current server we're connected to pthread_spinlock_t rttLock; // When accessing rttTestResult, betterFd or betterServer int rttTestResult; // RTT_* dnbd3_host_t betterServer; // The better server + int betterVersion; // protocol version of better server int betterFd; // Active connection to better server, ready to use uint8_t *recvBuffer; // Buffer for receiving payload uint32_t recvBufferLen; // Len of ^^ @@ -62,6 +63,8 @@ struct _dnbd3_connection int nextReplicationIndex; // Which index in the cache map we should start looking for incomplete blocks at uint64_t replicationHandle; // Handle of pending replication request uint64_t bytesReceived; // Number of bytes received by the connection. + int queueLen; // length of queue + dnbd3_queued_request_t queue[SERVER_MAX_UPLINK_QUEUE]; }; typedef struct -- cgit v1.2.3-55-g7522