"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/isc/win32/net.c" (7 Sep 2020, 7192 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "net.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 
   13 #include <config.h>
   14 
   15 #include <errno.h>
   16 #include <unistd.h>
   17 
   18 #include <isc/log.h>
   19 #include <isc/msgs.h>
   20 #include <isc/net.h>
   21 #include <isc/once.h>
   22 #include <isc/strerror.h>
   23 #include <isc/string.h>
   24 #include <isc/util.h>
   25 
   26 /*%
   27  * Definitions about UDP port range specification.  This is a total mess of
   28  * portability variants: some use sysctl (but the sysctl names vary), some use
   29  * system-specific interfaces, some have the same interface for IPv4 and IPv6,
   30  * some separate them, etc...
   31  */
   32 
   33 /*%
   34  * The last resort defaults: use all non well known port space
   35  */
   36 #ifndef ISC_NET_PORTRANGELOW
   37 #define ISC_NET_PORTRANGELOW 32768
   38 #endif  /* ISC_NET_PORTRANGELOW */
   39 #ifndef ISC_NET_PORTRANGEHIGH
   40 #define ISC_NET_PORTRANGEHIGH 65535
   41 #endif  /* ISC_NET_PORTRANGEHIGH */
   42 
   43 #if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRANY)
   44 const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
   45 #endif
   46 
   47 static isc_once_t   once = ISC_ONCE_INIT;
   48 static isc_once_t   once_ipv6only = ISC_ONCE_INIT;
   49 static isc_once_t   once_ipv6pktinfo = ISC_ONCE_INIT;
   50 static isc_result_t ipv4_result = ISC_R_NOTFOUND;
   51 static isc_result_t ipv6_result = ISC_R_NOTFOUND;
   52 static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
   53 static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
   54 
   55 void InitSockets(void);
   56 
   57 static isc_result_t
   58 try_proto(int domain) {
   59     SOCKET s;
   60     char strbuf[ISC_STRERRORSIZE];
   61     int errval;
   62 
   63     s = socket(domain, SOCK_STREAM, IPPROTO_TCP);
   64     if (s == INVALID_SOCKET) {
   65         errval = WSAGetLastError();
   66         switch (errval) {
   67         case WSAEAFNOSUPPORT:
   68         case WSAEPROTONOSUPPORT:
   69         case WSAEINVAL:
   70             return (ISC_R_NOTFOUND);
   71         default:
   72             isc__strerror(errval, strbuf, sizeof(strbuf));
   73             UNEXPECTED_ERROR(__FILE__, __LINE__,
   74                      "socket() %s: %s",
   75                      isc_msgcat_get(isc_msgcat,
   76                             ISC_MSGSET_GENERAL,
   77                             ISC_MSG_FAILED,
   78                             "failed"),
   79                      strbuf);
   80             return (ISC_R_UNEXPECTED);
   81         }
   82     }
   83 
   84     closesocket(s);
   85 
   86     return (ISC_R_SUCCESS);
   87 }
   88 
   89 static void
   90 initialize_action(void) {
   91     InitSockets();
   92     ipv4_result = try_proto(PF_INET);
   93 #ifdef ISC_PLATFORM_HAVEIPV6
   94 #ifdef WANT_IPV6
   95 #ifdef ISC_PLATFORM_HAVEIN6PKTINFO
   96     ipv6_result = try_proto(PF_INET6);
   97 #endif
   98 #endif
   99 #endif
  100 }
  101 
  102 static void
  103 initialize(void) {
  104     RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
  105 }
  106 
  107 isc_result_t
  108 isc_net_probeipv4(void) {
  109     initialize();
  110     return (ipv4_result);
  111 }
  112 
  113 isc_result_t
  114 isc_net_probeipv6(void) {
  115     initialize();
  116     return (ipv6_result);
  117 }
  118 
  119 isc_result_t
  120 isc_net_probeunix(void) {
  121     return (ISC_R_NOTFOUND);
  122 }
  123 
  124 #ifdef ISC_PLATFORM_HAVEIPV6
  125 #ifdef WANT_IPV6
  126 static void
  127 try_ipv6only(void) {
  128 #ifdef IPV6_V6ONLY
  129     SOCKET s;
  130     int on;
  131     char strbuf[ISC_STRERRORSIZE];
  132 #endif
  133     isc_result_t result;
  134 
  135     result = isc_net_probeipv6();
  136     if (result != ISC_R_SUCCESS) {
  137         ipv6only_result = result;
  138         return;
  139     }
  140 
  141 #ifndef IPV6_V6ONLY
  142     ipv6only_result = ISC_R_NOTFOUND;
  143     return;
  144 #else
  145     /* check for TCP sockets */
  146     s = socket(PF_INET6, SOCK_STREAM, 0);
  147     if (s == INVALID_SOCKET) {
  148         isc__strerror(errno, strbuf, sizeof(strbuf));
  149         UNEXPECTED_ERROR(__FILE__, __LINE__,
  150                  "socket() %s: %s",
  151                  isc_msgcat_get(isc_msgcat,
  152                         ISC_MSGSET_GENERAL,
  153                         ISC_MSG_FAILED,
  154                         "failed"),
  155                  strbuf);
  156         ipv6only_result = ISC_R_UNEXPECTED;
  157         return;
  158     }
  159 
  160     on = 1;
  161     if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on,
  162                sizeof(on)) < 0) {
  163         ipv6only_result = ISC_R_NOTFOUND;
  164         goto close;
  165     }
  166 
  167     closesocket(s);
  168 
  169     /* check for UDP sockets */
  170     s = socket(PF_INET6, SOCK_DGRAM, 0);
  171     if (s == INVALID_SOCKET) {
  172         isc__strerror(errno, strbuf, sizeof(strbuf));
  173         UNEXPECTED_ERROR(__FILE__, __LINE__,
  174                  "socket() %s: %s",
  175                  isc_msgcat_get(isc_msgcat,
  176                         ISC_MSGSET_GENERAL,
  177                         ISC_MSG_FAILED,
  178                         "failed"),
  179                  strbuf);
  180         ipv6only_result = ISC_R_UNEXPECTED;
  181         return;
  182     }
  183 
  184     on = 1;
  185     if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on,
  186                sizeof(on)) < 0) {
  187         ipv6only_result = ISC_R_NOTFOUND;
  188         goto close;
  189     }
  190 
  191     ipv6only_result = ISC_R_SUCCESS;
  192 
  193 close:
  194     closesocket(s);
  195     return;
  196 #endif /* IPV6_V6ONLY */
  197 }
  198 
  199 static void
  200 initialize_ipv6only(void) {
  201     RUNTIME_CHECK(isc_once_do(&once_ipv6only,
  202                   try_ipv6only) == ISC_R_SUCCESS);
  203 }
  204 
  205 #ifdef __notyet__
  206 /*
  207  * XXXMPA requires win32/socket.c to be updated to support
  208  * WSASendMsg and WSARecvMsg which are themselves Winsock
  209  * and compiler version dependent.
  210  */
  211 static void
  212 try_ipv6pktinfo(void) {
  213     SOCKET s;
  214     int on;
  215     char strbuf[ISC_STRERRORSIZE];
  216     isc_result_t result;
  217     int optname;
  218 
  219     result = isc_net_probeipv6();
  220     if (result != ISC_R_SUCCESS) {
  221         ipv6pktinfo_result = result;
  222         return;
  223     }
  224 
  225     /* we only use this for UDP sockets */
  226     s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
  227     if (s == INVALID_SOCKET) {
  228         isc__strerror(errno, strbuf, sizeof(strbuf));
  229         UNEXPECTED_ERROR(__FILE__, __LINE__,
  230                  "socket() %s: %s",
  231                  isc_msgcat_get(isc_msgcat,
  232                         ISC_MSGSET_GENERAL,
  233                         ISC_MSG_FAILED,
  234                         "failed"),
  235                  strbuf);
  236         ipv6pktinfo_result = ISC_R_UNEXPECTED;
  237         return;
  238     }
  239 
  240 #ifdef IPV6_RECVPKTINFO
  241     optname = IPV6_RECVPKTINFO;
  242 #else
  243     optname = IPV6_PKTINFO;
  244 #endif
  245     on = 1;
  246     if (setsockopt(s, IPPROTO_IPV6, optname, (const char *) &on,
  247                sizeof(on)) < 0) {
  248         ipv6pktinfo_result = ISC_R_NOTFOUND;
  249         goto close;
  250     }
  251 
  252     ipv6pktinfo_result = ISC_R_SUCCESS;
  253 
  254 close:
  255     closesocket(s);
  256     return;
  257 }
  258 
  259 static void
  260 initialize_ipv6pktinfo(void) {
  261     RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
  262                   try_ipv6pktinfo) == ISC_R_SUCCESS);
  263 }
  264 #endif /* __notyet__ */
  265 #endif /* WANT_IPV6 */
  266 #endif /* ISC_PLATFORM_HAVEIPV6 */
  267 
  268 isc_result_t
  269 isc_net_probe_ipv6only(void) {
  270 #ifdef ISC_PLATFORM_HAVEIPV6
  271 #ifdef WANT_IPV6
  272     initialize_ipv6only();
  273 #else
  274     ipv6only_result = ISC_R_NOTFOUND;
  275 #endif
  276 #endif
  277     return (ipv6only_result);
  278 }
  279 
  280 isc_result_t
  281 isc_net_probe_ipv6pktinfo(void) {
  282 #ifdef __notyet__
  283 #ifdef ISC_PLATFORM_HAVEIPV6
  284 #ifdef WANT_IPV6
  285     initialize_ipv6pktinfo();
  286 #else
  287     ipv6pktinfo_result = ISC_R_NOTFOUND;
  288 #endif
  289 #endif
  290 #endif /* __notyet__ */
  291     return (ipv6pktinfo_result);
  292 }
  293 
  294 isc_result_t
  295 isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) {
  296     int result = ISC_R_FAILURE;
  297 
  298     REQUIRE(low != NULL && high != NULL);
  299 
  300     UNUSED(af);
  301 
  302     if (result != ISC_R_SUCCESS) {
  303         *low = ISC_NET_PORTRANGELOW;
  304         *high = ISC_NET_PORTRANGEHIGH;
  305     }
  306 
  307     return (ISC_R_SUCCESS); /* we currently never fail in this function */
  308 }
  309 
  310 void
  311 isc_net_disableipv4(void) {
  312     initialize();
  313     if (ipv4_result == ISC_R_SUCCESS)
  314         ipv4_result = ISC_R_DISABLED;
  315 }
  316 
  317 void
  318 isc_net_disableipv6(void) {
  319     initialize();
  320     if (ipv6_result == ISC_R_SUCCESS)
  321         ipv6_result = ISC_R_DISABLED;
  322 }
  323 
  324 void
  325 isc_net_enableipv4(void) {
  326     initialize();
  327     if (ipv4_result == ISC_R_DISABLED)
  328         ipv4_result = ISC_R_SUCCESS;
  329 }
  330 
  331 void
  332 isc_net_enableipv6(void) {
  333     initialize();
  334     if (ipv6_result == ISC_R_DISABLED)
  335         ipv6_result = ISC_R_SUCCESS;
  336 }
  337 
  338 unsigned int
  339 isc_net_probedscp(void) {
  340     return (0);
  341 }