diff --git a/src/networking.c b/src/networking.c index 4f72e144a..24a601630 100644 --- a/src/networking.c +++ b/src/networking.c @@ -2820,18 +2820,24 @@ NULL } } -/* HELLO [AUTH ] [SETNAME ] */ +/* HELLO [ [AUTH ] [SETNAME ] ] */ void helloCommand(client *c) { - long long ver; + long long ver = 0; + int next_arg = 1; - if (getLongLongFromObject(c->argv[1],&ver) != C_OK || - ver < 2 || ver > 3) - { - addReplyError(c,"-NOPROTO unsupported protocol version"); - return; + if (c->argc >= 2) { + if (getLongLongFromObjectOrReply(c, c->argv[next_arg++], &ver, + "Protocol version is not an integer or out of range") != C_OK) { + return; + } + + if (ver < 2 || ver > 3) { + addReplyError(c,"-NOPROTO unsupported protocol version"); + return; + } } - for (int j = 2; j < c->argc; j++) { + for (int j = next_arg; j < c->argc; j++) { int moreargs = (c->argc-1) - j; const char *opt = c->argv[j]->ptr; if (!strcasecmp(opt,"AUTH") && moreargs >= 2) { @@ -2859,7 +2865,7 @@ void helloCommand(client *c) { } /* Let's switch to the specified RESP mode. */ - c->resp = ver; + if (ver) c->resp = ver; addReplyMapLen(c,6 + !server.sentinel_mode); addReplyBulkCString(c,"server"); @@ -2869,7 +2875,7 @@ void helloCommand(client *c) { addReplyBulkCString(c,REDIS_VERSION); addReplyBulkCString(c,"proto"); - addReplyLongLong(c,ver); + addReplyLongLong(c,c->resp); addReplyBulkCString(c,"id"); addReplyLongLong(c,c->id); diff --git a/src/sentinel.c b/src/sentinel.c index 9764f9004..1c1b4bf5b 100644 --- a/src/sentinel.c +++ b/src/sentinel.c @@ -469,7 +469,7 @@ struct redisCommand sentinelcmds[] = { {"client",clientCommand,-2,"admin random @connection",0,NULL,0,0,0,0,0}, {"shutdown",shutdownCommand,-1,"admin",0,NULL,0,0,0,0,0}, {"auth",authCommand,-2,"no-auth fast @connection",0,NULL,0,0,0,0,0}, - {"hello",helloCommand,-2,"no-auth fast @connection",0,NULL,0,0,0,0,0}, + {"hello",helloCommand,-1,"no-auth fast @connection",0,NULL,0,0,0,0,0}, {"acl",aclCommand,-2,"admin",0,NULL,0,0,0,0,0,0}, {"command",commandCommand,-1, "random @connection", 0,NULL,0,0,0,0,0,0} }; diff --git a/src/server.c b/src/server.c index ad78abeba..90f669bdb 100644 --- a/src/server.c +++ b/src/server.c @@ -869,7 +869,7 @@ struct redisCommand redisCommandTable[] = { "admin no-script random ok-loading ok-stale @connection", 0,NULL,0,0,0,0,0,0}, - {"hello",helloCommand,-2, + {"hello",helloCommand,-1, "no-auth no-script fast no-monitor ok-loading ok-stale no-slowlog @connection", 0,NULL,0,0,0,0,0,0}, diff --git a/tests/unit/tracking.tcl b/tests/unit/tracking.tcl index 555c4e75e..6f8b46c84 100644 --- a/tests/unit/tracking.tcl +++ b/tests/unit/tracking.tcl @@ -135,6 +135,32 @@ start_server {tags {"tracking"}} { assert {[lindex $reply 2] eq {proto 3}} } + test {HELLO without protover} { + set reply [r HELLO 3] + assert {[lindex $reply 2] eq {proto 3}} + + set reply [r HELLO] + assert {[lindex $reply 2] eq {proto 3}} + + set reply [r HELLO] + assert {[lindex $reply 2] eq {proto 3}} + + set reply [r HELLO 2] + assert {[lindex $reply 4] eq "proto"} + assert {[lindex $reply 5] eq 2} + + set reply [r HELLO] + assert {[lindex $reply 4] eq "proto"} + assert {[lindex $reply 5] eq 2} + + set reply [r HELLO] + assert {[lindex $reply 4] eq "proto"} + assert {[lindex $reply 5] eq 2} + + # restore RESP3 for next test + r HELLO 3 + } + test {RESP3 based basic invalidation} { r CLIENT TRACKING off r CLIENT TRACKING on