1#ifndef RUBY_SOCKET_H
2#define RUBY_SOCKET_H 1
3
4#include "ruby/ruby.h"
5#include "ruby/io.h"
6#include "ruby/thread.h"
7#include "ruby/util.h"
8#include "internal.h"
9#include <stdio.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12
13#ifdef HAVE_UNISTD_H
14#include <unistd.h>
15#endif
16
17#ifdef HAVE_SYS_UIO_H
18#include <sys/uio.h>
19#endif
20
21#ifdef HAVE_XTI_H
22#include <xti.h>
23#endif
24
25#ifndef _WIN32
26#if defined(__BEOS__) && !defined(__HAIKU__) && !defined(BONE)
27# include <net/socket.h>
28#else
29# include <sys/socket.h>
30#endif
31#include <netinet/in.h>
32#ifdef HAVE_NETINET_IN_SYSTM_H
33# include <netinet/in_systm.h>
34#endif
35#ifdef HAVE_NETINET_TCP_H
36# include <netinet/tcp.h>
37#endif
38#ifdef HAVE_NETINET_UDP_H
39# include <netinet/udp.h>
40#endif
41#ifdef HAVE_ARPA_INET_H
42# include <arpa/inet.h>
43#endif
44#include <netdb.h>
45#endif
46#include <errno.h>
47#ifdef HAVE_SYS_UN_H
48#include <sys/un.h>
49#endif
50
51#if defined(HAVE_FCNTL)
52#ifdef HAVE_SYS_SELECT_H
53#include <sys/select.h>
54#endif
55#ifdef HAVE_SYS_TYPES_H
56#include <sys/types.h>
57#endif
58#ifdef HAVE_SYS_TIME_H
59#include <sys/time.h>
60#endif
61#ifdef HAVE_FCNTL_H
62#include <fcntl.h>
63#endif
64#endif
65
66#ifdef HAVE_IFADDRS_H
67#include <ifaddrs.h>
68#endif
69#ifdef HAVE_SYS_IOCTL_H
70#include <sys/ioctl.h>
71#endif
72#ifdef HAVE_SYS_SOCKIO_H
73#include <sys/sockio.h>
74#endif
75#ifdef HAVE_NET_IF_H
76#include <net/if.h>
77#endif
78
79#ifdef HAVE_SYS_PARAM_H
80#include <sys/param.h>
81#endif
82#ifdef HAVE_SYS_UCRED_H
83#include <sys/ucred.h>
84#endif
85#ifdef HAVE_UCRED_H
86#include <ucred.h>
87#endif
88
89#ifndef EWOULDBLOCK
90#define EWOULDBLOCK EAGAIN
91#endif
92
93/*
94 * workaround for NetBSD, OpenBSD and etc.
95 * The problem is since 4.4BSD-Lite.
96 * FreeBSD fix the problem at FreeBSD 2.2.0.
97 * NetBSD fix the problem at NetBSD 3.0 by kern/29624.
98 * OpenBSD fix the problem at OpenBSD 3.8.
99 */
100#define pseudo_AF_FTIP pseudo_AF_RTIP
101
102#ifndef HAVE_GETADDRINFO
103#include "addrinfo.h"
104#endif
105#include "sockport.h"
106
107#ifndef NI_MAXHOST
108# define NI_MAXHOST 1025
109#endif
110#ifndef NI_MAXSERV
111# define NI_MAXSERV 32
112#endif
113
114#ifdef AF_INET6
115# define IS_IP_FAMILY(af) ((af) == AF_INET || (af) == AF_INET6)
116#else
117# define IS_IP_FAMILY(af) ((af) == AF_INET)
118#endif
119
120#ifndef IN6_IS_ADDR_UNIQUE_LOCAL
121# define IN6_IS_ADDR_UNIQUE_LOCAL(a) (((a)->s6_addr[0] == 0xfc) || ((a)->s6_addr[0] == 0xfd))
122#endif
123
124#ifndef HAVE_SOCKADDR_STORAGE
125/*
126 * RFC 2553: protocol-independent placeholder for socket addresses
127 */
128#define _SS_MAXSIZE     128
129#define _SS_ALIGNSIZE   (sizeof(double))
130#define _SS_PAD1SIZE    (_SS_ALIGNSIZE - sizeof(unsigned char) * 2)
131#define _SS_PAD2SIZE    (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \
132                                _SS_PAD1SIZE - _SS_ALIGNSIZE)
133
134struct sockaddr_storage {
135#ifdef HAVE_SA_LEN
136        unsigned char ss_len;           /* address length */
137        unsigned char ss_family;        /* address family */
138#else
139        unsigned short ss_family;
140#endif
141        char    __ss_pad1[_SS_PAD1SIZE];
142        double  __ss_align;     /* force desired structure storage alignment */
143        char    __ss_pad2[_SS_PAD2SIZE];
144};
145#endif
146
147#ifdef __APPLE__
148/*
149 * CMSG_ macros are broken on 64bit darwin, because __DARWIN_ALIGN
150 * aligns up to __darwin_size_t which is 64bit, but CMSG_DATA is
151 * 32bit-aligned.
152 */
153#undef __DARWIN_ALIGNBYTES
154#define __DARWIN_ALIGNBYTES (sizeof(unsigned int) - 1)
155#endif
156
157#if defined(_AIX)
158#ifndef CMSG_SPACE
159# define CMSG_SPACE(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + _CMSG_ALIGN(len))
160#endif
161#ifndef CMSG_LEN
162# define CMSG_LEN(len) (_CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
163#endif
164#endif
165
166#ifdef __BEOS__
167#undef close
168#define close closesocket
169#endif
170
171#define INET_CLIENT 0
172#define INET_SERVER 1
173#define INET_SOCKS  2
174
175extern int rsock_do_not_reverse_lookup;
176#define FMODE_NOREVLOOKUP 0x100
177
178extern VALUE rb_cBasicSocket;
179extern VALUE rb_cIPSocket;
180extern VALUE rb_cTCPSocket;
181extern VALUE rb_cTCPServer;
182extern VALUE rb_cUDPSocket;
183#ifdef HAVE_SYS_UN_H
184extern VALUE rb_cUNIXSocket;
185extern VALUE rb_cUNIXServer;
186#endif
187extern VALUE rb_cSocket;
188extern VALUE rb_cAddrinfo;
189extern VALUE rb_cSockOpt;
190
191extern VALUE rb_eSocket;
192
193#ifdef SOCKS
194extern VALUE rb_cSOCKSSocket;
195#ifdef SOCKS5
196#include <socks.h>
197#else
198void SOCKSinit();
199int Rconnect();
200#endif
201#endif
202
203#include "constdefs.h"
204
205#define BLOCKING_REGION(func, arg) (long)rb_thread_blocking_region((func), (arg), RUBY_UBF_IO, 0)
206#define BLOCKING_REGION_FD(func, arg) (long)rb_thread_io_blocking_region((func), (arg), (arg)->fd)
207
208#define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v))
209#define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v))
210VALUE rsock_sockaddr_string_value(volatile VALUE *);
211char *rsock_sockaddr_string_value_ptr(volatile VALUE *);
212VALUE rb_check_sockaddr_string_type(VALUE);
213
214NORETURN(void rsock_raise_socket_error(const char *, int));
215
216int rsock_family_arg(VALUE domain);
217int rsock_socktype_arg(VALUE type);
218int rsock_level_arg(int family, VALUE level);
219int rsock_optname_arg(int family, int level, VALUE optname);
220int rsock_cmsg_type_arg(int family, int level, VALUE type);
221int rsock_shutdown_how_arg(VALUE how);
222
223int rsock_getfamily(int sockfd);
224
225int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
226int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
227struct addrinfo *rsock_addrinfo(VALUE host, VALUE port, int socktype, int flags);
228struct addrinfo *rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack);
229VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
230VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
231
232VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname);
233
234VALUE rsock_make_ipaddr(struct sockaddr *addr);
235VALUE rsock_ipaddr(struct sockaddr *sockaddr, int norevlookup);
236VALUE rsock_make_hostent(VALUE host, struct addrinfo *addr, VALUE (*ipaddr)(struct sockaddr *, size_t));
237
238int rsock_revlookup_flag(VALUE revlookup, int *norevlookup);
239
240#ifdef HAVE_SYS_UN_H
241VALUE rsock_unixpath_str(struct sockaddr_un *sockaddr, socklen_t len);
242VALUE rsock_unixaddr(struct sockaddr_un *sockaddr, socklen_t len);
243socklen_t rsock_unix_sockaddr_len(VALUE path);
244#endif
245
246int rsock_socket(int domain, int type, int proto);
247VALUE rsock_init_sock(VALUE sock, int fd);
248VALUE rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass);
249VALUE rsock_init_inetsock(VALUE sock, VALUE remote_host, VALUE remote_serv, VALUE local_host, VALUE local_serv, int type);
250VALUE rsock_init_unixsock(VALUE sock, VALUE path, int server);
251
252struct rsock_send_arg {
253    int fd, flags;
254    VALUE mesg;
255    struct sockaddr *to;
256    socklen_t tolen;
257};
258
259VALUE rsock_sendto_blocking(void *data);
260VALUE rsock_send_blocking(void *data);
261VALUE rsock_bsock_send(int argc, VALUE *argv, VALUE sock);
262
263enum sock_recv_type {
264    RECV_RECV,                  /* BasicSocket#recv(no from) */
265    RECV_IP,                    /* IPSocket#recvfrom */
266    RECV_UNIX,                  /* UNIXSocket#recvfrom */
267    RECV_SOCKET                 /* Socket#recvfrom */
268};
269
270VALUE rsock_s_recvfrom_nonblock(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
271VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from);
272
273int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks);
274
275VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
276VALUE rsock_s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
277VALUE rsock_sock_listen(VALUE sock, VALUE log);
278
279VALUE rsock_sockopt_new(int family, int level, int optname, VALUE data);
280
281#if defined(HAVE_SENDMSG)
282VALUE rsock_bsock_sendmsg(int argc, VALUE *argv, VALUE sock);
283VALUE rsock_bsock_sendmsg_nonblock(int argc, VALUE *argv, VALUE sock);
284#else
285#define rsock_bsock_sendmsg rb_f_notimplement
286#define rsock_bsock_sendmsg_nonblock rb_f_notimplement
287#endif
288#if defined(HAVE_RECVMSG)
289VALUE rsock_bsock_recvmsg(int argc, VALUE *argv, VALUE sock);
290VALUE rsock_bsock_recvmsg_nonblock(int argc, VALUE *argv, VALUE sock);
291ssize_t rsock_recvmsg(int socket, struct msghdr *message, int flags);
292#else
293#define rsock_bsock_recvmsg rb_f_notimplement
294#define rsock_bsock_recvmsg_nonblock rb_f_notimplement
295#endif
296
297#ifdef HAVE_ST_MSG_CONTROL
298void rsock_discard_cmsg_resource(struct msghdr *mh, int msg_peek_p);
299#endif
300
301void rsock_init_basicsocket(void);
302void rsock_init_ipsocket(void);
303void rsock_init_tcpsocket(void);
304void rsock_init_tcpserver(void);
305void rsock_init_sockssocket(void);
306void rsock_init_udpsocket(void);
307void rsock_init_unixsocket(void);
308void rsock_init_unixserver(void);
309void rsock_init_socket_constants(void);
310void rsock_init_ancdata(void);
311void rsock_init_addrinfo(void);
312void rsock_init_sockopt(void);
313void rsock_init_socket_init(void);
314
315#endif
316