blob: 32c621ff18776a129da36e1c809a657ecad5ca44 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if !defined(hysock_h)
#define hysock_h
/******************************************************\
Portable socket library implementation.
\******************************************************/
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#if !defined(ZOS)
#include <netinet/tcp.h>
#else /* !defined(ZOS) */
#include <netinet/tcp_var.h>
#endif /* !defined(ZOS) */
#include <netdb.h>
#include <sys/time.h>
#include <stdlib.h>
#if !defined(ZOS)
#include <sys/socketvar.h>
#else /* !defined(ZOS) */
#include <arpa/inet.h>
#include <xti.h>
#endif /* !defined(ZOS) */
#include "hysocket.h"
#include "hycomp.h"
#include "hyport.h"
#if defined(DEBUG)
#define HYSOCKDEBUG(x, err) printf(x, err)
#define HYSOCKDEBUGH(x, err) printf(x, err)
#define HYSOCKDEBUGPRINT(x) printf(x)
#else
#define HYSOCKDEBUG(x, err)
#define HYSOCKDEBUGH(x, err)
#define HYSOCKDEBUGPRINT(x)
#endif
/* the following defines are used to determine how gethostby*_r calls should be handled.*/
/* HOSTENT_DATA_R: if the HOSTENT_DATA structure is used */
#define HOSTENT_DATA_R (defined(AIX))
/* GLIBC_R: uses the GLIBC versions */
#define GLIBC_R (defined(LINUX))
/* ORIGINAL_R: the original gethostby* call is thread safe */
#define ORIGINAL_R defined(FREEBSD)
/* TOFIX: FreeBSD man page says:
* Though these functions are thread-safe, still it is recommended to use
* the getaddrinfo(3) family of functions, instead.
*/
/* NO_R: gethostby*_r calls do not exist and the normal gethostby* calls are not threadsafe */
#define NO_R (defined(MACOSX))
/* OTHER_R: everything else */
#define OTHER_R ((!HOSTENT_DATA_R)&&(!GLIBC_R)&&(!ORIGINAL_R)&&(!NO_R))
/* Converts (seconds, microseconds) to milliseconds */
#define TO_MILLIS(sec, microsec) (sec * 1000 + (microsec + 999) / 1000)
/* os types */
typedef int OSSOCKET; /* as returned by socket() */
typedef struct sockaddr_in OSSOCKADDR; /* as used by bind() and friends */
typedef struct hostent OSHOSTENT;
typedef fd_set OSFDSET;
typedef struct timeval OSTIMEVAL;
typedef struct linger OSLINGER;
typedef struct sockaddr OSADDR;
typedef struct sockaddr_in6 OSSOCKADDR_IN6; /* IPv6 */
typedef struct ipv6_mreq OSIPMREQ6;
typedef struct addrinfo OSADDRINFO; /* IPv6 */
typedef struct sockaddr_storage OSSOCKADDR_STORAGE; /* IPv6 */
/*
* Socket Types
*/
#define OSSOCK_ANY 0 /* for getaddrinfo hints */
#define OSSOCK_STREAM SOCK_STREAM /* stream socket */
#define OSSOCK_DGRAM SOCK_DGRAM /* datagram socket */
#define OSSOCK_RAW SOCK_RAW /* raw-protocol interface */
#define OSSOCK_RDM SOCK_RDM /* reliably-delivered message */
#define OSSOCK_SEQPACKET SOCK_SEQPACKET /* sequenced packet stream */
#if defined(HOSTENT_DATA_R)
typedef struct hostent_data OSHOSTENT_DATA;
#endif
typedef struct ip_mreq OSIPMREQ;
#define OSSOMAXCONN SOMAXCONN
#define OS_BADSOCKET -1 /* Provide bad socket constant */
/* defines for socket levels */
#define OS_SOL_SOCKET SOL_SOCKET
#define OS_IPPROTO_TCP IPPROTO_TCP
#define OS_IPPROTO_IP IPPROTO_IP
#if defined(IPv6_FUNCTION_SUPPORT)
#define OS_IPPROTO_IPV6 IPPROTO_IPV6
#endif
/* defines for socket options */
#define OS_SO_LINGER SO_LINGER
#define OS_SO_KEEPALIVE SO_KEEPALIVE
#define OS_TCP_NODELAY TCP_NODELAY
#define OS_SO_REUSEADDR SO_REUSEADDR
#define OS_SO_SNDBUF SO_SNDBUF
#define OS_SO_RCVBUF SO_RCVBUF
#define OS_SO_BROADCAST SO_BROADCAST /* Support datagram broadcasts */
#define OS_SO_OOBINLINE SO_OOBINLINE
#define OS_IP_TOS IP_TOS
/* defines for socket options, multicast */
#define OS_MCAST_TTL IP_MULTICAST_TTL
#define OS_MCAST_ADD_MEMBERSHIP IP_ADD_MEMBERSHIP
#define OS_MCAST_DROP_MEMBERSHIP IP_DROP_MEMBERSHIP
#define OS_MCAST_INTERFACE IP_MULTICAST_IF
#define OS_MCAST_LOOP IP_MULTICAST_LOOP
#if defined(IPv6_FUNCTION_SUPPORT)
#define OS_MCAST_INTERFACE_2 IPV6_MULTICAST_IF
#if defined(FREEBSD) || defined(MACOSX)
#define OS_IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#define OS_IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#else
#define OS_IPV6_ADD_MEMBERSHIP IPV6_ADD_MEMBERSHIP
#define OS_IPV6_DROP_MEMBERSHIP IPV6_DROP_MEMBERSHIP
#endif
#endif
/* defines for the unix error constants. These may be overriden for specific platforms. */
#define HYPORT_ERROR_SOCKET_UNIX_CONNRESET ECONNRESET
#define HYPORT_ERROR_SOCKET_UNIX_EAGAIN EAGAIN
#define HYPORT_ERROR_SOCKET_UNIX_EAFNOSUPPORT EAFNOSUPPORT
#define HYPORT_ERROR_SOCKET_UNIX_EBADF EBADF
#define HYPORT_ERROR_SOCKET_UNIX_ECONNRESET ECONNRESET
#define HYPORT_ERROR_SOCKET_UNIX_EINVAL EINVAL
#define HYPORT_ERROR_SOCKET_UNIX_EINTR EINTR
#define HYPORT_ERROR_SOCKET_UNIX_EFAULT EFAULT
#define HYPORT_ERROR_SOCKET_UNIX_ENOPROTOOPT ENOPROTOOPT
#define HYPORT_ERROR_SOCKET_UNIX_ENOTCONN ENOTCONN
#define HYPORT_ERROR_SOCKET_UNIX_EPROTONOSUPPORT EPROTONOSUPPORT
#define HYPORT_ERROR_SOCKET_UNIX_HOSTNOTFOUND HOST_NOT_FOUND
#define HYPORT_ERROR_SOCKET_UNIX_ENOBUFS ENOBUFS
#define HYPORT_ERROR_SOCKET_UNIX_NODATA NO_DATA
#define HYPORT_ERROR_SOCKET_UNIX_NORECOVERY NO_RECOVERY
#define HYPORT_ERROR_SOCKET_UNIX_ENOTSOCK ENOTSOCK
#define HYPORT_ERROR_SOCKET_UNIX_TRYAGAIN TRY_AGAIN
#define HYPORT_ERROR_SOCKET_UNIX_EOPNOTSUP EOPNOTSUPP
#define HYPORT_ERROR_SOCKET_UNIX_ETIMEDOUT ETIMEDOUT
#define HYPORT_ERROR_SOCKET_UNIX_CONNREFUSED ECONNREFUSED
#define HYPORT_ERROR_SOCKET_UNIX_EINPROGRESS EINPROGRESS
#define HYPORT_ERROR_SOCKET_UNIX_ENETUNREACH ENETUNREACH
#define HYPORT_ERROR_SOCKET_UNIX_EACCES EACCES
/* platform constants */
#define HYSOCK_MAXCONN OSSOMAXCONN;
#define HYSOCK_BADSOCKET OS_BADSOCKET /* Provide bad socket constant */
/* defines added for IPv6 */
#define OS_AF_INET4 AF_INET
#define OS_AF_UNSPEC AF_UNSPEC
#define OS_PF_UNSPEC PF_UNSPEC
#define OS_PF_INET4 PF_INET
#define OS_INET4_ADDRESS_LENGTH INET_ADDRSTRLEN
#if defined(NI_MAXHOST)
#define OSNIMAXHOST NI_MAXHOST
#define OSNIMAXSERV NI_MAXSERV
#else
#define OSNIMAXHOST 1025
#define OSNIMAXSERV 32
#endif
#if defined(AF_INET6)
#define OS_AF_INET6 AF_INET6
#define OS_PF_INET6 PF_INET6
#define OS_INET6_ADDRESS_LENGTH INET6_ADDRSTRLEN
#else
#define OS_AF_INET6 -1
#define OS_PF_INET6 -1
#define OS_INET6_ADDRESS_LENGTH 46
#endif
/*platform structs */
typedef struct hysocket_struct
{
OSSOCKET sock;
U_16 family;
} hysocket_struct;
/* The sockets are now structs */
#if defined(NO_LVALUE_CASTING)
#define SOCKET_CAST(x) ((struct hysocket_struct*) x)->sock
#else
#define SOCKET_CAST(x) ((struct hysocket_struct*) x)->sock
#endif
typedef struct hysockaddr_struct
{
#if defined(IPv6_FUNCTION_SUPPORT)
OSSOCKADDR_STORAGE addr;
#else
OSSOCKADDR addr;
#endif
} hysockaddr_struct;
typedef struct hyhostent_struct
{
OSHOSTENT *entity;
} hyhostent_struct;
typedef struct hyfdset_struct
{
OSFDSET handle;
} hyfdset_struct;
typedef struct hytimeval_struct
{
OSTIMEVAL time;
} hytimeval_struct;
typedef struct hylinger_struct
{
OSLINGER linger;
} hylinger_struct;
typedef struct hyipmreq_struct
{
OSIPMREQ addrpair;
} hyipmreq_struct;
#define GET_HOST_BUFFER_SIZE 512
/* The gethostBuffer is allocated bufferSize + EXTRA_SPACE, while gethostby*_r is only aware of bufferSize
* because there seems to be a bug on Linux 386 where gethostbyname_r writes past the end of the
* buffer. This bug has not been observed on other platforms, but EXTRA_SPACE is added anyway as a precaution.*/
#define EXTRA_SPACE 128
/*size is 16 because an IP string is "xxx.xxx.xxx.xxx" + 1 null character */
#define NTOA_SIZE 16
/** new structure for IPv6 mulitcast requests */
typedef struct hyipv6_mreq_struct
{
#if defined(IPv6_FUNCTION_SUPPORT)
OSIPMREQ6 mreq;
#else
int dummy;
#endif
} hyipv6_mreq_struct;
/* structure for returning either and IPV4 or IPV6 ip address */
typedef struct hyipAddress_struct
{
union
{
#if defined(IPv6_FUNCTION_SUPPORT)
U_8 bytes[sizeof (struct in6_addr)];
#else
U_8 bytes[sizeof (struct in_addr)];
#endif
struct in_addr inAddr;
#if defined(IPv6_FUNCTION_SUPPORT)
struct in6_addr in6Addr;
#endif
} addr;
U_32 length;
U_32 scope;
} hyipAddress_struct;
/* structure for returning network interface information */
typedef struct hyNetworkInterface_struct
{
char *name;
char *displayName;
U_32 numberAddresses;
U_32 index;
struct hyipAddress_struct *addresses;
} hyNetworkInterface_struct;
/* array of network interface structures */
typedef struct hyNetworkInterfaceArray_struct
{
U_32 length;
struct hyNetworkInterface_struct *elements;
} hyNetworkInterfaceArray_struct;
/** new structure for IPv6 addrinfo will either point to a hostent or
an addr info depending on the IPv6 support for this OS */
typedef struct hyaddrinfo_struct
{
void *addr_info;
int length;
} hyaddrinfo_struct;
#endif