Add socket-mark-id support for marking sockets. (#10349)
Add a configuration option to attach an operating system-specific identifier to Redis sockets, supporting advanced network configurations using iptables (Linux) or ipfw (FreeBSD).
This commit is contained in:
parent
a1c85eebf4
commit
aba2865c86
10
redis.conf
10
redis.conf
@ -175,6 +175,16 @@ timeout 0
|
||||
# Redis default starting with Redis 3.2.1.
|
||||
tcp-keepalive 300
|
||||
|
||||
# Apply OS-specific mechanism to mark the listening socket with the specified
|
||||
# ID, to support advanced routing and filtering capabilities.
|
||||
#
|
||||
# On Linux, the ID represents a connection mark.
|
||||
# On FreeBSD, the ID represents a socket cookie ID.
|
||||
# On OpenBSD, the ID represents a route table ID.
|
||||
#
|
||||
# The default value is 0, which implies no marking is required.
|
||||
# socket-mark-id 0
|
||||
|
||||
################################# TLS/SSL #####################################
|
||||
|
||||
# By default, TLS/SSL is disabled. To enable it, the "tls-port" configuration
|
||||
|
17
src/anet.c
17
src/anet.c
@ -49,6 +49,8 @@
|
||||
#include "anet.h"
|
||||
#include "config.h"
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
static void anetSetError(char *err, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -680,3 +682,18 @@ error:
|
||||
close(fds[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int anetSetSockMarkId(char *err, int fd, uint32_t id) {
|
||||
#ifdef HAVE_SOCKOPTMARKID
|
||||
if (setsockopt(fd, SOL_SOCKET, SOCKOPTMARKID, (void *)&id, sizeof(id)) == -1) {
|
||||
anetSetError(err, "setsockopt: %s", strerror(errno));
|
||||
return ANET_ERR;
|
||||
}
|
||||
return ANET_OK;
|
||||
#else
|
||||
UNUSED(fd);
|
||||
UNUSED(id);
|
||||
anetSetError(err,"anetSetSockMarkid unsupported on this platform");
|
||||
return ANET_OK;
|
||||
#endif
|
||||
}
|
||||
|
@ -73,5 +73,6 @@ int anetKeepAlive(char *err, int fd, int interval);
|
||||
int anetFormatAddr(char *fmt, size_t fmt_len, char *ip, int port);
|
||||
int anetFormatFdAddr(int fd, char *buf, size_t buf_len, int fd_to_str_type);
|
||||
int anetPipe(int fds[2], int read_flags, int write_flags);
|
||||
int anetSetSockMarkId(char *err, int fd, uint32_t id);
|
||||
|
||||
#endif
|
||||
|
@ -2977,6 +2977,7 @@ standardConfig static_configs[] = {
|
||||
/* Unsigned int configs */
|
||||
createUIntConfig("maxclients", NULL, MODIFIABLE_CONFIG, 1, UINT_MAX, server.maxclients, 10000, INTEGER_CONFIG, NULL, updateMaxclients),
|
||||
createUIntConfig("unixsocketperm", NULL, IMMUTABLE_CONFIG, 0, 0777, server.unixsocketperm, 0, OCTAL_CONFIG, NULL, NULL),
|
||||
createUIntConfig("socket-mark-id", NULL, IMMUTABLE_CONFIG, 0, UINT_MAX, server.socket_mark_id, 0, INTEGER_CONFIG, NULL, NULL),
|
||||
|
||||
/* Unsigned Long configs */
|
||||
createULongConfig("active-defrag-max-scan-fields", NULL, MODIFIABLE_CONFIG, 1, LONG_MAX, server.active_defrag_max_scan_fields, 1000, INTEGER_CONFIG, NULL, NULL), /* Default: keys with more than 1000 fields will be processed separately */
|
||||
|
18
src/config.h
18
src/config.h
@ -80,6 +80,10 @@
|
||||
/* MSG_NOSIGNAL. */
|
||||
#ifdef __linux__
|
||||
#define HAVE_MSG_NOSIGNAL 1
|
||||
#if defined(SO_MARK)
|
||||
#define HAVE_SOCKOPTMARKID 1
|
||||
#define SOCKOPTMARKID SO_MARK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Test for polling API */
|
||||
@ -113,6 +117,20 @@
|
||||
#define redis_fsync(fd) fsync(fd)
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#if defined(SO_USER_COOKIE)
|
||||
#define HAVE_SOCKOPTMARKID 1
|
||||
#define SOCKOPTMARKID SO_USER_COOKIE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#if defined(SO_RTABLE)
|
||||
#define HAVE_SOCKOPTMARKID 1
|
||||
#define SOCKOPTMARKID SO_RTABLE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 4
|
||||
#define redis_unreachable __builtin_unreachable
|
||||
#else
|
||||
|
@ -2293,6 +2293,7 @@ int listenToPort(int port, socketFds *sfd) {
|
||||
closeSocketListeners(sfd);
|
||||
return C_ERR;
|
||||
}
|
||||
if (server.socket_mark_id > 0) anetSetSockMarkId(NULL, sfd->fd[sfd->count], server.socket_mark_id);
|
||||
anetNonBlock(NULL,sfd->fd[sfd->count]);
|
||||
anetCloexec(sfd->fd[sfd->count]);
|
||||
sfd->count++;
|
||||
|
@ -1494,6 +1494,7 @@ struct redisServer {
|
||||
socketFds ipfd; /* TCP socket file descriptors */
|
||||
socketFds tlsfd; /* TLS socket file descriptors */
|
||||
int sofd; /* Unix socket file descriptor */
|
||||
uint32_t socket_mark_id; /* ID for listen socket marking */
|
||||
socketFds cfd; /* Cluster bus listening socket */
|
||||
list *clients; /* List of active clients */
|
||||
list *clients_to_close; /* Clients to close asynchronously */
|
||||
|
@ -215,6 +215,7 @@ start_server {tags {"introspection"}} {
|
||||
dbfilename
|
||||
logfile
|
||||
dir
|
||||
socket-mark-id
|
||||
}
|
||||
|
||||
if {!$::tls} {
|
||||
|
Loading…
x
Reference in New Issue
Block a user