MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / startServers

Method startServers

programs/local/LocalServer.cpp:569–834  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

567
568
569void LocalServer::startServers(const ServerType & server_type)
570{
571 validateLocalServerListenType(server_type);
572
573 const auto & config = getClientConfiguration();
574 const Settings & settings = global_context->getSettingsRef();
575
576 /// The configured `tcp_port` / `http_port` is the port that the listener binds, and `createServer`
577 /// casts it to `UInt16`, so a value outside `0..65535` would silently wrap (`-1` -> `65535`,
578 /// `70000` -> `4464`) and bring the listener up on an unexpected port. `--tcp_port` / `--http_port`
579 /// are already range-checked when parsed, but a value coming from a loaded config file reaches this
580 /// path unchecked, so validate the effective value here for every protocol being started. `0` means
581 /// an OS-assigned port and is allowed.
582 auto validate_port_range = [&](const char * port_name)
583 {
584 if (!config.has(port_name))
585 return;
586 Int64 port = config.getInt64(port_name);
587 if (port < 0 || port > 65535)
588 throw Exception(
589 ErrorCodes::BAD_ARGUMENTS,
590 "Invalid value {} for {}: a port number must be in the range 0..65535 (use 0 for an OS-assigned port)",
591 port, port_name);
592 };
593 if (server_type.shouldStart(ServerType::Type::TCP))
594 validate_port_range("tcp_port");
595 if (server_type.shouldStart(ServerType::Type::HTTP))
596 validate_port_range("http_port");
597
598 /// An explicit `--listen_host` on the command line is a hard override: bind only that single host
599 /// and ignore any `listen_host` entries from a loaded config file. This matters because
600 /// `getMultipleValuesFromConfig` returns the union of repeated `listen_host[...]` keys across all
601 /// configuration layers, so a plain `config.setString("listen_host", ...)` would replace only the
602 /// first entry and leave lower-priority hosts (possibly non-loopback) from the config still bound,
603 /// defeating the documented hardening path.
604 std::vector<std::string> listen_hosts;
605 if (cli_listen_host.has_value())
606 listen_hosts.emplace_back(*cli_listen_host);
607 else
608 listen_hosts = DB::getMultipleValuesFromConfig(config, "", "listen_host");
609
610 const bool hosts_explicitly_configured = !listen_hosts.empty();
611 if (listen_hosts.empty())
612 {
613 listen_hosts.emplace_back("::1");
614 listen_hosts.emplace_back("127.0.0.1");
615 }
616
617 /// Mirror `clickhouse-server`'s `getListenTry`: honor an explicit `listen_try` server setting,
618 /// and otherwise fall back to `listen_try=true` only when the user has not named any host
619 /// explicitly (so the implicit `::1` + `127.0.0.1` defaults don't fail on a host without
620 /// IPv6). When the user names hosts explicitly with `listen_try=0`, surface bind failures.
621 bool listen_try = server_settings[ServerSetting::listen_try];
622 if (!listen_try)
623 listen_try = !hosts_explicitly_configured;
624
625 /// `getServerPort` stores a single value per `port_name`, so an OS-assigned ephemeral
626 /// port (`port=0`) combined with multiple `listen_host` values would produce an

Callers

nothing calls this directly

Calls 15

createServerFunction · 0.85
socketBindListenFunction · 0.85
loggerFunction · 0.85
createHandlerFactoryFunction · 0.85
shouldStartMethod · 0.80
setMaxQueuedMethod · 0.80
registerServerPortMethod · 0.80
ExceptionClass · 0.50

Tested by

no test coverage detected