summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/networking.c')
-rw-r--r--src/networking.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/networking.c b/src/networking.c
index ea54697df..25d2b4c34 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -134,7 +134,7 @@ client *createClient(connection *conn) {
connSetReadHandler(conn, readQueryFromClient);
connSetPrivateData(conn, c);
}
- c->buf = zmalloc(PROTO_REPLY_CHUNK_BYTES);
+ c->buf = zmalloc_usable(PROTO_REPLY_CHUNK_BYTES, &c->buf_usable_size);
selectDb(c,0);
uint64_t client_id;
atomicGetIncr(server.next_client_id, client_id, 1);
@@ -150,7 +150,6 @@ client *createClient(connection *conn) {
c->lib_name = NULL;
c->lib_ver = NULL;
c->bufpos = 0;
- c->buf_usable_size = zmalloc_usable_size(c->buf);
c->buf_peak = c->buf_usable_size;
c->buf_peak_last_reset_time = server.unixtime;
c->ref_repl_buf_node = NULL;
@@ -621,9 +620,9 @@ void addReplyErrorSdsSafe(client *c, sds err) {
addReplyErrorSdsEx(c, err, 0);
}
-/* Internal function used by addReplyErrorFormat and addReplyErrorFormatEx.
+/* Internal function used by addReplyErrorFormat, addReplyErrorFormatEx and RM_ReplyWithErrorFormat.
* Refer to afterErrorReply for more information about the flags. */
-static void addReplyErrorFormatInternal(client *c, int flags, const char *fmt, va_list ap) {
+void addReplyErrorFormatInternal(client *c, int flags, const char *fmt, va_list ap) {
va_list cpy;
va_copy(cpy,ap);
sds s = sdscatvprintf(sdsempty(),fmt,cpy);
@@ -701,11 +700,12 @@ void trimReplyUnusedTailSpace(client *c) {
if (tail->size - tail->used > tail->size / 4 &&
tail->used < PROTO_REPLY_CHUNK_BYTES)
{
+ size_t usable_size;
size_t old_size = tail->size;
- tail = zrealloc(tail, tail->used + sizeof(clientReplyBlock));
+ tail = zrealloc_usable(tail, tail->used + sizeof(clientReplyBlock), &usable_size);
/* take over the allocation's internal fragmentation (at least for
* memory usage tracking) */
- tail->size = zmalloc_usable_size(tail) - sizeof(clientReplyBlock);
+ tail->size = usable_size - sizeof(clientReplyBlock);
c->reply_bytes = c->reply_bytes + tail->size - old_size;
listNodeValue(ln) = tail;
}
@@ -785,9 +785,10 @@ void setDeferredReply(client *c, void *node, const char *s, size_t length) {
listDelNode(c->reply,ln);
} else {
/* Create a new node */
- clientReplyBlock *buf = zmalloc(length + sizeof(clientReplyBlock));
+ size_t usable_size;
+ clientReplyBlock *buf = zmalloc_usable(length + sizeof(clientReplyBlock), &usable_size);
/* Take over the allocation's internal fragmentation */
- buf->size = zmalloc_usable_size(buf) - sizeof(clientReplyBlock);
+ buf->size = usable_size - sizeof(clientReplyBlock);
buf->used = length;
memcpy(buf->buf, s, length);
listNodeValue(ln) = buf;
@@ -872,6 +873,7 @@ void addReplyDouble(client *c, double d) {
const int dlen = d2string(dbuf+7,sizeof(dbuf)-7,d);
int digits = digits10(dlen);
int start = 4 - digits;
+ serverAssert(start >= 0);
dbuf[start] = '$';
/* Convert `dlen` to string, putting it's digits after '$' and before the
@@ -1583,6 +1585,8 @@ void freeClient(client *c) {
c->querybuf = NULL;
/* Deallocate structures used to block on blocking ops. */
+ /* If there is any in-flight command, we don't record their duration. */
+ c->duration = 0;
if (c->flags & CLIENT_BLOCKED) unblockClient(c, 1);
dictRelease(c->bstate.keys);
@@ -2039,8 +2043,10 @@ void resetClient(client *c) {
c->multibulklen = 0;
c->bulklen = -1;
c->slot = -1;
- c->duration = 0;
c->flags &= ~CLIENT_EXECUTING_COMMAND;
+
+ /* Make sure the duration has been recorded to some command. */
+ serverAssert(c->duration == 0);
#ifdef LOG_REQ_RES
reqresReset(c, 1);
#endif
@@ -2337,6 +2343,9 @@ int processMultibulkBuffer(client *c) {
/* Hint the sds library about the amount of bytes this string is
* going to contain. */
c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf,ll+2-sdslen(c->querybuf));
+ /* We later set the peak to the used portion of the buffer, but here we over
+ * allocated because we know what we need, make sure it'll not be shrunk before used. */
+ if (c->querybuf_peak < (size_t)ll + 2) c->querybuf_peak = ll + 2;
}
}
c->bulklen = ll;
@@ -2631,6 +2640,9 @@ void readQueryFromClient(connection *conn) {
* the query buffer, we also don't wanna use the greedy growth, in order
* to avoid collision with the RESIZE_THRESHOLD mechanism. */
c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf, readlen);
+ /* We later set the peak to the used portion of the buffer, but here we over
+ * allocated because we know what we need, make sure it'll not be shrunk before used. */
+ if (c->querybuf_peak < qblen + readlen) c->querybuf_peak = qblen + readlen;
} else {
c->querybuf = sdsMakeRoomFor(c->querybuf, readlen);
@@ -2997,6 +3009,10 @@ void clientCommand(client *c) {
" Control the replies sent to the current connection.",
"SETNAME <name>",
" Assign the name <name> to the current connection.",
+"SETINFO <option> <value>",
+" Set client meta attr. Options are:",
+" * LIB-NAME: the client lib name.",
+" * LIB-VER: the client lib version.",
"UNBLOCK <clientid> [TIMEOUT|ERROR]",
" Unblock the specified blocked client.",
"TRACKING (ON|OFF) [REDIRECT <id>] [BCAST] [PREFIX <prefix> [...]]",
@@ -3606,7 +3622,13 @@ void securityWarningCommand(client *c) {
time_t now = time(NULL);
if (llabs(now-logged_time) > 60) {
- serverLog(LL_WARNING,"Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.");
+ char ip[NET_IP_STR_LEN];
+ int port;
+ if (connAddrPeerName(c->conn, ip, sizeof(ip), &port) == -1) {
+ serverLog(LL_WARNING,"Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection aborted.");
+ } else {
+ serverLog(LL_WARNING,"Possible SECURITY ATTACK detected. It looks like somebody is sending POST or Host: commands to Redis. This is likely due to an attacker attempting to use Cross Protocol Scripting to compromise your Redis instance. Connection from %s:%d aborted.", ip, port);
+ }
logged_time = now;
}
freeClientAsync(c);
@@ -3959,7 +3981,7 @@ void updatePausedActions(void) {
/* Unblock all paused clients (ones that where blocked by BLOCKED_POSTPONE (possibly in processCommand).
* This means they'll get re-processed in beforeSleep, and may get paused again if needed. */
-void unblockPostponedClients() {
+void unblockPostponedClients(void) {
listNode *ln;
listIter li;
listRewind(server.postponed_clients, &li);