43 int build_tree(
int* parent, uint16_t* kid_count,
size_t source_count,
int offset)
45 if (source_count == 1)
47 kid_count[offset] = 0;
51 int height = (int)floor(log((
double)source_count) / log(2.0));
52 int root = (1 << height) - 1;
53 int left_count = root;
54 int left_offset = offset;
55 int left_child =
build_tree(parent, kid_count, left_count, left_offset);
56 int oroot = root + offset;
57 parent[left_child] = oroot;
59 size_t right_count = source_count - left_count - 1;
62 int right_offset = oroot + 1;
64 int right_child =
build_tree(parent, kid_count, right_count, right_offset);
65 parent[right_child] = oroot;
76 if (send(fd, (
char*)buf, count, 0) == -1)
82 SpanningTree::SpanningTree(uint16_t port,
bool quiet) : m_stop(false), m_port(port), m_future(nullptr), m_quiet(quiet)
86 int lastError = WSAStartup(MAKEWORD(2, 2), &wsaData);
88 THROWERRNO(
"WSAStartup() returned error:" << lastError);
91 sock = socket(PF_INET, SOCK_STREAM, 0);
96 if (setsockopt(
sock, SOL_SOCKET, SO_REUSEADDR, (
char*)&on,
sizeof(on)) < 0)
100 address.sin_family = AF_INET;
101 address.sin_addr.s_addr = htonl(INADDR_ANY);
103 address.sin_port = htons(port);
104 if (::bind(
sock, (sockaddr*)&address,
sizeof(address)) < 0)
105 THROWERRNO(
"bind failed for " << inet_ntoa(address.sin_addr));
107 sockaddr_in bound_addr;
108 memset(&bound_addr, 0,
sizeof(bound_addr));
109 socklen_t len =
sizeof(bound_addr);
110 if (::getsockname(
sock, (sockaddr*)&bound_addr, &len) < 0)
111 THROWERRNO(
"getsockname: " << inet_ntoa(bound_addr.sin_addr));
114 m_port = ntohs(bound_addr.sin_port);
141 shutdown(
sock, SHUT_RD);
154 std::map<size_t, partial> partial_nodesets;
157 if (listen(
sock, 1024) < 0)
160 sockaddr_in client_address;
161 socklen_t size =
sizeof(client_address);
162 socket_t f = accept(
sock, (sockaddr*)&client_address, &size);
164 if (f == INVALID_SOCKET)
173 char dotted_quad[INET_ADDRSTRLEN];
174 if (NULL == inet_ntop(AF_INET, &(client_address.sin_addr), dotted_quad, INET_ADDRSTRLEN))
177 char hostname[NI_MAXHOST];
178 char servInfo[NI_MAXSERV];
179 if (getnameinfo((sockaddr*)&client_address,
sizeof(sockaddr), hostname, NI_MAXHOST, servInfo, NI_MAXSERV, 0))
183 std::cerr <<
"inbound connection from " << dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port)
184 <<
") serv=" << servInfo << std::endl;
187 if (recv(f, (
char*)&nonce,
sizeof(nonce), 0) !=
sizeof(nonce))
189 THROW(dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): nonce read failed, exiting");
194 std::cerr << dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): nonce=" << nonce << std::endl;
197 if (recv(f, (
char*)&total,
sizeof(total), 0) !=
sizeof(total))
199 THROW(dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): total node count read failed, exiting");
204 std::cerr << dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): total=" << total << std::endl;
207 if (recv(f, (
char*)&
id,
sizeof(
id), 0) !=
sizeof(
id))
209 THROW(dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): node id read failed, exiting");
214 std::cerr << dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): node id=" <<
id << std::endl;
221 std::cout << dotted_quad <<
"(" << hostname <<
':' << ntohs(
m_port) <<
"): invalid id=" <<
id 222 <<
" >= " << total <<
" !" << std::endl;
227 if (partial_nodesets.find(nonce) == partial_nodesets.end())
230 for (
size_t i = 0; i < total; i++) partial_nodeset.
nodes[i].
client_ip = (uint32_t)-1;
231 partial_nodeset.
filled = 0;
235 partial_nodeset = partial_nodesets[nonce];
236 partial_nodesets.erase(nonce);
249 if (partial_nodeset.
filled != total)
251 partial_nodesets[nonce] = partial_nodeset;
252 for (
size_t i = 0; i < total; i++)
257 std::cout <<
"nonce " << nonce <<
" still waiting for " << (total - partial_nodeset.
filled)
258 <<
" nodes out of " << total <<
" for example node " << i << std::endl;
268 int* parent = (
int*)calloc(total,
sizeof(
int));
269 uint16_t* kid_count = (uint16_t*)calloc(total,
sizeof(uint16_t));
271 int root =
build_tree(parent, kid_count, total, 0);
274 for (
size_t i = 0; i < total; i++)
279 uint16_t* client_ports = (uint16_t*)calloc(total,
sizeof(uint16_t));
281 for (
size_t i = 0; i < total; i++)
284 if (recv(partial_nodeset.
nodes[i].
socket, (
char*)&(client_ports[i]),
sizeof(client_ports[i]), 0) <
285 (int)
sizeof(client_ports[i]))
288 std::cerr <<
" Port read failed for node " << i <<
" read " << done << std::endl;
291 for (
size_t i = 0; i < total; i++)
297 fail_send(partial_nodeset.
nodes[i].
socket, &client_ports[parent[i]],
sizeof(client_ports[parent[i]]));
302 uint32_t bogus2 = -1;
309 free(partial_nodeset.
nodes);
int build_tree(int *parent, uint16_t *kid_count, size_t source_count, int offset)
void fail_send(const socket_t fd, const void *buf, const int count)
static int socket_sort(const void *s1, const void *s2)
short unsigned int BoundPort()
std::future< void > * m_future