Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251bool InitHTTPAllowList();253/**254* Bind to a new address:port, start listening and add the listen socket to `m_listen`.255* @param[in] to Where to bind.256* @returns {} or the reason for failure.257*/258util::Expected<void, std::string> BindAndStartListening(const CService& to);260/**261* Stop listening by closing all listening sockets.262*/263void StopListening();265/**266* Get the number of sockets the server is bound to and listening on267*/268size_t GetListeningSocketCount() const { return m_listen.size(); }270/**271* Get the number of HTTPRemoteClients we are connected to272*/273size_t GetConnectionsCount() const { return m_connected_size.load(std::memory_order_acquire); }275/**276* Start the necessary threads for sockets IO.277*/278void StartSocketsThreads();280/**281* Join (wait for) the threads started by `StartSocketsThreads()` to exit.282*/283void JoinSocketsThreads();285/**286* Stop network activity287*/288void InterruptNet() { m_interrupt_net(); }290/**291* Start disconnecting clients when possible in the I/O loop292*/293void DisconnectAllClients() { m_disconnect_all_clients = true; }295/**296* Update the request handler method.297* Used for shutdown to reject new requests.298*/299void SetRequestHandler(std::function<void(std::unique_ptr<HTTPRequest>&&)> func)300EXCLUSIVE_LOCKS_REQUIRED(!m_request_dispatcher_mutex)301{302WITH_LOCK(m_request_dispatcher_mutex,303m_request_dispatcher = std::move(func));304}306/**307* Stop accepting new connections in the I/O loop.308* Must be called first in StopHTTPServer() before DisconnectAllClients().309* A connection accepted after the "wait for 0 connections" loop exits would310* remain in m_connected when the destructor is called.311*/312void StopAccepting() { m_stop_accepting = true; }314/**315* Set the idle client timeout (-rpcservertimeout)316*/317void SetServerTimeout(std::chrono::seconds seconds) { m_rpcservertimeout = seconds; }319/**320* Set the maximum amount of connected HTTPClients (-rpcmaxconnections)321*/322void SetMaxConnections(int max_conn) { m_rpcmaxconnections = max_conn; }324/**325* Force-remove all remaining clients from m_connected without waiting for326* graceful disconnection. Must only be called after JoinSocketsThreads().327*/328void ClearConnectedClients();330private:331/**332* List of listening sockets.333*/334std::vector<std::shared_ptr<Sock>> m_listen;336/**337* The id to assign to the next created connection.338*/339std::atomic<Id> m_next_id{0};341/**342* List of HTTPRemoteClients with connected sockets.343* Connections will only be added and removed in the I/O thread, but344* weak pointers may be passed to worker threads to handle requests345* and send replies.346*/347std::vector<std::shared_ptr<HTTPRemoteClient>> m_connected;349/**350* Flag used during shutdown to stop accepting new connections.351* Set by main thread and read by the I/O thread.352*/353std::atomic_bool m_stop_accepting{false};355/**356* Flag used during shutdown.357* Overrides HTTPRemoteClient flags m_keep_alive and m_connection_busy.358* Set by main thread and read by the I/O thread.359*/360std::atomic_bool m_disconnect_all_clients{false};362/**363* The number of connected sockets.364* Updated from the I/O thread but safely readable from365* the main thread without locks.366*/367std::atomic<size_t> m_connected_size{0};369/**370* Info about which socket has which event ready and a reverse map371* back to the HTTPRemoteClient that owns the socket.372*/373struct IOReadiness {374/**375* Map of socket -> socket events. For example:376* socket1 -> { requested = SendEvent|RecvEvent, occurred = RecvEvent }377* socket2 -> { requested = SendEvent, occurred = SendEvent }378*/379Sock::EventsPerSock events_per_sock;381/**382* Map of socket -> HTTPRemoteClient. For example:383* socket1 -> HTTPRemoteClient{ id=23 }384* socket2 -> HTTPRemoteClient{ id=56 }385*/386std::unordered_map<Sock::EventsPerSock::key_type,387std::shared_ptr<HTTPRemoteClient>,388Sock::HashSharedPtrSock,389Sock::EqualSharedPtrSock>390httpclients_per_sock;391};393/**394* This is signaled when network activity should cease.395*/396CThreadInterrupt m_interrupt_net;398/**399* Thread that sends to and receives from sockets and accepts connections.400* Executes the I/O loop of the server.401*/402std::thread m_thread_socket_handler;404/*405* What to do with HTTP requests once received, validated and parsed.406* Set in main thread by server start and interrupt but read in407* worker threads.408*/409/// @{410mutable Mutex m_request_dispatcher_mutex;411std::function<void(std::unique_ptr<HTTPRequest>&&)> m_request_dispatcher GUARDED_BY(m_request_dispatcher_mutex);412/// @}414/**415* Idle timeout after which clients are disconnected416*/417std::chrono::seconds m_rpcservertimeout{DEFAULT_HTTP_SERVER_TIMEOUT};419/**420* List of subnets to allow HTTP connections from421*/422std::vector<CSubNet> m_allow_subnets;424/**425* Check an incoming connection's source IP against the allow list426*/427bool ClientAllowed(const CNetAddr& netaddr) const;429/**430* Maximum amount of concurrent connections431*/432int m_rpcmaxconnections{DEFAULT_MAX_HTTP_CONNECTIONS};434/**435* Accept a connection.436* @param[in] listen_sock Socket on which to accept the connection.437* @param[out] addr Address of the peer that was accepted.438* @return Newly created socket for the accepted connection.439*/440std::unique_ptr<Sock> AcceptConnection(const Sock& listen_sock, CService& addr);442/**443* Generate an id for a newly created connection.444*/445Id GetNewId();447/**448* After a new socket with a client has been created, configure its flags,449* make a new HTTPRemoteClient and Id and save its shared pointer.450* @param[in] sock The newly created socket.451* @param[in] addr Address of the new peer.452*/453void NewSockAccepted(std::unique_ptr<Sock>&& sock, const CService& addr);455/**456* Do the read/write for connected sockets that are ready for IO.457* @param[in] io_readiness Which sockets are ready and their corresponding HTTPRemoteClients.458*/459void SocketHandlerConnected(const IOReadiness& io_readiness) const460EXCLUSIVE_LOCKS_REQUIRED(!m_request_dispatcher_mutex);462/**463* Accept incoming connections, one from each read-ready listening socket.464* @param[in] events_per_sock Sockets that are ready for IO.465*/466void SocketHandlerListening(const Sock::EventsPerSock& events_per_sock);468/**469* Generate a collection of sockets to check for IO readiness.470* @return Sockets to check for readiness plus an aux map to find the471* corresponding HTTPRemoteClient given a socket.472*/473IOReadiness GenerateWaitSockets() const;475/**476* Check connected and listening sockets for IO readiness and process them accordingly.477* This is the main I/O loop of the server.478*/479void ThreadSocketHandler() EXCLUSIVE_LOCKS_REQUIRED(!m_request_dispatcher_mutex);481/**482* Close underlying socket connections for flagged clients483* by removing their shared pointer from m_connected. If an HTTPRemoteClient484* is busy in a worker thread, its connection will be closed once that485* job is done.486*/487void DisconnectClients();488};490std::optional<std::string> GetQueryParameterFromUri(std::string_view uri, std::string_view key);492class HTTPRemoteClient493{494public:495explicit HTTPRemoteClient(HTTPServer::Id id, const CService& addr, std::unique_ptr<Sock> socket)496: m_id(id), m_addr(addr), m_origin(addr.ToStringAddrPort()), m_sock{std::move(socket)}, m_idle_since{Now<SteadySeconds>()} {}498// Disable copies (should only be used as shared pointers)499HTTPRemoteClient(const HTTPRemoteClient&) = delete;500HTTPRemoteClient& operator=(const HTTPRemoteClient&) = delete;
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.