From a031fde5f8343d68e774a7087d3deac287ce3a24 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 22 Oct 2013 16:43:08 +0200 Subject: [SERVER] Refactoring, more debug output, try to check for cyclic proxying --- src/server/altservers.c | 10 +++++----- src/server/helper.h | 7 ++++++- src/server/locks.c | 4 +++- src/server/uplink.c | 9 +++++++++ 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/server/altservers.c b/src/server/altservers.c index e8ef14c..508a649 100644 --- a/src/server/altservers.c +++ b/src/server/altservers.c @@ -92,7 +92,7 @@ int altservers_add(dnbd3_host_t *host, const char *comment, const int isPrivate) int i, freeSlot = -1; spin_lock( &_alts_lock ); for (i = 0; i < _num_alts; ++i) { - if ( is_same_server( &_alt_servers[i].host, host ) ) { + if ( isSameAddressPort( &_alt_servers[i].host, host ) ) { spin_unlock( &_alts_lock ); return FALSE; } else if ( freeSlot == -1 && _alt_servers[i].host.type == 0 ) { @@ -242,7 +242,7 @@ static unsigned int altservers_updateRtt(const dnbd3_host_t * const host, const int i; spin_lock( &_alts_lock ); for (i = 0; i < _num_alts; ++i) { - if ( !is_same_server( host, &_alt_servers[i].host ) ) continue; + if ( !isSameAddressPort( host, &_alt_servers[i].host ) ) continue; _alt_servers[i].rtt[++_alt_servers[i].rttIndex % SERVER_RTT_PROBES] = rtt; #if SERVER_RTT_PROBES == 5 avg = (_alt_servers[i].rtt[0] + _alt_servers[i].rtt[1] + _alt_servers[i].rtt[2] + _alt_servers[i].rtt[3] + _alt_servers[i].rtt[4]) @@ -292,7 +292,7 @@ void altservers_serverFailed(const dnbd3_host_t * const host) const time_t now = time( NULL ); spin_lock( &_alts_lock ); for (i = 0; i < _num_alts; ++i) { - if ( !is_same_server( host, &_alt_servers[i].host ) ) continue; + if ( !isSameAddressPort( host, &_alt_servers[i].host ) ) continue; if ( now - _alt_servers[i].lastFail > SERVER_RTT_DELAY_INIT ) { _alt_servers[i].numFails++; _alt_servers[i].lastFail = now; @@ -381,7 +381,7 @@ static void *altservers_main(void *data) // Add current server if not already in list found = FALSE; for (itAlt = 0; itAlt < numAlts; ++itAlt) { - if ( !is_same_server( &uplink->currentServer, &servers[itAlt] ) ) continue; + if ( !isSameAddressPort( &uplink->currentServer, &servers[itAlt] ) ) continue; found = TRUE; break; } @@ -450,7 +450,7 @@ static void *altservers_main(void *data) // Measurement done - everything fine so far const unsigned int rtt = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000; // µs const unsigned int avg = altservers_updateRtt( &servers[itAlt], rtt ); - if ( uplink->fd != -1 && is_same_server( &servers[itAlt], &uplink->currentServer ) ) { + if ( uplink->fd != -1 && isSameAddressPort( &servers[itAlt], &uplink->currentServer ) ) { currentRtt = avg; close( sock ); } else if ( avg < bestRtt ) { diff --git a/src/server/helper.h b/src/server/helper.h index 301a5ea..95a5157 100644 --- a/src/server/helper.h +++ b/src/server/helper.h @@ -19,7 +19,12 @@ void trim_right(char * const string); void setThreadName(char *name); void blockNoncriticalSignals(); -static inline int is_same_server(const dnbd3_host_t * const a, const dnbd3_host_t * const b) +static inline int isSameAddress(const dnbd3_host_t * const a, const dnbd3_host_t * const b) +{ + return (a->type == b->type) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); +} + +static inline int isSameAddressPort(const dnbd3_host_t * const a, const dnbd3_host_t * const b) { return (a->type == b->type) && (a->port == b->port) && (0 == memcmp( a->addr, b->addr, (a->type == AF_INET ? 4 : 16) )); } diff --git a/src/server/locks.c b/src/server/locks.c index 413d317..72e6069 100644 --- a/src/server/locks.c +++ b/src/server/locks.c @@ -18,7 +18,7 @@ #include "memlog.h" #include "helper.h" -#define MAXLOCKS 500 +#define MAXLOCKS 2000 #define MAXTHREADS 500 #define LOCKLEN 60 typedef struct @@ -69,6 +69,8 @@ int debug_spin_init(const char *name, const char *file, int line, pthread_spinlo } if ( first == -1 ) { printf( "[ERROR] No more free debug locks (%s:%d)\n", file, line ); + pthread_spin_unlock( &initdestory ); + debug_dump_lock_stats(); exit( 4 ); } locks[first].lock = (void*)lock; diff --git a/src/server/uplink.c b/src/server/uplink.c index a21e50e..0f50fa0 100644 --- a/src/server/uplink.c +++ b/src/server/uplink.c @@ -115,6 +115,7 @@ void uplink_removeClient(dnbd3_connection_t *uplink, dnbd3_client_t *client) /** * Request a chunk of data through an uplink server + * Locks on: image.lock, uplink.queueLock */ int uplink_request(dnbd3_client_t *client, uint64_t handle, uint64_t start, uint32_t length) { @@ -122,9 +123,17 @@ int uplink_request(dnbd3_client_t *client, uint64_t handle, uint64_t start, uint spin_lock( &client->image->lock ); if ( client->image->uplink == NULL ) { spin_unlock( &client->image->lock ); + printf( "[DEBUG] Uplink request for image with no uplink (%s)\n", client->image->lower_name ); return FALSE; } dnbd3_connection_t * const uplink = client->image->uplink; + // Check if the client is the same host as the uplink. If so assume this is a circular proxy chain + if ( isSameAddress( &uplink->currentServer, &client->host ) ) { + spin_unlock( &client->image->lock ); + printf( "[DEBUG] Proxy cycle detected.\n" ); + return FALSE; + } + int foundExisting = -1; // Index of a pending request that is a superset of our range, -1 otherwise int existingType = -1; // ULR_* type of existing request int i; -- cgit v1.2.3-55-g7522