summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2022-08-24 08:35:46 +0300
committerGitHub <noreply@github.com>2022-08-24 08:35:46 +0300
commit41d9eb0291417c36d694894c936d8f4f29ec5504 (patch)
tree5c316244f4c134522d0051e6437e793b5afc6ecc /src/networking.c
parent90223759a37d2613cd6f2085050f8ce2f9a54ee3 (diff)
parent4faddf18ca8ca3adb93cf1e4e620be9eaf0f6bf4 (diff)
downloadredis-41d9eb0291417c36d694894c936d8f4f29ec5504.tar.gz
Merge: Fully abstract connection and make TLS dynamically loadable (#9320)
There are many commits in this PR, the detailed changes is described in each commit message. ### Main changes in this PR * Fully abstract connection type, and hide connection type specified methods. Ex, currently TLS class looks like: ``` static ConnectionType CT_TLS = { /* connection type */ .get_type = connTLSGetType, /* connection type initialize & finalize & configure */ .init = tlsInit, .cleanup = tlsCleanup, .configure = tlsConfigure, /* ae & accept & listen & error & address handler */ .ae_handler = tlsEventHandler, .accept_handler = tlsAcceptHandler, .addr = connTLSAddr, .listen = connTLSListen, /* create/close connection */ .conn_create = connCreateTLS, .conn_create_accepted = connCreateAcceptedTLS, .close = connTLSClose, /* connect & accept */ .connect = connTLSConnect, .blocking_connect = connTLSBlockingConnect, .accept = connTLSAccept, /* IO */ .read = connTLSRead, .write = connTLSWrite, .writev = connTLSWritev, .set_write_handler = connTLSSetWriteHandler, .set_read_handler = connTLSSetReadHandler, .get_last_error = connTLSGetLastError, .sync_write = connTLSSyncWrite, .sync_read = connTLSSyncRead, .sync_readline = connTLSSyncReadLine, /* pending data */ .has_pending_data = tlsHasPendingData, .process_pending_data = tlsProcessPendingData, /* TLS specified methods */ .get_peer_cert = connTLSGetPeerCert, }; int RedisRegisterConnectionTypeTLS() { return connTypeRegister(&CT_TLS); } ``` * Also abstract Unix socket class. Currently, the connection framework becomes like: ``` uplayer | connection layer / | \ TCP Unix TLS ``` * It's possible to build TLS as a shared library (`make BUILD_TLS=module`). Loading the shared library(redis-tls.so) into Redis by Redis module subsystem, and Redis starts to listen TLS port. Ex: ``` ./src/redis-server --tls-port 6379 --port 0 \ --tls-cert-file ./tests/tls/redis.crt \ --tls-key-file ./tests/tls/redis.key \ --tls-ca-cert-file ./tests/tls/ca.crt \ --loadmodule src/redis-tls.so ``` ### Interface changes * RM_GetContextFlags supports a new flag: REDISMODULE_CTX_FLAGS_SERVER_STARTUP * INFO SERVER includes a list of listeners: ``` listener0:name=tcp,bind=127.0.0.1,port=6380 listener1:name=unix,bind=/run/redis.sock listener2:name=tls,bind=127.0.0.1,port=6379 ``` ### Other notes * Fix wrong signature of RedisModuleDefragFunc, this could break compilation of a module, but not the ABI * Some reordering of initialization order in server.c: * Move initialization of listeners to be after loading the modules * Config TLS after initialization of listeners * Init cluster after initialization of listeners * Sentinel does not support the TLS module or any connection module since it uses hiredis for outbound connections, so when TLS is built as a module, sentinel lacks TLS support.
Diffstat (limited to 'src/networking.c')
-rw-r--r--src/networking.c76
1 files changed, 8 insertions, 68 deletions
diff --git a/src/networking.c b/src/networking.c
index d6471ee7c..7b3225fe9 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -1212,7 +1212,7 @@ int islocalClient(client *c) {
/* tcp */
char cip[NET_IP_STR_LEN+1] = { 0 };
- connPeerToString(c->conn, cip, sizeof(cip)-1, NULL);
+ connAddrPeerName(c->conn, cip, sizeof(cip)-1, NULL);
return !strcmp(cip,"127.0.0.1") || !strcmp(cip,"::1");
}
@@ -1271,8 +1271,7 @@ void clientAcceptHandler(connection *conn) {
c);
}
-#define MAX_ACCEPTS_PER_CALL 1000
-static void acceptCommonHandler(connection *conn, int flags, char *ip) {
+void acceptCommonHandler(connection *conn, int flags, char *ip) {
client *c;
char conninfo[100];
UNUSED(ip);
@@ -1344,65 +1343,6 @@ static void acceptCommonHandler(connection *conn, int flags, char *ip) {
}
}
-void acceptTcpHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
- int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
- char cip[NET_IP_STR_LEN];
- UNUSED(el);
- UNUSED(mask);
- UNUSED(privdata);
-
- while(max--) {
- cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
- if (cfd == ANET_ERR) {
- if (errno != EWOULDBLOCK)
- serverLog(LL_WARNING,
- "Accepting client connection: %s", server.neterr);
- return;
- }
- serverLog(LL_VERBOSE,"Accepted %s:%d", cip, cport);
- acceptCommonHandler(connCreateAcceptedSocket(cfd),0,cip);
- }
-}
-
-void acceptTLSHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
- int cport, cfd, max = MAX_ACCEPTS_PER_CALL;
- char cip[NET_IP_STR_LEN];
- UNUSED(el);
- UNUSED(mask);
- UNUSED(privdata);
-
- while(max--) {
- cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
- if (cfd == ANET_ERR) {
- if (errno != EWOULDBLOCK)
- serverLog(LL_WARNING,
- "Accepting client connection: %s", server.neterr);
- return;
- }
- serverLog(LL_VERBOSE,"Accepted %s:%d", cip, cport);
- acceptCommonHandler(connCreateAcceptedTLS(cfd, server.tls_auth_clients),0,cip);
- }
-}
-
-void acceptUnixHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
- int cfd, max = MAX_ACCEPTS_PER_CALL;
- UNUSED(el);
- UNUSED(mask);
- UNUSED(privdata);
-
- while(max--) {
- cfd = anetUnixAccept(server.neterr, fd);
- if (cfd == ANET_ERR) {
- if (errno != EWOULDBLOCK)
- serverLog(LL_WARNING,
- "Accepting client connection: %s", server.neterr);
- return;
- }
- serverLog(LL_VERBOSE,"Accepted connection to %s", server.unixsocket);
- acceptCommonHandler(connCreateAcceptedSocket(cfd),CLIENT_UNIX_SOCKET,NULL);
- }
-}
-
void freeClientOriginalArgv(client *c) {
/* We didn't rewrite this client */
if (!c->original_argv) return;
@@ -2716,13 +2656,13 @@ done:
* you want to relax error checking or need to display something anyway (see
* anetFdToString implementation for more info). */
void genClientAddrString(client *client, char *addr,
- size_t addr_len, int fd_to_str_type) {
+ size_t addr_len, int remote) {
if (client->flags & CLIENT_UNIX_SOCKET) {
/* Unix socket client. */
snprintf(addr,addr_len,"%s:0",server.unixsocket);
} else {
/* TCP client. */
- connFormatFdAddr(client->conn,addr,addr_len,fd_to_str_type);
+ connFormatAddr(client->conn,addr,addr_len,remote);
}
}
@@ -2731,10 +2671,10 @@ void genClientAddrString(client *client, char *addr,
* The Peer ID never changes during the life of the client, however it
* is expensive to compute. */
char *getClientPeerId(client *c) {
- char peerid[NET_ADDR_STR_LEN];
+ char peerid[NET_ADDR_STR_LEN] = {0};
if (c->peerid == NULL) {
- genClientAddrString(c,peerid,sizeof(peerid),FD_TO_PEER_NAME);
+ genClientAddrString(c,peerid,sizeof(peerid),1);
c->peerid = sdsnew(peerid);
}
return c->peerid;
@@ -2745,10 +2685,10 @@ char *getClientPeerId(client *c) {
* The Socket Name never changes during the life of the client, however it
* is expensive to compute. */
char *getClientSockname(client *c) {
- char sockname[NET_ADDR_STR_LEN];
+ char sockname[NET_ADDR_STR_LEN] = {0};
if (c->sockname == NULL) {
- genClientAddrString(c,sockname,sizeof(sockname),FD_TO_SOCK_NAME);
+ genClientAddrString(c,sockname,sizeof(sockname),0);
c->sockname = sdsnew(sockname);
}
return c->sockname;