summaryrefslogtreecommitdiff
path: root/src/socket.c
Commit message (Collapse)AuthorAgeFilesLines
* Remove prototypes with empty declarations (#12020)Madelyn Olson2023-05-021-1/+1
| | | Technically declaring a prototype with an empty declaration has been deprecated since the early days of C, but we never got a warning for it. C2x will apparently be introducing a breaking change if you are using this type of declarator, so Clang 15 has started issuing a warning with -pedantic. Although not apparently a problem for any of the compiler we build on, if feels like the right thing is to properly adhere to the C standard and use (void).
* Fix local clients detection (#11664)gx2023-04-041-1/+1
| | | Match 127.0.0.0/8 instead of just `127.0.0.1` to detect the local clients.
* Introduce .is_local method for connection layer (#11672)zhenwei pi2023-01-041-0/+10
| | | | | | | | | | Introduce .is_local method to connection, and implement for TCP/TLS/ Unix socket, also drop 'int islocalClient(client *c)'. Then we can hide the detail into the specific connection types. Uplayer tests a connection is local or not by abstract method only. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Introduce socket shutdown into connection type, used if a fork is active ↵Binbin2022-11-041-1/+8
| | | | | | | | | | | | | | | (#11376) Introduce socket `shutdown()` into connection type, and use it on normal socket if a fork is active. This allows us to close client connections when there are child processes sharing the file descriptors. Fixes #10077. The reason is that since the `fork()` child is holding the file descriptors, the `close` in `unlinkClient -> connClose` isn't sufficient. The client will not realize that the connection is disconnected until the child process ends. Let's try to be conservative and only use shutdown when the fork is active.
* Introduce .listen into connection typezhenwei pi2022-08-221-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce listen method into connection type, this allows no hard code of listen logic. Originally, we initialize server during startup like this: if (server.port) listenToPort(server.port,&server.ipfd); if (server.tls_port) listenToPort(server.port,&server.tlsfd); if (server.unixsocket) anetUnixServer(...server.unixsocket...); ... if (createSocketAcceptHandler(&server.ipfd, acceptTcpHandler) != C_OK) if (createSocketAcceptHandler(&server.tlsfd, acceptTcpHandler) != C_OK) if (createSocketAcceptHandler(&server.sofd, acceptTcpHandler) != C_OK) ... If a new connection type gets supported, we have to add more hard code to setup listener. Introduce .listen and refactor listener, and Unix socket supports this. this allows to setup listener arguments and create listener in a loop. What's more, '.listen' is defined in connection.h, so we should include server.h to import 'struct socketFds', but server.h has already include 'connection.h'. To avoid including loop(also to make code reasonable), define 'struct connListener' in connection.h instead of 'struct socketFds' in server.h. This leads this commit to get more changes. There are more fields in 'struct connListener', hence it's possible to simplify changeBindAddr & applyTLSPort() & updatePort() into a single logic: update the listener config from the server.xxx, and re-create the listener. Because of the new field 'priv' in struct connListener, we expect to pass this to the accept handler(even it's not used currently), this may be used in the future. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Use connection name of stringzhenwei pi2022-08-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | Suggested by Oran, use an array to store all the connection types instead of a linked list, and use connection name of string. The index of a connection is dynamically allocated. Currently we support max 8 connection types, include: - tcp - unix socket - tls and RDMA is in the plan, then we have another 4 types to support, it should be enough in a long time. Introduce 3 functions to get connection type by a fast path: - connectionTypeTcp() - connectionTypeTls() - connectionTypeUnix() Note that connectionByType() is designed to use only in unlikely code path. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Abstract accept handlerzhenwei pi2022-08-221-0/+21
| | | | | | | | | | Abstract accept handler for socket&TLS, and add helper function 'connAcceptHandler' to get accept handler by specified type. Also move acceptTcpHandler into socket.c, and move acceptTLSHandler into tls.c. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Fully abstract connection typezhenwei pi2022-08-221-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | Abstract common interface of connection type, so Redis can hide the implementation and uplayer only calls connection API without macro. uplayer | connection layer / \ socket TLS Currently, for both socket and TLS, all the methods of connection type are declared as static functions. It's possible to build TLS(even socket) as a shared library, and Redis loads it dynamically in the next step. Also add helper function connTypeOfCluster() and connTypeOfReplication() to simplify the code: link->conn = server.tls_cluster ? connCreateTLS() : connCreateSocket(); -> link->conn = connCreate(connTypeOfCluster()); Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Introduce pending data for connection typezhenwei pi2022-08-221-0/+4
| | | | | | | | | Introduce .has_pending_data and .process_pending_data for connection type, and hide tlsHasPendingData() and tlsProcessPendingData(). Also set .has_pending_data and .process_pending_data as NULL explicitly in socket.c. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Introduce connection layer frameworkzhenwei pi2022-08-221-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use connTypeRegister() to register a connection type into redis, and query connection by connectionByType() via type. With this change, we can hide TLS specified methods into connection type: - void tlsInit(void); - void tlsCleanup(void); - int tlsConfigure(redisTLSContextConfig *ctx_config); - int isTlsConfigured(void); Merge isTlsConfigured & tlsConfigure, use an argument *reconfigure* to distinguish: tlsConfigure(&server.tls_ctx_config) -> onnTypeConfigure(CONN_TYPE_TLS, &server.tls_ctx_config, 1) isTlsConfigured() && tlsConfigure(&server.tls_ctx_config) -> connTypeConfigure(CONN_TYPE_TLS, &server.tls_ctx_config, 0) Finally, we can remove USE_OPENSSL from config.c. If redis is built without TLS, and still run redis with TLS, then redis reports: # Missing implement of connection type 1 # Failed to configure TLS. Check logs for more info. The log can be optimised, let's leave it in the future. Maybe we can use connection type as a string. Although uninitialized fields of a static struct are zero, we still set them as NULL explicitly in socket.c, let them clear to read & maintain: .init = NULL, .cleanup = NULL, .configure = NULL, Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Introduce connAddrzhenwei pi2022-08-221-16/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Originally, connPeerToString is designed to get the address info from socket only(for both TCP & TLS), and the API 'connPeerToString' is oriented to operate a FD like: int connPeerToString(connection *conn, char *ip, size_t ip_len, int *port) { return anetFdToString(conn ? conn->fd : -1, ip, ip_len, port, FD_TO_PEER_NAME); } Introduce connAddr and implement .addr method for socket and TLS, thus the API 'connAddr' and 'connFormatAddr' become oriented to a connection like: static inline int connAddr(connection *conn, char *ip, size_t ip_len, int *port, int remote) { if (conn && conn->type->addr) { return conn->type->addr(conn, ip, ip_len, port, remote); } return -1; } Also remove 'FD_TO_PEER_NAME' & 'FD_TO_SOCK_NAME', use a boolean type 'remote' to get local/remote address of a connection. With these changes, it's possible to support the other connection types which does not use socket(Ex, RDMA). Thanks to Oran for suggestions! Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Reorder methods for ConnectionTypezhenwei pi2022-08-221-4/+13
| | | | | | | | | | Reorder methods for CT_Socket & CT_TLS, also add comments to make the methods clear. Also move the CT_TLS to the end of file, other methods can be static in the next step. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Move 'connGetSocketError' to 'anetGetError'zhenwei pi2022-08-221-11/+1
| | | | | | | getsockopt is part of TCP, rename 'connGetSocketError' to 'anetGetError', and move it into anet.c. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Move several conn functions to connection.hzhenwei pi2022-08-221-34/+0
| | | | | | | These functions are really short enough and they are the connection functions, separate them from the socket source. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
* Rename connection.c to socket.czhenwei pi2022-08-221-0/+453
ConnectionType CT_Socket is implemented in connection.c, so rename this file to socket.c. Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>