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;
if (write(c->fd,err,strlen(err)) == -1) {
/* Nothing to do, Just to avoid the warning... */
}
+ server.stat_rejected_conn++;
freeClient(c);
return;
}
} 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);
}
/* 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] = '?';
*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) {
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) {