44 std::unique_ptr<sockaddr_in>
get_sockaddr(
const std::string &ip_address, uint16_t command_port)
46 struct addrinfo hints, *res;
47 memset(&hints, 0,
sizeof(hints));
48 hints.ai_family = AF_INET;
49 hints.ai_socktype = 0;
51 const int addrstatus = getaddrinfo(ip_address.c_str(), NULL, &hints, &res);
52 if (addrstatus != 0 || res == NULL)
54 CRL_EXCEPTION(
"unable to resolve \"%s\": %s", ip_address.c_str(), strerror(errno));
58 memcpy(&addr, &(((
struct sockaddr_in *)(res->ai_addr))->sin_addr),
sizeof(in_addr));
60 auto socaddr = std::unique_ptr<sockaddr_in>(
new sockaddr_in);
61 socaddr->sin_family = AF_INET;
62 socaddr->sin_port = htons(command_port);
63 socaddr->sin_addr = addr;
72 auto socaddr = std::unique_ptr<sockaddr_in>(
new sockaddr_in);
73 socaddr->sin_family = AF_INET;
74 socaddr->sin_port = htons(command_port);
75 socaddr->sin_addr.s_addr = htonl(INADDR_BROADCAST);
80 std::tuple<socket_t, uint16_t>
bind(
const std::optional<std::string>& interface_name,
bool broadcast)
85 auto server_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
86 #if defined(__MINGW64__)
89 if (server_socket < 0)
96 if (interface_name && !interface_name->empty())
99 if (0 != setsockopt(server_socket,
102 interface_name->c_str(),
103 interface_name->size()))
105 CRL_EXCEPTION(
"Failed to bind to device %s. Error: %s", interface_name->c_str(),
109 if (0 != setsockopt(server_socket,
112 interface_name->c_str(),
113 interface_name->size() + 1))
115 CRL_EXCEPTION(
"Failed to bind to device %s. Error: %s", interface_name->c_str(),
119 if (interface_name && !interface_name->empty())
121 CRL_DEBUG(
"User specified binding to adapter %s, but this feature is only supported under linux."
122 "Ignoring bind to specific adapter", interface_name->c_str());
130 CRL_DEBUG(
"User specified configuring the socket to broadcast. This feature is only supported under linux."
131 "Ignoring the broadcast request");
134 if (0 != setsockopt(server_socket, SOL_SOCKET, SO_BROADCAST,
reinterpret_cast<char const*
>(&b),
sizeof(b)))
136 CRL_EXCEPTION(
"Failed to configure broadcasting on a the socket. Error: %s", strerror(errno));
144 u_long ioctl_arg = 1;
145 if (0 != ioctlsocket(server_socket, FIONBIO, &ioctl_arg))
146 CRL_EXCEPTION(
"failed to make a socket non-blocking: %d",WSAGetLastError ());
148 const int flags = fcntl(server_socket, F_GETFL, 0);
150 if (0 != fcntl(server_socket, F_SETFL, flags | O_NONBLOCK))
160 if (0 != setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, (
char*) &reuseSocket,
161 sizeof(reuseSocket)))
170 int bufferSize = 4 * 1024 * 1024;
172 int bufferSize = 48 * 1024 * 1024;
175 if (0 != setsockopt(server_socket, SOL_SOCKET, SO_RCVBUF, (
char*) &bufferSize,
176 sizeof(bufferSize)) ||
177 0 != setsockopt(server_socket, SOL_SOCKET, SO_SNDBUF, (
char*) &bufferSize,
180 CRL_EXCEPTION(
"failed to adjust socket buffer sizes (%d bytes): %s",
181 bufferSize, strerror(errno));
187 struct sockaddr_in address;
189 address.sin_family = AF_INET;
190 address.sin_port = htons(0);
191 address.sin_addr.s_addr = htonl(INADDR_ANY);
193 if (0 != ::
bind(server_socket, (
struct sockaddr*) &address,
sizeof(address)))
194 CRL_EXCEPTION(
"failed to bind the server socket to system-assigned port: %s",
200 int len =
sizeof(address);
202 socklen_t len =
sizeof(address);
204 if (0 != getsockname(server_socket, (
struct sockaddr*) &address, &len))
209 auto server_socket_port = htons(address.sin_port);
211 return std::make_tuple(server_socket, server_socket_port);