5 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
6 static VALUE rb_cAncillaryData;
11 ID name = intern_const(constant);
20 ip_cmsg_type_to_sym(
int level,
int cmsg_type)
87 ancdata_new(
int family,
int level,
int type,
VALUE data)
96 ancillary_family(
VALUE self)
112 ancillary_family_m(
VALUE self)
114 return INT2NUM(ancillary_family(
self));
118 ancillary_level(
VALUE self)
134 ancillary_level_m(
VALUE self)
136 return INT2NUM(ancillary_level(
self));
140 ancillary_type(
VALUE self)
156 ancillary_type_m(
VALUE self)
158 return INT2NUM(ancillary_type(
self));
171 ancillary_data(
VALUE self)
196 for (i = 0 ; i <
argc; i++) {
206 for (i = 0 ; i <
argc; i++) {
215 result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS, str);
220 #define ancillary_s_unix_rights rb_f_notimplement
255 ancillary_unix_rights(
VALUE self)
259 level = ancillary_level(
self);
260 type = ancillary_type(
self);
262 if (level != SOL_SOCKET || type != SCM_RIGHTS)
268 #define ancillary_unix_rights rb_f_notimplement
271 #if defined(SCM_TIMESTAMP) || defined(SCM_TIMESTAMPNS) || defined(SCM_BINTIME)
298 ancillary_timestamp(
VALUE self)
304 level = ancillary_level(
self);
305 type = ancillary_type(
self);
306 data = ancillary_data(
self);
308 # ifdef SCM_TIMESTAMP
309 if (level == SOL_SOCKET && type == SCM_TIMESTAMP &&
317 # ifdef SCM_TIMESTAMPNS
318 if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS &&
326 #define add(x,y) (rb_funcall((x), '+', 1, (y)))
327 #define mul(x,y) (rb_funcall((x), '*', 1, (y)))
328 #define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))
331 if (level == SOL_SOCKET && type == SCM_BINTIME &&
336 d = ULL2NUM(0x100000000ULL);
338 timev =
add(TIMET2NUM(bt.sec),
quo(ULL2NUM(bt.frac), d));
349 #define ancillary_timestamp rb_f_notimplement
370 return ancdata_new(family, level, type,
rb_str_new((
char*)&i,
sizeof(i)));
385 ancillary_int(
VALUE self)
389 data = ancillary_data(
self);
396 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
418 ancillary_s_ip_pktinfo(
int argc,
VALUE *argv,
VALUE self)
420 VALUE v_addr, v_ifindex, v_spec_dst;
421 unsigned int ifindex;
422 struct sockaddr_in sa;
423 struct in_pktinfo pktinfo;
425 rb_scan_args(argc, argv,
"21", &v_addr, &v_ifindex, &v_spec_dst);
429 if (
NIL_P(v_spec_dst))
434 memset(&pktinfo, 0,
sizeof(pktinfo));
436 memset(&sa, 0,
sizeof(sa));
440 if (sa.sin_family != AF_INET)
442 memcpy(&pktinfo.ipi_addr, &sa.sin_addr,
sizeof(pktinfo.ipi_addr));
444 pktinfo.ipi_ifindex = ifindex;
446 memset(&sa, 0,
sizeof(sa));
450 if (sa.sin_family != AF_INET)
452 memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr,
sizeof(pktinfo.ipi_spec_dst));
454 return ancdata_new(AF_INET, IPPROTO_IP, IP_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
457 #define ancillary_s_ip_pktinfo rb_f_notimplement
460 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
481 ancillary_ip_pktinfo(
VALUE self)
485 struct in_pktinfo pktinfo;
486 struct sockaddr_in sa;
487 VALUE v_spec_dst, v_addr;
489 level = ancillary_level(
self);
490 type = ancillary_type(
self);
491 data = ancillary_data(
self);
493 if (level != IPPROTO_IP || type != IP_PKTINFO ||
499 memset(&sa, 0,
sizeof(sa));
501 sa.sin_family = AF_INET;
502 memcpy(&sa.sin_addr, &pktinfo.ipi_addr,
sizeof(sa.sin_addr));
505 sa.sin_family = AF_INET;
506 memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst,
sizeof(sa.sin_addr));
512 #define ancillary_ip_pktinfo rb_f_notimplement
515 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
533 unsigned int ifindex;
534 struct sockaddr_in6 sa;
535 struct in6_pktinfo pktinfo;
540 memset(&pktinfo, 0,
sizeof(pktinfo));
542 memset(&sa, 0,
sizeof(sa));
546 if (sa.sin6_family != AF_INET6)
548 memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr,
sizeof(pktinfo.ipi6_addr));
550 pktinfo.ipi6_ifindex = ifindex;
552 return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
555 #define ancillary_s_ipv6_pktinfo rb_f_notimplement
558 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
560 extract_ipv6_pktinfo(
VALUE self,
struct in6_pktinfo *pktinfo_ptr,
struct sockaddr_in6 *sa_ptr)
565 level = ancillary_level(
self);
566 type = ancillary_type(
self);
567 data = ancillary_data(
self);
569 if (level != IPPROTO_IPV6 || type != IPV6_PKTINFO ||
576 INIT_SOCKADDR((
struct sockaddr *)sa_ptr, AF_INET6,
sizeof(*sa_ptr));
577 memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr,
sizeof(sa_ptr->sin6_addr));
578 if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
579 sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
583 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
599 ancillary_ipv6_pktinfo(
VALUE self)
601 struct in6_pktinfo pktinfo;
602 struct sockaddr_in6 sa;
605 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
610 #define ancillary_ipv6_pktinfo rb_f_notimplement
613 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
629 ancillary_ipv6_pktinfo_addr(
VALUE self)
631 struct in6_pktinfo pktinfo;
632 struct sockaddr_in6 sa;
633 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
637 #define ancillary_ipv6_pktinfo_addr rb_f_notimplement
640 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
656 ancillary_ipv6_pktinfo_ifindex(
VALUE self)
658 struct in6_pktinfo pktinfo;
659 struct sockaddr_in6 sa;
660 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
661 return UINT2NUM(pktinfo.ipi6_ifindex);
664 #define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement
667 #if defined(SOL_SOCKET) && defined(SCM_RIGHTS)
669 anc_inspect_socket_rights(
int level,
int type,
VALUE data,
VALUE ret)
671 if (level == SOL_SOCKET && type == SCM_RIGHTS &&
687 #if defined(SCM_CREDENTIALS)
689 anc_inspect_passcred_credentials(
int level,
int type,
VALUE data,
VALUE ret)
691 if (level == SOL_SOCKET && type == SCM_CREDENTIALS &&
695 rb_str_catf(ret,
" pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
705 #if defined(SCM_CREDS)
706 #define INSPECT_SCM_CREDS
708 anc_inspect_socket_creds(
int level,
int type,
VALUE data,
VALUE ret)
710 if (level != SOL_SOCKET && type != SCM_CREDS)
724 #if defined(HAVE_TYPE_STRUCT_CMSGCRED)
725 if (
RSTRING_LEN(data) ==
sizeof(
struct cmsgcred)) {
726 struct cmsgcred cred;
732 if (cred.cmcred_ngroups) {
734 const char *sep =
" groups=";
735 for (i = 0; i < cred.cmcred_ngroups; i++) {
736 rb_str_catf(ret,
"%s%u", sep, cred.cmcred_groups[i]);
744 #if defined(HAVE_TYPE_STRUCT_SOCKCRED)
745 if ((
size_t)
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
746 struct sockcred cred0, *cred;
748 if ((
size_t)
RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
749 cred = (
struct sockcred *)
ALLOCA_N(
char, SOCKCREDSIZE(cred0.sc_ngroups));
755 if (cred0.sc_ngroups) {
757 const char *sep =
" groups=";
758 for (i = 0; i < cred0.sc_ngroups; i++) {
772 #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR)
774 anc_inspect_ip_recvdstaddr(
int level,
int type,
VALUE data,
VALUE ret)
776 if (level == IPPROTO_IP && type == IP_RECVDSTADDR &&
779 char addrbuf[INET_ADDRSTRLEN];
793 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
795 anc_inspect_ip_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
797 if (level == IPPROTO_IP && type == IP_PKTINFO &&
799 struct in_pktinfo pktinfo;
802 if (
inet_ntop(AF_INET, &pktinfo.ipi_addr, buf,
sizeof(buf)) ==
NULL)
806 if (if_indextoname(pktinfo.ipi_ifindex, buf) ==
NULL)
807 rb_str_catf(ret,
" ifindex:%d", pktinfo.ipi_ifindex);
810 if (
inet_ntop(AF_INET, &pktinfo.ipi_spec_dst, buf,
sizeof(buf)) ==
NULL)
822 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
824 anc_inspect_ipv6_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
826 if (level == IPPROTO_IPV6 && type == IPV6_PKTINFO &&
828 struct in6_pktinfo *pktinfo = (
struct in6_pktinfo *)
RSTRING_PTR(data);
829 struct in6_addr addr;
830 unsigned int ifindex;
831 char addrbuf[INET6_ADDRSTRLEN], ifbuf[
IFNAMSIZ];
832 memcpy(&addr, &pktinfo->ipi6_addr,
sizeof(addr));
833 memcpy(&ifindex, &pktinfo->ipi6_ifindex,
sizeof(ifindex));
838 if (if_indextoname(ifindex, ifbuf) ==
NULL)
850 #if defined(SCM_TIMESTAMP)
852 inspect_timeval_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
861 tm = *localtime(&time);
862 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
863 rb_str_catf(ret,
" %s.%06ld", buf, (
long)tv.tv_usec);
872 #if defined(SCM_TIMESTAMPNS)
874 inspect_timespec_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
881 tm = *localtime(&ts.tv_sec);
882 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
883 rb_str_catf(ret,
" %s.%09ld", buf, (
long)ts.tv_nsec);
892 #if defined(SCM_BINTIME)
894 inspect_bintime_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
905 tm = *localtime(&bt.sec);
906 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
910 frac_h = bt.frac >> 32;
911 frac_l = bt.frac & 0xffffffff;
913 scale_h = 0x8ac72304;
914 scale_l = 0x89e80000;
916 res_h = frac_h * scale_h;
917 res_l = frac_l * scale_l;
919 tmp1 = frac_h * scale_l;
922 res_l += tmp1 & 0xffffffff;
923 if (res_l < tmp2) res_h++;
925 tmp1 = frac_l * scale_h;
928 res_l += tmp1 & 0xffffffff;
929 if (res_l < tmp2) res_h++;
950 ancillary_inspect(
VALUE self)
955 ID family_id, level_id, type_id;
959 family = ancillary_family(
self);
960 level = ancillary_level(
self);
961 type = ancillary_type(
self);
962 data = ancillary_data(
self);
966 family_id = rsock_intern_family_noprefix(family);
972 if (level == SOL_SOCKET) {
975 type_id = rsock_intern_scm_optname(type);
982 level_id = rsock_intern_iplevel(level);
988 vtype = ip_cmsg_type_to_sym(level, type);
1001 if (level == SOL_SOCKET)
1007 # if defined(SOL_SOCKET)
1010 # if defined(SCM_TIMESTAMP)
1011 case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret);
break;
1013 # if defined(SCM_TIMESTAMPNS)
1014 case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret);
break;
1016 # if defined(SCM_BINTIME)
1017 case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret);
break;
1019 # if defined(SCM_RIGHTS)
1020 case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret);
break;
1022 # if defined(SCM_CREDENTIALS)
1023 case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret);
break;
1025 # if defined(INSPECT_SCM_CREDS)
1026 case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret);
break;
1039 # if defined(IPPROTO_IP)
1042 # if defined(IP_RECVDSTADDR)
1043 case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret);
break;
1045 # if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
1046 case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret);
break;
1052 # if defined(IPPROTO_IPV6)
1055 # if defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
1056 case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret);
break;
1090 int family = ancillary_family(
self);
1094 if (ancillary_level(
self) == level &&
1095 ancillary_type(
self) == type)
1103 #if defined(HAVE_SENDMSG)
1104 struct sendmsg_args_struct {
1111 nogvl_sendmsg_func(
void *
ptr)
1113 struct sendmsg_args_struct *
args =
ptr;
1114 return (
void *)(
VALUE)
sendmsg(args->fd, args->msg, args->flags);
1120 struct sendmsg_args_struct args;
1128 bsock_sendmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1135 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1136 VALUE controls_str = 0;
1144 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1148 data = vflags = dest_sockaddr =
Qnil;
1153 if (1 < argc) vflags = argv[1];
1154 if (2 < argc) dest_sockaddr = argv[2];
1155 controls_num = 3 < argc ? argc - 3 : 0;
1156 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1157 if (3 < argc) { controls_ptr = &argv[3]; }
1163 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1165 size_t last_pad = 0;
1166 #if defined(__NetBSD__)
1171 for (i = 0; i < controls_num; i++) {
1172 VALUE elt = controls_ptr[
i],
v;
1173 VALUE vlevel, vtype;
1201 memset((
char *)cmsg, 0, cspace);
1202 memset((
char *)&cmh, 0,
sizeof(cmh));
1203 cmh.cmsg_level =
level;
1204 cmh.cmsg_type =
type;
1206 MEMCPY(cmsg, &cmh,
char,
sizeof(cmh));
1208 #if defined(__NetBSD__)
1209 last_level = cmh.cmsg_level;
1210 last_type = cmh.cmsg_type;
1212 last_pad = cspace - cmh.cmsg_len;
1235 #if defined(__NetBSD__)
1236 if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS)
1248 flags |= MSG_DONTWAIT;
1251 if (!
NIL_P(dest_sockaddr))
1257 memset(&mh, 0,
sizeof(mh));
1258 if (!
NIL_P(dest_sockaddr)) {
1266 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1272 mh.msg_control =
NULL;
1273 mh.msg_controllen = 0;
1281 ss = rb_sendmsg(fptr->
fd, &mh, flags);
1292 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1300 #if defined(HAVE_SENDMSG)
1336 return bsock_sendmsg_internal(argc, argv, sock, 0);
1340 #if defined(HAVE_SENDMSG)
1355 return bsock_sendmsg_internal(argc, argv, sock, 1);
1359 #if defined(HAVE_RECVMSG)
1360 struct recvmsg_args_struct {
1367 rsock_recvmsg(
int socket,
struct msghdr *message,
int flags)
1371 #ifdef MSG_CMSG_CLOEXEC
1373 flags |= MSG_CMSG_CLOEXEC;
1376 ret =
recvmsg(socket, message, flags);
1383 nogvl_recvmsg_func(
void *ptr)
1385 struct recvmsg_args_struct *args =
ptr;
1386 int flags = args->flags;
1387 return (
void *)rsock_recvmsg(args->fd, args->msg, flags);
1391 rb_recvmsg(
int fd,
struct msghdr *msg,
int flags)
1393 struct recvmsg_args_struct args;
1400 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1402 discard_cmsg(
struct cmsghdr *cmh,
char *msg_end,
int msg_peek_p)
1404 # if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
1416 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1417 int *fdp = (
int *)CMSG_DATA(cmh);
1418 int *
end = (
int *)((
char *)cmh + cmh->cmsg_len);
1419 while ((
char *)fdp +
sizeof(
int) <= (
char *)end &&
1420 (
char *)fdp +
sizeof(
int) <= msg_end) {
1430 rsock_discard_cmsg_resource(
struct msghdr *mh,
int msg_peek_p)
1432 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1433 struct cmsghdr *cmh;
1441 for (cmh = CMSG_FIRSTHDR(mh); cmh !=
NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1442 discard_cmsg(cmh, msg_end, msg_peek_p);
1447 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1449 make_io_for_unix_rights(
VALUE ctl,
struct cmsghdr *cmh,
char *msg_end)
1451 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1455 fdp = (
int *)CMSG_DATA(cmh);
1456 end = (
int *)((
char *)cmh + cmh->cmsg_len);
1457 while ((
char *)fdp +
sizeof(
int) <= (
char *)end &&
1458 (
char *)fdp +
sizeof(
int) <= msg_end) {
1462 if (
fstat(fd, &stbuf) == -1)
1465 if (S_ISSOCK(stbuf.st_mode))
1479 bsock_recvmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1482 VALUE vmaxdatlen, vmaxctllen, vflags;
1486 int flags, orig_flags;
1490 char datbuf0[4096], *datbuf;
1494 int request_scm_rights;
1495 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1496 struct cmsghdr *cmh;
1500 struct cmsghdr align;
1509 rb_scan_args(argc, argv,
"03:", &vmaxdatlen, &vflags, &vmaxctllen, &vopts);
1511 maxdatlen =
NIL_P(vmaxdatlen) ?
sizeof(datbuf0) :
NUM2SIZET(vmaxdatlen);
1512 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1513 maxctllen =
NIL_P(vmaxctllen) ?
sizeof(ctlbuf0) :
NUM2SIZET(vmaxctllen);
1515 if (!
NIL_P(vmaxctllen))
1521 flags |= MSG_DONTWAIT;
1525 grow_buffer =
NIL_P(vmaxdatlen) ||
NIL_P(vmaxctllen);
1527 request_scm_rights = 0;
1529 request_scm_rights = 1;
1530 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1531 if (request_scm_rights)
1540 #if !defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1544 if (getsockopt(fptr->
fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen) == -1) {
1547 if (socktype == SOCK_STREAM)
1553 if (maxdatlen <=
sizeof(datbuf0))
1563 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1564 if (maxctllen <=
sizeof(ctlbuf0))
1565 ctlbuf = ctlbuf0.bytes;
1575 memset(&mh, 0,
sizeof(mh));
1577 memset(&namebuf, 0,
sizeof(namebuf));
1583 iov.iov_base = datbuf;
1584 iov.iov_len = maxdatlen;
1586 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1598 ss = rb_recvmsg(fptr->
fd, &mh, flags);
1607 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1626 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1634 #define BIG_ENOUGH_SPACE 65536
1635 if (BIG_ENOUGH_SPACE < maxctllen &&
1640 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1650 #undef BIG_ENOUGH_SPACE
1653 if (
NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) {
1661 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1666 if (flags != orig_flags) {
1667 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1684 #
if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1691 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1695 for (cmh = CMSG_FIRSTHDR(&mh); cmh !=
NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1699 if (cmh->cmsg_len == 0) {
1702 ctl_end = (
char*)cmh + cmh->cmsg_len;
1703 clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (
char*)CMSG_DATA(cmh);
1704 ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type,
rb_tainted_str_new((
char*)CMSG_DATA(cmh), clen));
1705 if (request_scm_rights)
1706 make_io_for_unix_rights(ctl, cmh, msg_end);
1708 discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1719 #if defined(HAVE_RECVMSG)
1776 return bsock_recvmsg_internal(argc, argv, sock, 0);
1780 #if defined(HAVE_RECVMSG)
1795 return bsock_recvmsg_internal(argc, argv, sock, 1);
1802 #if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
1811 rb_define_method(rb_cAncillaryData,
"initialize", ancillary_initialize, 4);
1824 rb_define_method(rb_cAncillaryData,
"unix_rights", ancillary_unix_rights, 0);
1829 rb_define_method(rb_cAncillaryData,
"ip_pktinfo", ancillary_ip_pktinfo, 0);
1832 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1833 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1834 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
#define RB_TYPE_P(obj, type)
VALUE rb_time_num_new(VALUE, VALUE)
VALUE rb_ary_entry(VALUE ary, long offset)
void rb_io_set_nonblock(rb_io_t *fptr)
const char * rb_obj_classname(VALUE)
#define SockAddrStringValue(v)
VALUE rb_str_tmp_new(long)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
int sendmsg(int, const struct msghdr *, int)
rb_funcall(memo->yielder, id_lshift, 1, rb_assoc_new(memo->prev_value, memo->prev_elts))
VALUE rb_time_nano_new(time_t, long)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rsock_init_sock(VALUE sock, int fd)
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
void rb_raise(VALUE exc, const char *fmt,...)
#define rsock_bsock_sendmsg
RUBY_EXTERN VALUE rb_eIOError
VALUE rb_obj_reveal(VALUE obj, VALUE klass)
int rsock_getfamily(int sockfd)
int recvmsg(int, struct msghdr *, int)
#define GetOpenFile(obj, fp)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
void rb_fd_fix_cloexec(int fd)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
memset(y->frac+ix+1, 0,(y->Prec-(ix+1))*sizeof(BDIGIT))
unsigned long long uint64_t
int rsock_family_arg(VALUE domain)
#define rsock_bsock_sendmsg_nonblock
VALUE rb_str_cat2(VALUE, const char *)
int rsock_level_arg(int family, VALUE level)
int rb_io_wait_writable(int)
static const char * inet_ntop(int af, const void *addr, char *numaddr, size_t numaddr_len)
void rsock_init_ancdata(void)
unsigned char buf[MIME_BUF_SIZE]
#define rsock_bsock_recvmsg_nonblock
#define ALLOCA_N(type, n)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
#define RB_IO_WAIT_WRITABLE
#define INIT_SOCKADDR(addr, family, len)
VALUE rb_str_buf_cat(VALUE, const char *, long)
VALUE rb_tainted_str_new(const char *, long)
static VALUE constant_to_sym(int constant, ID(*intern_const)(int))
VALUE rb_str_resize(VALUE, long)
VALUE rb_sprintf(const char *format,...)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
#define RB_IO_WAIT_READABLE
VALUE rb_str_buf_new(long)
void rb_readwrite_sys_fail(int writable, const char *mesg)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_time_new(time_t, long)
void rb_sys_fail(const char *mesg)
RUBY_EXTERN VALUE rb_cString
#define MEMCPY(p1, p2, type, n)
#define NEWOBJ_OF(obj, type, klass, flags)
int rb_io_read_pending(rb_io_t *)
VALUE rb_str_catf(VALUE str, const char *format,...)
RUBY_EXTERN VALUE rb_cObject
for(i=0;i< RARRAY_LEN(args);i++)
rb_ivar_set(yielder, id_memo, LONG2NUM(++count))
VALUE rb_str_new(const char *, long)
VALUE rb_obj_alloc(VALUE)
const char * rb_id2name(ID id)
VALUE rb_hash_aref(VALUE, VALUE)
#define rsock_bsock_recvmsg
int rb_io_wait_readable(int)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
void rb_io_check_closed(rb_io_t *)
int rsock_cmsg_type_arg(int family, int level, VALUE type)
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
VALUE rb_io_fdopen(int, int, const char *)
void rb_str_set_len(VALUE, long)