summaryrefslogtreecommitdiff
path: root/src/anet.c
diff options
context:
space:
mode:
authoryoav-steinberg <yoav@monfort.co.il>2020-10-28 21:13:44 +0200
committerGitHub <noreply@github.com>2020-10-28 21:13:44 +0200
commit84b3c18f71ec5b03e58a823fbf75de9c4c80969c (patch)
treeec12b94b1147586e2e03eb953956b8246e194f61 /src/anet.c
parent441bfa2dfb57e0dbfddad167bafa559b3f051b5b (diff)
downloadredis-84b3c18f71ec5b03e58a823fbf75de9c4c80969c.tar.gz
Add local address to CLIENT LIST, and a CLIENT KILL filter. (#7913)
Useful when you want to know through which bind address the client connected to the server in case of multiple bind addresses. - Adding `laddr` field to CLIENT list showing the local (bind) address. - Adding `LADDR` option to CLIENT KILL to kill all the clients connected to a specific local address. - Refactoring to share code.
Diffstat (limited to 'src/anet.c')
-rw-r--r--src/anet.c46
1 files changed, 10 insertions, 36 deletions
diff --git a/src/anet.c b/src/anet.c
index e9615a128..d46ce5398 100644
--- a/src/anet.c
+++ b/src/anet.c
@@ -592,11 +592,15 @@ int anetUnixAccept(char *err, int s) {
return fd;
}
-int anetPeerToString(int fd, char *ip, size_t ip_len, int *port) {
+int anetFdToString(int fd, char *ip, size_t ip_len, int *port, int fd_to_str_type) {
struct sockaddr_storage sa;
socklen_t salen = sizeof(sa);
- if (getpeername(fd,(struct sockaddr*)&sa,&salen) == -1) goto error;
+ if (fd_to_str_type == FD_TO_PEER_NAME) {
+ if (getpeername(fd, (struct sockaddr *)&sa, &salen) == -1) goto error;
+ } else {
+ if (getsockname(fd, (struct sockaddr *)&sa, &salen) == -1) goto error;
+ }
if (ip_len == 0) goto error;
if (sa.ss_family == AF_INET) {
@@ -608,7 +612,7 @@ int anetPeerToString(int fd, char *ip, size_t ip_len, int *port) {
if (ip) inet_ntop(AF_INET6,(void*)&(s->sin6_addr),ip,ip_len);
if (port) *port = ntohs(s->sin6_port);
} else if (sa.ss_family == AF_UNIX) {
- if (ip) strncpy(ip,"/unixsocket",ip_len);
+ if (ip) snprintf(ip, ip_len, "/unixsocket");
if (port) *port = 0;
} else {
goto error;
@@ -636,41 +640,11 @@ int anetFormatAddr(char *buf, size_t buf_len, char *ip, int port) {
"[%s]:%d" : "%s:%d", ip, port);
}
-/* Like anetFormatAddr() but extract ip and port from the socket's peer. */
-int anetFormatPeer(int fd, char *buf, size_t buf_len) {
+/* Like anetFormatAddr() but extract ip and port from the socket's peer/sockname. */
+int anetFormatFdAddr(int fd, char *buf, size_t buf_len, int fd_to_str_type) {
char ip[INET6_ADDRSTRLEN];
int port;
- anetPeerToString(fd,ip,sizeof(ip),&port);
+ anetFdToString(fd,ip,sizeof(ip),&port,fd_to_str_type);
return anetFormatAddr(buf, buf_len, ip, port);
}
-
-int anetSockName(int fd, char *ip, size_t ip_len, int *port) {
- struct sockaddr_storage sa;
- socklen_t salen = sizeof(sa);
-
- if (getsockname(fd,(struct sockaddr*)&sa,&salen) == -1) {
- if (port) *port = 0;
- ip[0] = '?';
- ip[1] = '\0';
- return -1;
- }
- if (sa.ss_family == AF_INET) {
- struct sockaddr_in *s = (struct sockaddr_in *)&sa;
- if (ip) inet_ntop(AF_INET,(void*)&(s->sin_addr),ip,ip_len);
- if (port) *port = ntohs(s->sin_port);
- } else {
- struct sockaddr_in6 *s = (struct sockaddr_in6 *)&sa;
- if (ip) inet_ntop(AF_INET6,(void*)&(s->sin6_addr),ip,ip_len);
- if (port) *port = ntohs(s->sin6_port);
- }
- return 0;
-}
-
-int anetFormatSock(int fd, char *fmt, size_t fmt_len) {
- char ip[INET6_ADDRSTRLEN];
- int port;
-
- anetSockName(fd,ip,sizeof(ip),&port);
- return anetFormatAddr(fmt, fmt_len, ip, port);
-}