| 851 | } |
| 852 | |
| 853 | bool TryToBindAddresses(const THttpServerOptions& options, const std::function<void(TSocket)>* callbackOnBoundAddress) { |
| 854 | THttpServerOptions::TBindAddresses addrs; |
| 855 | try { |
| 856 | options.BindAddresses(addrs); |
| 857 | } catch (const std::exception&) { |
| 858 | return false; |
| 859 | } |
| 860 | |
| 861 | for (const auto& na : addrs) { |
| 862 | for (TNetworkAddress::TIterator ai = na.Begin(); ai != na.End(); ++ai) { |
| 863 | NAddr::TAddrInfo addr(&*ai); |
| 864 | |
| 865 | TSocket socket(::socket(addr.Addr()->sa_family, SOCK_STREAM, 0)); |
| 866 | |
| 867 | if (socket == INVALID_SOCKET) { |
| 868 | return false; |
| 869 | } |
| 870 | |
| 871 | FixIPv6ListenSocket(socket); |
| 872 | |
| 873 | if (options.ReuseAddress) { |
| 874 | int yes = 1; |
| 875 | ::setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes)); |
| 876 | } |
| 877 | |
| 878 | if (options.ReusePort) { |
| 879 | SetReusePort(socket, true); |
| 880 | } |
| 881 | |
| 882 | if (::bind(socket, addr.Addr(), addr.Len()) == SOCKET_ERROR) { |
| 883 | return false; |
| 884 | } |
| 885 | |
| 886 | if (::listen(socket, options.ListenBacklog) == SOCKET_ERROR) { |
| 887 | return false; |
| 888 | } |
| 889 | |
| 890 | if (callbackOnBoundAddress != nullptr) { |
| 891 | (*callbackOnBoundAddress)(socket); |
| 892 | } |
| 893 | } |
| 894 | } |
| 895 | |
| 896 | return true; |
| 897 | } |
no test coverage detected