diff options
author | Oran Agra <oran@redislabs.com> | 2022-08-24 08:35:46 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-24 08:35:46 +0300 |
commit | 41d9eb0291417c36d694894c936d8f4f29ec5504 (patch) | |
tree | 5c316244f4c134522d0051e6437e793b5afc6ecc /src/networking.c | |
parent | 90223759a37d2613cd6f2085050f8ce2f9a54ee3 (diff) | |
parent | 4faddf18ca8ca3adb93cf1e4e620be9eaf0f6bf4 (diff) | |
download | redis-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.c | 76 |
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; |