⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.cxx

📁 开源代码的pwlib的1.10.0版本,使用openh323的1.18.0版本毕备
💻 CXX
📖 第 1 页 / 共 4 页
字号:
/*
 * socket.cxx
 *
 * Berkley sockets classes implementation
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: socket.cxx,v $
 * Revision 1.115.2.2  2006/02/22 00:04:39  csoutheren
 * Backport interface table fix from HEAD
 *
 * Revision 1.115.2.1  2006/02/18 16:01:19  dsandras
 * Backport from HEAD.
 *
 * Revision 1.117  2006/02/21 13:57:31  csoutheren
 * Second attempt at fixing problem with interfaces having multiple addresses
 *
 * Revision 1.116  2006/02/18 15:57:45  dsandras
 * Applied patch from Richard van der Hoff and Stephane Epardaud <stef lunatech
 * com> to fix infinite loop with IPv6 interfaces. Thanks!
 *
 * Revision 1.115  2005/11/30 12:47:42  csoutheren
 * Removed tabs, reformatted some code, and changed tags for Doxygen
 *
 * Revision 1.114  2005/11/23 11:47:03  shorne
 * Changed EnableQoS to EnableGQoS
 *
 * Revision 1.113  2005/07/15 12:45:13  rogerhardiman
 * Fix bug 1237508 (M Zygmuntowicz). Make IPV6 code use #if instead of #ifdef.
 *
 * Revision 1.112  2005/07/13 11:48:55  csoutheren
 * Backported QOS changes from isvo branch
 *
 * Revision 1.111  2005/02/07 12:12:31  csoutheren
 * Expanded interface list routines to include IPV6 addresses
 * Added IPV6 to GetLocalAddress
 *
 * Revision 1.110  2004/08/24 07:08:11  csoutheren
 * Added use of recvmsg to determine which interface UDP packets arrive on
 *
 * Revision 1.109  2004/07/11 07:56:36  csoutheren
 * Applied jumbo VxWorks patch, thanks to Eize Slange
 *
 * Revision 1.108  2004/07/08 00:57:29  csoutheren
 * Added check for EINTR on connect
 * Thanks to Alex Vishnev
 *
 * Revision 1.107  2004/07/03 23:50:42  csoutheren
 * Removed warnings under Solaris
 *
 * Revision 1.106  2004/05/06 11:28:30  rjongbloed
 * Changed P_fd_set to use malloc/free isntead of new/delete due to pedantry about [].
 *
 * Revision 1.105  2004/05/05 06:52:37  ykiryanov
 * Made BeOS changes
 *
 * Revision 1.104  2004/04/27 04:37:51  rjongbloed
 * Fixed ability to break of a PSocket::Select call under linux when a socket
 *   is closed by another thread.
 *
 * Revision 1.103  2004/04/24 06:28:12  rjongbloed
 * Fixed GCC 3.4.0 warnings about PAssertNULL and improved recoverability on
 *   NULL pointer usage in various bits of code.
 *
 * Revision 1.102  2004/04/18 07:46:32  rjongbloed
 * Fixed other unix builds after Yuri's BeOS changes.
 *
 * Revision 1.101  2004/04/18 00:21:35  ykiryanov
 * Cleaned up BeOS related code. Less ifdefs, more functionality
 *
 * Revision 1.100  2003/10/27 04:06:14  csoutheren
 * Added code to allow compilation of new QoS code on Unix
 *
 * Revision 1.99  2003/01/24 10:21:06  robertj
 * Fixed issues in RTEMS support, thanks Vladimir Nesic
 *
 * Revision 1.98  2002/11/22 10:14:07  robertj
 * QNX port, thanks Xiaodan Tang
 *
 * Revision 1.97  2002/11/02 00:32:21  robertj
 * Further fixes to VxWorks (Tornado) port, thanks Andreas Sikkema.
 *
 * Revision 1.96  2002/10/22 10:25:07  rogerh
 * Fix process_rtentry() following Thomas's patch.
 *
 * Revision 1.95  2002/10/22 07:42:52  robertj
 * Added extra debugging for file handle and thread leak detection.
 *
 * Revision 1.94  2002/10/22 06:53:38  craigs
 * Fixed signed/unsigned problem in GetRoutTable thanks to Thomas Jalsovsky
 *
 * Revision 1.93  2002/10/19 06:12:20  robertj
 * Moved P_fd_set::Zero() from platform independent to platform dependent
 *   code as Win32 implementation is completely different from Unix.
 *
 * Revision 1.92  2002/10/17 13:44:27  robertj
 * Port to RTEMS, thanks Vladimir Nesic.
 *
 * Revision 1.91  2002/10/17 12:57:24  robertj
 * Added ability to increase maximum file handles on a process.
 *
 * Revision 1.90  2002/10/10 04:43:44  robertj
 * VxWorks port, thanks Martijn Roest
 *
 * Revision 1.89  2002/10/08 14:31:43  robertj
 * Changed for IPv6 support, thanks S閎astien Josset.
 *
 * Revision 1.88  2002/06/05 12:29:16  craigs
 * Changes for gcc 3.1
 *
 * Revision 1.87  2002/04/18 06:16:06  robertj
 * Fixed Net BSD problem with RTF_CLONED flag, thanks Motoyuki OHMORI
 * Fixed operator precedence problem with bit mask tests in RTF_CLONE code.
 *
 * Revision 1.86  2002/04/12 07:57:41  robertj
 * Fixed bug introduced into Accept() by previous change.
 *
 * Revision 1.85  2002/04/12 01:42:41  robertj
 * Changed return value on os_connect() and os_accept() to make sure
 *   get the correct error codes propagated up under unix.
 *
 * Revision 1.84  2002/02/13 02:19:47  robertj
 * Fixed mistake in previous patch, is if not ifdef!
 *
 * Revision 1.83  2002/02/13 00:50:32  robertj
 * Fixed use of symbol in older versionsof Solaris, thanks Markus Storm
 *
 * Revision 1.82  2002/01/31 22:52:18  robertj
 * Added fix for buffer too small in Solaris GetRouteTable(), thanks Markus Storm.
 *
 * Revision 1.81  2001/12/17 23:33:50  robertj
 * Solaris 8 porting changes, thanks James Dugal
 *
 * Revision 1.80  2001/12/10 07:07:27  rogerh
 * Take out some #includes which were already in pachdep.h. Fixes openBSD 2.9
 *
 * Revision 1.79  2001/11/22 12:29:57  rogerh
 * Take out the cloned flag on OpenBSD so it compiles
 *
 * Revision 1.78  2001/11/14 10:37:32  rogerh
 * Define _SIZEOF_ADDR_IFREQ as OpenBSD does not have it
 *
 * Revision 1.77  2001/10/28 23:00:10  robertj
 * Fixed Solaris and IRIX compatibility issue, thanks Andre Schulze
 *
 * Revision 1.76  2001/10/11 02:20:54  robertj
 * Added IRIX support (no audio/video), thanks Andre Schulze.
 *
 * Revision 1.75  2001/10/03 19:31:56  rogerh
 * Add MAC OS X support to GetInterfaceTable
 *
 * Revision 1.74  2001/10/03 10:18:15  rogerh
 * Make Mac OS X (Darwin) use the new GetRouteTable() function.
 *
 * Revision 1.73  2001/09/24 15:37:35  rogerh
 * Add GetRouteTable() for BSD Unix. Based on FreeBSD's own networking code,
 * and from an implementation by Martin Nilsson <martin@gneto.com>
 *
 * Revision 1.72  2001/09/19 00:41:20  robertj
 * Fixed GetInterfaceTable so does not add duplicate interfaces into list.
 * Changed the loop condition to allow for BSD variable length records.
 *
 * Revision 1.71  2001/09/18 05:56:03  robertj
 * Fixed numerous problems with thread suspend/resume and signals handling.
 *
 * Revision 1.70  2001/09/10 03:03:36  robertj
 * Major change to fix problem with error codes being corrupted in a
 *   PChannel when have simultaneous reads and writes in threads.
 *
 * Revision 1.69  2001/08/16 11:58:22  rogerh
 * Add more Mac OS X changes from John Woods <jfw@jfwhome.funhouse.com>
 *
 * Revision 1.68  2001/08/12 07:12:40  rogerh
 * More Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
 *
 * Revision 1.67  2001/08/12 06:34:33  rogerh
 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
 *
 * Revision 1.66  2001/08/07 02:27:22  robertj
 * Fixed some incorrect error values returned in Read() and Write() functions.
 *
 * Revision 1.65  2001/07/03 04:41:25  yurik
 * Corrections to Jac's submission from 6/28
 *
 * Revision 1.64  2001/06/30 06:59:07  yurik
 * Jac Goudsmit from Be submit these changes 6/28. Implemented by Yuri Kiryanov
 *
 * Revision 1.63  2001/06/19 12:09:13  rogerh
 * Mac OS X change
 *
 * Revision 1.62  2001/04/16 22:46:22  craigs
 * Fixed problem with os_connect not correctly reporting errors
 *
 * Revision 1.61  2001/03/26 03:31:53  robertj
 * Fixed Solaris compile error.
 *
 * Revision 1.60  2001/03/20 06:44:25  robertj
 * Lots of changes to fix the problems with terminating threads that are I/O
 *   blocked, especially when doing orderly shutdown of service via SIGTERM.
 *
 * Revision 1.59  2001/03/07 23:37:59  robertj
 * Fixed slow down in UDP packet send, thanks Dmitriy Reka
 *
 * Revision 1.58  2001/03/07 06:56:36  yurik
 * Made adjustment for BONE platforms as requested by Jac Goudsmit
 *
 * Revision 1.57  2001/03/06 00:16:59  robertj
 * Fixed BSD compatibility problem.
 *
 * Revision 1.56  2001/03/05 04:28:56  robertj
 * Added net mask to interface info returned by GetInterfaceTable()
 *
 * Revision 1.55  2001/02/02 23:31:30  robertj
 * Fixed enumeration of interfaces, thanks Bertrand Croq.
 *
 * Revision 1.54  2001/01/17 03:48:25  rogerh
 * Fix GetInterfaceTable so it actually works through all interfaces rather
 * than falling over after the first entry.
 *
 * Revision 1.53  2001/01/16 12:56:01  rogerh
 * On BeOS sa_data is 'unsigned char *'. Linux and BSD defines sa_data as 'char *'
 * Add typecast, submitted by Jac Goudsmit <jac_goudsmit@yahoo.com>
 *
 * Revision 1.52  2000/06/21 01:01:22  robertj
 * AIX port, thanks Wolfgang Platzer (wolfgang.platzer@infonova.at).
 *
 * Revision 1.51  2000/04/19 00:13:53  robertj
 * BeOS port changes.
 *
 * Revision 1.50  2000/04/07 05:43:48  rogerh
 * Fix a compilation error in a non-pthreaded function. Found by Kevin Packard
 *
 * Revision 1.49  2000/03/17 03:45:40  craigs
 * Fixed problem with connect call hanging
 *
 * Revision 1.48  2000/02/17 23:47:40  robertj
 * Fixed error in check for SIOCGHWADDR define, thanks Markus Storm.
 *
 * Revision 1.47  2000/01/20 08:20:57  robertj
 * FreeBSD v3 compatibility changes, thanks Roger Hardiman & Motonori Shindo
 *
 * Revision 1.46  1999/11/18 13:45:21  craigs
 * Removed obsolete declaration of iostream semaphore
 *
 * Revision 1.45  1999/10/30 13:43:01  craigs
 * Added correct method of aborting socket operations asynchronously
 *
 * Revision 1.44  1999/09/27 01:04:42  robertj
 * BeOS support changes.
 *
 * Revision 1.43  1999/09/12 07:06:23  craigs
 * Added support for getting Solaris interface info
 *
 * Revision 1.42  1999/09/10 02:31:19  craigs
 * Added interface table routines
 *
 * Revision 1.41  1999/09/03 02:26:25  robertj
 * Changes to aid in breaking I/O locks on thread termination. Still needs more work esp in BSD!
 *
 * Revision 1.40  1999/05/01 03:52:20  robertj
 * Fixed various egcs warnings.
 *
 * Revision 1.39  1999/03/02 05:41:59  robertj
 * More BeOS changes
 *
 * Revision 1.38  1999/02/26 04:10:39  robertj
 * More BeOS port changes
 *
 * Revision 1.37  1999/02/22 13:26:54  robertj
 * BeOS port changes.
 *
 * Revision 1.36  1998/11/30 21:51:58  robertj
 * New directory structure.
 *
 * Revision 1.35  1998/11/24 09:39:22  robertj
 * FreeBSD port.
 *
 * Revision 1.34  1998/11/22 08:11:37  craigs
 * *** empty log message ***
 *
 * Revision 1.33  1998/11/14 10:37:38  robertj
 * Changed semantics of os_sendto to return TRUE if ANY bytes are sent.
 *
 * Revision 1.32  1998/10/16 01:16:55  craigs
 * Added Yield to help with cooperative multithreading.
 *
 * Revision 1.31  1998/10/11 02:23:16  craigs
 * Fixed problem with socket writes not correctly detecting EOF
 *
 * Revision 1.30  1998/09/24 08:21:11  robertj
 * Fixed warning on GNU 6 library.
 *
 * Revision 1.29  1998/09/24 07:55:51  robertj
 * Fixed warning on solaris build.
 *
 * Revision 1.28  1998/09/24 04:13:49  robertj
 * Added open software license.
 *
 * Revision 1.27  1998/09/18 05:46:00  robertj
 * Fixed incorrectly returning success on a connect() error other than a timeout.
 *
 * Revision 1.26  1998/09/08 11:31:51  robertj
 * Fixed ippp bug on very full packets.
 *
 * Revision 1.25  1998/09/08 09:54:31  robertj
 * Fixed ppp and ippp compatibility.
 *
 * Revision 1.24  1998/09/08 05:15:14  robertj
 * Fixed problem in Windows requiring snmpapi.dll for PEthSocket class.
 *
 * Revision 1.23  1998/08/27 01:13:20  robertj
 * Changes to resolve signedness in GNU C library v6
 * Remove Linux EthSocket stuff from Sun build, still needs implementing.
 *
 * Revision 1.22  1998/08/21 05:30:59  robertj
 * Ethernet socket implementation.
 *
 */

#pragma implementation "sockets.h"
#pragma implementation "socket.h"
#pragma implementation "ipsock.h"
#pragma implementation "udpsock.h"
#pragma implementation "tcpsock.h"
#pragma implementation "ipdsock.h"
#pragma implementation "ethsock.h"
#pragma implementation "qos.h"


#include <ptlib.h>
#include <ptlib/sockets.h>


#if defined(SIOCGENADDR)
#define SIO_Get_MAC_Address SIOCGENADDR
#define  ifr_macaddr         ifr_ifru.ifru_enaddr
#elif defined(SIOCGIFHWADDR)
#define SIO_Get_MAC_Address SIOCGIFHWADDR
#define  ifr_macaddr         ifr_hwaddr.sa_data
#endif

#if defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_SOLARIS) || defined(P_MACOSX) || defined(P_MACOS) || defined(P_IRIX) || defined(P_VXWORKS) || defined(P_RTEMS) || defined(P_QNX)
#define ifr_netmask ifr_addr

#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>

#include <netinet/in.h>
#if !defined(P_QNX)
#include <netinet/if_ether.h>
#endif

#define ROUNDUP(a) \
        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))

#endif

#if defined(P_FREEBSD) || defined(P_OPENBSD) || defined(P_NETBSD) || defined(P_MACOSX) || defined(P_MACOS) || defined(P_QNX)
#include <sys/sysctl.h>
#endif

#ifdef P_RTEMS
#include <bsp.h>
#endif

#ifdef __BEOS__
#include <posix/sys/ioctl.h> // for FIONBIO
#include <be/bone/net/if.h> // for ifconf
#include <be/bone/sys/sockio.h> // for SIOCGI*
#endif

int PX_NewHandle(const char *, int);

#ifdef P_VXWORKS
// VxWorks variant of inet_ntoa() allocates INET_ADDR_LEN bytes via malloc
// BUT DOES NOT FREE IT !!!  Use inet_ntoa_b() instead.
#define INET_ADDR_LEN      18
extern "C" void inet_ntoa_b(struct in_addr inetAddress, char *pString);
#endif // P_VXWORKS

//////////////////////////////////////////////////////////////////////////////
// P_fd_set

void P_fd_set::Construct()
{
  max_fd = PProcess::Current().GetMaxHandles();
  set = (fd_set *)malloc((max_fd+7)>>3);
}


void P_fd_set::Zero()
{
  if (PAssertNULL(set) != NULL)
    memset(set, 0, (max_fd+7)>>3);
}


//////////////////////////////////////////////////////////////////////////////

PSocket::~PSocket()
{
  os_close();
}

int PSocket::os_close()
{
  if (os_handle < 0)
    return -1;

  // send a shutdown to the other end
  ::shutdown(os_handle, 2);

  return PXClose();
}


static int SetNonBlocking(int fd)
{
  if (fd < 0)
    return -1;

  // Set non-blocking so we can use select calls to break I/O block on close
  int cmd = 1;
#if defined(P_VXWORKS)
  if (::ioctl(fd, FIONBIO, &cmd) == 0)
#else
  if (::ioctl(fd, FIONBIO, &cmd) == 0 && ::fcntl(fd, F_SETFD, 1) == 0)
#endif
    return fd;

  ::close(fd);
  return -1;
}


int PSocket::os_socket(int af, int type, int protocol)
{
  // attempt to create a socket
  return SetNonBlocking(PX_NewHandle(GetClass(), ::socket(af, type, protocol)));
}


BOOL PSocket::os_connect(struct sockaddr * addr, PINDEX size)
{
  int val;
  do {
    val = ::connect(os_handle, addr, size);
  } while (val != 0 && errno == EINTR);
  if (val == 0 || errno != EINPROGRESS)
    return ConvertOSError(val);

  if (!PXSetIOBlock(PXConnectBlock, readTimeout))
    return FALSE;

  // A successful select() call does not necessarily mean the socket connected OK.
  int optval = -1;
  socklen_t optlen = sizeof(optval);
  getsockopt(os_handle, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen);
  if (optval != 0) {
    errno = optval;
    return ConvertOSError(-1);
  }

  return TRUE;
}


BOOL PSocket::os_accept(PSocket & listener, struct sockaddr * addr, PINDEX * size)
{
  if (!listener.PXSetIOBlock(PXAcceptBlock, listener.GetReadTimeout()))
    return SetErrorValues(listener.GetErrorCode(), listener.GetErrorNumber());

#if defined(E_PROTO)
  for (;;) {
    int new_fd = ::accept(listener.GetHandle(), addr, (socklen_t *)size);
    if (new_fd >= 0)
      return ConvertOSError(os_handle = SetNonBlocking(new_fd));

    if (errno != EPROTO)
      return ConvertOSError(-1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -