summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2013-07-09 12:49:20 +0200
committerantirez <antirez@gmail.com>2013-07-09 12:49:20 +0200
commit5cdc5da990d10b211f3554afa62395f1f0a41655 (patch)
treef464f8266c0ba7ceee24ec1f888100585629637f
parent631d656a94bdc8e23bcfaad3e64cb8210cc03aa9 (diff)
downloadredis-5cdc5da990d10b211f3554afa62395f1f0a41655.tar.gz
getClientPeerID introduced.
The function returns an unique identifier for the client, as ip:port for IPv4 and IPv6 clients, or as path:0 for Unix socket clients. See the top comment in the function for more info.
-rw-r--r--src/networking.c41
-rw-r--r--src/redis.h2
2 files changed, 36 insertions, 7 deletions
diff --git a/src/networking.c b/src/networking.c
index 59f056436..458f4f398 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -1126,14 +1126,42 @@ void getClientsMaxBuffers(unsigned long *longest_output_list,
*biggest_input_buffer = bib;
}
+/* A Redis "Peer ID" is a colon separated ip:port pair.
+ * For IPv4 it's in the form x.y.z.k:pork, example: "127.0.0.1:1234".
+ * For IPv6 addresses we use [] around the IP part, like in "[::1]:1234".
+ * For Unix socekts we use path:0, like in "/tmp/redis:0".
+ *
+ * A Peer ID always fits inside a buffer of REDIS_PEER_ID_LEN bytes, including
+ * the null term.
+ *
+ * The function is always successful, but if the IP or port can't be extracted
+ * for some reason, "?" and "0" are used (this is the semantics of
+ * anetPeerToString() from anet.c). In practical terms this should never
+ * happen. */
+void getClientPeerId(redisClient *client, char *peerid, size_t peerid_len) {
+ char ip[REDIS_IP_STR_LEN];
+ int port;
+
+ if (client->flags & REDIS_UNIX_SOCKET) {
+ /* Unix socket client. */
+ snprintf(peerid,peerid_len,"%s:0",server.unixsocket);
+ return;
+ } else {
+ /* TCP client. */
+ anetPeerToString(client->fd,ip,sizeof(ip),&port);
+ if (strchr(ip,':'))
+ snprintf(peerid,peerid_len,"[%s]:%d",ip,port);
+ else
+ snprintf(peerid,peerid_len,"%s:%d",ip,port);
+ }
+}
+
/* Turn a Redis client into an sds string representing its state. */
sds getClientInfoString(redisClient *client) {
- char ip[REDIS_IP_STR_LEN], flags[16], events[3], *p;
- int port = 0; /* initialized to zero for the unix socket case. */
+ char peerid[REDIS_PEER_ID_LEN], flags[16], events[3], *p;
int emask;
- if (!(client->flags & REDIS_UNIX_SOCKET))
- anetPeerToString(client->fd,ip,sizeof(ip),&port);
+ getClientPeerId(client,peerid,sizeof(peerid));
p = flags;
if (client->flags & REDIS_SLAVE) {
if (client->flags & REDIS_MONITOR)
@@ -1158,9 +1186,8 @@ sds getClientInfoString(redisClient *client) {
if (emask & AE_WRITABLE) *p++ = 'w';
*p = '\0';
return sdscatprintf(sdsempty(),
- "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",
- (client->flags & REDIS_UNIX_SOCKET) ? server.unixsocket : ip,
- port,
+ "addr=%s 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",
+ peerid,
client->fd,
client->name ? (char*)client->name->ptr : "",
(long)(server.unixtime - client->ctime),
diff --git a/src/redis.h b/src/redis.h
index 808bb9211..901969d0d 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -121,6 +121,7 @@
#define REDIS_DEFAULT_MIN_SLAVES_TO_WRITE 0
#define REDIS_DEFAULT_MIN_SLAVES_MAX_LAG 10
#define REDIS_IP_STR_LEN INET6_ADDRSTRLEN
+#define REDIS_PEER_ID_LEN (REDIS_IP_STR_LEN+32) /* Must be enough for ip:port */
#define REDIS_BINDADDR_MAX 16
/* Protocol and I/O related defines */
@@ -1072,6 +1073,7 @@ void copyClientOutputBuffer(redisClient *dst, redisClient *src);
void *dupClientReplyValue(void *o);
void getClientsMaxBuffers(unsigned long *longest_output_list,
unsigned long *biggest_input_buffer);
+void getClientPeerId(redisClient *client, char *peerid, size_t peerid_len);
sds getClientInfoString(redisClient *client);
sds getAllClientsInfoString(void);
void rewriteClientCommandVector(redisClient *c, int argc, ...);