| 1599 | } |
| 1600 | |
| 1601 | static rem_port* aux_request( rem_port* port, PACKET* packet) |
| 1602 | { |
| 1603 | /************************************** |
| 1604 | * |
| 1605 | * a u x _ r e q u e s t |
| 1606 | * |
| 1607 | ************************************** |
| 1608 | * |
| 1609 | * Functional description |
| 1610 | * A remote interface has requested the server prepare an auxiliary |
| 1611 | * connection; the server calls aux_request to set up the connection. |
| 1612 | * |
| 1613 | **************************************/ |
| 1614 | |
| 1615 | // listen on (local) address of the original socket |
| 1616 | SockAddr our_address; |
| 1617 | if (our_address.getsockname(port->port_handle) < 0) |
| 1618 | { |
| 1619 | gds__log("INET/aux_request: failed to get local address of the original socket"); |
| 1620 | inet_error(false, port, "getsockname", isc_net_event_listen_err, INET_ERRNO); |
| 1621 | } |
| 1622 | unsigned short aux_port = port->getPortConfig()->getRemoteAuxPort(); |
| 1623 | our_address.setPort(aux_port); // may be 0 |
| 1624 | |
| 1625 | SOCKET n = os_utils::socket(our_address.family(), SOCK_STREAM, 0); |
| 1626 | if (n == INVALID_SOCKET) |
| 1627 | { |
| 1628 | inet_error(false, port, "socket", isc_net_event_listen_err, INET_ERRNO); |
| 1629 | } |
| 1630 | |
| 1631 | int optval; |
| 1632 | #ifndef WIN_NT |
| 1633 | // dimitr: on Windows, lack of SO_REUSEADDR works the same way as it was specified on POSIX, |
| 1634 | // i.e. it allows binding to a port in a TIME_WAIT/FIN_WAIT state. If this option |
| 1635 | // is turned on explicitly, then a port can be re-bound regardless of its state, |
| 1636 | // e.g. while it's listening. This is surely not what we want. |
| 1637 | |
| 1638 | optval = TRUE; |
| 1639 | if (setsockopt(n, SOL_SOCKET, SO_REUSEADDR, (SCHAR*) &optval, sizeof(optval)) < 0) |
| 1640 | { |
| 1641 | inet_error(false, port, "setsockopt REUSE", isc_net_event_listen_err, INET_ERRNO); |
| 1642 | } |
| 1643 | #endif |
| 1644 | |
| 1645 | optval = port->getPortConfig()->getIPv6V6Only() ? 1 : 0; |
| 1646 | // ignore failure, we already have it logged from the main listening port |
| 1647 | setsockopt(n, IPPROTO_IPV6, IPV6_V6ONLY, (SCHAR*) &optval, sizeof(optval)); |
| 1648 | |
| 1649 | if (bind(n, our_address.ptr(), our_address.length()) < 0) |
| 1650 | { |
| 1651 | inet_error(false, port, "bind", isc_net_event_listen_err, INET_ERRNO); |
| 1652 | } |
| 1653 | |
| 1654 | if (our_address.getsockname(n) < 0) |
| 1655 | { |
| 1656 | inet_error(false, port, "getsockname", isc_net_event_listen_err, INET_ERRNO); |
| 1657 | } |
| 1658 |
nothing calls this directly
no test coverage detected