in src/server/worker.cc [114:194]
void Worker::newTCPConnection(evconnlistener *listener, evutil_socket_t fd, [[maybe_unused]] sockaddr *address,
[[maybe_unused]] int socklen) {
int local_port = util::GetLocalPort(fd); // NOLINT
debug("[worker] New connection: fd={} from port: {} thread #{}", fd, local_port, fmt::streamed(tid_));
auto s = util::SockSetTcpKeepalive(fd, 120);
if (!s.IsOK()) {
error("[worker] Failed to set tcp-keepalive on socket. Error: {}", s.Msg());
evutil_closesocket(fd);
return;
}
s = util::SockSetTcpNoDelay(fd, 1);
if (!s.IsOK()) {
error("[worker] Failed to set tcp-nodelay on socket. Error: {}", s.Msg());
evutil_closesocket(fd);
return;
}
event_base *base = evconnlistener_get_base(listener);
auto ev_thread_safe_flags =
BEV_OPT_THREADSAFE | BEV_OPT_DEFER_CALLBACKS | BEV_OPT_UNLOCK_CALLBACKS | BEV_OPT_CLOSE_ON_FREE;
bufferevent *bev = nullptr;
ssl_st *ssl = nullptr;
#ifdef ENABLE_OPENSSL
if (uint32_t(local_port) == srv->GetConfig()->tls_port) {
ssl = SSL_new(srv->ssl_ctx.get());
if (!ssl) {
error("[worker] Failed to construct SSL structure for new connection: {}", fmt::streamed(SSLErrors{}));
evutil_closesocket(fd);
return;
}
bev = bufferevent_openssl_socket_new(base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ev_thread_safe_flags);
} else {
bev = bufferevent_socket_new(base, fd, ev_thread_safe_flags);
}
#else
bev = bufferevent_socket_new(base, fd, ev_thread_safe_flags);
#endif
if (!bev) {
auto socket_err = evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR());
#ifdef ENABLE_OPENSSL
error("[worker] Failed to construct socket for new connection: {}, SSL error: {}", socket_err,
fmt::streamed(SSLErrors{}));
if (ssl) SSL_free(ssl);
#else
error("[worker] Failed to construct socket for new connection: {}", socket_err);
#endif
evutil_closesocket(fd);
return;
}
#ifdef ENABLE_OPENSSL
if (uint32_t(local_port) == srv->GetConfig()->tls_port) {
bufferevent_openssl_set_allow_dirty_shutdown(bev, 1);
}
#endif
auto conn = new redis::Connection(bev, this);
conn->SetCB(bev);
bufferevent_enable(bev, EV_READ);
s = AddConnection(conn);
if (!s.IsOK()) {
std::string err_msg = redis::Error({Status::NotOK, s.Msg()});
s = util::SockSend(fd, err_msg, ssl);
if (!s.IsOK()) {
warn("[worker] Failed to send error response to socket: {}", s.Msg());
}
conn->Close();
return;
}
if (auto s = util::GetPeerAddr(fd)) {
auto [ip, port] = std::move(*s);
conn->SetAddr(ip, port);
}
if (rate_limit_group_) {
bufferevent_add_to_rate_limit_group(bev, rate_limit_group_);
}
}