| 1345 | } |
| 1346 | |
| 1347 | void Networking::startQuery(IP_PORT ip_port) |
| 1348 | { |
| 1349 | if (ip_port.port <= 1024) |
| 1350 | return; |
| 1351 | |
| 1352 | if (!query_alive) |
| 1353 | { |
| 1354 | if (ip_port.port == MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE) |
| 1355 | { |
| 1356 | PRINT_DEBUG("Source Query in Shared Mode"); |
| 1357 | return; |
| 1358 | } |
| 1359 | |
| 1360 | int retry = 0; |
| 1361 | constexpr auto max_retry = 10; |
| 1362 | |
| 1363 | while (retry++ < max_retry) |
| 1364 | { |
| 1365 | query_socket = static_cast<sock_t>(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)); |
| 1366 | if (is_socket_valid(query_socket)) |
| 1367 | break; |
| 1368 | if (retry > max_retry) |
| 1369 | { |
| 1370 | reset_last_error(); |
| 1371 | return; |
| 1372 | } |
| 1373 | } |
| 1374 | retry = 0; |
| 1375 | |
| 1376 | sockaddr_in addr{}; |
| 1377 | addr.sin_addr.s_addr = htonl(ip_port.ip); |
| 1378 | addr.sin_port = htons(ip_port.port); |
| 1379 | addr.sin_family = AF_INET; |
| 1380 | |
| 1381 | while (retry++ < max_retry) |
| 1382 | { |
| 1383 | int res = bind(query_socket, (sockaddr*)&addr, sizeof(sockaddr_in)); |
| 1384 | if (res == 0) |
| 1385 | { |
| 1386 | set_socket_nonblocking(query_socket); |
| 1387 | break; |
| 1388 | } |
| 1389 | |
| 1390 | if (retry >= max_retry) |
| 1391 | { |
| 1392 | kill_socket(query_socket); |
| 1393 | query_socket = -1; |
| 1394 | reset_last_error(); |
| 1395 | return; |
| 1396 | } |
| 1397 | } |
| 1398 | |
| 1399 | char str_ip[16]{}; |
| 1400 | inet_ntop(AF_INET, &(addr.sin_addr), str_ip, 16); |
| 1401 | |
| 1402 | PRINT_DEBUG("Started query server on %s:%d", str_ip, htons(addr.sin_port)); |
| 1403 | } |
| 1404 | query_alive = true; |
no test coverage detected