1 /* 2 * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * * Neither the name of Redis nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "redis.h" 31 #include <sys/uio.h> 32 33 static void setProtocolError(redisClient *c, int pos); 34 35 /* To evaluate the output buffer size of a client we need to get size of 36 * allocated objects, however we can't used zmalloc_size() directly on sds 37 * strings because of the trick they use to work (the header is before the 38 * returned pointer), so we use this helper function. */ 39 size_t zmalloc_size_sds(sds s) { 40 return zmalloc_size(s-sizeof(struct sdshdr)); 41 } 42 43 void *dupClientReplyValue(void *o) { 44 incrRefCount((robj*)o); 45 return o; 46 } 47 48 int listMatchObjects(void *a, void *b) { 49 return equalStringObjects(a,b); 50 } 51 52 redisClient *createClient(int fd) { 53 redisClient *c = zmalloc(sizeof(redisClient)); 54 55 /* passing -1 as fd it is possible to create a non connected client. 56 * This is useful since all the Redis commands needs to be executed 57 * in the context of a client. When commands are executed in other 58 * contexts (for instance a Lua script) we need a non connected client. */ 59 if (fd != -1) { 60 anetNonBlock(NULL,fd); 61 anetTcpNoDelay(NULL,fd); 62 if (aeCreateFileEvent(server.el,fd,AE_READABLE, 63 readQueryFromClient, c) == AE_ERR) 64 { 65 close(fd); 66 zfree(c); 67 return NULL; 68 } 69 } 70 71 selectDb(c,0); 72 c->fd = fd; 73 c->name = NULL; 74 c->bufpos = 0; 75 c->querybuf = sdsempty(); 76 c->querybuf_peak = 0; 77 c->reqtype = 0; 78 c->argc = 0; 79 c->argv = NULL; 80 c->cmd = c->lastcmd = NULL; 81 c->multibulklen = 0; 82 c->bulklen = -1; 83 c->sentlen = 0; 84 c->flags = 0; 85 c->ctime = c->lastinteraction = server.unixtime; 86 c->authenticated = 0; 87 c->replstate = REDIS_REPL_NONE; 88 c->slave_listening_port = 0; 89 c->reply = listCreate(); 90 c->reply_bytes = 0; 91 c->obuf_soft_limit_reached_time = 0; 92 listSetFreeMethod(c->reply,decrRefCountVoid); 93 listSetDupMethod(c->reply,dupClientReplyValue); 94 c->bpop.keys = dictCreate(&setDictType,NULL); 95 c->bpop.timeout = 0; 96 c->bpop.target = NULL; 97 c->io_keys = listCreate(); 98 c->watched_keys = listCreate(); 99 listSetFreeMethod(c->io_keys,decrRefCountVoid); 100 c->pubsub_channels = dictCreate(&setDictType,NULL); 101 c->pubsub_patterns = listCreate(); 102 listSetFreeMethod(c->pubsub_patterns,decrRefCountVoid); 103 listSetMatchMethod(c->pubsub_patterns,listMatchObjects); 104 if (fd != -1) listAddNodeTail(server.clients,c); 105 initClientMultiState(c); 106 return c; 107 } 108 109 /* This function is called every time we are going to transmit new data 110 * to the client. The behavior is the following: 111 * 112 * If the client should receive new data (normal clients will) the function 113 * returns REDIS_OK, and make sure to install the write handler in our event 114 * loop so that when the socket is writable new data gets written. 115 * 116 * If the client should not receive new data, because it is a fake client 117 * or a slave, or because the setup of the write handler failed, the function 118 * returns REDIS_ERR. 119 * 120 * Typically gets called every time a reply is built, before adding more 121 * data to the clients output buffers. If the function returns REDIS_ERR no 122 * data should be appended to the output buffers. */ 123 int prepareClientToWrite(redisClient *c) { 124 if (c->flags & REDIS_LUA_CLIENT) return REDIS_OK; 125 if (c->fd <= 0) return REDIS_ERR; /* Fake client */ 126 if (c->bufpos == 0 && listLength(c->reply) == 0 && 127 (c->replstate == REDIS_REPL_NONE || 128 c->replstate == REDIS_REPL_ONLINE) && 129 aeCreateFileEvent(server.el, c->fd, AE_WRITABLE, 130 sendReplyToClient, c) == AE_ERR) return REDIS_ERR; 131 return REDIS_OK; 132 } 133 134 /* Create a duplicate of the last object in the reply list when 135 * it is not exclusively owned by the reply list. */ 136 robj *dupLastObjectIfNeeded(list *reply) { 137 robj *new, *cur; 138 listNode *ln; 139 redisAssert(listLength(reply) > 0); 140 ln = listLast(reply); 141 cur = listNodeValue(ln); 142 if (cur->refcount > 1) { 143 new = dupStringObject(cur); 144 decrRefCount(cur); 145 listNodeValue(ln) = new; 146 } 147 return listNodeValue(ln); 148 } 149 150 /* ----------------------------------------------------------------------------- 151 * Low level functions to add more data to output buffers. 152 * -------------------------------------------------------------------------- */ 153 154 int _addReplyToBuffer(redisClient *c, char *s, size_t len) { 155 size_t available = sizeof(c->buf)-c->bufpos; 156 157 if (c->flags & REDIS_CLOSE_AFTER_REPLY) return REDIS_OK; 158 159 /* If there already are entries in the reply list, we cannot 160 * add anything more to the static buffer. */ 161 if (listLength(c->reply) > 0) return REDIS_ERR; 162 163 /* Check that the buffer has enough space available for this string. */ 164 if (len > available) return REDIS_ERR; 165 166 memcpy(c->buf+c->bufpos,s,len); 167 c->bufpos+=len; 168 return REDIS_OK; 169 } 170 171 void _addReplyObjectToList(redisClient *c, robj *o) { 172 robj *tail; 173 174 if (c->flags & REDIS_CLOSE_AFTER_REPLY) return; 175 176 if (listLength(c->reply) == 0) { 177 incrRefCount(o); 178 listAddNodeTail(c->reply,o); 179 c->reply_bytes += zmalloc_size_sds(o->ptr); 180 } else { 181 tail = listNodeValue(listLast(c->reply)); 182 183 /* Append to this object when possible. */ 184 if (tail->ptr != NULL && 185 sdslen(tail->ptr)+sdslen(o->ptr) <= REDIS_REPLY_CHUNK_BYTES) 186 { 187 c->reply_bytes -= zmalloc_size_sds(tail->ptr); 188 tail = dupLastObjectIfNeeded(c->reply); 189 tail->ptr = sdscatlen(tail->ptr,o->ptr,sdslen(o->ptr)); 190 c->reply_bytes += zmalloc_size_sds(tail->ptr); 191 } else { 192 incrRefCount(o); 193 listAddNodeTail(c->reply,o); 194 c->reply_bytes += zmalloc_size_sds(o->ptr); 195 } 196 } 197 asyncCloseClientOnOutputBufferLimitReached(c); 198 } 199 200 /* This method takes responsibility over the sds. When it is no longer 201 * needed it will be free'd, otherwise it ends up in a robj. */ 202 void _addReplySdsToList(redisClient *c, sds s) { 203 robj *tail; 204 205 if (c->flags & REDIS_CLOSE_AFTER_REPLY) { 206 sdsfree(s); 207 return; 208 } 209 210 if (listLength(c->reply) == 0) { 211 listAddNodeTail(c->reply,createObject(REDIS_STRING,s)); 212 c->reply_bytes += zmalloc_size_sds(s); 213 } else { 214 tail = listNodeValue(listLast(c->reply)); 215 216 /* Append to this object when possible. */ 217 if (tail->ptr != NULL && 218 sdslen(tail->ptr)+sdslen(s) <= REDIS_REPLY_CHUNK_BYTES) 219 { 220 c->reply_bytes -= zmalloc_size_sds(tail->ptr); 221 tail = dupLastObjectIfNeeded(c->reply); 222 tail->ptr = sdscatlen(tail->ptr,s,sdslen(s)); 223 c->reply_bytes += zmalloc_size_sds(tail->ptr); 224 sdsfree(s); 225 } else { 226 listAddNodeTail(c->reply,createObject(REDIS_STRING,s)); 227 c->reply_bytes += zmalloc_size_sds(s); 228 } 229 } 230 asyncCloseClientOnOutputBufferLimitReached(c); 231 } 232 233 void _addReplyStringToList(redisClient *c, char *s, size_t len) { 234 robj *tail; 235 236 if (c->flags & REDIS_CLOSE_AFTER_REPLY) return; 237 238 if (listLength(c->reply) == 0) { 239 robj *o = createStringObject(s,len); 240 241 listAddNodeTail(c->reply,o); 242 c->reply_bytes += zmalloc_size_sds(o->ptr); 243 } else { 244 tail = listNodeValue(listLast(c->reply)); 245 246 /* Append to this object when possible. */ 247 if (tail->ptr != NULL && 248 sdslen(tail->ptr)+len <= REDIS_REPLY_CHUNK_BYTES) 249 { 250 c->reply_bytes -= zmalloc_size_sds(tail->ptr); 251 tail = dupLastObjectIfNeeded(c->reply); 252 tail->ptr = sdscatlen(tail->ptr,s,len); 253 c->reply_bytes += zmalloc_size_sds(tail->ptr); 254 } else { 255 robj *o = createStringObject(s,len); 256 257 listAddNodeTail(c->reply,o); 258 c->reply_bytes += zmalloc_size_sds(o->ptr); 259 } 260 } 261 asyncCloseClientOnOutputBufferLimitReached(c); 262 } 263 264 /* ----------------------------------------------------------------------------- 265 * Higher level functions to queue data on the client output buffer. 266 * The following functions are the ones that commands implementations will call. 267 * -------------------------------------------------------------------------- */ 268 269 void addReply(redisClient *c, robj *obj) { 270 if (prepareClientToWrite(c) != REDIS_OK) return; 271 272 /* This is an important place where we can avoid copy-on-write 273 * when there is a saving child running, avoiding touching the 274 * refcount field of the object if it's not needed. 275 * 276 * If the encoding is RAW and there is room in the static buffer 277 * we'll be able to send the object to the client without 278 * messing with its page. */ 279 if (obj->encoding == REDIS_ENCODING_RAW) { 280 if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK) 281 _addReplyObjectToList(c,obj); 282 } else if (obj->encoding == REDIS_ENCODING_INT) { 283 /* Optimization: if there is room in the static buffer for 32 bytes 284 * (more than the max chars a 64 bit integer can take as string) we 285 * avoid decoding the object and go for the lower level approach. */ 286 if (listLength(c->reply) == 0 && (sizeof(c->buf) - c->bufpos) >= 32) { 287 char buf[32]; 288 int len; 289 290 len = ll2string(buf,sizeof(buf),(long)obj->ptr); 291 if (_addReplyToBuffer(c,buf,len) == REDIS_OK) 292 return; 293 /* else... continue with the normal code path, but should never 294 * happen actually since we verified there is room. */ 295 } 296 obj = getDecodedObject(obj); 297 if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK) 298 _addReplyObjectToList(c,obj); 299 decrRefCount(obj); 300 } else { 301 redisPanic("Wrong obj->encoding in addReply()"); 302 } 303 } 304 305 void addReplySds(redisClient *c, sds s) { 306 if (prepareClientToWrite(c) != REDIS_OK) { 307 /* The caller expects the sds to be free'd. */ 308 sdsfree(s); 309 return; 310 } 311 if (_addReplyToBuffer(c,s,sdslen(s)) == REDIS_OK) { 312 sdsfree(s); 313 } else { 314 /* This method free's the sds when it is no longer needed. */ 315 _addReplySdsToList(c,s); 316 } 317 } 318 319 void addReplyString(redisClient *c, char *s, size_t len) { 320 if (prepareClientToWrite(c) != REDIS_OK) return; 321 if (_addReplyToBuffer(c,s,len) != REDIS_OK) 322 _addReplyStringToList(c,s,len); 323 } 324 325 void addReplyErrorLength(redisClient *c, char *s, size_t len) { 326 addReplyString(c,"-ERR ",5); 327 addReplyString(c,s,len); 328 addReplyString(c,"\r\n",2); 329 } 330 331 void addReplyError(redisClient *c, char *err) { 332 addReplyErrorLength(c,err,strlen(err)); 333 } 334 335 void addReplyErrorFormat(redisClient *c, const char *fmt, ...) { 336 size_t l, j; 337 va_list ap; 338 va_start(ap,fmt); 339 sds s = sdscatvprintf(sdsempty(),fmt,ap); 340 va_end(ap); 341 /* Make sure there are no newlines in the string, otherwise invalid protocol 342 * is emitted. */ 343 l = sdslen(s); 344 for (j = 0; j < l; j++) { 345 if (s[j] == '\r' || s[j] == '\n') s[j] = ' '; 346 } 347 addReplyErrorLength(c,s,sdslen(s)); 348 sdsfree(s); 349 } 350 351 void addReplyStatusLength(redisClient *c, char *s, size_t len) { 352 addReplyString(c,"+",1); 353 addReplyString(c,s,len); 354 addReplyString(c,"\r\n",2); 355 } 356 357 void addReplyStatus(redisClient *c, char *status) { 358 addReplyStatusLength(c,status,strlen(status)); 359 } 360 361 void addReplyStatusFormat(redisClient *c, const char *fmt, ...) { 362 va_list ap; 363 va_start(ap,fmt); 364 sds s = sdscatvprintf(sdsempty(),fmt,ap); 365 va_end(ap); 366 addReplyStatusLength(c,s,sdslen(s)); 367 sdsfree(s); 368 } 369 370 /* Adds an empty object to the reply list that will contain the multi bulk 371 * length, which is not known when this function is called. */ 372 void *addDeferredMultiBulkLength(redisClient *c) { 373 /* Note that we install the write event here even if the object is not 374 * ready to be sent, since we are sure that before returning to the 375 * event loop setDeferredMultiBulkLength() will be called. */ 376 if (prepareClientToWrite(c) != REDIS_OK) return NULL; 377 listAddNodeTail(c->reply,createObject(REDIS_STRING,NULL)); 378 return listLast(c->reply); 379 } 380 381 /* Populate the length object and try gluing it to the next chunk. */ 382 void setDeferredMultiBulkLength(redisClient *c, void *node, long length) { 383 listNode *ln = (listNode*)node; 384 robj *len, *next; 385 386 /* Abort when *node is NULL (see addDeferredMultiBulkLength). */ 387 if (node == NULL) return; 388 389 len = listNodeValue(ln); 390 len->ptr = sdscatprintf(sdsempty(),"*%ld\r\n",length); 391 c->reply_bytes += zmalloc_size_sds(len->ptr); 392 if (ln->next != NULL) { 393 next = listNodeValue(ln->next); 394 395 /* Only glue when the next node is non-NULL (an sds in this case) */ 396 if (next->ptr != NULL) { 397 c->reply_bytes -= zmalloc_size_sds(len->ptr); 398 c->reply_bytes -= zmalloc_size_sds(next->ptr); 399 len->ptr = sdscatlen(len->ptr,next->ptr,sdslen(next->ptr)); 400 c->reply_bytes += zmalloc_size_sds(len->ptr); 401 listDelNode(c->reply,ln->next); 402 } 403 } 404 asyncCloseClientOnOutputBufferLimitReached(c); 405 } 406 407 /* Add a double as a bulk reply */ 408 void addReplyDouble(redisClient *c, double d) { 409 char dbuf[128], sbuf[128]; 410 int dlen, slen; 411 dlen = snprintf(dbuf,sizeof(dbuf),"%.17g",d); 412 slen = snprintf(sbuf,sizeof(sbuf),"$%d\r\n%s\r\n",dlen,dbuf); 413 addReplyString(c,sbuf,slen); 414 } 415 416 /* Add a long long as integer reply or bulk len / multi bulk count. 417 * Basically this is used to output <prefix><long long><crlf>. */ 418 void addReplyLongLongWithPrefix(redisClient *c, long long ll, char prefix) { 419 char buf[128]; 420 int len; 421 422 /* Things like $3\r\n or *2\r\n are emitted very often by the protocol 423 * so we have a few shared objects to use if the integer is small 424 * like it is most of the times. */ 425 if (prefix == '*' && ll < REDIS_SHARED_BULKHDR_LEN) { 426 addReply(c,shared.mbulkhdr[ll]); 427 return; 428 } else if (prefix == '$' && ll < REDIS_SHARED_BULKHDR_LEN) { 429 addReply(c,shared.bulkhdr[ll]); 430 return; 431 } 432 433 buf[0] = prefix; 434 len = ll2string(buf+1,sizeof(buf)-1,ll); 435 buf[len+1] = '\r'; 436 buf[len+2] = '\n'; 437 addReplyString(c,buf,len+3); 438 } 439 440 void addReplyLongLong(redisClient *c, long long ll) { 441 if (ll == 0) 442 addReply(c,shared.czero); 443 else if (ll == 1) 444 addReply(c,shared.cone); 445 else 446 addReplyLongLongWithPrefix(c,ll,':'); 447 } 448 449 void addReplyMultiBulkLen(redisClient *c, long length) { 450 addReplyLongLongWithPrefix(c,length,'*'); 451 } 452 453 /* Create the length prefix of a bulk reply, example: $2234 */ 454 void addReplyBulkLen(redisClient *c, robj *obj) { 455 size_t len; 456 457 if (obj->encoding == REDIS_ENCODING_RAW) { 458 len = sdslen(obj->ptr); 459 } else { 460 long n = (long)obj->ptr; 461 462 /* Compute how many bytes will take this integer as a radix 10 string */ 463 len = 1; 464 if (n < 0) { 465 len++; 466 n = -n; 467 } 468 while((n = n/10) != 0) { 469 len++; 470 } 471 } 472 addReplyLongLongWithPrefix(c,len,'$'); 473 } 474 475 /* Add a Redis Object as a bulk reply */ 476 void addReplyBulk(redisClient *c, robj *obj) { 477 addReplyBulkLen(c,obj); 478 addReply(c,obj); 479 addReply(c,shared.crlf); 480 } 481 482 /* Add a C buffer as bulk reply */ 483 void addReplyBulkCBuffer(redisClient *c, void *p, size_t len) { 484 addReplyLongLongWithPrefix(c,len,'$'); 485 addReplyString(c,p,len); 486 addReply(c,shared.crlf); 487 } 488 489 /* Add a C nul term string as bulk reply */ 490 void addReplyBulkCString(redisClient *c, char *s) { 491 if (s == NULL) { 492 addReply(c,shared.nullbulk); 493 } else { 494 addReplyBulkCBuffer(c,s,strlen(s)); 495 } 496 } 497 498 /* Add a long long as a bulk reply */ 499 void addReplyBulkLongLong(redisClient *c, long long ll) { 500 char buf[64]; 501 int len; 502 503 len = ll2string(buf,64,ll); 504 addReplyBulkCBuffer(c,buf,len); 505 } 506 507 /* Copy 'src' client output buffers into 'dst' client output buffers. 508 * The function takes care of freeing the old output buffers of the 509 * destination client. */ 510 void copyClientOutputBuffer(redisClient *dst, redisClient *src) { 511 listRelease(dst->reply); 512 dst->reply = listDup(src->reply); 513 memcpy(dst->buf,src->buf,src->bufpos); 514 dst->bufpos = src->bufpos; 515 dst->reply_bytes = src->reply_bytes; 516 } 517 518 static void acceptCommonHandler(int fd, int flags) { 519 redisClient *c; 520 if ((c = createClient(fd)) == NULL) { 521 redisLog(REDIS_WARNING, 522 "Error registering fd event for the new client: %s (fd=%d)", 523 strerror(errno),fd); 524 close(fd); /* May be already closed, just ignore errors */ 525 return; 526 } 527 /* If maxclient directive is set and this is one client more... close the 528 * connection. Note that we create the client instead to check before 529 * for this condition, since now the socket is already set in non-blocking 530 * mode and we can send an error for free using the Kernel I/O */ 531 if (listLength(server.clients) > server.maxclients) { 532 char *err = "-ERR max number of clients reached\r\n"; 533 534 /* That's a best effort error message, don't check write errors */ 535 if (write(c->fd,err,strlen(err)) == -1) { 536 /* Nothing to do, Just to avoid the warning... */ 537 } 538 server.stat_rejected_conn++; 539 freeClient(c); 540 return; 541 } 542 server.stat_numconnections++; 543 c->flags |= flags; 544 } 545 546 void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 547 int cport, cfd; 548 char cip[128]; 549 REDIS_NOTUSED(el); 550 REDIS_NOTUSED(mask); 551 REDIS_NOTUSED(privdata); 552 553 cfd = anetTcpAccept(server.neterr, fd, cip, &cport); 554 if (cfd == AE_ERR) { 555 redisLog(REDIS_WARNING,"Accepting client connection: %s", server.neterr); 556 return; 557 } 558 redisLog(REDIS_VERBOSE,"Accepted %s:%d", cip, cport); 559 acceptCommonHandler(cfd,0); 560 } 561 562 void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) { 563 int cfd; 564 REDIS_NOTUSED(el); 565 REDIS_NOTUSED(mask); 566 REDIS_NOTUSED(privdata); 567 568 cfd = anetUnixAccept(server.neterr, fd); 569 if (cfd == AE_ERR) { 570 redisLog(REDIS_WARNING,"Accepting client connection: %s", server.neterr); 571 return; 572 } 573 redisLog(REDIS_VERBOSE,"Accepted connection to %s", server.unixsocket); 574 acceptCommonHandler(cfd,REDIS_UNIX_SOCKET); 575 } 576 577 578 static void freeClientArgv(redisClient *c) { 579 int j; 580 for (j = 0; j < c->argc; j++) 581 decrRefCount(c->argv[j]); 582 c->argc = 0; 583 c->cmd = NULL; 584 } 585 586 /* Close all the slaves connections. This is useful in chained replication 587 * when we resync with our own master and want to force all our slaves to 588 * resync with us as well. */ 589 void disconnectSlaves(void) { 590 while (listLength(server.slaves)) { 591 listNode *ln = listFirst(server.slaves); 592 freeClient((redisClient*)ln->value); 593 } 594 } 595 596 void freeClient(redisClient *c) { 597 listNode *ln; 598 599 /* If this is marked as current client unset it */ 600 if (server.current_client == c) server.current_client = NULL; 601 602 /* Note that if the client we are freeing is blocked into a blocking 603 * call, we have to set querybuf to NULL *before* to call 604 * unblockClientWaitingData() to avoid processInputBuffer() will get 605 * called. Also it is important to remove the file events after 606 * this, because this call adds the READABLE event. */ 607 sdsfree(c->querybuf); 608 c->querybuf = NULL; 609 if (c->flags & REDIS_BLOCKED) 610 unblockClientWaitingData(c); 611 dictRelease(c->bpop.keys); 612 613 /* UNWATCH all the keys */ 614 unwatchAllKeys(c); 615 listRelease(c->watched_keys); 616 /* Unsubscribe from all the pubsub channels */ 617 pubsubUnsubscribeAllChannels(c,0); 618 pubsubUnsubscribeAllPatterns(c,0); 619 dictRelease(c->pubsub_channels); 620 listRelease(c->pubsub_patterns); 621 /* Obvious cleanup */ 622 aeDeleteFileEvent(server.el,c->fd,AE_READABLE); 623 aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); 624 listRelease(c->reply); 625 freeClientArgv(c); 626 close(c->fd); 627 /* Remove from the list of clients */ 628 ln = listSearchKey(server.clients,c); 629 redisAssert(ln != NULL); 630 listDelNode(server.clients,ln); 631 /* When client was just unblocked because of a blocking operation, 632 * remove it from the list with unblocked clients. */ 633 if (c->flags & REDIS_UNBLOCKED) { 634 ln = listSearchKey(server.unblocked_clients,c); 635 redisAssert(ln != NULL); 636 listDelNode(server.unblocked_clients,ln); 637 } 638 listRelease(c->io_keys); 639 /* Master/slave cleanup. 640 * Case 1: we lost the connection with a slave. */ 641 if (c->flags & REDIS_SLAVE) { 642 if (c->replstate == REDIS_REPL_SEND_BULK && c->repldbfd != -1) 643 close(c->repldbfd); 644 list *l = (c->flags & REDIS_MONITOR) ? server.monitors : server.slaves; 645 ln = listSearchKey(l,c); 646 redisAssert(ln != NULL); 647 listDelNode(l,ln); 648 } 649 650 /* Case 2: we lost the connection with the master. */ 651 if (c->flags & REDIS_MASTER) { 652 server.master = NULL; 653 server.repl_state = REDIS_REPL_CONNECT; 654 server.repl_down_since = server.unixtime; 655 /* We lost connection with our master, force our slaves to resync 656 * with us as well to load the new data set. 657 * 658 * If server.masterhost is NULL the user called SLAVEOF NO ONE so 659 * slave resync is not needed. */ 660 if (server.masterhost != NULL) disconnectSlaves(); 661 } 662 663 /* If this client was scheduled for async freeing we need to remove it 664 * from the queue. */ 665 if (c->flags & REDIS_CLOSE_ASAP) { 666 ln = listSearchKey(server.clients_to_close,c); 667 redisAssert(ln != NULL); 668 listDelNode(server.clients_to_close,ln); 669 } 670 671 /* Release memory */ 672 if (c->name) decrRefCount(c->name); 673 zfree(c->argv); 674 freeClientMultiState(c); 675 zfree(c); 676 } 677 678 /* Schedule a client to free it at a safe time in the serverCron() function. 679 * This function is useful when we need to terminate a client but we are in 680 * a context where calling freeClient() is not possible, because the client 681 * should be valid for the continuation of the flow of the program. */ 682 void freeClientAsync(redisClient *c) { 683 if (c->flags & REDIS_CLOSE_ASAP) return; 684 c->flags |= REDIS_CLOSE_ASAP; 685 listAddNodeTail(server.clients_to_close,c); 686 } 687 688 void freeClientsInAsyncFreeQueue(void) { 689 while (listLength(server.clients_to_close)) { 690 listNode *ln = listFirst(server.clients_to_close); 691 redisClient *c = listNodeValue(ln); 692 693 c->flags &= ~REDIS_CLOSE_ASAP; 694 freeClient(c); 695 listDelNode(server.clients_to_close,ln); 696 } 697 } 698 699 void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask) { 700 redisClient *c = privdata; 701 int nwritten = 0, totwritten = 0, objlen; 702 size_t objmem; 703 robj *o; 704 REDIS_NOTUSED(el); 705 REDIS_NOTUSED(mask); 706 707 while(c->bufpos > 0 || listLength(c->reply)) { 708 if (c->bufpos > 0) { 709 if (c->flags & REDIS_MASTER) { 710 /* Don't reply to a master */ 711 nwritten = c->bufpos - c->sentlen; 712 } else { 713 nwritten = write(fd,c->buf+c->sentlen,c->bufpos-c->sentlen); 714 if (nwritten <= 0) break; 715 } 716 c->sentlen += nwritten; 717 totwritten += nwritten; 718 719 /* If the buffer was sent, set bufpos to zero to continue with 720 * the remainder of the reply. */ 721 if (c->sentlen == c->bufpos) { 722 c->bufpos = 0; 723 c->sentlen = 0; 724 } 725 } else { 726 o = listNodeValue(listFirst(c->reply)); 727 objlen = sdslen(o->ptr); 728 objmem = zmalloc_size_sds(o->ptr); 729 730 if (objlen == 0) { 731 listDelNode(c->reply,listFirst(c->reply)); 732 continue; 733 } 734 735 if (c->flags & REDIS_MASTER) { 736 /* Don't reply to a master */ 737 nwritten = objlen - c->sentlen; 738 } else { 739 nwritten = write(fd, ((char*)o->ptr)+c->sentlen,objlen-c->sentlen); 740 if (nwritten <= 0) break; 741 } 742 c->sentlen += nwritten; 743 totwritten += nwritten; 744 745 /* If we fully sent the object on head go to the next one */ 746 if (c->sentlen == objlen) { 747 listDelNode(c->reply,listFirst(c->reply)); 748 c->sentlen = 0; 749 c->reply_bytes -= objmem; 750 } 751 } 752 /* Note that we avoid to send more than REDIS_MAX_WRITE_PER_EVENT 753 * bytes, in a single threaded server it's a good idea to serve 754 * other clients as well, even if a very large request comes from 755 * super fast link that is always able to accept data (in real world 756 * scenario think about 'KEYS *' against the loopback interface). 757 * 758 * However if we are over the maxmemory limit we ignore that and 759 * just deliver as much data as it is possible to deliver. */ 760 if (totwritten > REDIS_MAX_WRITE_PER_EVENT && 761 (server.maxmemory == 0 || 762 zmalloc_used_memory() < server.maxmemory)) break; 763 } 764 if (nwritten == -1) { 765 if (errno == EAGAIN) { 766 nwritten = 0; 767 } else { 768 redisLog(REDIS_VERBOSE, 769 "Error writing to client: %s", strerror(errno)); 770 freeClient(c); 771 return; 772 } 773 } 774 if (totwritten > 0) c->lastinteraction = server.unixtime; 775 if (c->bufpos == 0 && listLength(c->reply) == 0) { 776 c->sentlen = 0; 777 aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); 778 779 /* Close connection after entire reply has been sent. */ 780 if (c->flags & REDIS_CLOSE_AFTER_REPLY) freeClient(c); 781 } 782 } 783 784 /* resetClient prepare the client to process the next command */ 785 void resetClient(redisClient *c) { 786 freeClientArgv(c); 787 c->reqtype = 0; 788 c->multibulklen = 0; 789 c->bulklen = -1; 790 /* We clear the ASKING flag as well if we are not inside a MULTI. */ 791 if (!(c->flags & REDIS_MULTI)) c->flags &= (~REDIS_ASKING); 792 } 793 794 int processInlineBuffer(redisClient *c) { 795 char *newline = strstr(c->querybuf,"\r\n"); 796 int argc, j; 797 sds *argv; 798 size_t querylen; 799 800 /* Nothing to do without a \r\n */ 801 if (newline == NULL) { 802 if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) { 803 addReplyError(c,"Protocol error: too big inline request"); 804 setProtocolError(c,0); 805 } 806 return REDIS_ERR; 807 } 808 809 /* Split the input buffer up to the \r\n */ 810 querylen = newline-(c->querybuf); 811 argv = sdssplitlen(c->querybuf,querylen," ",1,&argc); 812 813 /* Leave data after the first line of the query in the buffer */ 814 c->querybuf = sdsrange(c->querybuf,querylen+2,-1); 815 816 /* Setup argv array on client structure */ 817 if (c->argv) zfree(c->argv); 818 c->argv = zmalloc(sizeof(robj*)*argc); 819 820 /* Create redis objects for all arguments. */ 821 for (c->argc = 0, j = 0; j < argc; j++) { 822 if (sdslen(argv[j])) { 823 c->argv[c->argc] = createObject(REDIS_STRING,argv[j]); 824 c->argc++; 825 } else { 826 sdsfree(argv[j]); 827 } 828 } 829 zfree(argv); 830 return REDIS_OK; 831 } 832 833 /* Helper function. Trims query buffer to make the function that processes 834 * multi bulk requests idempotent. */ 835 static void setProtocolError(redisClient *c, int pos) { 836 if (server.verbosity >= REDIS_VERBOSE) { 837 sds client = getClientInfoString(c); 838 redisLog(REDIS_VERBOSE, 839 "Protocol error from client: %s", client); 840 sdsfree(client); 841 } 842 c->flags |= REDIS_CLOSE_AFTER_REPLY; 843 c->querybuf = sdsrange(c->querybuf,pos,-1); 844 } 845 846 int processMultibulkBuffer(redisClient *c) { 847 char *newline = NULL; 848 int pos = 0, ok; 849 long long ll; 850 851 if (c->multibulklen == 0) { 852 /* The client should have been reset */ 853 redisAssertWithInfo(c,NULL,c->argc == 0); 854 855 /* Multi bulk length cannot be read without a \r\n */ 856 newline = strchr(c->querybuf,'\r'); 857 if (newline == NULL) { 858 if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) { 859 addReplyError(c,"Protocol error: too big mbulk count string"); 860 setProtocolError(c,0); 861 } 862 return REDIS_ERR; 863 } 864 865 /* Buffer should also contain \n */ 866 if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2)) 867 return REDIS_ERR; 868 869 /* We know for sure there is a whole line since newline != NULL, 870 * so go ahead and find out the multi bulk length. */ 871 redisAssertWithInfo(c,NULL,c->querybuf[0] == '*'); 872 ok = string2ll(c->querybuf+1,newline-(c->querybuf+1),&ll); 873 if (!ok || ll > 1024*1024) { 874 addReplyError(c,"Protocol error: invalid multibulk length"); 875 setProtocolError(c,pos); 876 return REDIS_ERR; 877 } 878 879 pos = (newline-c->querybuf)+2; 880 if (ll <= 0) { 881 c->querybuf = sdsrange(c->querybuf,pos,-1); 882 return REDIS_OK; 883 } 884 885 c->multibulklen = ll; 886 887 /* Setup argv array on client structure */ 888 if (c->argv) zfree(c->argv); 889 c->argv = zmalloc(sizeof(robj*)*c->multibulklen); 890 } 891 892 redisAssertWithInfo(c,NULL,c->multibulklen > 0); 893 while(c->multibulklen) { 894 /* Read bulk length if unknown */ 895 if (c->bulklen == -1) { 896 newline = strchr(c->querybuf+pos,'\r'); 897 if (newline == NULL) { 898 if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) { 899 addReplyError(c,"Protocol error: too big bulk count string"); 900 setProtocolError(c,0); 901 } 902 break; 903 } 904 905 /* Buffer should also contain \n */ 906 if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2)) 907 break; 908 909 if (c->querybuf[pos] != '$') { 910 addReplyErrorFormat(c, 911 "Protocol error: expected '$', got '%c'", 912 c->querybuf[pos]); 913 setProtocolError(c,pos); 914 return REDIS_ERR; 915 } 916 917 ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll); 918 if (!ok || ll < 0 || ll > 512*1024*1024) { 919 addReplyError(c,"Protocol error: invalid bulk length"); 920 setProtocolError(c,pos); 921 return REDIS_ERR; 922 } 923 924 pos += newline-(c->querybuf+pos)+2; 925 if (ll >= REDIS_MBULK_BIG_ARG) { 926 /* If we are going to read a large object from network 927 * try to make it likely that it will start at c->querybuf 928 * boundary so that we can optimized object creation 929 * avoiding a large copy of data. */ 930 c->querybuf = sdsrange(c->querybuf,pos,-1); 931 pos = 0; 932 /* Hint the sds library about the amount of bytes this string is 933 * going to contain. */ 934 c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2); 935 } 936 c->bulklen = ll; 937 } 938 939 /* Read bulk argument */ 940 if (sdslen(c->querybuf)-pos < (unsigned)(c->bulklen+2)) { 941 /* Not enough data (+2 == trailing \r\n) */ 942 break; 943 } else { 944 /* Optimization: if the buffer contains JUST our bulk element 945 * instead of creating a new object by *copying* the sds we 946 * just use the current sds string. */ 947 if (pos == 0 && 948 c->bulklen >= REDIS_MBULK_BIG_ARG && 949 (signed) sdslen(c->querybuf) == c->bulklen+2) 950 { 951 c->argv[c->argc++] = createObject(REDIS_STRING,c->querybuf); 952 sdsIncrLen(c->querybuf,-2); /* remove CRLF */ 953 c->querybuf = sdsempty(); 954 /* Assume that if we saw a fat argument we'll see another one 955 * likely... */ 956 c->querybuf = sdsMakeRoomFor(c->querybuf,c->bulklen+2); 957 pos = 0; 958 } else { 959 c->argv[c->argc++] = 960 createStringObject(c->querybuf+pos,c->bulklen); 961 pos += c->bulklen+2; 962 } 963 c->bulklen = -1; 964 c->multibulklen--; 965 } 966 } 967 968 /* Trim to pos */ 969 if (pos) c->querybuf = sdsrange(c->querybuf,pos,-1); 970 971 /* We're done when c->multibulk == 0 */ 972 if (c->multibulklen == 0) return REDIS_OK; 973 974 /* Still not read to process the command */ 975 return REDIS_ERR; 976 } 977 978 void processInputBuffer(redisClient *c) { 979 /* Keep processing while there is something in the input buffer */ 980 while(sdslen(c->querybuf)) { 981 /* Immediately abort if the client is in the middle of something. */ 982 if (c->flags & REDIS_BLOCKED) return; 983 984 /* REDIS_CLOSE_AFTER_REPLY closes the connection once the reply is 985 * written to the client. Make sure to not let the reply grow after 986 * this flag has been set (i.e. don't process more commands). */ 987 if (c->flags & REDIS_CLOSE_AFTER_REPLY) return; 988 989 /* Determine request type when unknown. */ 990 if (!c->reqtype) { 991 if (c->querybuf[0] == '*') { 992 c->reqtype = REDIS_REQ_MULTIBULK; 993 } else { 994 c->reqtype = REDIS_REQ_INLINE; 995 } 996 } 997 998 if (c->reqtype == REDIS_REQ_INLINE) { 999 if (processInlineBuffer(c) != REDIS_OK) break; 1000 } else if (c->reqtype == REDIS_REQ_MULTIBULK) { 1001 if (processMultibulkBuffer(c) != REDIS_OK) break; 1002 } else { 1003 redisPanic("Unknown request type"); 1004 } 1005 1006 /* Multibulk processing could see a <= 0 length. */ 1007 if (c->argc == 0) { 1008 resetClient(c); 1009 } else { 1010 /* Only reset the client when the command was executed. */ 1011 if (processCommand(c) == REDIS_OK) 1012 resetClient(c); 1013 } 1014 } 1015 } 1016 1017 void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { 1018 redisClient *c = (redisClient*) privdata; 1019 int nread, readlen; 1020 size_t qblen; 1021 REDIS_NOTUSED(el); 1022 REDIS_NOTUSED(mask); 1023 1024 server.current_client = c; 1025 readlen = REDIS_IOBUF_LEN; 1026 /* If this is a multi bulk request, and we are processing a bulk reply 1027 * that is large enough, try to maximize the probability that the query 1028 * buffer contains exactly the SDS string representing the object, even 1029 * at the risk of requiring more read(2) calls. This way the function 1030 * processMultiBulkBuffer() can avoid copying buffers to create the 1031 * Redis Object representing the argument. */ 1032 if (c->reqtype == REDIS_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1 1033 && c->bulklen >= REDIS_MBULK_BIG_ARG) 1034 { 1035 int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf); 1036 1037 if (remaining < readlen) readlen = remaining; 1038 } 1039 1040 qblen = sdslen(c->querybuf); 1041 if (c->querybuf_peak < qblen) c->querybuf_peak = qblen; 1042 c->querybuf = sdsMakeRoomFor(c->querybuf, readlen); 1043 nread = read(fd, c->querybuf+qblen, readlen); 1044 if (nread == -1) { 1045 if (errno == EAGAIN) { 1046 nread = 0; 1047 } else { 1048 redisLog(REDIS_VERBOSE, "Reading from client: %s",strerror(errno)); 1049 freeClient(c); 1050 return; 1051 } 1052 } else if (nread == 0) { 1053 redisLog(REDIS_VERBOSE, "Client closed connection"); 1054 freeClient(c); 1055 return; 1056 } 1057 if (nread) { 1058 sdsIncrLen(c->querybuf,nread); 1059 c->lastinteraction = server.unixtime; 1060 } else { 1061 server.current_client = NULL; 1062 return; 1063 } 1064 if (sdslen(c->querybuf) > server.client_max_querybuf_len) { 1065 sds ci = getClientInfoString(c), bytes = sdsempty(); 1066 1067 bytes = sdscatrepr(bytes,c->querybuf,64); 1068 redisLog(REDIS_WARNING,"Closing client that reached max query buffer length: %s (qbuf initial bytes: %s)", ci, bytes); 1069 sdsfree(ci); 1070 sdsfree(bytes); 1071 freeClient(c); 1072 return; 1073 } 1074 processInputBuffer(c); 1075 server.current_client = NULL; 1076 } 1077 1078 void getClientsMaxBuffers(unsigned long *longest_output_list, 1079 unsigned long *biggest_input_buffer) { 1080 redisClient *c; 1081 listNode *ln; 1082 listIter li; 1083 unsigned long lol = 0, bib = 0; 1084 1085 listRewind(server.clients,&li); 1086 while ((ln = listNext(&li)) != NULL) { 1087 c = listNodeValue(ln); 1088 1089 if (listLength(c->reply) > lol) lol = listLength(c->reply); 1090 if (sdslen(c->querybuf) > bib) bib = sdslen(c->querybuf); 1091 } 1092 *longest_output_list = lol; 1093 *biggest_input_buffer = bib; 1094 } 1095 1096 /* Turn a Redis client into an sds string representing its state. */ 1097 sds getClientInfoString(redisClient *client) { 1098 char ip[32], flags[16], events[3], *p; 1099 int port = 0; /* initialized to zero for the unix socket case. */ 1100 int emask; 1101 1102 if (!(client->flags & REDIS_UNIX_SOCKET)) 1103 anetPeerToString(client->fd,ip,&port); 1104 p = flags; 1105 if (client->flags & REDIS_SLAVE) { 1106 if (client->flags & REDIS_MONITOR) 1107 *p++ = 'O'; 1108 else 1109 *p++ = 'S'; 1110 } 1111 if (client->flags & REDIS_MASTER) *p++ = 'M'; 1112 if (client->flags & REDIS_MULTI) *p++ = 'x'; 1113 if (client->flags & REDIS_BLOCKED) *p++ = 'b'; 1114 if (client->flags & REDIS_DIRTY_CAS) *p++ = 'd'; 1115 if (client->flags & REDIS_CLOSE_AFTER_REPLY) *p++ = 'c'; 1116 if (client->flags & REDIS_UNBLOCKED) *p++ = 'u'; 1117 if (client->flags & REDIS_CLOSE_ASAP) *p++ = 'A'; 1118 if (client->flags & REDIS_UNIX_SOCKET) *p++ = 'U'; 1119 if (p == flags) *p++ = 'N'; 1120 *p++ = '\0'; 1121 1122 emask = client->fd == -1 ? 0 : aeGetFileEvents(server.el,client->fd); 1123 p = events; 1124 if (emask & AE_READABLE) *p++ = 'r'; 1125 if (emask & AE_WRITABLE) *p++ = 'w'; 1126 *p = '\0'; 1127 return sdscatprintf(sdsempty(), 1128 "addr=%s:%d fd=%d name=%s age=%ld idle=%ld flags=%s db=%d sub=%d psub=%d multi=%d qbuf=%lu qbuf-free=%lu obl=%lu oll=%lu omem=%lu events=%s cmd=%s", 1129 (client->flags & REDIS_UNIX_SOCKET) ? server.unixsocket : ip, 1130 port, 1131 client->fd, 1132 client->name ? (char*)client->name->ptr : "", 1133 (long)(server.unixtime - client->ctime), 1134 (long)(server.unixtime - client->lastinteraction), 1135 flags, 1136 client->db->id, 1137 (int) dictSize(client->pubsub_channels), 1138 (int) listLength(client->pubsub_patterns), 1139 (client->flags & REDIS_MULTI) ? client->mstate.count : -1, 1140 (unsigned long) sdslen(client->querybuf), 1141 (unsigned long) sdsavail(client->querybuf), 1142 (unsigned long) client->bufpos, 1143 (unsigned long) listLength(client->reply), 1144 getClientOutputBufferMemoryUsage(client), 1145 events, 1146 client->lastcmd ? client->lastcmd->name : "NULL"); 1147 } 1148 1149 sds getAllClientsInfoString(void) { 1150 listNode *ln; 1151 listIter li; 1152 redisClient *client; 1153 sds o = sdsempty(); 1154 1155 listRewind(server.clients,&li); 1156 while ((ln = listNext(&li)) != NULL) { 1157 sds cs; 1158 1159 client = listNodeValue(ln); 1160 cs = getClientInfoString(client); 1161 o = sdscatsds(o,cs); 1162 sdsfree(cs); 1163 o = sdscatlen(o,"\n",1); 1164 } 1165 return o; 1166 } 1167 1168 void clientCommand(redisClient *c) { 1169 listNode *ln; 1170 listIter li; 1171 redisClient *client; 1172 1173 if (!strcasecmp(c->argv[1]->ptr,"list") && c->argc == 2) { 1174 sds o = getAllClientsInfoString(); 1175 addReplyBulkCBuffer(c,o,sdslen(o)); 1176 sdsfree(o); 1177 } else if (!strcasecmp(c->argv[1]->ptr,"kill") && c->argc == 3) { 1178 listRewind(server.clients,&li); 1179 while ((ln = listNext(&li)) != NULL) { 1180 char ip[32], addr[64]; 1181 int port; 1182 1183 client = listNodeValue(ln); 1184 if (anetPeerToString(client->fd,ip,&port) == -1) continue; 1185 snprintf(addr,sizeof(addr),"%s:%d",ip,port); 1186 if (strcmp(addr,c->argv[2]->ptr) == 0) { 1187 addReply(c,shared.ok); 1188 if (c == client) { 1189 client->flags |= REDIS_CLOSE_AFTER_REPLY; 1190 } else { 1191 freeClient(client); 1192 } 1193 return; 1194 } 1195 } 1196 addReplyError(c,"No such client"); 1197 } else if (!strcasecmp(c->argv[1]->ptr,"setname") && c->argc == 3) { 1198 int j, len = sdslen(c->argv[2]->ptr); 1199 char *p = c->argv[2]->ptr; 1200 1201 /* Setting the client name to an empty string actually removes 1202 * the current name. */ 1203 if (len == 0) { 1204 if (c->name) decrRefCount(c->name); 1205 c->name = NULL; 1206 addReply(c,shared.ok); 1207 return; 1208 } 1209 1210 /* Otherwise check if the charset is ok. We need to do this otherwise 1211 * CLIENT LIST format will break. You should always be able to 1212 * split by space to get the different fields. */ 1213 for (j = 0; j < len; j++) { 1214 if (p[j] < '!' || p[j] > '~') { /* ASCII is assumed. */ 1215 addReplyError(c, 1216 "Client names cannot contain spaces, " 1217 "newlines or special characters."); 1218 return; 1219 } 1220 } 1221 if (c->name) decrRefCount(c->name); 1222 c->name = c->argv[2]; 1223 incrRefCount(c->name); 1224 addReply(c,shared.ok); 1225 } else if (!strcasecmp(c->argv[1]->ptr,"getname") && c->argc == 2) { 1226 if (c->name) 1227 addReplyBulk(c,c->name); 1228 else 1229 addReply(c,shared.nullbulk); 1230 } else { 1231 addReplyError(c, "Syntax error, try CLIENT (LIST | KILL ip:port | GETNAME | SETNAME connection-name)"); 1232 } 1233 } 1234 1235 /* Rewrite the command vector of the client. All the new objects ref count 1236 * is incremented. The old command vector is freed, and the old objects 1237 * ref count is decremented. */ 1238 void rewriteClientCommandVector(redisClient *c, int argc, ...) { 1239 va_list ap; 1240 int j; 1241 robj **argv; /* The new argument vector */ 1242 1243 argv = zmalloc(sizeof(robj*)*argc); 1244 va_start(ap,argc); 1245 for (j = 0; j < argc; j++) { 1246 robj *a; 1247 1248 a = va_arg(ap, robj*); 1249 argv[j] = a; 1250 incrRefCount(a); 1251 } 1252 /* We free the objects in the original vector at the end, so we are 1253 * sure that if the same objects are reused in the new vector the 1254 * refcount gets incremented before it gets decremented. */ 1255 for (j = 0; j < c->argc; j++) decrRefCount(c->argv[j]); 1256 zfree(c->argv); 1257 /* Replace argv and argc with our new versions. */ 1258 c->argv = argv; 1259 c->argc = argc; 1260 c->cmd = lookupCommand(c->argv[0]->ptr); 1261 redisAssertWithInfo(c,NULL,c->cmd != NULL); 1262 va_end(ap); 1263 } 1264 1265 /* Rewrite a single item in the command vector. 1266 * The new val ref count is incremented, and the old decremented. */ 1267 void rewriteClientCommandArgument(redisClient *c, int i, robj *newval) { 1268 robj *oldval; 1269 1270 redisAssertWithInfo(c,NULL,i < c->argc); 1271 oldval = c->argv[i]; 1272 c->argv[i] = newval; 1273 incrRefCount(newval); 1274 decrRefCount(oldval); 1275 1276 /* If this is the command name make sure to fix c->cmd. */ 1277 if (i == 0) { 1278 c->cmd = lookupCommand(c->argv[0]->ptr); 1279 redisAssertWithInfo(c,NULL,c->cmd != NULL); 1280 } 1281 } 1282 1283 /* This function returns the number of bytes that Redis is virtually 1284 * using to store the reply still not read by the client. 1285 * It is "virtual" since the reply output list may contain objects that 1286 * are shared and are not really using additional memory. 1287 * 1288 * The function returns the total sum of the length of all the objects 1289 * stored in the output list, plus the memory used to allocate every 1290 * list node. The static reply buffer is not taken into account since it 1291 * is allocated anyway. 1292 * 1293 * Note: this function is very fast so can be called as many time as 1294 * the caller wishes. The main usage of this function currently is 1295 * enforcing the client output length limits. */ 1296 unsigned long getClientOutputBufferMemoryUsage(redisClient *c) { 1297 unsigned long list_item_size = sizeof(listNode)+sizeof(robj); 1298 1299 return c->reply_bytes + (list_item_size*listLength(c->reply)); 1300 } 1301 1302 /* Get the class of a client, used in order to enforce limits to different 1303 * classes of clients. 1304 * 1305 * The function will return one of the following: 1306 * REDIS_CLIENT_LIMIT_CLASS_NORMAL -> Normal client 1307 * REDIS_CLIENT_LIMIT_CLASS_SLAVE -> Slave or client executing MONITOR command 1308 * REDIS_CLIENT_LIMIT_CLASS_PUBSUB -> Client subscribed to Pub/Sub channels 1309 */ 1310 int getClientLimitClass(redisClient *c) { 1311 if (c->flags & REDIS_SLAVE) return REDIS_CLIENT_LIMIT_CLASS_SLAVE; 1312 if (dictSize(c->pubsub_channels) || listLength(c->pubsub_patterns)) 1313 return REDIS_CLIENT_LIMIT_CLASS_PUBSUB; 1314 return REDIS_CLIENT_LIMIT_CLASS_NORMAL; 1315 } 1316 1317 int getClientLimitClassByName(char *name) { 1318 if (!strcasecmp(name,"normal")) return REDIS_CLIENT_LIMIT_CLASS_NORMAL; 1319 else if (!strcasecmp(name,"slave")) return REDIS_CLIENT_LIMIT_CLASS_SLAVE; 1320 else if (!strcasecmp(name,"pubsub")) return REDIS_CLIENT_LIMIT_CLASS_PUBSUB; 1321 else return -1; 1322 } 1323 1324 char *getClientLimitClassName(int class) { 1325 switch(class) { 1326 case REDIS_CLIENT_LIMIT_CLASS_NORMAL: return "normal"; 1327 case REDIS_CLIENT_LIMIT_CLASS_SLAVE: return "slave"; 1328 case REDIS_CLIENT_LIMIT_CLASS_PUBSUB: return "pubsub"; 1329 default: return NULL; 1330 } 1331 } 1332 1333 /* The function checks if the client reached output buffer soft or hard 1334 * limit, and also update the state needed to check the soft limit as 1335 * a side effect. 1336 * 1337 * Return value: non-zero if the client reached the soft or the hard limit. 1338 * Otherwise zero is returned. */ 1339 int checkClientOutputBufferLimits(redisClient *c) { 1340 int soft = 0, hard = 0, class; 1341 unsigned long used_mem = getClientOutputBufferMemoryUsage(c); 1342 1343 class = getClientLimitClass(c); 1344 if (server.client_obuf_limits[class].hard_limit_bytes && 1345 used_mem >= server.client_obuf_limits[class].hard_limit_bytes) 1346 hard = 1; 1347 if (server.client_obuf_limits[class].soft_limit_bytes && 1348 used_mem >= server.client_obuf_limits[class].soft_limit_bytes) 1349 soft = 1; 1350 1351 /* We need to check if the soft limit is reached continuously for the 1352 * specified amount of seconds. */ 1353 if (soft) { 1354 if (c->obuf_soft_limit_reached_time == 0) { 1355 c->obuf_soft_limit_reached_time = server.unixtime; 1356 soft = 0; /* First time we see the soft limit reached */ 1357 } else { 1358 time_t elapsed = server.unixtime - c->obuf_soft_limit_reached_time; 1359 1360 if (elapsed <= 1361 server.client_obuf_limits[class].soft_limit_seconds) { 1362 soft = 0; /* The client still did not reached the max number of 1363 seconds for the soft limit to be considered 1364 reached. */ 1365 } 1366 } 1367 } else { 1368 c->obuf_soft_limit_reached_time = 0; 1369 } 1370 return soft || hard; 1371 } 1372 1373 /* Asynchronously close a client if soft or hard limit is reached on the 1374 * output buffer size. The caller can check if the client will be closed 1375 * checking if the client REDIS_CLOSE_ASAP flag is set. 1376 * 1377 * Note: we need to close the client asynchronously because this function is 1378 * called from contexts where the client can't be freed safely, i.e. from the 1379 * lower level functions pushing data inside the client output buffers. */ 1380 void asyncCloseClientOnOutputBufferLimitReached(redisClient *c) { 1381 redisAssert(c->reply_bytes < ULONG_MAX-(1024*64)); 1382 if (c->reply_bytes == 0 || c->flags & REDIS_CLOSE_ASAP) return; 1383 if (checkClientOutputBufferLimits(c)) { 1384 sds client = getClientInfoString(c); 1385 1386 freeClientAsync(c); 1387 redisLog(REDIS_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", client); 1388 sdsfree(client); 1389 } 1390 } 1391 1392 /* Helper function used by freeMemoryIfNeeded() in order to flush slaves 1393 * output buffers without returning control to the event loop. */ 1394 void flushSlavesOutputBuffers(void) { 1395 listIter li; 1396 listNode *ln; 1397 1398 listRewind(server.slaves,&li); 1399 while((ln = listNext(&li))) { 1400 redisClient *slave = listNodeValue(ln); 1401 int events; 1402 1403 events = aeGetFileEvents(server.el,slave->fd); 1404 if (events & AE_WRITABLE && 1405 slave->replstate == REDIS_REPL_ONLINE && 1406 listLength(slave->reply)) 1407 { 1408 sendReplyToClient(server.el,slave->fd,slave,0); 1409 } 1410 } 1411 } 1412