Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/io/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Quelle  prmapopt.c   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/*
 * This file defines _PR_MapOptionName().  The purpose of putting
 * _PR_MapOptionName() in a separate file is to work around a Winsock
 * header file problem on Windows NT.
 *
 * On Windows NT, if we define _WIN32_WINNT to be 0x0400 (in order
 * to use Service Pack 3 extensions), windows.h includes winsock2.h
 * (instead of winsock.h), which doesn't define many socket options
 * defined in winsock.h.
 *
 * We need the socket options defined in winsock.h.  So this file
 * includes winsock.h, with _WIN32_WINNT undefined.
 */


#if defined(WINNT) || defined(__MINGW32__)
#  include <winsock.h>
#endif

/* MinGW doesn't define these in its winsock.h. */
#ifdef __MINGW32__
#  ifndef IP_TTL
#    define IP_TTL 7
#  endif
#  ifndef IP_TOS
#    define IP_TOS 8
#  endif
#endif

#include "primpl.h"

#if defined(LINUX) || defined(ANDROID)
#  include <netinet/in.h>
#endif

#ifdef DARWIN
#  include <netinet/in.h>
#  include <netinet/ip.h>
#endif

#ifdef HAVE_NETINET_TCP_H
#  include <netinet/tcp.h> /* TCP_NODELAY, TCP_MAXSEG */
#endif

#ifndef _PR_PTHREADS

PRStatus PR_CALLBACK _PR_SocketGetSocketOption(PRFileDesc* fd,
                                               PRSocketOptionData* data) {
  PRStatus rv;
  PRInt32 length;
  PRInt32 level, name;

  /*
   * PR_SockOpt_Nonblocking is a special case that does not
   * translate to a getsockopt() call
   */

  if (PR_SockOpt_Nonblocking == data->option) {
    data->value.non_blocking = fd->secret->nonblocking;
    return PR_SUCCESS;
  }

  rv = _PR_MapOptionName(data->option, &level, &name);
  if (PR_SUCCESS == rv) {
    switch (data->option) {
      case PR_SockOpt_Linger: {
        struct linger linger;
        length = sizeof(linger);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&linger, &length);
        if (PR_SUCCESS == rv) {
          PR_ASSERT(sizeof(linger) == length);
          data->value.linger.polarity = (linger.l_onoff) ? PR_TRUE : PR_FALSE;
          data->value.linger.linger = PR_SecondsToInterval(linger.l_linger);
        }
        break;
      }
      case PR_SockOpt_Reuseaddr:
      case PR_SockOpt_Keepalive:
      case PR_SockOpt_NoDelay:
      case PR_SockOpt_Broadcast:
      case PR_SockOpt_Reuseport: {
#  ifdef WIN32 /* Winsock */
        BOOL value;
#  else
        PRIntn value;
#  endif
        length = sizeof(value);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&value, &length);
        if (PR_SUCCESS == rv) {
          data->value.reuse_addr = (0 == value) ? PR_FALSE : PR_TRUE;
        }
        break;
      }
      case PR_SockOpt_McastLoopback: {
#  ifdef WIN32 /* Winsock */
        BOOL bool;
#  else
        PRUint8 bool;
#  endif
        length = sizeof(bool);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&bool, &length);
        if (PR_SUCCESS == rv) {
          data->value.mcast_loopback = (0 == bool) ? PR_FALSE : PR_TRUE;
        }
        break;
      }
      case PR_SockOpt_RecvBufferSize:
      case PR_SockOpt_SendBufferSize:
      case PR_SockOpt_MaxSegment: {
        PRIntn value;
        length = sizeof(value);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&value, &length);
        if (PR_SUCCESS == rv) {
          data->value.recv_buffer_size = value;
        }
        break;
      }
      case PR_SockOpt_IpTimeToLive:
      case PR_SockOpt_IpTypeOfService: {
        /* These options should really be an int (or PRIntn). */
        length = sizeof(PRUintn);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&data->value.ip_ttl,
                               &length);
        break;
      }
      case PR_SockOpt_McastTimeToLive: {
#  ifdef WIN32 /* Winsock */
        int ttl;
#  else
        PRUint8 ttl;
#  endif
        length = sizeof(ttl);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&ttl, &length);
        if (PR_SUCCESS == rv) {
          data->value.mcast_ttl = ttl;
        }
        break;
      }
#  ifdef IP_ADD_MEMBERSHIP
      case PR_SockOpt_AddMember:
      case PR_SockOpt_DropMember: {
        struct ip_mreq mreq;
        length = sizeof(mreq);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&mreq, &length);
        if (PR_SUCCESS == rv) {
          data->value.add_member.mcaddr.inet.ip = mreq.imr_multiaddr.s_addr;
          data->value.add_member.ifaddr.inet.ip = mreq.imr_interface.s_addr;
        }
        break;
      }
#  endif /* IP_ADD_MEMBERSHIP */
      case PR_SockOpt_McastInterface: {
        /* This option is a struct in_addr. */
        length = sizeof(data->value.mcast_if.inet.ip);
        rv = _PR_MD_GETSOCKOPT(fd, level, name,
                               (char*)&data->value.mcast_if.inet.ip, &length);
        break;
      }
      case PR_SockOpt_DontFrag: {
#  if !defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && \
      !defined(ANDROID)
        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
        rv = PR_FAILURE;
#  else
#    ifdef WIN32 /* Winsock */
        DWORD value;
#    else
        PRIntn value;
#    endif
        length = sizeof(value);
        rv = _PR_MD_GETSOCKOPT(fd, level, name, (char*)&value, &length);
#    if defined(WIN32) || defined(DARWIN)
        data->value.dont_fragment = value;
#    else
        data->value.dont_fragment = (value == IP_PMTUDISC_DO) ? 1 : 0;
#    endif
#  endif /* !(!defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && \
            !defined(ANDROID)) */

        break;
      }
      default:
        PR_NOT_REACHED("Unknown socket option");
        break;
    }
  }
  return rv;
/* _PR_SocketGetSocketOption */

PRStatus PR_CALLBACK _PR_SocketSetSocketOption(PRFileDesc* fd,
                                               const PRSocketOptionData* data) {
  PRStatus rv;
  PRInt32 level, name;

  /*
   * PR_SockOpt_Nonblocking is a special case that does not
   * translate to a setsockopt call.
   */

  if (PR_SockOpt_Nonblocking == data->option) {
#  ifdef WINNT
    PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE) ||
              (fd->secret->nonblocking == data->value.non_blocking));
    if (fd->secret->md.io_model_committed &&
        (fd->secret->nonblocking != data->value.non_blocking)) {
      /*
       * On NT, once we have associated a socket with the io
       * completion port, we can't disassociate it.  So we
       * can't change the nonblocking option of the socket
       * afterwards.
       */

      PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
      return PR_FAILURE;
    }
#  endif
    fd->secret->nonblocking = data->value.non_blocking;
    return PR_SUCCESS;
  }

  rv = _PR_MapOptionName(data->option, &level, &name);
  if (PR_SUCCESS == rv) {
    switch (data->option) {
      case PR_SockOpt_Linger: {
        struct linger linger;
        linger.l_onoff = data->value.linger.polarity;
        linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&linger, sizeof(linger));
        break;
      }
      case PR_SockOpt_Reuseaddr:
      case PR_SockOpt_Keepalive:
      case PR_SockOpt_NoDelay:
      case PR_SockOpt_Broadcast:
      case PR_SockOpt_Reuseport: {
#  ifdef WIN32 /* Winsock */
        BOOL value;
#  else
        PRIntn value;
#  endif
        value = (data->value.reuse_addr) ? 1 : 0;
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&value, sizeof(value));
        break;
      }
      case PR_SockOpt_McastLoopback: {
#  ifdef WIN32 /* Winsock */
        BOOL bool;
#  else
        PRUint8 bool;
#  endif
        bool = data->value.mcast_loopback ? 1 : 0;
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&boolsizeof(bool));
        break;
      }
      case PR_SockOpt_RecvBufferSize:
      case PR_SockOpt_SendBufferSize:
      case PR_SockOpt_MaxSegment: {
        PRIntn value = data->value.recv_buffer_size;
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&value, sizeof(value));
        break;
      }
      case PR_SockOpt_IpTimeToLive:
      case PR_SockOpt_IpTypeOfService: {
        /* These options should really be an int (or PRIntn). */
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&data->value.ip_ttl,
                               sizeof(PRUintn));
        break;
      }
      case PR_SockOpt_McastTimeToLive: {
#  ifdef WIN32 /* Winsock */
        int ttl;
#  else
        PRUint8 ttl;
#  endif
        ttl = data->value.mcast_ttl;
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&ttl, sizeof(ttl));
        break;
      }
#  ifdef IP_ADD_MEMBERSHIP
      case PR_SockOpt_AddMember:
      case PR_SockOpt_DropMember: {
        struct ip_mreq mreq;
        mreq.imr_multiaddr.s_addr = data->value.add_member.mcaddr.inet.ip;
        mreq.imr_interface.s_addr = data->value.add_member.ifaddr.inet.ip;
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&mreq, sizeof(mreq));
        break;
      }
#  endif /* IP_ADD_MEMBERSHIP */
      case PR_SockOpt_McastInterface: {
        /* This option is a struct in_addr. */
        rv = _PR_MD_SETSOCKOPT(fd, level, name,
                               (char*)&data->value.mcast_if.inet.ip,
                               sizeof(data->value.mcast_if.inet.ip));
        break;
      }
      case PR_SockOpt_DontFrag: {
#  if !defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && \
      !defined(ANDROID)
        PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
        rv = PR_FAILURE;
#  else
#    if defined(WIN32) /* Winsock */
        DWORD value;
        value = (data->value.dont_fragment) ? 1 : 0;
#    elif defined(LINUX) || defined(ANDROID)
        PRIntn value;
        value = (data->value.dont_fragment) ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
#    elif defined(DARWIN)
        PRIntn value;
        value = data->value.dont_fragment;
#    endif
        rv = _PR_MD_SETSOCKOPT(fd, level, name, (char*)&value, sizeof(value));
#  endif /* !(!defined(WIN32) && !defined(DARWIN) && !defined(LINUX) && \
            !defined(ANDROID)) */

        break;
      }
      default:
        PR_NOT_REACHED("Unknown socket option");
        break;
    }
  }
  return rv;
/* _PR_SocketSetSocketOption */

#endif /* ! _PR_PTHREADS */

/*
 *********************************************************************
 *********************************************************************
 **
 ** Make sure that the following is at the end of this file,
 ** because we will be playing with macro redefines.
 **
 *********************************************************************
 *********************************************************************
 */


/*
 * Not every platform has all the socket options we want to
 * support.  Some older operating systems such as SunOS 4.1.3
 * don't have the IP multicast socket options.  Win32 doesn't
 * have TCP_MAXSEG.
 *
 * To deal with this problem, we define the missing socket
 * options as _PR_NO_SUCH_SOCKOPT.  _PR_MapOptionName() fails with
 * PR_OPERATION_NOT_SUPPORTED_ERROR if a socket option not
 * available on the platform is requested.
 */


/*
 * Sanity check.  SO_LINGER and TCP_NODELAY should be available
 * on all platforms.  Just to make sure we have included the
 * appropriate header files.  Then any undefined socket options
 * are really missing.
 */


#if !defined(SO_LINGER)
#  error "SO_LINGER is not defined"
#endif

#if !defined(TCP_NODELAY)
#  error "TCP_NODELAY is not defined"
#endif

/*
 * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
 * a valid socket option.
 */

#define _PR_NO_SUCH_SOCKOPT -1

#ifndef SO_KEEPALIVE
#  define SO_KEEPALIVE _PR_NO_SUCH_SOCKOPT
#endif

#ifndef SO_SNDBUF
#  define SO_SNDBUF _PR_NO_SUCH_SOCKOPT
#endif

#ifndef SO_RCVBUF
#  define SO_RCVBUF _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_MULTICAST_IF /* set/get IP multicast interface   */
#  define IP_MULTICAST_IF _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_MULTICAST_TTL /* set/get IP multicast timetolive  */
#  define IP_MULTICAST_TTL _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_MULTICAST_LOOP /* set/get IP multicast loopback    */
#  define IP_MULTICAST_LOOP _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_ADD_MEMBERSHIP /* add  an IP group membership      */
#  define IP_ADD_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_DROP_MEMBERSHIP /* drop an IP group membership      */
#  define IP_DROP_MEMBERSHIP _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_TTL /* set/get IP Time To Live          */
#  define IP_TTL _PR_NO_SUCH_SOCKOPT
#endif

#ifndef IP_TOS /* set/get IP Type Of Service       */
#  define IP_TOS _PR_NO_SUCH_SOCKOPT
#endif

/* set/get IP do not fragment */
#if defined(WIN32)
#  ifndef IP_DONTFRAGMENT
#    define IP_DONTFRAGMENT _PR_NO_SUCH_SOCKOPT
#  endif

#elif defined(LINUX) || defined(ANDROID)
#  ifndef IP_MTU_DISCOVER
#    define IP_MTU_DISCOVER _PR_NO_SUCH_SOCKOPT
#  endif

#elif defined(DARWIN)
#  ifndef IP_DONTFRAG
#    define IP_DONTFRAG _PR_NO_SUCH_SOCKOPT
#  endif
#endif

#ifndef TCP_NODELAY /* don't delay to coalesce data     */
#  define TCP_NODELAY _PR_NO_SUCH_SOCKOPT
#endif

#ifndef TCP_MAXSEG /* maxumum segment size for tcp     */
#  define TCP_MAXSEG _PR_NO_SUCH_SOCKOPT
#endif

#ifndef SO_BROADCAST /* enable broadcast on UDP sockets  */
#  define SO_BROADCAST _PR_NO_SUCH_SOCKOPT
#endif

#ifndef SO_REUSEPORT /* allow local address & port reuse */
#  define SO_REUSEPORT _PR_NO_SUCH_SOCKOPT
#endif

PRStatus _PR_MapOptionName(PRSockOption optname, PRInt32* level,
                           PRInt32* name) {
  static PRInt32 socketOptions[PR_SockOpt_Last] = {
      0,
      SO_LINGER,
      SO_REUSEADDR,
      SO_KEEPALIVE,
      SO_RCVBUF,
      SO_SNDBUF,
      IP_TTL,
      IP_TOS,
      IP_ADD_MEMBERSHIP,
      IP_DROP_MEMBERSHIP,
      IP_MULTICAST_IF,
      IP_MULTICAST_TTL,
      IP_MULTICAST_LOOP,
      TCP_NODELAY,
      TCP_MAXSEG,
      SO_BROADCAST,
      SO_REUSEPORT,
#if defined(WIN32)
      IP_DONTFRAGMENT,
#elif defined(LINUX) || defined(ANDROID)
      IP_MTU_DISCOVER,
#elif defined(DARWIN)
      IP_DONTFRAG,
#else
      _PR_NO_SUCH_SOCKOPT,
#endif
  };
  static PRInt32 socketLevels[PR_SockOpt_Last] = {
      0,          SOL_SOCKET,  SOL_SOCKET,  SOL_SOCKET, SOL_SOCKET, SOL_SOCKET,
      IPPROTO_IP, IPPROTO_IP,  IPPROTO_IP,  IPPROTO_IP, IPPROTO_IP, IPPROTO_IP,
      IPPROTO_IP, IPPROTO_TCP, IPPROTO_TCP, SOL_SOCKET, SOL_SOCKET, IPPROTO_IP};

  if ((optname < PR_SockOpt_Linger) || (optname >= PR_SockOpt_Last)) {
    PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
    return PR_FAILURE;
  }

  if (socketOptions[optname] == _PR_NO_SUCH_SOCKOPT) {
    PR_SetError(PR_OPERATION_NOT_SUPPORTED_ERROR, 0);
    return PR_FAILURE;
  }
  *name = socketOptions[optname];
  *level = socketLevels[optname];
  return PR_SUCCESS;
/* _PR_MapOptionName */

Messung V0.5
C=92 H=100 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.