2009-01-16 23:11:27 -05:00
|
|
|
#ifndef RUBY_SOCKET_H
|
|
|
|
#define RUBY_SOCKET_H 1
|
|
|
|
|
2019-12-04 03:16:30 -05:00
|
|
|
#include "ruby/config.h"
|
|
|
|
#include RUBY_EXTCONF_H
|
|
|
|
|
2020-04-08 00:28:13 -04:00
|
|
|
#ifdef __sun
|
|
|
|
/* (Recent?) Solaris' <nfs/nfs.h> have conflicting definition of T_DATA. Let
|
|
|
|
* us honour system definition by undefining ours.
|
|
|
|
*
|
|
|
|
* See also [ruby-core:4261]
|
|
|
|
*/
|
|
|
|
# include "ruby/ruby.h"
|
|
|
|
# undef T_DATA
|
|
|
|
#endif
|
|
|
|
|
2019-12-04 03:16:30 -05:00
|
|
|
#include <errno.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#include <stdio.h>
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
#include <sys/types.h>
|
2009-02-18 18:47:21 -05:00
|
|
|
#include <sys/stat.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <unistd.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_UIO_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/uio.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_XTI_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <xti.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
2013-05-11 10:07:20 -04:00
|
|
|
#ifdef _WIN32
|
|
|
|
# if defined(_MSC_VER)
|
|
|
|
# undef HAVE_TYPE_STRUCT_SOCKADDR_DL
|
|
|
|
# endif
|
|
|
|
#else
|
2015-11-23 19:17:11 -05:00
|
|
|
# include <sys/socket.h>
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <netinet/in.h>
|
|
|
|
# ifdef HAVE_NETINET_IN_SYSTM_H
|
|
|
|
# include <netinet/in_systm.h>
|
|
|
|
# endif
|
|
|
|
# ifdef HAVE_NETINET_TCP_H
|
|
|
|
# include <netinet/tcp.h>
|
|
|
|
# endif
|
2014-05-19 07:52:03 -04:00
|
|
|
# ifdef HAVE_NETINET_TCP_FSM_H
|
|
|
|
# include <netinet/tcp_fsm.h>
|
|
|
|
# endif
|
2013-02-15 17:53:59 -05:00
|
|
|
# ifdef HAVE_NETINET_UDP_H
|
|
|
|
# include <netinet/udp.h>
|
|
|
|
# endif
|
|
|
|
# ifdef HAVE_ARPA_INET_H
|
|
|
|
# include <arpa/inet.h>
|
|
|
|
# endif
|
|
|
|
# include <netdb.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
2013-02-15 17:53:59 -05:00
|
|
|
|
2013-05-11 04:32:26 -04:00
|
|
|
#ifdef HAVE_NETPACKET_PACKET_H
|
|
|
|
# include <netpacket/packet.h>
|
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2013-05-11 04:32:26 -04:00
|
|
|
#ifdef HAVE_NET_ETHERNET_H
|
|
|
|
# include <net/ethernet.h>
|
|
|
|
#endif
|
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
#ifdef HAVE_SYS_UN_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/un.h>
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(HAVE_FCNTL)
|
2013-02-15 17:53:59 -05:00
|
|
|
# ifdef HAVE_SYS_SELECT_H
|
|
|
|
# include <sys/select.h>
|
|
|
|
# endif
|
|
|
|
# ifdef HAVE_SYS_TYPES_H
|
|
|
|
# include <sys/types.h>
|
|
|
|
# endif
|
|
|
|
# ifdef HAVE_SYS_TIME_H
|
|
|
|
# include <sys/time.h>
|
|
|
|
# endif
|
|
|
|
# ifdef HAVE_FCNTL_H
|
|
|
|
# include <fcntl.h>
|
|
|
|
# endif
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
2009-01-20 06:06:22 -05:00
|
|
|
|
2009-01-20 06:19:09 -05:00
|
|
|
#ifdef HAVE_IFADDRS_H
|
2015-10-24 09:51:25 -04:00
|
|
|
# ifdef __HAIKU__
|
|
|
|
# define _BSD_SOURCE
|
|
|
|
# endif
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <ifaddrs.h>
|
2009-01-20 06:19:09 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-01-20 06:19:09 -05:00
|
|
|
#ifdef HAVE_SYS_IOCTL_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/ioctl.h>
|
2009-01-20 06:19:09 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-01-20 06:19:09 -05:00
|
|
|
#ifdef HAVE_SYS_SOCKIO_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/sockio.h>
|
2009-01-20 06:19:09 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-01-20 06:19:09 -05:00
|
|
|
#ifdef HAVE_NET_IF_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <net/if.h>
|
2009-01-20 06:19:09 -05:00
|
|
|
#endif
|
|
|
|
|
2009-02-08 10:37:55 -05:00
|
|
|
#ifdef HAVE_SYS_PARAM_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/param.h>
|
2009-02-08 10:37:55 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-02-08 10:37:55 -05:00
|
|
|
#ifdef HAVE_SYS_UCRED_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <sys/ucred.h>
|
2009-02-08 10:37:55 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2009-02-12 07:43:04 -05:00
|
|
|
#ifdef HAVE_UCRED_H
|
2013-02-15 17:53:59 -05:00
|
|
|
# include <ucred.h>
|
2009-02-12 07:43:04 -05:00
|
|
|
#endif
|
2019-12-04 03:16:30 -05:00
|
|
|
|
2013-05-11 04:32:26 -04:00
|
|
|
#ifdef HAVE_NET_IF_DL_H
|
|
|
|
# include <net/if_dl.h>
|
|
|
|
#endif
|
2009-02-08 10:37:55 -05:00
|
|
|
|
2019-12-04 03:16:30 -05:00
|
|
|
#ifdef SOCKS5
|
|
|
|
# include <socks.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_GETADDRINFO
|
|
|
|
# include "addrinfo.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include "internal/array.h"
|
|
|
|
#include "internal/error.h"
|
|
|
|
#include "internal/gc.h"
|
|
|
|
#include "internal/io.h"
|
|
|
|
#include "internal/thread.h"
|
|
|
|
#include "internal/vm.h"
|
|
|
|
#include "ruby/io.h"
|
|
|
|
#include "ruby/ruby.h"
|
|
|
|
#include "ruby/thread.h"
|
|
|
|
#include "ruby/util.h"
|
|
|
|
#include "sockport.h"
|
|
|
|
|
2013-02-13 07:01:24 -05:00
|
|
|
#ifndef HAVE_TYPE_SOCKLEN_T
|
|
|
|
typedef int socklen_t;
|
|
|
|
#endif
|
2013-04-17 07:01:17 -04:00
|
|
|
|
2013-05-14 10:24:42 -04:00
|
|
|
#ifdef NEED_IF_INDEXTONAME_DECL
|
|
|
|
char *if_indextoname(unsigned int, char *);
|
|
|
|
#endif
|
|
|
|
#ifdef NEED_IF_NAMETOINDEX_DECL
|
|
|
|
unsigned int if_nametoindex(const char *);
|
|
|
|
#endif
|
|
|
|
|
2013-04-17 07:01:17 -04:00
|
|
|
#define SOCKLEN_MAX \
|
2013-04-17 09:08:13 -04:00
|
|
|
(0 < (socklen_t)-1 ? \
|
2013-04-17 07:01:17 -04:00
|
|
|
~(socklen_t)0 : \
|
|
|
|
(((((socklen_t)1) << (sizeof(socklen_t) * CHAR_BIT - 2)) - 1) * 2 + 1))
|
|
|
|
|
2013-04-06 03:58:51 -04:00
|
|
|
#ifndef RSTRING_SOCKLEN
|
|
|
|
# define RSTRING_SOCKLEN (socklen_t)RSTRING_LENINT
|
|
|
|
#endif
|
2013-02-13 07:01:24 -05:00
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
#ifndef EWOULDBLOCK
|
2013-02-15 17:53:59 -05:00
|
|
|
# define EWOULDBLOCK EAGAIN
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
2009-01-20 06:06:22 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* workaround for NetBSD, OpenBSD and etc.
|
|
|
|
* The problem is since 4.4BSD-Lite.
|
|
|
|
* FreeBSD fix the problem at FreeBSD 2.2.0.
|
|
|
|
* NetBSD fix the problem at NetBSD 3.0 by kern/29624.
|
|
|
|
* OpenBSD fix the problem at OpenBSD 3.8.
|
|
|
|
*/
|
|
|
|
#define pseudo_AF_FTIP pseudo_AF_RTIP
|
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
|
|
|
|
#ifndef NI_MAXHOST
|
2013-02-15 17:53:59 -05:00
|
|
|
# define NI_MAXHOST 1025
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
#ifndef NI_MAXSERV
|
2013-02-15 17:53:59 -05:00
|
|
|
# define NI_MAXSERV 32
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
2009-01-17 13:14:34 -05:00
|
|
|
#ifdef AF_INET6
|
2013-02-15 17:53:59 -05:00
|
|
|
# define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6)
|
2009-01-17 13:14:34 -05:00
|
|
|
#else
|
2013-02-15 17:53:59 -05:00
|
|
|
# define IS_IP_FAMILY(af) ((af) == AF_INET)
|
2009-01-17 13:14:34 -05:00
|
|
|
#endif
|
|
|
|
|
2012-07-19 20:32:35 -04:00
|
|
|
#ifndef IN6_IS_ADDR_UNIQUE_LOCAL
|
2013-02-15 17:53:59 -05:00
|
|
|
# define IN6_IS_ADDR_UNIQUE_LOCAL(a) (((a)->s6_addr[0] == 0xfc) || ((a)->s6_addr[0] == 0xfd))
|
2012-07-19 20:32:35 -04:00
|
|
|
#endif
|
|
|
|
|
2013-02-14 22:36:05 -05:00
|
|
|
#ifndef HAVE_TYPE_STRUCT_SOCKADDR_STORAGE
|
2009-01-16 23:11:27 -05:00
|
|
|
/*
|
|
|
|
* RFC 2553: protocol-independent placeholder for socket addresses
|
|
|
|
*/
|
2013-02-15 17:53:59 -05:00
|
|
|
# define _SS_MAXSIZE 128
|
|
|
|
# define _SS_ALIGNSIZE (sizeof(double))
|
|
|
|
# define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
|
|
|
|
# define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
|
2009-01-16 23:11:27 -05:00
|
|
|
_SS_PAD1SIZE - _SS_ALIGNSIZE)
|
|
|
|
|
|
|
|
struct sockaddr_storage {
|
2013-02-15 17:53:59 -05:00
|
|
|
# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
2009-01-16 23:11:27 -05:00
|
|
|
unsigned char ss_len; /* address length */
|
|
|
|
unsigned char ss_family; /* address family */
|
2013-02-15 17:53:59 -05:00
|
|
|
# else
|
2009-01-16 23:11:27 -05:00
|
|
|
unsigned short ss_family;
|
2013-02-15 17:53:59 -05:00
|
|
|
# endif
|
2009-01-16 23:11:27 -05:00
|
|
|
char __ss_pad1[_SS_PAD1SIZE];
|
|
|
|
double __ss_align; /* force desired structure storage alignment */
|
|
|
|
char __ss_pad2[_SS_PAD2SIZE];
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
2013-02-24 12:51:17 -05:00
|
|
|
typedef union {
|
|
|
|
struct sockaddr addr;
|
|
|
|
struct sockaddr_in in;
|
|
|
|
#ifdef AF_INET6
|
|
|
|
struct sockaddr_in6 in6;
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_TYPE_STRUCT_SOCKADDR_UN
|
|
|
|
struct sockaddr_un un;
|
2013-05-11 04:32:26 -04:00
|
|
|
#endif
|
|
|
|
#ifdef HAVE_TYPE_STRUCT_SOCKADDR_DL
|
|
|
|
struct sockaddr_dl dl; /* AF_LINK */
|
2013-02-24 12:51:17 -05:00
|
|
|
#endif
|
2013-04-08 16:27:01 -04:00
|
|
|
struct sockaddr_storage storage;
|
2013-02-27 08:55:19 -05:00
|
|
|
char place_holder[2048]; /* sockaddr_storage is not enough for Unix domain sockets on SunOS and Darwin. */
|
2013-02-24 12:51:17 -05:00
|
|
|
} union_sockaddr;
|
|
|
|
|
2012-07-09 11:52:49 -04:00
|
|
|
#ifdef __APPLE__
|
2010-09-13 06:56:52 -04:00
|
|
|
/*
|
|
|
|
* CMSG_ macros are broken on 64bit darwin, because __DARWIN_ALIGN
|
|
|
|
* aligns up to __darwin_size_t which is 64bit, but CMSG_DATA is
|
|
|
|
* 32bit-aligned.
|
|
|
|
*/
|
2013-02-15 17:53:59 -05:00
|
|
|
# undef __DARWIN_ALIGNBYTES
|
|
|
|
# define __DARWIN_ALIGNBYTES (sizeof(unsigned int) - 1)
|
2010-09-13 06:56:52 -04:00
|
|
|
#endif
|
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
#if defined(_AIX)
|
2013-02-15 17:53:59 -05:00
|
|
|
# ifndef CMSG_SPACE
|
|
|
|
# define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
|
|
|
|
# endif
|
|
|
|
# ifndef CMSG_LEN
|
|
|
|
# define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
|
|
|
|
# endif
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#define INET_CLIENT 0
|
|
|
|
#define INET_SERVER 1
|
|
|
|
#define INET_SOCKS 2
|
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
extern int rsock_do_not_reverse_lookup;
|
2009-01-16 23:11:27 -05:00
|
|
|
#define FMODE_NOREVLOOKUP 0x100
|
|
|
|
|
2015-07-01 21:58:14 -04:00
|
|
|
/* common socket families only */
|
|
|
|
#define FMODE_UNIX 0x00200000
|
|
|
|
#define FMODE_INET 0x00400000
|
|
|
|
#define FMODE_INET6 0x00800000
|
|
|
|
#define FMODE_SOCK (FMODE_UNIX|FMODE_INET|FMODE_INET6)
|
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
extern VALUE rb_cBasicSocket;
|
|
|
|
extern VALUE rb_cIPSocket;
|
|
|
|
extern VALUE rb_cTCPSocket;
|
|
|
|
extern VALUE rb_cTCPServer;
|
|
|
|
extern VALUE rb_cUDPSocket;
|
2009-01-18 21:22:57 -05:00
|
|
|
#ifdef HAVE_SYS_UN_H
|
2009-01-16 23:11:27 -05:00
|
|
|
extern VALUE rb_cUNIXSocket;
|
|
|
|
extern VALUE rb_cUNIXServer;
|
|
|
|
#endif
|
|
|
|
extern VALUE rb_cSocket;
|
2009-02-05 06:01:43 -05:00
|
|
|
extern VALUE rb_cAddrinfo;
|
2009-02-01 20:53:02 -05:00
|
|
|
extern VALUE rb_cSockOpt;
|
2009-01-16 23:11:27 -05:00
|
|
|
|
|
|
|
extern VALUE rb_eSocket;
|
|
|
|
|
|
|
|
#ifdef SOCKS
|
|
|
|
extern VALUE rb_cSOCKSSocket;
|
2019-12-04 03:16:30 -05:00
|
|
|
# ifndef SOCKS5
|
2009-01-16 23:11:27 -05:00
|
|
|
void SOCKSinit();
|
|
|
|
int Rconnect();
|
2013-02-15 17:53:59 -05:00
|
|
|
# endif
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|
|
|
|
|
2009-01-17 05:19:03 -05:00
|
|
|
#include "constdefs.h"
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2011-02-12 00:44:23 -05:00
|
|
|
#define BLOCKING_REGION_FD(func, arg) (long)rb_thread_io_blocking_region((func), (arg), (arg)->fd)
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
#define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v))
|
|
|
|
#define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v))
|
2013-04-06 01:50:42 -04:00
|
|
|
#define SockAddrStringValueWithAddrinfo(v, rai_ret) rsock_sockaddr_string_value_with_addrinfo(&(v), &(rai_ret))
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_sockaddr_string_value(volatile VALUE *);
|
|
|
|
char *rsock_sockaddr_string_value_ptr(volatile VALUE *);
|
2013-04-06 01:50:42 -04:00
|
|
|
VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret);
|
|
|
|
|
2009-01-17 11:39:03 -05:00
|
|
|
VALUE rb_check_sockaddr_string_type(VALUE);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
NORETURN(void rsock_raise_socket_error(const char *, int));
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
int rsock_family_arg(VALUE domain);
|
|
|
|
int rsock_socktype_arg(VALUE type);
|
|
|
|
int rsock_level_arg(int family, VALUE level);
|
|
|
|
int rsock_optname_arg(int family, int level, VALUE optname);
|
|
|
|
int rsock_cmsg_type_arg(int family, int level, VALUE type);
|
|
|
|
int rsock_shutdown_how_arg(VALUE how);
|
2009-02-09 08:56:43 -05:00
|
|
|
|
2015-07-01 21:58:14 -04:00
|
|
|
int rsock_getfamily(rb_io_t *fptr);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2014-02-19 04:38:24 -05:00
|
|
|
struct rb_addrinfo {
|
|
|
|
struct addrinfo *ai;
|
2014-02-19 05:37:43 -05:00
|
|
|
int allocated_by_malloc;
|
2014-02-19 04:38:24 -05:00
|
|
|
};
|
|
|
|
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct rb_addrinfo **res);
|
|
|
|
void rb_freeaddrinfo(struct rb_addrinfo *ai);
|
|
|
|
VALUE rsock_freeaddrinfo(VALUE arg);
|
2009-01-16 23:11:27 -05:00
|
|
|
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
|
2015-10-12 23:14:13 -04:00
|
|
|
int rsock_fd_family(int fd);
|
|
|
|
struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags);
|
2014-02-19 04:38:24 -05:00
|
|
|
struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
|
|
|
|
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname);
|
2013-04-06 01:50:42 -04:00
|
|
|
VALUE rsock_addrinfo_inspect_sockaddr(VALUE rai);
|
2009-01-20 06:19:09 -05:00
|
|
|
|
2013-02-14 06:28:49 -05:00
|
|
|
VALUE rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen);
|
|
|
|
VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup);
|
2014-02-19 04:38:24 -05:00
|
|
|
VALUE rsock_make_hostent(VALUE host, struct rb_addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, socklen_t));
|
2013-05-11 04:32:26 -04:00
|
|
|
VALUE rsock_inspect_sockaddr(struct sockaddr *addr, socklen_t socklen, VALUE ret);
|
|
|
|
socklen_t rsock_sockaddr_len(struct sockaddr *addr);
|
|
|
|
VALUE rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2010-03-21 11:51:07 -04:00
|
|
|
int rsock_revlookup_flag(VALUE revlookup, int *norevlookup);
|
|
|
|
|
2009-01-18 21:22:57 -05:00
|
|
|
#ifdef HAVE_SYS_UN_H
|
2012-04-25 23:34:12 -04:00
|
|
|
VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len);
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len);
|
2013-01-25 18:33:50 -05:00
|
|
|
socklen_t rsock_unix_sockaddr_len(VALUE path);
|
2009-01-18 21:22:57 -05:00
|
|
|
#endif
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:48:22 -05:00
|
|
|
int rsock_socket(int domain, int type, int proto);
|
2014-01-28 09:37:34 -05:00
|
|
|
int rsock_detect_cloexec(int fd);
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_init_sock(VALUE sock, int fd);
|
2009-03-01 01:48:22 -05:00
|
|
|
VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass);
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type);
|
|
|
|
VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
struct rsock_send_arg {
|
2009-01-16 23:11:27 -05:00
|
|
|
int fd, flags;
|
|
|
|
VALUE mesg;
|
|
|
|
struct sockaddr *to;
|
|
|
|
socklen_t tolen;
|
|
|
|
};
|
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_sendto_blocking(void *data);
|
|
|
|
VALUE rsock_send_blocking(void *data);
|
|
|
|
VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
|
|
|
enum sock_recv_type {
|
|
|
|
RECV_RECV, /* BasicSocket#recv(no from) */
|
|
|
|
RECV_IP, /* IPSocket#recvfrom */
|
|
|
|
RECV_UNIX, /* UNIXSocket#recvfrom */
|
|
|
|
RECV_SOCKET /* Socket#recvfrom */
|
|
|
|
};
|
|
|
|
|
socket: avoid arg parsing in rsock_s_recvfrom_nonblock
* ext/socket/init.c (rsock_s_recvfrom_nonblock):
avoid arg parsing with C API
[ruby-core:71439] [Feature #11339]
* ext/socket/basicsocket.c (bsock_recv_nonblock):
adjust for above change, make private
* ext/socket/socket.c (sock_recvfrom_nonblock): ditto
* ext/socket/udpsocket.c (udp_recvfrom_nonblock): ditto
* ext/socket/lib/socket.rb (BasicSocket#recv_nonblock):
new wrapper for private method, move RDoc
(Socket#recvfrom_nonblock): ditto
(UDPSocket#recvfrom_nonblock): ditto
Note, not adding bm_recv_nonblock.rb to benchmark/ directory
since it is non-portable. It is only in this commit message.
Benchmark results + code
target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52540) [x86_64-linux])
target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52540) [x86_64-linux]
-----------------------------------------------------------
recv_nonblock
require 'socket'
nr = 1000000
msg = 'hello world'
buf = ''
size = msg.bytesize
UNIXSocket.pair(:SEQPACKET) do |a, b|
nr.times do
a.sendmsg(msg)
b.recv_nonblock(size, 0, buf, exception: false)
end
end
-----------------------------------------------------------
raw data:
[["recv_nonblock",
[[1.83511221408844,
1.8703329525887966,
1.8448856547474861,
1.859263762831688,
1.8331583738327026],
[1.5637447573244572,
1.4062932096421719,
1.4247371144592762,
1.4108827747404575,
1.4802536629140377]]]]
Elapsed time: 16.530452496 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name a b
recv_nonblock 1.833 1.406
Speedup ratio: compare with the result of `a' (greater is better)
name b
recv_nonblock 1.304
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52598 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16 18:25:03 -05:00
|
|
|
VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str,
|
|
|
|
VALUE ex, enum sock_recv_type from);
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:48:22 -05:00
|
|
|
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
|
socket: avoid arg parsing in rsock_s_accept_nonblock
* ext/socket/init.c (rsock_s_accept_nonblock): avoid parsing args
[ruby-core:71439] [Feature #11339]
* ext/socket/rubysocket.h: adjust prototype
* ext/socket/socket.c (sock_accept_nonblock): make private
* ext/socket/tcpserver.c (tcp_accept_nonblock): ditto
* ext/socket/unixserver.c (unix_accept_nonblock): ditto
* ext/socket/lib/socket.rb (Socket#accept_nonblock):
implement as wrapper, move RDoc
(TCPServer#accept_nonblock): ditto
(UNIXServer#accept_nonblock): ditto
target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux])
target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux]
-----------------------------------------------------------
accept_nonblock
require 'tempfile'
require 'socket'
require 'io/wait'
nr = 500000
Tempfile.create(%w(accept_nonblock .sock)) do |tmp|
path = tmp.path
File.unlink(path)
s = UNIXServer.new(path)
addr = Socket.sockaddr_un(path).freeze
nr.times do
s.accept_nonblock(exception: false)
c = UNIXSocket.new(path)
s.wait_readable
s.accept_nonblock(exception: false).close
c.close
end
end
-----------------------------------------------------------
raw data:
[["accept_nonblock",
[[4.807877402752638,
4.930681671947241,
4.738454818725586,
4.69268161803484,
4.684675686061382],
[4.253904823213816,
4.255124930292368,
4.295955188572407,
4.248479191213846,
4.213303029537201]]]]
Elapsed time: 45.123040065 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name a b
accept_nonblock 4.685 4.213
Speedup ratio: compare with the result of `a' (greater is better)
name b
accept_nonblock 1.112
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16 18:40:15 -05:00
|
|
|
VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr,
|
|
|
|
struct sockaddr *sockaddr, socklen_t *len);
|
2010-03-21 06:50:52 -04:00
|
|
|
VALUE rsock_sock_listen(VALUE sock, VALUE log);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2009-03-01 01:30:41 -05:00
|
|
|
VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data);
|
2009-02-01 20:53:02 -05:00
|
|
|
|
2010-03-21 06:50:52 -04:00
|
|
|
#if defined(HAVE_SENDMSG)
|
socket: avoid arg parsing in bsock_sendmsg_internal
* ext/socket/ancdata.c (bsock_sendmsg_internal): avoid arg parsing
[ruby-core:71439] [Feature #11339]
(rsock_bsock_sendmsg): make private, adjust for above
(rsock_bsock_sendmsg_nonblock): ditto
* ext/socket/rubysocket.h: adjust prototypes
(rsock_opt_false_p): remove
* ext/socket/basicsocket.c (rsock_init_basicsocket):
define private methods
* ext/socket/lib/socket.rb (BasicSocket#sendmsg): new wrapper
(BasicSocket#sendmsg_nonblock): ditto
target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux])
target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux]
-----------------------------------------------------------
sendmsg_nonblock
require 'socket'
nr = 1_000_000
i = 0
msg = '.'
buf = '.'
begin
r, w = UNIXSocket.pair(:SEQPACKET)
while i < nr
i += 1
w.sendmsg_nonblock(msg, exception: false)
r.recv(1, 0, buf)
end
ensure
r.close
w.close
end
-----------------------------------------------------------
raw data:
[["sendmsg_nonblock",
[[1.875997293740511,
1.8452614955604076,
1.8449317328631878,
1.8418389447033405,
1.869386937469244],
[1.5175109766423702,
1.4987873211503029,
1.4989623799920082,
1.47918451577425,
1.5017359890043736]]]]
Elapsed time: 16.775453245 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name a b
sendmsg_nonblock 1.842 1.479
Speedup ratio: compare with the result of `a' (greater is better)
name b
sendmsg_nonblock 1.245
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52603 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16 20:05:30 -05:00
|
|
|
VALUE rsock_bsock_sendmsg(VALUE sock, VALUE data, VALUE flags,
|
|
|
|
VALUE dest_sockaddr, VALUE controls);
|
|
|
|
VALUE rsock_bsock_sendmsg_nonblock(VALUE sock, VALUE data, VALUE flags,
|
|
|
|
VALUE dest_sockaddr, VALUE controls, VALUE ex);
|
2010-04-28 03:16:30 -04:00
|
|
|
#else
|
|
|
|
#define rsock_bsock_sendmsg rb_f_notimplement
|
|
|
|
#define rsock_bsock_sendmsg_nonblock rb_f_notimplement
|
2010-03-21 06:50:52 -04:00
|
|
|
#endif
|
2013-02-15 17:53:59 -05:00
|
|
|
|
2010-03-21 06:50:52 -04:00
|
|
|
#if defined(HAVE_RECVMSG)
|
socket (bsock_recvmsg_internal): avoid arg parsing
* ext/socket/ancdata.c (bsock_recvmsg_internal): avoid arg parsing
(rsock_bsock_recvmsg): adjust for above change
(rsock_bsock_recvmsg_nonblock): ditto
[ruby-core:71439] [Feature #11339]
* ext/socket/rubysocket.h: adjust prototypes for above
* ext/socket/basicsocket.c (rsock_init_basicsocket):
adjust private methods
* ext/socket/lib/socket.rb (BasicSocket#recvmsg): wrapper method
(BasicSocket#recvmsg_nonblock): ditto
target 0: a (ruby 2.3.0dev (2015-11-12 trunk 52550) [x86_64-linux])
target 1: b (ruby 2.3.0dev (2015-11-12 avoid-kwarg-capi 52550) [x86_64-linux]
-----------------------------------------------------------
recvmsg_nonblock
require 'socket'
nr = 1_000_000
i = 0
msg = '.'
buf = '.'
begin
r, w = UNIXSocket.pair(:SEQPACKET)
while i < nr
i += 1
w.sendmsg(msg)
r.recvmsg_nonblock(1, exception: false)
end
ensure
r.close
w.close
end
-----------------------------------------------------------
raw data:
[["recvmsg_nonblock",
[[3.721687912940979,
3.6072621569037437,
3.580637402832508,
3.614185404032469,
3.6029579415917397],
[2.4694008752703667,
2.4908322244882584,
2.5051278844475746,
2.5037173740565777,
2.548359278589487]]]]
Elapsed time: 30.646087052 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name a b
recvmsg_nonblock 3.581 2.469
Speedup ratio: compare with the result of `a' (greater is better)
name b
recvmsg_nonblock 1.450
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-16 19:58:23 -05:00
|
|
|
VALUE rsock_bsock_recvmsg(VALUE sock, VALUE dlen, VALUE clen, VALUE flags,
|
|
|
|
VALUE scm_rights);
|
|
|
|
VALUE rsock_bsock_recvmsg_nonblock(VALUE sock, VALUE dlen, VALUE clen,
|
|
|
|
VALUE flags, VALUE scm_rights, VALUE ex);
|
2011-11-06 01:51:43 -04:00
|
|
|
ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags);
|
2010-04-28 03:16:30 -04:00
|
|
|
#else
|
|
|
|
#define rsock_bsock_recvmsg rb_f_notimplement
|
|
|
|
#define rsock_bsock_recvmsg_nonblock rb_f_notimplement
|
2010-03-21 06:50:52 -04:00
|
|
|
#endif
|
|
|
|
|
2013-05-08 23:08:58 -04:00
|
|
|
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
|
2011-07-23 04:13:37 -04:00
|
|
|
void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p);
|
2009-02-25 09:03:42 -05:00
|
|
|
#endif
|
|
|
|
|
2010-03-22 12:15:21 -04:00
|
|
|
void rsock_init_basicsocket(void);
|
|
|
|
void rsock_init_ipsocket(void);
|
|
|
|
void rsock_init_tcpsocket(void);
|
|
|
|
void rsock_init_tcpserver(void);
|
|
|
|
void rsock_init_sockssocket(void);
|
|
|
|
void rsock_init_udpsocket(void);
|
|
|
|
void rsock_init_unixsocket(void);
|
|
|
|
void rsock_init_unixserver(void);
|
|
|
|
void rsock_init_socket_constants(void);
|
|
|
|
void rsock_init_ancdata(void);
|
|
|
|
void rsock_init_addrinfo(void);
|
|
|
|
void rsock_init_sockopt(void);
|
2013-05-11 04:32:26 -04:00
|
|
|
void rsock_init_sockifaddr(void);
|
2010-03-22 12:15:21 -04:00
|
|
|
void rsock_init_socket_init(void);
|
2009-01-16 23:11:27 -05:00
|
|
|
|
2014-01-04 05:13:36 -05:00
|
|
|
NORETURN(void rsock_syserr_fail_host_port(int err, const char *, VALUE, VALUE));
|
|
|
|
NORETURN(void rsock_syserr_fail_path(int err, const char *, VALUE));
|
|
|
|
NORETURN(void rsock_syserr_fail_sockaddr(int err, const char *mesg, struct sockaddr *addr, socklen_t len));
|
|
|
|
NORETURN(void rsock_syserr_fail_raddrinfo(int err, const char *mesg, VALUE rai));
|
|
|
|
NORETURN(void rsock_syserr_fail_raddrinfo_or_sockaddr(int err, const char *mesg, VALUE addr, VALUE rai));
|
|
|
|
|
2013-04-05 23:41:01 -04:00
|
|
|
NORETURN(void rsock_sys_fail_host_port(const char *, VALUE, VALUE));
|
|
|
|
NORETURN(void rsock_sys_fail_path(const char *, VALUE));
|
2013-04-06 07:04:45 -04:00
|
|
|
NORETURN(void rsock_sys_fail_sockaddr(const char *, struct sockaddr *addr, socklen_t len));
|
2013-04-06 07:21:05 -04:00
|
|
|
NORETURN(void rsock_sys_fail_raddrinfo(const char *, VALUE rai));
|
|
|
|
NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VALUE rai));
|
2013-04-05 22:39:44 -04:00
|
|
|
|
2014-01-18 09:13:22 -05:00
|
|
|
/*
|
|
|
|
* It is safe on Linux to attempt using a socket without waiting on it in
|
|
|
|
* all cases. For some syscalls (e.g. accept/accept4), blocking on the
|
|
|
|
* syscall instead of relying on select/poll allows the kernel to use
|
|
|
|
* "wake-one" behavior and avoid the thundering herd problem.
|
2018-11-10 19:46:31 -05:00
|
|
|
* This is likely safe on all other *nix-like systems, so this safe list
|
2014-01-18 09:13:22 -05:00
|
|
|
* can be expanded by interested parties.
|
|
|
|
*/
|
|
|
|
#if defined(__linux__)
|
|
|
|
static inline int rsock_maybe_fd_writable(int fd) { return 1; }
|
|
|
|
static inline void rsock_maybe_wait_fd(int fd) { }
|
2015-05-28 22:24:18 -04:00
|
|
|
# ifdef MSG_DONTWAIT
|
|
|
|
# define MSG_DONTWAIT_RELIABLE 1
|
|
|
|
# endif
|
2014-01-18 09:13:22 -05:00
|
|
|
#else /* some systems (mswin/mingw) need these. ref: r36946 */
|
|
|
|
# define rsock_maybe_fd_writable(fd) rb_thread_fd_writable((fd))
|
|
|
|
# define rsock_maybe_wait_fd(fd) rb_thread_wait_fd((fd))
|
|
|
|
#endif
|
|
|
|
|
2015-05-28 22:24:18 -04:00
|
|
|
/*
|
|
|
|
* some OSes may support MSG_DONTWAIT inconsistently depending on socket
|
|
|
|
* type, we only expect Linux to support it consistently for all socket types.
|
|
|
|
*/
|
|
|
|
#ifndef MSG_DONTWAIT_RELIABLE
|
|
|
|
# define MSG_DONTWAIT_RELIABLE 0
|
|
|
|
#endif
|
|
|
|
|
2017-10-27 19:26:48 -04:00
|
|
|
VALUE rsock_read_nonblock(VALUE sock, VALUE length, VALUE buf, VALUE ex);
|
|
|
|
VALUE rsock_write_nonblock(VALUE sock, VALUE buf, VALUE ex);
|
|
|
|
|
2018-11-22 03:46:51 -05:00
|
|
|
void rsock_make_fd_nonblock(int fd);
|
|
|
|
|
2016-08-01 23:37:02 -04:00
|
|
|
#if !defined HAVE_INET_NTOP && ! defined _WIN32
|
|
|
|
const char *inet_ntop(int, const void *, char *, size_t);
|
|
|
|
#elif defined __MINGW32__
|
|
|
|
# define inet_ntop(f,a,n,l) rb_w32_inet_ntop(f,a,n,l)
|
|
|
|
#elif defined _MSC_VER && RUBY_MSVCRT_VERSION < 90
|
|
|
|
const char *WSAAPI inet_ntop(int, const void *, char *, size_t);
|
|
|
|
#endif
|
|
|
|
|
2009-01-16 23:11:27 -05:00
|
|
|
#endif
|