Bind HTTP server to specified addresses */
| 389 | |
| 390 | /** Bind HTTP server to specified addresses */ |
| 391 | static bool HTTPBindAddresses(struct evhttp *http) { |
| 392 | uint16_t http_port{static_cast<uint16_t>( |
| 393 | gArgs.GetIntArg("-rpcport", BaseParams().RPCPort()))}; |
| 394 | std::vector<std::pair<std::string, uint16_t>> endpoints; |
| 395 | |
| 396 | // Determine what addresses to bind to |
| 397 | if (!(gArgs.IsArgSet("-rpcallowip") && gArgs.IsArgSet("-rpcbind"))) { |
| 398 | // Default to loopback if not allowing external IPs. |
| 399 | endpoints.push_back(std::make_pair("::1", http_port)); |
| 400 | endpoints.push_back(std::make_pair("127.0.0.1", http_port)); |
| 401 | if (gArgs.IsArgSet("-rpcallowip")) { |
| 402 | LogPrintf("WARNING: option -rpcallowip was specified without " |
| 403 | "-rpcbind; this doesn't usually make sense\n"); |
| 404 | } |
| 405 | if (gArgs.IsArgSet("-rpcbind")) { |
| 406 | LogPrintf("WARNING: option -rpcbind was ignored because " |
| 407 | "-rpcallowip was not specified, refusing to allow " |
| 408 | "everyone to connect\n"); |
| 409 | } |
| 410 | } else if (gArgs.IsArgSet("-rpcbind")) { |
| 411 | // Specific bind address. |
| 412 | for (const std::string &strRPCBind : gArgs.GetArgs("-rpcbind")) { |
| 413 | uint16_t port{http_port}; |
| 414 | std::string host; |
| 415 | SplitHostPort(strRPCBind, port, host); |
| 416 | endpoints.push_back(std::make_pair(host, port)); |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | // Bind addresses |
| 421 | for (std::vector<std::pair<std::string, uint16_t>>::iterator i = |
| 422 | endpoints.begin(); |
| 423 | i != endpoints.end(); ++i) { |
| 424 | LogPrint(BCLog::HTTP, "Binding RPC on address %s port %i\n", i->first, |
| 425 | i->second); |
| 426 | evhttp_bound_socket *bind_handle = evhttp_bind_socket_with_handle( |
| 427 | http, i->first.empty() ? nullptr : i->first.c_str(), i->second); |
| 428 | if (bind_handle) { |
| 429 | const std::optional<CNetAddr> addr{LookupHost(i->first, false)}; |
| 430 | if (i->first.empty() || (addr.has_value() && addr->IsBindAny())) { |
| 431 | LogPrintf("WARNING: the RPC server is not safe to expose to " |
| 432 | "untrusted networks such as the public internet\n"); |
| 433 | } |
| 434 | boundSockets.push_back(bind_handle); |
| 435 | } else { |
| 436 | LogPrintf("Binding RPC on address %s port %i failed.\n", i->first, |
| 437 | i->second); |
| 438 | } |
| 439 | } |
| 440 | return !boundSockets.empty(); |
| 441 | } |
| 442 | |
| 443 | /** Simple wrapper to set thread name and run work queue */ |
| 444 | static void HTTPWorkQueueRun(WorkQueue<HTTPClosure> *queue, int worker_num) { |
no test coverage detected