diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/ext/socket/rubysocket.h |
Fresh start
Diffstat (limited to 'jni/ruby/ext/socket/rubysocket.h')
-rw-r--r-- | jni/ruby/ext/socket/rubysocket.h | 415 |
1 files changed, 415 insertions, 0 deletions
diff --git a/jni/ruby/ext/socket/rubysocket.h b/jni/ruby/ext/socket/rubysocket.h new file mode 100644 index 0000000..8beffd2 --- /dev/null +++ b/jni/ruby/ext/socket/rubysocket.h @@ -0,0 +1,415 @@ +#ifndef RUBY_SOCKET_H +#define RUBY_SOCKET_H 1 + +#include "ruby/ruby.h" +#include "ruby/io.h" +#include "ruby/thread.h" +#include "ruby/util.h" +#include "internal.h" +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +#ifdef HAVE_SYS_UIO_H +# include <sys/uio.h> +#endif + +#ifdef HAVE_XTI_H +# include <xti.h> +#endif + +#ifdef _WIN32 +# if defined(_MSC_VER) +# undef HAVE_TYPE_STRUCT_SOCKADDR_DL +# endif +#else +# if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE) +# include <net/socket.h> +# else +# include <sys/socket.h> +# endif +# 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 +# ifdef HAVE_NETINET_TCP_FSM_H +# include <netinet/tcp_fsm.h> +# endif +# ifdef HAVE_NETINET_UDP_H +# include <netinet/udp.h> +# endif +# ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +# endif +# include <netdb.h> +#endif + +#ifdef HAVE_NETPACKET_PACKET_H +# include <netpacket/packet.h> +#endif +#ifdef HAVE_NET_ETHERNET_H +# include <net/ethernet.h> +#endif + +#include <errno.h> + +#ifdef HAVE_SYS_UN_H +# include <sys/un.h> +#endif + +#if defined(HAVE_FCNTL) +# 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 +#endif + +#ifdef HAVE_IFADDRS_H +# include <ifaddrs.h> +#endif +#ifdef HAVE_SYS_IOCTL_H +# include <sys/ioctl.h> +#endif +#ifdef HAVE_SYS_SOCKIO_H +# include <sys/sockio.h> +#endif +#ifdef HAVE_NET_IF_H +# include <net/if.h> +#endif + +#ifdef HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif +#ifdef HAVE_SYS_UCRED_H +# include <sys/ucred.h> +#endif +#ifdef HAVE_UCRED_H +# include <ucred.h> +#endif +#ifdef HAVE_NET_IF_DL_H +# include <net/if_dl.h> +#endif + +#ifndef HAVE_TYPE_SOCKLEN_T +typedef int socklen_t; +#endif + +#ifdef NEED_IF_INDEXTONAME_DECL +char *if_indextoname(unsigned int, char *); +#endif +#ifdef NEED_IF_NAMETOINDEX_DECL +unsigned int if_nametoindex(const char *); +#endif + +#define SOCKLEN_MAX \ + (0 < (socklen_t)-1 ? \ + ~(socklen_t)0 : \ + (((((socklen_t)1) << (sizeof(socklen_t) * CHAR_BIT - 2)) - 1) * 2 + 1)) + +#ifndef RSTRING_SOCKLEN +# define RSTRING_SOCKLEN (socklen_t)RSTRING_LENINT +#endif + +#ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN +#endif + +/* + * 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 + +#ifndef HAVE_GETADDRINFO +# include "addrinfo.h" +#endif + +#include "sockport.h" + +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +#ifdef AF_INET6 +# define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6) +#else +# define IS_IP_FAMILY(af) ((af) == AF_INET) +#endif + +#ifndef IN6_IS_ADDR_UNIQUE_LOCAL +# define IN6_IS_ADDR_UNIQUE_LOCAL(a) (((a)->s6_addr[0] == 0xfc) || ((a)->s6_addr[0] == 0xfd)) +#endif + +#ifndef HAVE_TYPE_STRUCT_SOCKADDR_STORAGE +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +# 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 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { +# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + unsigned char ss_len; /* address length */ + unsigned char ss_family; /* address family */ +# else + unsigned short ss_family; +# endif + char __ss_pad1[_SS_PAD1SIZE]; + double __ss_align; /* force desired structure storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif + +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; +#endif +#ifdef HAVE_TYPE_STRUCT_SOCKADDR_DL + struct sockaddr_dl dl; /* AF_LINK */ +#endif + struct sockaddr_storage storage; + char place_holder[2048]; /* sockaddr_storage is not enough for Unix domain sockets on SunOS and Darwin. */ +} union_sockaddr; + +#ifdef __APPLE__ +/* + * 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. + */ +# undef __DARWIN_ALIGNBYTES +# define __DARWIN_ALIGNBYTES (sizeof(unsigned int) - 1) +#endif + +#if defined(_AIX) +# 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 +#endif + +#ifdef __BEOS__ +# undef close +# define close closesocket +#endif + +#define INET_CLIENT 0 +#define INET_SERVER 1 +#define INET_SOCKS 2 + +extern int rsock_do_not_reverse_lookup; +extern int rsock_cmsg_cloexec_state; +#define FMODE_NOREVLOOKUP 0x100 + +extern VALUE rb_cBasicSocket; +extern VALUE rb_cIPSocket; +extern VALUE rb_cTCPSocket; +extern VALUE rb_cTCPServer; +extern VALUE rb_cUDPSocket; +#ifdef HAVE_SYS_UN_H +extern VALUE rb_cUNIXSocket; +extern VALUE rb_cUNIXServer; +#endif +extern VALUE rb_cSocket; +extern VALUE rb_cAddrinfo; +extern VALUE rb_cSockOpt; + +extern VALUE rb_eSocket; + +#ifdef SOCKS +extern VALUE rb_cSOCKSSocket; +# ifdef SOCKS5 +# include <socks.h> +# else +void SOCKSinit(); +int Rconnect(); +# endif +#endif + +#include "constdefs.h" + +#define BLOCKING_REGION_FD(func, arg) (long)rb_thread_io_blocking_region((func), (arg), (arg)->fd) + +#define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v)) +#define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v)) +#define SockAddrStringValueWithAddrinfo(v, rai_ret) rsock_sockaddr_string_value_with_addrinfo(&(v), &(rai_ret)) +VALUE rsock_sockaddr_string_value(volatile VALUE *); +char *rsock_sockaddr_string_value_ptr(volatile VALUE *); +VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret); + +VALUE rb_check_sockaddr_string_type(VALUE); + +NORETURN(void rsock_raise_socket_error(const char *, int)); + +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); + +int rsock_getfamily(int sockfd); + +struct rb_addrinfo { + struct addrinfo *ai; + int allocated_by_malloc; +}; +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); +int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags); +struct rb_addrinfo *rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags); +struct rb_addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack); +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); + +VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname); +VALUE rsock_addrinfo_inspect_sockaddr(VALUE rai); + +VALUE rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen); +VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup); +VALUE rsock_make_hostent(VALUE host, struct rb_addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, socklen_t)); +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); + +int rsock_revlookup_flag(VALUE revlookup, int *norevlookup); + +#ifdef HAVE_SYS_UN_H +VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len); +VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len); +socklen_t rsock_unix_sockaddr_len(VALUE path); +#endif + +int rsock_socket(int domain, int type, int proto); +int rsock_detect_cloexec(int fd); +VALUE rsock_init_sock(VALUE sock, int fd); +VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass); +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); + +struct rsock_send_arg { + int fd, flags; + VALUE mesg; + struct sockaddr *to; + socklen_t tolen; +}; + +VALUE rsock_sendto_blocking(void *data); +VALUE rsock_send_blocking(void *data); +VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock); + +enum sock_recv_type { + RECV_RECV, /* BasicSocket#recv(no from) */ + RECV_IP, /* IPSocket#recvfrom */ + RECV_UNIX, /* UNIXSocket#recvfrom */ + RECV_SOCKET /* Socket#recvfrom */ +}; + +VALUE rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from); +VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from); + +int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks); + +VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len); +VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len); +VALUE rsock_sock_listen(VALUE sock, VALUE log); + +VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data); + +#if defined(HAVE_SENDMSG) +VALUE rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock); +#else +#define rsock_bsock_sendmsg rb_f_notimplement +#define rsock_bsock_sendmsg_nonblock rb_f_notimplement +#endif + +#if defined(HAVE_RECVMSG) +VALUE rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock); +VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock); +ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags); +#else +#define rsock_bsock_recvmsg rb_f_notimplement +#define rsock_bsock_recvmsg_nonblock rb_f_notimplement +#endif + +#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL +void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p); +#endif + +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); +void rsock_init_sockifaddr(void); +void rsock_init_socket_init(void); + +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)); + +NORETURN(void rsock_sys_fail_host_port(const char *, VALUE, VALUE)); +NORETURN(void rsock_sys_fail_path(const char *, VALUE)); +NORETURN(void rsock_sys_fail_sockaddr(const char *, struct sockaddr *addr, socklen_t len)); +NORETURN(void rsock_sys_fail_raddrinfo(const char *, VALUE rai)); +NORETURN(void rsock_sys_fail_raddrinfo_or_sockaddr(const char *, VALUE addr, VALUE rai)); + +/* + * 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. + * This is likely safe on all other *nix-like systems, so this whitelist + * 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) { } +#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 + +#endif |