/** * * @file TcpServer.h * @author An Tao * * Copyright 2018, An Tao. All rights reserved. * https://github.com/an-tao/trantor * Use of this source code is governed by a BSD-style license * that can be found in the License file. * * Trantor * */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include namespace trantor { class Acceptor; class SSLContext; /** * @brief This class represents a TCP server. * */ class TRANTOR_EXPORT TcpServer : NonCopyable { public: /** * @brief Construct a new TCP server instance. * * @param loop The event loop in which the acceptor of the server is * handled. * @param address The address of the server. * @param name The name of the server. * @param reUseAddr The SO_REUSEADDR option. * @param reUsePort The SO_REUSEPORT option. */ TcpServer(EventLoop *loop, const InetAddress &address, const std::string &name, bool reUseAddr = true, bool reUsePort = true); ~TcpServer(); /** * @brief Start the server. * */ void start(); /** * @brief Stop the server. * */ void stop(); /** * @brief Set the number of event loops in which the I/O of connections to * the server is handled. * * @param num */ void setIoLoopNum(size_t num) { assert(!started_); loopPoolPtr_ = std::make_shared(num); loopPoolPtr_->start(); } /** * @brief Set the event loops pool in which the I/O of connections to * the server is handled. * * @param pool */ void setIoLoopThreadPool(const std::shared_ptr &pool) { assert(pool->size() > 0); assert(!started_); loopPoolPtr_ = pool; loopPoolPtr_->start(); } /** * @brief Set the message callback. * * @param cb The callback is called when some data is received on a * connection to the server. */ void setRecvMessageCallback(const RecvMessageCallback &cb) { recvMessageCallback_ = cb; } void setRecvMessageCallback(RecvMessageCallback &&cb) { recvMessageCallback_ = std::move(cb); } /** * @brief Set the connection callback. * * @param cb The callback is called when a connection is established or * closed. */ void setConnectionCallback(const ConnectionCallback &cb) { connectionCallback_ = cb; } void setConnectionCallback(ConnectionCallback &&cb) { connectionCallback_ = std::move(cb); } /** * @brief Set the write complete callback. * * @param cb The callback is called when data to send is written to the * socket of a connection. */ void setWriteCompleteCallback(const WriteCompleteCallback &cb) { writeCompleteCallback_ = cb; } void setWriteCompleteCallback(WriteCompleteCallback &&cb) { writeCompleteCallback_ = std::move(cb); } /** * @brief Get the name of the server. * * @return const std::string& */ const std::string &name() const { return serverName_; } /** * @brief Get the IP and port string of the server. * * @return const std::string */ const std::string ipPort() const; /** * @brief Get the address of the server. * * @return const trantor::InetAddress& */ const trantor::InetAddress &address() const; /** * @brief Get the event loop of the server. * * @return EventLoop* */ EventLoop *getLoop() const { return loop_; } /** * @brief Get the I/O event loops of the server. * * @return std::vector */ std::vector getIoLoops() const { return loopPoolPtr_->getLoops(); } /** * @brief An idle connection is a connection that has no read or write, kick * off it after timeout seconds. * * @param timeout */ void kickoffIdleConnections(size_t timeout) { loop_->runInLoop([this, timeout]() { assert(!started_); idleTimeout_ = timeout; }); } /** * @brief Enable SSL encryption. * * @param certPath The path of the certificate file. * @param keyPath The path of the private key file. * @param useOldTLS If true, the TLS 1.0 and 1.1 are supported by the * server. * @param sslConfCmds The commands used to call the SSL_CONF_cmd function in * OpenSSL. * @note It's well known that TLS 1.0 and 1.1 are not considered secure in * 2020. And it's a good practice to only use TLS 1.2 and above. */ void enableSSL(const std::string &certPath, const std::string &keyPath, bool useOldTLS = false, const std::vector> &sslConfCmds = {}); private: EventLoop *loop_; std::unique_ptr acceptorPtr_; void newConnection(int fd, const InetAddress &peer); std::string serverName_; std::set connSet_; RecvMessageCallback recvMessageCallback_; ConnectionCallback connectionCallback_; WriteCompleteCallback writeCompleteCallback_; size_t idleTimeout_{0}; std::map> timingWheelMap_; void connectionClosed(const TcpConnectionPtr &connectionPtr); std::shared_ptr loopPoolPtr_; #ifndef _WIN32 class IgnoreSigPipe { public: IgnoreSigPipe() { ::signal(SIGPIPE, SIG_IGN); LOG_TRACE << "Ignore SIGPIPE"; } }; IgnoreSigPipe initObj; #endif bool started_{false}; // OpenSSL SSL context Object; std::shared_ptr sslCtxPtr_; }; } // namespace trantor