From 1587f73c38c9228a1a93889aae6351eff891cbe8 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 2 Nov 2017 13:41:35 +0100 Subject: [SERVER] Support finer control over replication when a proxy connects to a proxy Introduce new flag in "select image" message to tell the uplink server whether we have background replication enabled or not. Also reject a connecting proxy if the connecting proxy uses BGR but we don't, as this would basically force the image to be replicated locally too. --- src/server/altservers.c | 2 +- src/server/globals.c | 2 ++ src/server/globals.h | 7 +++++++ src/server/image.c | 2 +- src/server/net.c | 24 ++++++++++++++++++++++-- 5 files changed, 33 insertions(+), 4 deletions(-) (limited to 'src/server') diff --git a/src/server/altservers.c b/src/server/altservers.c index 28ea91e..2ae0d16 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -437,7 +437,7 @@ static void *altservers_main(void *data UNUSED) int sock = sock_connect( &servers[itAlt], 750, _uplinkTimeout ); if ( sock < 0 ) continue; // Select image ++++++++++++++++++++++++++++++ - if ( !dnbd3_select_image( sock, image->name, image->rid, FLAGS8_SERVER ) ) { + if ( !dnbd3_select_image( sock, image->name, image->rid, SI_SERVER_FLAGS ) ) { goto server_failed; } // See if selecting the image succeeded ++++++++++++++++++++++++++++++ diff --git a/src/server/globals.c b/src/server/globals.c index d6f077b..50d7885 100644 --- a/src/server/globals.c +++ b/src/server/globals.c @@ -14,6 +14,7 @@ bool _removeMissingImages = true; bool _isProxy = false; bool _proxyPrivateOnly = false; bool _backgroundReplication = true; +bool _lookupMissingForProxy = true; int _listenPort = PORT; int _uplinkTimeout = SOCKET_TIMEOUT_UPLINK; int _clientTimeout = SOCKET_TIMEOUT_CLIENT; @@ -32,6 +33,7 @@ static int ini_handler(void *custom UNUSED, const char* section, const char* key SAVE_TO_VAR_BOOL( dnbd3, isProxy ); SAVE_TO_VAR_BOOL( dnbd3, proxyPrivateOnly ); SAVE_TO_VAR_BOOL( dnbd3, backgroundReplication ); + SAVE_TO_VAR_BOOL( dnbd3, lookupMissingForProxy ); SAVE_TO_VAR_BOOL( dnbd3, removeMissingImages ); SAVE_TO_VAR_BOOL( dnbd3, closeUnusedFd ); SAVE_TO_VAR_INT( dnbd3, serverPenalty ); diff --git a/src/server/globals.h b/src/server/globals.h index 2dbabd5..1475981 100644 --- a/src/server/globals.h +++ b/src/server/globals.h @@ -206,6 +206,13 @@ extern bool _closeUnusedFd; */ extern bool _backgroundReplication; +/** + * (In proxy mode): If connecting client is a proxy, and the requested image + * is not known locally, should we ask our known alt servers for it? + * Otherwise the request is rejected. + */ +extern bool _lookupMissingForProxy; + /** * Port to listen on (default: #define PORT (5003)) */ diff --git a/src/server/image.c b/src/server/image.c index e356dbf..91d7572 100644 --- a/src/server/image.c +++ b/src/server/image.c @@ -1236,7 +1236,7 @@ static dnbd3_image_t *loadImageProxy(char * const name, const uint16_t revision, bool ok = false; int sock = sock_connect( &servers[i], 750, _uplinkTimeout ); if ( sock == -1 ) continue; - if ( !dnbd3_select_image( sock, name, revision, FLAGS8_SERVER ) ) goto server_fail; + if ( !dnbd3_select_image( sock, name, revision, SI_SERVER_FLAGS ) ) goto server_fail; if ( !dnbd3_select_image_reply( &serialized, sock, &remoteProtocolVersion, &remoteName, &remoteRid, &remoteImageSize ) ) goto server_fail; if ( remoteProtocolVersion < MIN_SUPPORTED_SERVER || remoteRid == 0 ) goto server_fail; if ( revision != 0 && remoteRid != revision ) goto server_fail; // Want specific revision but uplink supplied different rid diff --git a/src/server/net.c b/src/server/net.c index 5866f25..1e484ac 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -27,6 +27,7 @@ #include "../shared/sockhelper.h" #include "../shared/timing.h" +#include "../shared/protocol.h" #include "../serialize.h" #include @@ -251,7 +252,8 @@ void* net_handleNewConnection(void *clientPtr) client_version = serializer_get_uint16( &payload ); image_name = serializer_get_string( &payload ); rid = serializer_get_uint16( &payload ); - client->isServer = serializer_get_uint8( &payload ); + const uint8_t flags = serializer_get_uint8( &payload ); + client->isServer = ( flags & FLAGS8_SERVER ); if ( request.size < 3 || !image_name || client_version < MIN_SUPPORTED_CLIENT ) { if ( client_version < MIN_SUPPORTED_CLIENT ) { logadd( LOG_DEBUG1, "Client %s too old", client->hostName ); @@ -259,7 +261,25 @@ void* net_handleNewConnection(void *clientPtr) logadd( LOG_DEBUG1, "Incomplete handshake received from %s", client->hostName ); } } else { - image = image_getOrLoad( image_name, rid ); + if ( !client->isServer || !_isProxy ) { + // Is a normal client, or we're not proxy + image = image_getOrLoad( image_name, rid ); + } else if ( !_backgroundReplication && ( flags & FLAGS8_BG_REP ) ) { + // We're a proxy, client is another proxy, we don't do BGR, but connecting proxy does... + // Reject, as this would basically force this proxy to do BGR too. + image = image_get( image_name, rid, true ); + if ( image != NULL && image->cache_map != NULL ) { + // Only exception is if the image is complete locally + image = image_release( image ); + } + } else if ( _lookupMissingForProxy ) { + // No BGR mismatch and we're told to lookup missing images on a known uplink server + // if the requesting client is a proxy + image = image_getOrLoad( image_name, rid ); + } else { + // No BGR mismatch, but don't lookup if image is unknown locally + image = image_get( image_name, rid, true ); + } spin_lock( &client->lock ); client->image = image; spin_unlock( &client->lock ); -- cgit v1.2.3-55-g7522