1. 22 Aug, 2022 9 commits
    • zhenwei pi's avatar
      Abstract accept handler · 0ae02ce9
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      0ae02ce9
    • zhenwei pi's avatar
      Fully abstract connection type · 1234e3a5
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      1234e3a5
    • zhenwei pi's avatar
      Introduce pending data for connection type · 709b55b0
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      709b55b0
    • zhenwei pi's avatar
      Introduce connection layer framework · 8234a512
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      8234a512
    • zhenwei pi's avatar
      Introduce connAddr · bff7ecc7
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      bff7ecc7
    • zhenwei pi's avatar
      Reorder methods for ConnectionType · b9d77288
      zhenwei pi authored
      
      
      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: default avatarzhenwei pi <pizhenwei@bytedance.com>
      b9d77288
    • zhenwei pi's avatar
      Move 'connGetSocketError' to 'anetGetError' · 8045e26e
      zhenwei pi authored
      
      
      getsockopt is part of TCP, rename 'connGetSocketError' to
      'anetGetError', and move it into anet.c.
      Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
      8045e26e
    • zhenwei pi's avatar
      Move several conn functions to connection.h · dca5c6ff
      zhenwei pi authored
      
      
      These functions are really short enough and they are the connection
      functions, separate them from the socket source.
      Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
      dca5c6ff
    • zhenwei pi's avatar
      Rename connection.c to socket.c · 22e74e47
      zhenwei pi authored
      
      
      ConnectionType CT_Socket is implemented in connection.c, so rename
      this file to socket.c.
      Signed-off-by: default avatarzhenwei pi <pizhenwei@bytedance.com>
      22e74e47
  2. 20 Jul, 2022 1 commit
  3. 22 Feb, 2022 1 commit
    • Andy Pan's avatar
      Reduce system calls of write for client->reply by introducing writev (#9934) · 496375fc
      Andy Pan authored
      There are scenarios where it results in many small objects in the reply list,
      such as commands heavily using deferred array replies (`addReplyDeferredLen`).
      E.g. what COMMAND command and CLUSTER SLOTS used to do (see #10056, #7123),
      but also in case of a transaction or a pipeline of commands that use just one differed array reply.
      
      We used to have to run multiple loops along with multiple calls to `write()` to send data back to
      peer based on the current code, but by means of `writev()`, we can gather those scattered
      objects in reply list and include the static reply buffer as well, then send it by one system call,
      that ought to achieve higher performance.
      
      In the case of TLS,  we simply check and concatenate buffers into one big buffer and send it
      away by one call to `connTLSWrite()`, if the amount of all buffers exceeds `NET_MAX_WRITES_PER_EVENT`,
      then invoke `connTLSWrite()` multiple times to avoid a huge massive of memory copies.
      
      Note that aside of reducing system calls, this change will also reduce the amount of
      small TCP packets sent.
      496375fc
  4. 08 Nov, 2021 1 commit
    • Yossi Gottlieb's avatar
      Fix EINTR test failures. (#9751) · a1aba4bf
      Yossi Gottlieb authored
      * Clean up EINTR handling so EINTR will not change connection state to begin with.
      * On TLS, catch EINTR and return it as-is before going through OpenSSL error handling (which seems to not distinguish it from EAGAIN).
      a1aba4bf
  5. 01 Mar, 2021 1 commit
  6. 25 Nov, 2020 1 commit
  7. 28 Oct, 2020 1 commit
    • yoav-steinberg's avatar
      Add local address to CLIENT LIST, and a CLIENT KILL filter. (#7913) · 84b3c18f
      yoav-steinberg authored
      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.
      84b3c18f
  8. 22 Sep, 2020 2 commits
    • yixiang's avatar
      Fix connGetSocketError usage (#7811) · b96c3595
      yixiang authored
      b96c3595
    • Yossi Gottlieb's avatar
      Fix occasional hangs on replication reconnection. (#7830) · 1980f639
      Yossi Gottlieb authored
      This happens only on diskless replicas when attempting to reconnect after 
      failing to load an RDB file. It is more likely to occur with larger datasets.
      
      After reconnection is initiated, replicationEmptyDbCallback() may get called 
      and try to write to an unconnected socket. This triggered another issue where
      the connection is put into an error state and the connect handler never gets
      called. The problem is a regression introduced by commit c17e597d.
      1980f639
  9. 17 Aug, 2020 1 commit
  10. 28 Jul, 2020 1 commit
  11. 22 Mar, 2020 1 commit
    • Yossi Gottlieb's avatar
      Conns: Fix connClose() / connAccept() behavior. · fa9aa908
      Yossi Gottlieb authored
      We assume accept handlers may choose to reject a connection and close
      it, but connAccept() callers can't distinguish between this state and
      other error states requiring connClose().
      
      This makes it safe (and mandatory!) to always call connClose() if
      connAccept() fails, and safe for accept handlers to close connections
      (which will defer).
      fa9aa908
  12. 15 Oct, 2019 2 commits
  13. 07 Oct, 2019 3 commits
    • Oran Agra's avatar
      TLS: Implement support for write barrier. · 6b629480
      Oran Agra authored
      6b629480
    • Oran Agra's avatar
      diskless replication rdb transfer uses pipe, and writes to sockets form the parent process. · 5a477946
      Oran Agra authored
      misc:
      - handle SSL_has_pending by iterating though these in beforeSleep, and setting timeout of 0 to aeProcessEvents
      - fix issue with epoll signaling EPOLLHUP and EPOLLERR only to the write handlers. (needed to detect the rdb pipe was closed)
      - add key-load-delay config for testing
      - trim connShutdown which is no longer needed
      - rioFdsetWrite -> rioFdWrite - simplified since there's no longer need to write to multiple FDs
      - don't detect rdb child exited (don't call wait3) until we detect the pipe is closed
      - Cleanup bad optimization from rio.c, add another one
      5a477946
    • Yossi Gottlieb's avatar
      TLS: Connections refactoring and TLS support. · b087dd1d
      Yossi Gottlieb authored
      * Introduce a connection abstraction layer for all socket operations and
      integrate it across the code base.
      * Provide an optional TLS connections implementation based on OpenSSL.
      * Pull a newer version of hiredis with TLS support.
      * Tests, redis-cli updates for TLS support.
      b087dd1d