]> git.saurik.com Git - redis.git/blobdiff - src/networking.c
Added regression tests for issue #209
[redis.git] / src / networking.c
index 073bf4dfcb928bbf43e61d0039bda6339d392ef6..c16e182f2653cf218c9a53b6f28de51ef608ecd9 100644 (file)
@@ -36,7 +36,7 @@ redisClient *createClient(int fd) {
     c->reqtype = 0;
     c->argc = 0;
     c->argv = NULL;
-    c->cmd = NULL;
+    c->cmd = c->lastcmd = NULL;
     c->multibulklen = 0;
     c->bulklen = -1;
     c->sentlen = 0;
@@ -419,6 +419,7 @@ static void acceptCommonHandler(int fd) {
         if (write(c->fd,err,strlen(err)) == -1) {
             /* Nothing to do, Just to avoid the warning... */
         }
+        server.stat_rejected_conn++;
         freeClient(c);
         return;
     }
@@ -903,6 +904,13 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) {
     } else {
         return;
     }
+    if (sdslen(c->querybuf) > server.client_max_querybuf_len) {
+        sds ci = getClientInfoString(c);
+        redisLog(REDIS_WARNING,"Closing client that reached max query buffer length: %s", ci);
+        sdsfree(ci);
+        freeClient(c);
+        return;
+    }
     processInputBuffer(c);
 }
 
@@ -926,9 +934,10 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
 
 /* Turn a Redis client into an sds string representing its state. */
 sds getClientInfoString(redisClient *client) {
-    char ip[32], flags[16], *p;
+    char ip[32], flags[16], events[3], *p;
     int port;
     time_t now = time(NULL);
+    int emask;
 
     if (anetPeerToString(client->fd,ip,&port) == -1) {
         ip[0] = '?';
@@ -943,21 +952,47 @@ sds getClientInfoString(redisClient *client) {
             *p++ = 'S';
     }
     if (client->flags & REDIS_MASTER) *p++ = 'M';
-    if (p == flags) *p++ = 'N';
     if (client->flags & REDIS_MULTI) *p++ = 'x';
     if (client->flags & REDIS_BLOCKED) *p++ = 'b';
     if (client->flags & REDIS_DIRTY_CAS) *p++ = 'd';
     if (client->flags & REDIS_CLOSE_AFTER_REPLY) *p++ = 'c';
     if (client->flags & REDIS_UNBLOCKED) *p++ = 'u';
+    if (p == flags) *p++ = 'N';
     *p++ = '\0';
+
+    emask = client->fd == -1 ? 0 : aeGetFileEvents(server.el,client->fd);
+    p = events;
+    if (emask & AE_READABLE) *p++ = 'r';
+    if (emask & AE_WRITABLE) *p++ = 'w';
+    *p = '\0';
     return sdscatprintf(sdsempty(),
-        "addr=%s:%d fd=%d idle=%ld flags=%s db=%d sub=%d psub=%d",
+        "addr=%s:%d fd=%d idle=%ld flags=%s db=%d sub=%d psub=%d qbuf=%lu obl=%lu oll=%lu events=%s cmd=%s",
         ip,port,client->fd,
         (long)(now - client->lastinteraction),
         flags,
         client->db->id,
         (int) dictSize(client->pubsub_channels),
-        (int) listLength(client->pubsub_patterns));
+        (int) listLength(client->pubsub_patterns),
+        (unsigned long) sdslen(client->querybuf),
+        (unsigned long) client->bufpos,
+        (unsigned long) listLength(client->reply),
+        events,
+        client->lastcmd ? client->lastcmd->name : "NULL");
+}
+
+sds getAllClientsInfoString(void) {
+    listNode *ln;
+    listIter li;
+    redisClient *client;
+    sds o = sdsempty();
+
+    listRewind(server.clients,&li);
+    while ((ln = listNext(&li)) != NULL) {
+        client = listNodeValue(ln);
+        o = sdscatsds(o,getClientInfoString(client));
+        o = sdscatlen(o,"\n",1);
+    }
+    return o;
 }
 
 void clientCommand(redisClient *c) {
@@ -966,14 +1001,7 @@ void clientCommand(redisClient *c) {
     redisClient *client;
 
     if (!strcasecmp(c->argv[1]->ptr,"list") && c->argc == 2) {
-        sds o = sdsempty();
-
-        listRewind(server.clients,&li);
-        while ((ln = listNext(&li)) != NULL) {
-            client = listNodeValue(ln);
-            o = sdscatsds(o,getClientInfoString(client));
-            o = sdscatlen(o,"\n",1);
-        }
+        sds o = getAllClientsInfoString();
         addReplyBulkCBuffer(c,o,sdslen(o));
         sdsfree(o);
     } else if (!strcasecmp(c->argv[1]->ptr,"kill") && c->argc == 3) {