5 #if defined(HAVE_ST_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 ||
498 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(
struct in_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 ||
574 memcpy(pktinfo_ptr,
RSTRING_PTR(data),
sizeof(*pktinfo_ptr));
576 memset(sa_ptr, 0,
sizeof(*sa_ptr));
577 SET_SA_LEN((
struct sockaddr *)sa_ptr,
sizeof(
struct sockaddr_in6));
578 sa_ptr->sin6_family = AF_INET6;
579 memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr,
sizeof(sa_ptr->sin6_addr));
580 if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
581 sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
585 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
601 ancillary_ipv6_pktinfo(
VALUE self)
603 struct in6_pktinfo pktinfo;
604 struct sockaddr_in6 sa;
607 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
612 #define ancillary_ipv6_pktinfo rb_f_notimplement
615 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
631 ancillary_ipv6_pktinfo_addr(
VALUE self)
633 struct in6_pktinfo pktinfo;
634 struct sockaddr_in6 sa;
635 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
639 #define ancillary_ipv6_pktinfo_addr rb_f_notimplement
642 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
658 ancillary_ipv6_pktinfo_ifindex(
VALUE self)
660 struct in6_pktinfo pktinfo;
661 struct sockaddr_in6 sa;
662 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
663 return UINT2NUM(pktinfo.ipi6_ifindex);
666 #define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement
669 #if defined(SOL_SOCKET) && defined(SCM_RIGHTS)
671 anc_inspect_socket_rights(
int level,
int type,
VALUE data,
VALUE ret)
673 if (level == SOL_SOCKET && type == SCM_RIGHTS &&
676 for (off = 0; off <
RSTRING_LEN(data); off +=
sizeof(int)) {
678 memcpy((
char*)&fd,
RSTRING_PTR(data)+off,
sizeof(
int));
689 #if defined(SCM_CREDENTIALS)
691 anc_inspect_passcred_credentials(
int level,
int type,
VALUE data,
VALUE ret)
693 if (level == SOL_SOCKET && type == SCM_CREDENTIALS &&
696 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct ucred));
697 rb_str_catf(ret,
" pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
707 #if defined(SCM_CREDS)
708 #define INSPECT_SCM_CREDS
710 anc_inspect_socket_creds(
int level,
int type,
VALUE data,
VALUE ret)
712 if (level != SOL_SOCKET && type != SCM_CREDS)
726 #if defined(HAVE_TYPE_STRUCT_CMSGCRED)
727 if (
RSTRING_LEN(data) ==
sizeof(
struct cmsgcred)) {
728 struct cmsgcred cred;
729 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct cmsgcred));
734 if (cred.cmcred_ngroups) {
736 const char *sep =
" groups=";
737 for (i = 0; i < cred.cmcred_ngroups; i++) {
738 rb_str_catf(ret,
"%s%u", sep, cred.cmcred_groups[i]);
746 #if defined(HAVE_TYPE_STRUCT_SOCKCRED)
747 if ((
size_t)
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
748 struct sockcred cred0, *cred;
749 memcpy(&cred0,
RSTRING_PTR(data), SOCKCREDSIZE(0));
750 if ((
size_t)
RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
751 cred = (
struct sockcred *)
ALLOCA_N(
char, SOCKCREDSIZE(cred0.sc_ngroups));
752 memcpy(cred,
RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
757 if (cred0.sc_ngroups) {
759 const char *sep =
" groups=";
760 for (i = 0; i < cred0.sc_ngroups; i++) {
774 #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR)
776 anc_inspect_ip_recvdstaddr(
int level,
int type,
VALUE data,
VALUE ret)
778 if (level == IPPROTO_IP && type == IP_RECVDSTADDR &&
781 char addrbuf[INET_ADDRSTRLEN];
783 if (
inet_ntop(AF_INET, &addr, addrbuf, (socklen_t)
sizeof(addrbuf)) ==
NULL)
795 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
797 anc_inspect_ip_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
799 if (level == IPPROTO_IP && type == IP_PKTINFO &&
801 struct in_pktinfo pktinfo;
803 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(pktinfo));
804 if (
inet_ntop(AF_INET, &pktinfo.ipi_addr, buf,
sizeof(buf)) ==
NULL)
808 if (if_indextoname(pktinfo.ipi_ifindex, buf) ==
NULL)
809 rb_str_catf(ret,
" ifindex:%d", pktinfo.ipi_ifindex);
812 if (
inet_ntop(AF_INET, &pktinfo.ipi_spec_dst, buf,
sizeof(buf)) ==
NULL)
824 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
826 anc_inspect_ipv6_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
828 if (level == IPPROTO_IPV6 && type == IPV6_PKTINFO &&
830 struct in6_pktinfo *pktinfo = (
struct in6_pktinfo *)
RSTRING_PTR(data);
831 struct in6_addr addr;
832 unsigned int ifindex;
833 char addrbuf[INET6_ADDRSTRLEN], ifbuf[
IFNAMSIZ];
834 memcpy(&addr, &pktinfo->ipi6_addr,
sizeof(addr));
835 memcpy(&ifindex, &pktinfo->ipi6_ifindex,
sizeof(ifindex));
836 if (
inet_ntop(AF_INET6, &addr, addrbuf, (socklen_t)
sizeof(addrbuf)) ==
NULL)
840 if (if_indextoname(ifindex, ifbuf) ==
NULL)
852 #if defined(SCM_TIMESTAMP)
854 inspect_timeval_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
863 tm = *localtime(&time);
864 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
865 rb_str_catf(ret,
" %s.%06ld", buf, (
long)tv.tv_usec);
874 #if defined(SCM_TIMESTAMPNS)
876 inspect_timespec_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
883 tm = *localtime(&ts.tv_sec);
884 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
885 rb_str_catf(ret,
" %s.%09ld", buf, (
long)ts.tv_nsec);
894 #if defined(SCM_BINTIME)
896 inspect_bintime_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
907 tm = *localtime(&bt.sec);
908 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
912 frac_h = bt.frac >> 32;
913 frac_l = bt.frac & 0xffffffff;
915 scale_h = 0x8ac72304;
916 scale_l = 0x89e80000;
918 res_h = frac_h * scale_h;
919 res_l = frac_l * scale_l;
921 tmp1 = frac_h * scale_l;
924 res_l += tmp1 & 0xffffffff;
925 if (res_l < tmp2) res_h++;
927 tmp1 = frac_l * scale_h;
930 res_l += tmp1 & 0xffffffff;
931 if (res_l < tmp2) res_h++;
952 ancillary_inspect(
VALUE self)
957 ID family_id, level_id, type_id;
961 family = ancillary_family(
self);
962 level = ancillary_level(
self);
963 type = ancillary_type(
self);
964 data = ancillary_data(
self);
968 family_id = rsock_intern_family_noprefix(family);
974 if (level == SOL_SOCKET) {
977 type_id = rsock_intern_scm_optname(type);
984 level_id = rsock_intern_iplevel(level);
990 vtype = ip_cmsg_type_to_sym(level, type);
1003 if (level == SOL_SOCKET)
1009 # if defined(SOL_SOCKET)
1012 # if defined(SCM_TIMESTAMP)
1013 case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret);
break;
1015 # if defined(SCM_TIMESTAMPNS)
1016 case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret);
break;
1018 # if defined(SCM_BINTIME)
1019 case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret);
break;
1021 # if defined(SCM_RIGHTS)
1022 case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret);
break;
1024 # if defined(SCM_CREDENTIALS)
1025 case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret);
break;
1027 # if defined(INSPECT_SCM_CREDS)
1028 case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret);
break;
1041 # if defined(IPPROTO_IP)
1044 # if defined(IP_RECVDSTADDR)
1045 case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret);
break;
1047 # if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
1048 case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret);
break;
1054 # if defined(IPPROTO_IPV6)
1057 # if defined(IPV6_PKTINFO)
1058 case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret);
break;
1092 int family = ancillary_family(
self);
1096 if (ancillary_level(
self) == level &&
1097 ancillary_type(
self) == type)
1105 #if defined(HAVE_SENDMSG)
1106 struct sendmsg_args_struct {
1113 nogvl_sendmsg_func(
void *ptr)
1115 struct sendmsg_args_struct *
args = ptr;
1116 return (
void *)(
VALUE)
sendmsg(args->fd, args->msg, args->flags);
1120 rb_sendmsg(
int fd,
const struct msghdr *
msg,
int flags)
1122 struct sendmsg_args_struct args;
1130 bsock_sendmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1133 VALUE data, vflags, dest_sockaddr;
1134 VALUE *controls_ptr;
1138 #if defined(HAVE_ST_MSG_CONTROL)
1139 volatile VALUE controls_str = 0;
1149 data = vflags = dest_sockaddr =
Qnil;
1150 controls_ptr =
NULL;
1156 if (1 < argc) vflags = argv[1];
1157 if (2 < argc) dest_sockaddr = argv[2];
1158 if (3 < argc) { controls_ptr = &argv[3]; controls_num = argc - 3; }
1163 #if defined(HAVE_ST_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;
1205 cmh.cmsg_len = (socklen_t)CMSG_LEN(
RSTRING_LEN(cdata));
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_ST_MSG_CONTROL)
1272 mh.msg_control =
NULL;
1273 mh.msg_controllen = 0;
1281 ss = rb_sendmsg(fptr->
fd, &mh, flags);
1297 #if defined(HAVE_SENDMSG)
1333 return bsock_sendmsg_internal(argc, argv, sock, 0);
1337 #if defined(HAVE_SENDMSG)
1352 return bsock_sendmsg_internal(argc, argv, sock, 1);
1356 #if defined(HAVE_RECVMSG)
1357 struct recvmsg_args_struct {
1364 rsock_recvmsg(
int socket,
struct msghdr *message,
int flags)
1366 #ifdef MSG_CMSG_CLOEXEC
1368 flags |= MSG_CMSG_CLOEXEC;
1370 return recvmsg(socket, message, flags);
1374 nogvl_recvmsg_func(
void *ptr)
1376 struct recvmsg_args_struct *args = ptr;
1377 int flags = args->flags;
1378 return (
void *)rsock_recvmsg(args->fd, args->msg, flags);
1382 rb_recvmsg(
int fd,
struct msghdr *msg,
int flags)
1384 struct recvmsg_args_struct args;
1391 #if defined(HAVE_ST_MSG_CONTROL)
1393 discard_cmsg(
struct cmsghdr *cmh,
char *msg_end,
int msg_peek_p)
1395 # if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
1407 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1408 int *fdp = (
int *)CMSG_DATA(cmh);
1409 int *end = (
int *)((
char *)cmh + cmh->cmsg_len);
1410 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1411 (
char *)fdp +
sizeof(
int) <= msg_end) {
1421 rsock_discard_cmsg_resource(
struct msghdr *mh,
int msg_peek_p)
1423 #if defined(HAVE_ST_MSG_CONTROL)
1424 struct cmsghdr *cmh;
1432 for (cmh = CMSG_FIRSTHDR(mh); cmh !=
NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1433 discard_cmsg(cmh, msg_end, msg_peek_p);
1438 #if defined(HAVE_ST_MSG_CONTROL)
1440 make_io_for_unix_rights(
VALUE ctl,
struct cmsghdr *cmh,
char *msg_end)
1442 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1446 fdp = (
int *)CMSG_DATA(cmh);
1447 end = (
int *)((
char *)cmh + cmh->cmsg_len);
1448 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1449 (
char *)fdp +
sizeof(
int) <= msg_end) {
1453 if (
fstat(fd, &stbuf) == -1)
1456 if (S_ISSOCK(stbuf.st_mode))
1470 bsock_recvmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1473 VALUE vmaxdatlen, vmaxctllen, vflags, vopts;
1476 int flags, orig_flags;
1477 int request_scm_rights;
1481 char datbuf0[4096], *datbuf;
1485 #if defined(HAVE_ST_MSG_CONTROL)
1486 struct cmsghdr *cmh;
1490 struct cmsghdr align;
1502 vopts = argv[--
argc];
1504 rb_scan_args(argc, argv,
"03", &vmaxdatlen, &vflags, &vmaxctllen);
1506 maxdatlen =
NIL_P(vmaxdatlen) ?
sizeof(datbuf0) :
NUM2SIZET(vmaxdatlen);
1507 #if defined(HAVE_ST_MSG_CONTROL)
1508 maxctllen =
NIL_P(vmaxctllen) ?
sizeof(ctlbuf0) :
NUM2SIZET(vmaxctllen);
1510 if (!
NIL_P(vmaxctllen))
1516 flags |= MSG_DONTWAIT;
1520 grow_buffer =
NIL_P(vmaxdatlen) ||
NIL_P(vmaxctllen);
1522 request_scm_rights = 0;
1524 request_scm_rights = 1;
1531 #if !defined(HAVE_ST_MSG_CONTROL)
1534 socklen_t optlen = (socklen_t)
sizeof(socktype);
1535 if (getsockopt(fptr->
fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen) == -1) {
1538 if (socktype == SOCK_STREAM)
1544 if (maxdatlen <=
sizeof(datbuf0))
1554 #if defined(HAVE_ST_MSG_CONTROL)
1555 if (maxctllen <=
sizeof(ctlbuf0))
1556 ctlbuf = ctlbuf0.bytes;
1566 memset(&mh, 0,
sizeof(mh));
1568 memset(&namebuf, 0,
sizeof(namebuf));
1569 mh.
msg_name = (
struct sockaddr *)&namebuf;
1574 iov.iov_base = datbuf;
1575 iov.iov_len = maxdatlen;
1577 #if defined(HAVE_ST_MSG_CONTROL)
1589 ss = rb_recvmsg(fptr->
fd, &mh, flags);
1598 #if defined(HAVE_ST_MSG_CONTROL)
1617 #if defined(HAVE_ST_MSG_CONTROL)
1625 #define BIG_ENOUGH_SPACE 65536
1626 if (BIG_ENOUGH_SPACE < maxctllen &&
1631 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1641 #undef BIG_ENOUGH_SPACE
1644 if (
NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) {
1652 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1657 if (flags != orig_flags) {
1658 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1675 #
if defined(HAVE_ST_MSG_CONTROL)
1682 #if defined(HAVE_ST_MSG_CONTROL)
1686 for (cmh = CMSG_FIRSTHDR(&mh); cmh !=
NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1690 if (cmh->cmsg_len == 0) {
1693 ctl_end = (
char*)cmh + cmh->cmsg_len;
1694 clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (
char*)CMSG_DATA(cmh);
1695 ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type,
rb_tainted_str_new((
char*)CMSG_DATA(cmh), clen));
1696 if (request_scm_rights)
1697 make_io_for_unix_rights(ctl, cmh, msg_end);
1699 discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1709 #if defined(HAVE_RECVMSG)
1766 return bsock_recvmsg_internal(argc, argv, sock, 0);
1770 #if defined(HAVE_RECVMSG)
1785 return bsock_recvmsg_internal(argc, argv, sock, 1);
1792 #if defined(HAVE_ST_MSG_CONTROL)
1801 rb_define_method(rb_cAncillaryData,
"initialize", ancillary_initialize, 4);
1814 rb_define_method(rb_cAncillaryData,
"unix_rights", ancillary_unix_rights, 0);
1819 rb_define_method(rb_cAncillaryData,
"ip_pktinfo", ancillary_ip_pktinfo, 0);
1822 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1823 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1824 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
RUBY_EXTERN VALUE rb_cString
VALUE rb_ary_entry(VALUE ary, long offset)
void rb_io_set_nonblock(rb_io_t *fptr)
VALUE rb_time_nano_new(time_t, long)
#define SockAddrStringValue(v)
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)
#define SET_SA_LEN(sa, len)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE rsock_init_sock(VALUE sock, int fd)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
void rb_str_set_len(VALUE, long)
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
VALUE rb_ary_new3(long n,...)
int rsock_getfamily(int sockfd)
int recvmsg(int, struct msghdr *, int)
VALUE rb_str_tmp_new(long)
#define GetOpenFile(obj, fp)
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len)
const char * rb_obj_classname(VALUE)
VALUE rb_str_buf_cat(VALUE, const char *, long)
#define NEWOBJ_OF(obj, type, klass, flags)
#define RB_TYPE_P(obj, type)
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname)
RUBY_EXTERN VALUE rb_mWaitReadable
unsigned long long uint64_t
int rsock_family_arg(VALUE domain)
#define rsock_bsock_sendmsg_nonblock
RUBY_EXTERN VALUE rb_cObject
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)
#define ALLOCA_N(type, n)
#define MEMCPY(p1, p2, type, n)
#define rsock_bsock_recvmsg_nonblock
VALUE rb_obj_alloc(VALUE)
void * rb_thread_call_without_gvl(void *(*func)(void *), void *data1, rb_unblock_function_t *ubf, void *data2)
VALUE rb_time_new(time_t, long)
VALUE rb_str_resize(VALUE, long)
static VALUE constant_to_sym(int constant, ID(*intern_const)(int))
VALUE rb_io_fdopen(int, int, const char *)
VALUE rb_sprintf(const char *format,...)
RUBY_EXTERN VALUE rb_mWaitWritable
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
unsigned char buf[MIME_BUF_SIZE]
void rb_sys_fail(const char *mesg)
int rb_io_read_pending(rb_io_t *)
VALUE rb_check_convert_type(VALUE, int, const char *, const char *)
void rb_mod_sys_fail(VALUE mod, const char *mesg)
void rb_fd_fix_cloexec(int fd)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_str_catf(VALUE str, const char *format,...)
RUBY_EXTERN VALUE rb_eIOError
const char * rb_id2name(ID id)
#define RSTRING_LENINT(str)
#define rsock_bsock_recvmsg
VALUE rb_tainted_str_new(const char *, long)
VALUE rb_str_buf_new(long)
int rb_io_wait_readable(int)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_append(VALUE, VALUE)
void rb_io_check_closed(rb_io_t *)
VALUE rb_time_num_new(VALUE, VALUE)
int rsock_cmsg_type_arg(int family, int level, VALUE type)
VALUE rb_attr_get(VALUE, ID)
VALUE rb_str_new(const char *, long)