-------------------------------------------------------------------------*\ * Tries to bind socket to (address, port) \*-------------------------------------------------------------------------*/
| 465 | * Tries to bind socket to (address, port) |
| 466 | \*-------------------------------------------------------------------------*/ |
| 467 | const char *inet_trybind(p_socket ps, const char *address, const char *serv, |
| 468 | struct addrinfo *bindhints) |
| 469 | { |
| 470 | struct addrinfo *iterator = NULL, *resolved = NULL; |
| 471 | const char *err = NULL; |
| 472 | t_socket sock = *ps; |
| 473 | /* translate luasocket special values to C */ |
| 474 | if (strcmp(address, "*") == 0) address = NULL; |
| 475 | if (!serv) serv = "0"; |
| 476 | /* try resolving */ |
| 477 | err = socket_gaistrerror(getaddrinfo(address, serv, bindhints, &resolved)); |
| 478 | if (err) { |
| 479 | if (resolved) freeaddrinfo(resolved); |
| 480 | return err; |
| 481 | } |
| 482 | /* iterate over resolved addresses until one is good */ |
| 483 | for (iterator = resolved; iterator; iterator = iterator->ai_next) { |
| 484 | if(sock == SOCKET_INVALID) { |
| 485 | err = socket_strerror(socket_create(&sock, iterator->ai_family, |
| 486 | iterator->ai_socktype, iterator->ai_protocol)); |
| 487 | if(err) |
| 488 | continue; |
| 489 | } |
| 490 | /* try binding to local address */ |
| 491 | err = socket_strerror(socket_bind(&sock, |
| 492 | (SA *) iterator->ai_addr, |
| 493 | (socklen_t) iterator->ai_addrlen)); |
| 494 | |
| 495 | /* keep trying unless bind succeeded */ |
| 496 | if (err) { |
| 497 | if(sock != *ps) |
| 498 | socket_destroy(&sock); |
| 499 | } else { |
| 500 | /* remember what we connected to, particularly the family */ |
| 501 | *bindhints = *iterator; |
| 502 | break; |
| 503 | } |
| 504 | } |
| 505 | /* cleanup and return error */ |
| 506 | freeaddrinfo(resolved); |
| 507 | *ps = sock; |
| 508 | return err; |
| 509 | } |
| 510 | |
| 511 | /*-------------------------------------------------------------------------*\ |
| 512 | * Some systems do not provide these so that we provide our own. |
no test coverage detected