13static VALUE sym_wait_writable;
143 setup_domain_and_type(domain, &d,
type, &
t);
150#if defined HAVE_SOCKETPAIR
152io_call_close(
VALUE io)
160 return rb_rescue(io_call_close, io, 0, 0);
164pair_yield(
VALUE pair)
170#if defined HAVE_SOCKETPAIR
172rsock_socketpair0(
int domain,
int type,
int protocol,
int descriptors[2])
175 type |= SOCK_CLOEXEC;
179 type |= SOCK_NONBLOCK;
201rsock_socketpair(
int domain,
int type,
int protocol,
int descriptors[2])
205 result = rsock_socketpair0(domain,
type, protocol, descriptors);
208 result = rsock_socketpair0(domain,
type, protocol, descriptors);
255 setup_domain_and_type(domain, &d,
type, &
t);
257 ret = rsock_socketpair(d,
t, p, sp);
266 return rb_ensure(pair_yield, r, io_close, s1);
271#define rsock_sock_s_socketpair rb_f_notimplement
421 return sym_wait_writable;
614 if (listen(fptr->
fd, backlog) < 0)
753sock_accept(
VALUE sock)
773 struct sockaddr *addr = &
buf.addr;
823sock_sysaccept(
VALUE sock)
836#ifdef HAVE_GETHOSTNAME
851#if defined(NI_MAXHOST)
852# define RUBY_MAX_HOST_NAME_LEN NI_MAXHOST
853#elif defined(HOST_NAME_MAX)
854# define RUBY_MAX_HOST_NAME_LEN HOST_NAME_MAX
856# define RUBY_MAX_HOST_NAME_LEN 1024
859 long len = RUBY_MAX_HOST_NAME_LEN;
884#include <sys/utsname.h>
895#define sock_gethostname rb_f_notimplement
900make_addrinfo(
struct rb_addrinfo *res0,
int norevlookup)
909 for (res = res0->
ai; res; res = res->
ai_next) {
927 switch (addr->sa_family) {
929 ptr = (
char*)&((
struct sockaddr_in*)addr)->sin_addr.s_addr;
930 len = (
socklen_t)
sizeof(((
struct sockaddr_in*)addr)->sin_addr.s_addr);
934 ptr = (
char*)&((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr;
935 len = (
socklen_t)
sizeof(((
struct sockaddr_in6*)addr)->sin6_addr.s6_addr);
968 rb_warn(
"Socket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead.");
1008 rb_warn(
"Socket.gethostbyaddr is deprecated; use Addrinfo#getnameinfo instead.");
1012 if (!
NIL_P(family)) {
1022#ifdef HAVE_HSTRERROR
1033 if (h->h_aliases !=
NULL) {
1034 for (pch = h->h_aliases; *pch; pch++) {
1040 for (pch = h->h_addr_list; *pch; pch++) {
1066 VALUE service, proto;
1069 const char *servicename, *protoname =
"tcp";
1076 sp = getservbyname(servicename, protoname);
1078 port = ntohs(sp->s_port);
1083 port =
STRTOUL(servicename, &end, 0);
1110 const char *protoname =
"tcp";
1114 if (portnum != (uint16_t)portnum) {
1115 const char *s = portnum > 0 ?
"big" :
"small";
1120 sp = getservbyport((
int)htons((uint16_t)portnum), protoname);
1165 VALUE host, port, family, socktype, protocol, flags, ret, revlookup;
1170 rb_scan_args(
argc,
argv,
"25", &host, &port, &family, &socktype, &protocol, &flags, &revlookup);
1175 if (!
NIL_P(socktype)) {
1178 if (!
NIL_P(protocol)) {
1179 hints.ai_protocol =
NUM2INT(protocol);
1181 if (!
NIL_P(flags)) {
1182 hints.ai_flags =
NUM2INT(flags);
1190 ret = make_addrinfo(res, norevlookup);
1222 char hbuf[1024], pbuf[1024];
1226 int error, saved_errno;
1228 struct sockaddr *sap;
1235 if (!
NIL_P(flags)) {
1273#ifdef AI_NUMERICHOST
1288 hbuf[
sizeof(hbuf) - 1] =
'\0';
1302 pbuf[
sizeof(pbuf) - 1] =
'\0';
1305 hints.ai_socktype = (fl &
NI_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
1309 if (
error)
goto error_exit_addr;
1319 pbuf,
sizeof(pbuf), fl);
1320 if (
error)
goto error_exit_name;
1323 char hbuf2[1024], pbuf2[1024];
1328 pbuf2,
sizeof(pbuf2), fl);
1329 if (
error)
goto error_exit_name;
1330 if (strcmp(hbuf, hbuf2) != 0|| strcmp(pbuf, pbuf2) != 0) {
1340 saved_errno = errno;
1342 errno = saved_errno;
1346 saved_errno = errno;
1348 errno = saved_errno;
1393sock_s_unpack_sockaddr_in(
VALUE self,
VALUE addr)
1395 struct sockaddr_in * sockaddr;
1400 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1401 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1404 if (((
struct sockaddr *)sockaddr)->sa_family != AF_INET
1406 && ((
struct sockaddr *)sockaddr)->sa_family != AF_INET6
1432sock_s_pack_sockaddr_un(
VALUE self,
VALUE path)
1434 struct sockaddr_un sockaddr;
1438 INIT_SOCKADDR_UN(&sockaddr,
sizeof(
struct sockaddr_un));
1439 if (
sizeof(sockaddr.sun_path) < (
size_t)
RSTRING_LEN(path)) {
1441 (
size_t)
RSTRING_LEN(path),
sizeof(sockaddr.sun_path));
1444 addr =
rb_str_new((
char*)&sockaddr, rsock_unix_sockaddr_len(path));
1462sock_s_unpack_sockaddr_un(
VALUE self,
VALUE addr)
1464 struct sockaddr_un * sockaddr;
1469 (
char*)&((
struct sockaddr *)sockaddr)->sa_family +
1470 sizeof(((
struct sockaddr *)sockaddr)->sa_family) -
1473 if (((
struct sockaddr *)sockaddr)->sa_family != AF_UNIX) {
1476 if (
sizeof(
struct sockaddr_un) < (
size_t)
RSTRING_LEN(addr)) {
1478 RSTRING_LEN(addr), (
int)
sizeof(
struct sockaddr_un));
1485#if defined(HAVE_GETIFADDRS) || defined(SIOCGLIFCONF) || defined(SIOCGIFCONF) || defined(_WIN32)
1488sockaddr_len(
struct sockaddr *addr)
1493#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1494 if (addr->sa_len != 0)
1495 return addr->sa_len;
1498 switch (addr->sa_family) {
1500 return (
socklen_t)
sizeof(
struct sockaddr_in);
1504 return (
socklen_t)
sizeof(
struct sockaddr_in6);
1509 return (
socklen_t)
sizeof(
struct sockaddr_un);
1514 return (
socklen_t)(
offsetof(
struct sockaddr_ll, sll_addr) + ((
struct sockaddr_ll *)addr)->sll_halen);
1518 return (
socklen_t)(
offsetof(
struct sockaddr, sa_family) +
sizeof(addr->sa_family));
1525 return sockaddr_len(addr);
1531#if defined(AF_INET6) && defined(__KAME__)
1532 struct sockaddr_in6 addr6;
1538 len = sockaddr_len(addr);
1540#if defined(__KAME__) && defined(AF_INET6)
1541 if (addr->sa_family == AF_INET6) {
1547 addr = (
struct sockaddr *)&addr6;
1548 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1549 addr6.sin6_scope_id == 0 &&
1550 (addr6.sin6_addr.s6_addr[2] || addr6.sin6_addr.s6_addr[3])) {
1551 addr6.sin6_scope_id = (addr6.sin6_addr.s6_addr[2] << 8) | addr6.sin6_addr.s6_addr[3];
1552 addr6.sin6_addr.s6_addr[2] = 0;
1553 addr6.sin6_addr.s6_addr[3] = 0;
1564 return sockaddr_obj(addr,
len);
1569#if defined(HAVE_GETIFADDRS) || (defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)) || defined(SIOCGIFCONF) || defined(_WIN32)
1588#if defined(HAVE_GETIFADDRS)
1600 for (p = ifp; p; p = p->
ifa_next) {
1602 struct sockaddr *addr = p->
ifa_addr;
1603#if defined(AF_INET6) && defined(__sun)
1609 struct sockaddr_in6 addr6;
1610 if (addr->sa_family == AF_INET6) {
1613 addr = (
struct sockaddr *)&addr6;
1614 if (IN6_IS_ADDR_LINKLOCAL(&addr6.sin6_addr) &&
1615 addr6.sin6_scope_id == 0) {
1616 unsigned int ifindex = if_nametoindex(p->
ifa_name);
1618 addr6.sin6_scope_id = ifindex;
1623 rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
1630#elif defined(SIOCGLIFCONF) && defined(SIOCGLIFNUM) && !defined(__hpux)
1637 const char *reason =
NULL;
1644 fd = socket(AF_INET, SOCK_DGRAM, 0);
1648 memset(&ln, 0,
sizeof(ln));
1651 ret =
ioctl(fd, SIOCGLIFNUM, &ln);
1653 reason =
"SIOCGLIFNUM";
1657 memset(&lc, 0,
sizeof(lc));
1660 lc.lifc_len =
sizeof(
struct lifreq) * ln.lifn_count;
1661 lc.lifc_req =
xmalloc(lc.lifc_len);
1663 ret =
ioctl(fd, SIOCGLIFCONF, &lc);
1665 reason =
"SIOCGLIFCONF";
1670 for (i = 0; i < ln.lifn_count; i++) {
1671 struct lifreq *req = &lc.lifc_req[i];
1673 if (req->lifr_addr.ss_family == AF_INET6 &&
1674 IN6_IS_ADDR_LINKLOCAL(&((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_addr) &&
1675 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id == 0) {
1677 memcpy(req2.lifr_name, req->lifr_name, LIFNAMSIZ);
1678 ret =
ioctl(fd, SIOCGLIFINDEX, &req2);
1680 reason =
"SIOCGLIFINDEX";
1683 ((
struct sockaddr_in6 *)(&req->lifr_addr))->sin6_scope_id = req2.lifr_index;
1685 rb_ary_push(list, sockaddr_obj((
struct sockaddr *)&req->lifr_addr, req->lifr_addrlen));
1691 if (lc.lifc_buf !=
NULL)
1701#elif defined(SIOCGIFCONF)
1704#define EXTRA_SPACE ((int)(sizeof(struct ifconf) + sizeof(union_sockaddr)))
1705 char initbuf[4096+EXTRA_SPACE];
1706 char *
buf = initbuf;
1711 const char *reason =
NULL;
1714 fd = socket(AF_INET, SOCK_DGRAM, 0);
1718 bufsize =
sizeof(initbuf);
1722 conf.ifc_len = bufsize;
1723 conf.ifc_req = (
struct ifreq *)
buf;
1727 ret =
ioctl(fd, SIOCGIFCONF, &conf);
1729 reason =
"SIOCGIFCONF";
1735 if (bufsize - EXTRA_SPACE < conf.ifc_len) {
1736 if (bufsize < conf.ifc_len) {
1738 bufsize = conf.ifc_len + EXTRA_SPACE;
1741 bufsize = bufsize << 1;
1754 while ((
char*)req < (
char*)conf.ifc_req + conf.ifc_len) {
1755 struct sockaddr *addr = &req->ifr_addr;
1757 rb_ary_push(list, sockaddr_obj(addr, sockaddr_len(addr)));
1759#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
1760# ifndef _SIZEOF_ADDR_IFREQ
1761# define _SIZEOF_ADDR_IFREQ(r) \
1762 (sizeof(struct ifreq) + \
1763 (sizeof(struct sockaddr) < (r).ifr_addr.sa_len ? \
1764 (r).ifr_addr.sa_len - sizeof(struct sockaddr) : \
1767 req = (
struct ifreq *)((
char*)req + _SIZEOF_ADDR_IFREQ(*req));
1769 req = (
struct ifreq *)((
char*)req +
sizeof(
struct ifreq));
1787#elif defined(_WIN32)
1788 typedef struct ip_adapter_unicast_address_st {
1789 unsigned LONG_LONG dummy0;
1790 struct ip_adapter_unicast_address_st *
Next;
1792 struct sockaddr *lpSockaddr;
1793 int iSockaddrLength;
1801 } ip_adapter_unicast_address_t;
1802 typedef struct ip_adapter_anycast_address_st {
1803 unsigned LONG_LONG dummy0;
1804 struct ip_adapter_anycast_address_st *
Next;
1806 struct sockaddr *lpSockaddr;
1807 int iSockaddrLength;
1809 } ip_adapter_anycast_address_t;
1810 typedef struct ip_adapter_addresses_st {
1811 unsigned LONG_LONG dummy0;
1812 struct ip_adapter_addresses_st *
Next;
1814 ip_adapter_unicast_address_t *FirstUnicastAddress;
1815 ip_adapter_anycast_address_t *FirstAnycastAddress;
1830 } ip_adapter_addresses_t;
1831 typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG, ULONG, PVOID, ip_adapter_addresses_t *, PULONG);
1833 GetAdaptersAddresses_t pGetAdaptersAddresses;
1836 ip_adapter_addresses_t *adapters;
1839 h = LoadLibrary(
"iphlpapi.dll");
1842 pGetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(h,
"GetAdaptersAddresses");
1843 if (!pGetAdaptersAddresses) {
1849 if (ret != ERROR_SUCCESS && ret != ERROR_BUFFER_OVERFLOW) {
1854 adapters = (ip_adapter_addresses_t *)
ALLOCA_N(BYTE,
len);
1856 if (ret != ERROR_SUCCESS) {
1863 for (; adapters; adapters = adapters->Next) {
1864 ip_adapter_unicast_address_t *uni;
1865 ip_adapter_anycast_address_t *any;
1866 if (adapters->OperStatus != 1)
1868 for (uni = adapters->FirstUnicastAddress; uni; uni = uni->Next) {
1870 if (uni->Address.lpSockaddr->sa_family == AF_INET)
1874 rb_ary_push(list, sockaddr_obj(uni->Address.lpSockaddr, uni->Address.iSockaddrLength));
1876 for (any = adapters->FirstAnycastAddress; any; any = any->Next) {
1878 if (any->Address.lpSockaddr->sa_family == AF_INET)
1882 rb_ary_push(list, sockaddr_obj(any->Address.lpSockaddr, any->Address.iSockaddrLength));
1891#define socket_s_ip_address_list rb_f_notimplement
2027 "__connect_nonblock", sock_connect_nonblock, 2);
2035 "__accept_nonblock", sock_accept_nonblock, 1);
2043 "__recvfrom_nonblock", sock_recvfrom_nonblock, 4);
#define offsetof(p_type, field)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rb_check_array_type(VALUE ary)
VALUE rb_ary_entry(VALUE ary, long offset)
VALUE rb_assoc_new(VALUE car, VALUE cdr)
#define UNREACHABLE_RETURN
void rsock_init_basicsocket(void)
int rsock_family_arg(VALUE domain)
int rsock_socktype_arg(VALUE type)
#define rb_define_method(klass, mid, func, arity)
Defines klass#mid.
#define rb_define_singleton_method(klass, mid, func, arity)
Defines klass.mid.
#define rb_define_private_method(klass, mid, func, arity)
Defines klass#mid and makes it private.
char str[HTML_ESCAPE_MAX_LEN+1]
#define RSTRING_LEN(string)
#define RSTRING_PTR(string)
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
void rb_notimplement(void)
void rb_syserr_fail(int e, const char *mesg)
void rb_raise(VALUE exc, const char *fmt,...)
void rb_syserr_fail_str(int e, VALUE mesg)
void rb_warn(const char *fmt,...)
VALUE rb_rescue(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*r_proc)(VALUE, VALUE), VALUE data2)
An equivalent of rescue clause.
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
void rb_sys_fail(const char *mesg)
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
void rb_readwrite_syserr_fail(enum rb_io_wait_readwrite, int, const char *)
#define RB_IO_WAIT_WRITABLE
void rb_fd_fix_cloexec(int fd)
void rb_ext_ractor_safe(bool flag)
VALUE rb_str_resize(VALUE, long)
#define rb_str_new(str, len)
void rb_str_modify_expand(VALUE, long)
ID rb_intern(const char *)
void rb_io_set_nonblock(rb_io_t *fptr)
void rsock_raise_socket_error(const char *reason, int error)
void rsock_make_fd_nonblock(int fd)
VALUE rsock_s_recvfrom_nonblock(VALUE sock, VALUE len, VALUE flg, VALUE str, VALUE ex, enum sock_recv_type from)
VALUE rsock_s_accept_nonblock(VALUE klass, VALUE ex, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len)
VALUE rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
int rsock_socket(int domain, int type, int proto)
VALUE rsock_init_sock(VALUE sock, int fd)
int rsock_do_not_reverse_lookup
VALUE rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from)
void rsock_init_socket_init(void)
int rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks, struct timeval *timeout)
int rb_gc_for_fd(int err)
int rsock_revlookup_flag(VALUE revlookup, int *norevlookup)
#define ALLOCA_N(type, n)
#define MEMZERO(p, type, n)
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define RARRAY_AREF(a, i)
void rb_freeaddrinfo(struct rb_addrinfo *ai)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
struct rb_addrinfo * rsock_getaddrinfo(VALUE host, VALUE port, struct addrinfo *hints, int socktype_hack)
VALUE rsock_make_hostent(VALUE host, struct rb_addrinfo *addr, VALUE(*ipaddr)(struct sockaddr *, socklen_t))
VALUE rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen)
VALUE rsock_addrinfo_inspect_sockaddr(VALUE self)
VALUE rb_check_sockaddr_string_type(VALUE val)
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct rb_addrinfo **res)
struct rb_addrinfo * rsock_addrinfo(VALUE host, VALUE port, int family, int socktype, int flags)
VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup)
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
#define StringValueCStr(v)
#define SockAddrStringValueWithAddrinfo(v, rai_ret)
#define SockAddrStringValuePtr(v)
VALUE rsock_sockaddr_obj(struct sockaddr *addr, socklen_t len)
socklen_t rsock_sockaddr_len(struct sockaddr *addr)
#define rsock_sock_s_socketpair
void rsock_sys_fail_raddrinfo_or_sockaddr(const char *mesg, VALUE addr, VALUE rai)
void rsock_sys_fail_host_port(const char *mesg, VALUE host, VALUE port)
void rsock_sys_fail_raddrinfo(const char *mesg, VALUE rai)
void rsock_syserr_fail_host_port(int err, const char *mesg, VALUE host, VALUE port)
void rsock_syserr_fail_sockaddr(int err, const char *mesg, struct sockaddr *addr, socklen_t len)
void rsock_sys_fail_path(const char *mesg, VALUE path)
void rsock_syserr_fail_path(int err, const char *mesg, VALUE path)
#define socket_s_ip_address_list
void rsock_syserr_fail_raddrinfo(int err, const char *mesg, VALUE rai)
void rsock_sys_fail_sockaddr(const char *mesg, struct sockaddr *addr, socklen_t len)
void rsock_syserr_fail_raddrinfo_or_sockaddr(int err, const char *mesg, VALUE addr, VALUE rai)
VALUE rsock_sock_listen(VALUE sock, VALUE log)
#define VALIDATE_SOCKLEN(addr, len)
VALUE rb_sprintf(const char *,...)
size_t strlen(const char *)
struct sockaddr * ai_addr
struct addrinfo * ai_next
struct sockaddr * ifa_addr
struct ifaddrs * ifa_next
void error(const char *msg)
int rb_w32_map_errno(DWORD)
void freeifaddrs(struct ifaddrs *)
int socketpair(int, int, int, int *)
int getifaddrs(struct ifaddrs **)