diff options
author | Simon Rettberg | 2017-10-17 12:08:55 +0200 |
---|---|---|
committer | Simon Rettberg | 2017-10-17 12:08:55 +0200 |
commit | 102705470366b871109d2c3bf182c151ab71eb01 (patch) | |
tree | b174c068ab12967491ff78458523c842b04f7b92 /src/server/altservers.c | |
parent | [SERVER] rpc: Support querying storage size + available space (diff) | |
download | dnbd3-102705470366b871109d2c3bf182c151ab71eb01.tar.gz dnbd3-102705470366b871109d2c3bf182c151ab71eb01.tar.xz dnbd3-102705470366b871109d2c3bf182c151ab71eb01.zip |
[*] 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.
Diffstat (limited to 'src/server/altservers.c')
-rw-r--r-- | src/server/altservers.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/src/server/altservers.c b/src/server/altservers.c index bf9d8f2..1e4af7e 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -407,6 +407,7 @@ static void *altservers_main(void *data UNUSED) // Test them all int bestSock = -1; int bestIndex = -1; + int bestProtocolVersion = -1; unsigned int bestRtt = 0xfffffff; unsigned int currentRtt = 0xfffffff; for (itAlt = 0; itAlt < numAlts; ++itAlt) { @@ -439,7 +440,7 @@ static void *altservers_main(void *data UNUSED) imageSize, image->virtualFilesize, image->name ); } // Request first block (NOT random!) ++++++++++++++++++++++++++++++ - if ( !dnbd3_get_block( sock, 0, DNBD3_BLOCK_SIZE, 0 ) ) { + if ( !dnbd3_get_block( sock, 0, DNBD3_BLOCK_SIZE, 0, COND_HOPCOUNT( protocolVersion, 1 ) ) ) { ERROR_GOTO( server_failed, "[RTT] Could not request first block for %s", image->name ); } // See if requesting the block succeeded ++++++++++++++++++++++ @@ -471,6 +472,7 @@ static void *altservers_main(void *data UNUSED) bestSock = sock; bestRtt = avg; bestIndex = itAlt; + bestProtocolVersion = protocolVersion; } else { // Was too slow, ignore close( sock ); @@ -492,6 +494,7 @@ static void *altservers_main(void *data UNUSED) spin_lock( &uplink->rttLock ); uplink->betterFd = bestSock; uplink->betterServer = servers[bestIndex]; + uplink->betterVersion = bestProtocolVersion; uplink->rttTestResult = RTT_DOCHANGE; spin_unlock( &uplink->rttLock ); signal_call( uplink->signal ); |