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)
97 ancillary_family(
VALUE self)
113 ancillary_family_m(
VALUE self)
115 return INT2NUM(ancillary_family(
self));
119 ancillary_level(
VALUE self)
135 ancillary_level_m(
VALUE self)
137 return INT2NUM(ancillary_level(
self));
141 ancillary_type(
VALUE self)
157 ancillary_type_m(
VALUE self)
159 return INT2NUM(ancillary_type(
self));
172 ancillary_data(
VALUE self)
197 for (i = 0 ; i <
argc; i++) {
207 for (i = 0 ; i <
argc; i++) {
216 result = ancdata_new(AF_UNIX, SOL_SOCKET, SCM_RIGHTS, str);
221 #define ancillary_s_unix_rights rb_f_notimplement
256 ancillary_unix_rights(
VALUE self)
260 level = ancillary_level(
self);
261 type = ancillary_type(
self);
263 if (level != SOL_SOCKET || type != SCM_RIGHTS)
269 #define ancillary_unix_rights rb_f_notimplement
272 #if defined(SCM_TIMESTAMP) || defined(SCM_TIMESTAMPNS) || defined(SCM_BINTIME)
299 ancillary_timestamp(
VALUE self)
305 level = ancillary_level(
self);
306 type = ancillary_type(
self);
307 data = ancillary_data(
self);
309 # ifdef SCM_TIMESTAMP
310 if (level == SOL_SOCKET && type == SCM_TIMESTAMP &&
318 # ifdef SCM_TIMESTAMPNS
319 if (level == SOL_SOCKET && type == SCM_TIMESTAMPNS &&
327 #define add(x,y) (rb_funcall((x), '+', 1, (y)))
328 #define mul(x,y) (rb_funcall((x), '*', 1, (y)))
329 #define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y)))
332 if (level == SOL_SOCKET && type == SCM_BINTIME &&
337 d = ULL2NUM(0x100000000ULL);
339 timev =
add(TIMET2NUM(bt.sec),
quo(ULL2NUM(bt.frac), d));
350 #define ancillary_timestamp rb_f_notimplement
371 return ancdata_new(family, level, type,
rb_str_new((
char*)&i,
sizeof(i)));
386 ancillary_int(
VALUE self)
390 data = ancillary_data(
self);
397 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
419 ancillary_s_ip_pktinfo(
int argc,
VALUE *argv,
VALUE self)
421 VALUE v_addr, v_ifindex, v_spec_dst;
422 unsigned int ifindex;
423 struct sockaddr_in sa;
424 struct in_pktinfo pktinfo;
426 rb_scan_args(argc, argv,
"21", &v_addr, &v_ifindex, &v_spec_dst);
430 if (
NIL_P(v_spec_dst))
435 memset(&pktinfo, 0,
sizeof(pktinfo));
437 memset(&sa, 0,
sizeof(sa));
441 if (sa.sin_family != AF_INET)
443 memcpy(&pktinfo.ipi_addr, &sa.sin_addr,
sizeof(pktinfo.ipi_addr));
445 pktinfo.ipi_ifindex = ifindex;
447 memset(&sa, 0,
sizeof(sa));
451 if (sa.sin_family != AF_INET)
453 memcpy(&pktinfo.ipi_spec_dst, &sa.sin_addr,
sizeof(pktinfo.ipi_spec_dst));
455 return ancdata_new(AF_INET, IPPROTO_IP, IP_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
458 #define ancillary_s_ip_pktinfo rb_f_notimplement
461 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
482 ancillary_ip_pktinfo(
VALUE self)
486 struct in_pktinfo pktinfo;
487 struct sockaddr_in sa;
488 VALUE v_spec_dst, v_addr;
490 level = ancillary_level(
self);
491 type = ancillary_type(
self);
492 data = ancillary_data(
self);
494 if (level != IPPROTO_IP || type != IP_PKTINFO ||
499 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(
struct in_pktinfo));
500 memset(&sa, 0,
sizeof(sa));
502 sa.sin_family = AF_INET;
503 memcpy(&sa.sin_addr, &pktinfo.ipi_addr,
sizeof(sa.sin_addr));
506 sa.sin_family = AF_INET;
507 memcpy(&sa.sin_addr, &pktinfo.ipi_spec_dst,
sizeof(sa.sin_addr));
513 #define ancillary_ip_pktinfo rb_f_notimplement
516 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
534 unsigned int ifindex;
535 struct sockaddr_in6 sa;
536 struct in6_pktinfo pktinfo;
541 memset(&pktinfo, 0,
sizeof(pktinfo));
543 memset(&sa, 0,
sizeof(sa));
547 if (sa.sin6_family != AF_INET6)
549 memcpy(&pktinfo.ipi6_addr, &sa.sin6_addr,
sizeof(pktinfo.ipi6_addr));
551 pktinfo.ipi6_ifindex = ifindex;
553 return ancdata_new(AF_INET6, IPPROTO_IPV6, IPV6_PKTINFO,
rb_str_new((
char *)&pktinfo,
sizeof(pktinfo)));
556 #define ancillary_s_ipv6_pktinfo rb_f_notimplement
559 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
561 extract_ipv6_pktinfo(
VALUE self,
struct in6_pktinfo *pktinfo_ptr,
struct sockaddr_in6 *sa_ptr)
566 level = ancillary_level(
self);
567 type = ancillary_type(
self);
568 data = ancillary_data(
self);
570 if (level != IPPROTO_IPV6 || type != IPV6_PKTINFO ||
575 memcpy(pktinfo_ptr,
RSTRING_PTR(data),
sizeof(*pktinfo_ptr));
577 memset(sa_ptr, 0,
sizeof(*sa_ptr));
578 SET_SA_LEN((
struct sockaddr *)sa_ptr,
sizeof(
struct sockaddr_in6));
579 sa_ptr->sin6_family = AF_INET6;
580 memcpy(&sa_ptr->sin6_addr, &pktinfo_ptr->ipi6_addr,
sizeof(sa_ptr->sin6_addr));
581 if (IN6_IS_ADDR_LINKLOCAL(&sa_ptr->sin6_addr))
582 sa_ptr->sin6_scope_id = pktinfo_ptr->ipi6_ifindex;
586 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
602 ancillary_ipv6_pktinfo(
VALUE self)
604 struct in6_pktinfo pktinfo;
605 struct sockaddr_in6 sa;
608 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
613 #define ancillary_ipv6_pktinfo rb_f_notimplement
616 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
632 ancillary_ipv6_pktinfo_addr(
VALUE self)
634 struct in6_pktinfo pktinfo;
635 struct sockaddr_in6 sa;
636 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
640 #define ancillary_ipv6_pktinfo_addr rb_f_notimplement
643 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO)
659 ancillary_ipv6_pktinfo_ifindex(
VALUE self)
661 struct in6_pktinfo pktinfo;
662 struct sockaddr_in6 sa;
663 extract_ipv6_pktinfo(
self, &pktinfo, &sa);
664 return UINT2NUM(pktinfo.ipi6_ifindex);
667 #define ancillary_ipv6_pktinfo_ifindex rb_f_notimplement
670 #if defined(SOL_SOCKET) && defined(SCM_RIGHTS)
672 anc_inspect_socket_rights(
int level,
int type,
VALUE data,
VALUE ret)
674 if (level == SOL_SOCKET && type == SCM_RIGHTS &&
677 for (off = 0; off <
RSTRING_LEN(data); off +=
sizeof(int)) {
679 memcpy((
char*)&fd,
RSTRING_PTR(data)+off,
sizeof(
int));
690 #if defined(SCM_CREDENTIALS)
692 anc_inspect_passcred_credentials(
int level,
int type,
VALUE data,
VALUE ret)
694 if (level == SOL_SOCKET && type == SCM_CREDENTIALS &&
697 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct ucred));
698 rb_str_catf(ret,
" pid=%u uid=%u gid=%u", cred.pid, cred.uid, cred.gid);
708 #if defined(SCM_CREDS)
709 #define INSPECT_SCM_CREDS
711 anc_inspect_socket_creds(
int level,
int type,
VALUE data,
VALUE ret)
713 if (level != SOL_SOCKET && type != SCM_CREDS)
727 #if defined(HAVE_TYPE_STRUCT_CMSGCRED)
728 if (
RSTRING_LEN(data) ==
sizeof(
struct cmsgcred)) {
729 struct cmsgcred cred;
730 memcpy(&cred,
RSTRING_PTR(data),
sizeof(
struct cmsgcred));
735 if (cred.cmcred_ngroups) {
737 const char *sep =
" groups=";
738 for (i = 0; i < cred.cmcred_ngroups; i++) {
739 rb_str_catf(ret,
"%s%u", sep, cred.cmcred_groups[i]);
747 #if defined(HAVE_TYPE_STRUCT_SOCKCRED)
748 if ((
size_t)
RSTRING_LEN(data) >= SOCKCREDSIZE(0)) {
749 struct sockcred cred0, *cred;
750 memcpy(&cred0,
RSTRING_PTR(data), SOCKCREDSIZE(0));
751 if ((
size_t)
RSTRING_LEN(data) == SOCKCREDSIZE(cred0.sc_ngroups)) {
752 cred = (
struct sockcred *)
ALLOCA_N(
char, SOCKCREDSIZE(cred0.sc_ngroups));
753 memcpy(cred,
RSTRING_PTR(data), SOCKCREDSIZE(cred0.sc_ngroups));
758 if (cred0.sc_ngroups) {
760 const char *sep =
" groups=";
761 for (i = 0; i < cred0.sc_ngroups; i++) {
775 #if defined(IPPROTO_IP) && defined(IP_RECVDSTADDR)
777 anc_inspect_ip_recvdstaddr(
int level,
int type,
VALUE data,
VALUE ret)
779 if (level == IPPROTO_IP && type == IP_RECVDSTADDR &&
782 char addrbuf[INET_ADDRSTRLEN];
784 if (
inet_ntop(AF_INET, &addr, addrbuf, (socklen_t)
sizeof(addrbuf)) ==
NULL)
796 #if defined(IPPROTO_IP) && defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
798 anc_inspect_ip_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
800 if (level == IPPROTO_IP && type == IP_PKTINFO &&
802 struct in_pktinfo pktinfo;
804 memcpy(&pktinfo,
RSTRING_PTR(data),
sizeof(pktinfo));
805 if (
inet_ntop(AF_INET, &pktinfo.ipi_addr, buf,
sizeof(buf)) ==
NULL)
809 if (if_indextoname(pktinfo.ipi_ifindex, buf) ==
NULL)
810 rb_str_catf(ret,
" ifindex:%d", pktinfo.ipi_ifindex);
813 if (
inet_ntop(AF_INET, &pktinfo.ipi_spec_dst, buf,
sizeof(buf)) ==
NULL)
825 #if defined(IPPROTO_IPV6) && defined(IPV6_PKTINFO) && defined(HAVE_TYPE_STRUCT_IN6_PKTINFO)
827 anc_inspect_ipv6_pktinfo(
int level,
int type,
VALUE data,
VALUE ret)
829 if (level == IPPROTO_IPV6 && type == IPV6_PKTINFO &&
831 struct in6_pktinfo *pktinfo = (
struct in6_pktinfo *)
RSTRING_PTR(data);
832 struct in6_addr addr;
833 unsigned int ifindex;
834 char addrbuf[INET6_ADDRSTRLEN], ifbuf[
IFNAMSIZ];
835 memcpy(&addr, &pktinfo->ipi6_addr,
sizeof(addr));
836 memcpy(&ifindex, &pktinfo->ipi6_ifindex,
sizeof(ifindex));
837 if (
inet_ntop(AF_INET6, &addr, addrbuf, (socklen_t)
sizeof(addrbuf)) ==
NULL)
841 if (if_indextoname(ifindex, ifbuf) ==
NULL)
853 #if defined(SCM_TIMESTAMP)
855 inspect_timeval_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
864 tm = *localtime(&time);
865 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
866 rb_str_catf(ret,
" %s.%06ld", buf, (
long)tv.tv_usec);
875 #if defined(SCM_TIMESTAMPNS)
877 inspect_timespec_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
884 tm = *localtime(&ts.tv_sec);
885 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
886 rb_str_catf(ret,
" %s.%09ld", buf, (
long)ts.tv_nsec);
895 #if defined(SCM_BINTIME)
897 inspect_bintime_as_abstime(
int level,
int optname,
VALUE data,
VALUE ret)
908 tm = *localtime(&bt.sec);
909 strftime(buf,
sizeof(buf),
"%Y-%m-%d %H:%M:%S", &tm);
913 frac_h = bt.frac >> 32;
914 frac_l = bt.frac & 0xffffffff;
916 scale_h = 0x8ac72304;
917 scale_l = 0x89e80000;
919 res_h = frac_h * scale_h;
920 res_l = frac_l * scale_l;
922 tmp1 = frac_h * scale_l;
925 res_l += tmp1 & 0xffffffff;
926 if (res_l < tmp2) res_h++;
928 tmp1 = frac_l * scale_h;
931 res_l += tmp1 & 0xffffffff;
932 if (res_l < tmp2) res_h++;
953 ancillary_inspect(
VALUE self)
956 int family, level,
type;
958 ID family_id, level_id, type_id;
962 family = ancillary_family(
self);
963 level = ancillary_level(
self);
964 type = ancillary_type(
self);
965 data = ancillary_data(
self);
969 family_id = rsock_intern_family_noprefix(family);
975 if (level == SOL_SOCKET) {
978 type_id = rsock_intern_scm_optname(type);
985 level_id = rsock_intern_iplevel(level);
991 vtype = ip_cmsg_type_to_sym(level, type);
1004 if (level == SOL_SOCKET)
1010 # if defined(SOL_SOCKET)
1013 # if defined(SCM_TIMESTAMP)
1014 case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret);
break;
1016 # if defined(SCM_TIMESTAMPNS)
1017 case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret);
break;
1019 # if defined(SCM_BINTIME)
1020 case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret);
break;
1022 # if defined(SCM_RIGHTS)
1023 case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret);
break;
1025 # if defined(SCM_CREDENTIALS)
1026 case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret);
break;
1028 # if defined(INSPECT_SCM_CREDS)
1029 case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret);
break;
1042 # if defined(IPPROTO_IP)
1045 # if defined(IP_RECVDSTADDR)
1046 case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret);
break;
1048 # if defined(IP_PKTINFO) && defined(HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST)
1049 case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret);
break;
1055 # if defined(IPPROTO_IPV6)
1058 # if defined(IPV6_PKTINFO)
1059 case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret);
break;
1093 int family = ancillary_family(
self);
1097 if (ancillary_level(
self) == level &&
1098 ancillary_type(
self) == type)
1106 #if defined(HAVE_SENDMSG)
1107 struct sendmsg_args_struct {
1114 nogvl_sendmsg_func(
void *ptr)
1116 struct sendmsg_args_struct *
args = ptr;
1117 return sendmsg(args->fd, args->msg, args->flags);
1121 rb_sendmsg(
int fd,
const struct msghdr *
msg,
int flags)
1123 struct sendmsg_args_struct
args;
1131 bsock_sendmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1134 VALUE data, vflags, dest_sockaddr;
1135 VALUE *controls_ptr;
1139 #if defined(HAVE_ST_MSG_CONTROL)
1140 volatile VALUE controls_str = 0;
1150 data = vflags = dest_sockaddr =
Qnil;
1151 controls_ptr =
NULL;
1157 if (1 < argc) vflags = argv[1];
1158 if (2 < argc) dest_sockaddr = argv[2];
1159 if (3 < argc) { controls_ptr = &argv[3]; controls_num = argc - 3; }
1164 #if defined(HAVE_ST_MSG_CONTROL)
1166 size_t last_pad = 0;
1170 for (i = 0; i < controls_num; i++) {
1171 VALUE elt = controls_ptr[
i],
v;
1172 VALUE vlevel, vtype;
1200 memset((
char *)cmsg, 0, cspace);
1201 memset((
char *)&cmh, 0,
sizeof(cmh));
1202 cmh.cmsg_level = level;
1203 cmh.cmsg_type =
type;
1204 cmh.cmsg_len = (socklen_t)CMSG_LEN(
RSTRING_LEN(cdata));
1205 MEMCPY(cmsg, &cmh,
char,
sizeof(cmh));
1207 last_level = cmh.cmsg_level;
1208 last_type = cmh.cmsg_type;
1209 last_pad = cspace - cmh.cmsg_len;
1232 #if defined(__NetBSD__)
1233 if (last_level == SOL_SOCKET && last_type == SCM_RIGHTS)
1245 flags |= MSG_DONTWAIT;
1248 if (!
NIL_P(dest_sockaddr))
1254 memset(&mh, 0,
sizeof(mh));
1255 if (!
NIL_P(dest_sockaddr)) {
1263 #if defined(HAVE_ST_MSG_CONTROL)
1269 mh.msg_control =
NULL;
1270 mh.msg_controllen = 0;
1278 ss = rb_sendmsg(fptr->
fd, &mh, flags);
1295 #if defined(HAVE_SENDMSG)
1331 return bsock_sendmsg_internal(argc, argv, sock, 0);
1335 #if defined(HAVE_SENDMSG)
1350 return bsock_sendmsg_internal(argc, argv, sock, 1);
1354 #if defined(HAVE_RECVMSG)
1355 struct recvmsg_args_struct {
1362 nogvl_recvmsg_func(
void *ptr)
1364 struct recvmsg_args_struct *
args = ptr;
1365 return recvmsg(args->fd, args->msg, args->flags);
1369 rb_recvmsg(
int fd,
struct msghdr *
msg,
int flags)
1371 struct recvmsg_args_struct
args;
1378 #if defined(HAVE_ST_MSG_CONTROL)
1380 discard_cmsg(
struct cmsghdr *cmh,
char *msg_end,
int msg_peek_p)
1382 # if !defined(FD_PASSING_WORK_WITH_RECVMSG_MSG_PEEK)
1394 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1395 int *fdp = (
int *)CMSG_DATA(cmh);
1396 int *end = (
int *)((
char *)cmh + cmh->cmsg_len);
1397 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1398 (
char *)fdp +
sizeof(
int) <= msg_end) {
1408 rsock_discard_cmsg_resource(
struct msghdr *mh,
int msg_peek_p)
1410 #if defined(HAVE_ST_MSG_CONTROL)
1411 struct cmsghdr *cmh;
1419 for (cmh = CMSG_FIRSTHDR(mh); cmh !=
NULL; cmh = CMSG_NXTHDR(mh, cmh)) {
1420 discard_cmsg(cmh, msg_end, msg_peek_p);
1425 #if defined(HAVE_ST_MSG_CONTROL)
1427 make_io_for_unix_rights(
VALUE ctl,
struct cmsghdr *cmh,
char *msg_end)
1429 if (cmh->cmsg_level == SOL_SOCKET && cmh->cmsg_type == SCM_RIGHTS) {
1433 fdp = (
int *)CMSG_DATA(cmh);
1434 end = (
int *)((
char *)cmh + cmh->cmsg_len);
1435 while ((
char *)fdp +
sizeof(int) <= (
char *)end &&
1436 (
char *)fdp +
sizeof(
int) <= msg_end) {
1440 if (
fstat(fd, &stbuf) == -1)
1443 if (S_ISSOCK(stbuf.st_mode))
1457 bsock_recvmsg_internal(
int argc,
VALUE *argv,
VALUE sock,
int nonblock)
1460 VALUE vmaxdatlen, vmaxctllen, vflags, vopts;
1463 int flags, orig_flags;
1464 int request_scm_rights;
1468 char datbuf0[4096], *datbuf;
1472 #if defined(HAVE_ST_MSG_CONTROL)
1473 struct cmsghdr *cmh;
1477 struct cmsghdr align;
1488 if (0 < argc &&
TYPE(argv[argc-1]) ==
T_HASH)
1489 vopts = argv[--
argc];
1491 rb_scan_args(argc, argv,
"03", &vmaxdatlen, &vflags, &vmaxctllen);
1493 maxdatlen =
NIL_P(vmaxdatlen) ?
sizeof(datbuf0) :
NUM2SIZET(vmaxdatlen);
1494 #if defined(HAVE_ST_MSG_CONTROL)
1495 maxctllen =
NIL_P(vmaxctllen) ?
sizeof(ctlbuf0) :
NUM2SIZET(vmaxctllen);
1497 if (!
NIL_P(vmaxctllen))
1503 flags |= MSG_DONTWAIT;
1507 grow_buffer =
NIL_P(vmaxdatlen) ||
NIL_P(vmaxctllen);
1509 request_scm_rights = 0;
1511 request_scm_rights = 1;
1518 #if !defined(HAVE_ST_MSG_CONTROL)
1521 socklen_t optlen = (socklen_t)
sizeof(socktype);
1522 if (getsockopt(fptr->
fd, SOL_SOCKET, SO_TYPE, (
void*)&socktype, &optlen) == -1) {
1525 if (socktype == SOCK_STREAM)
1531 if (maxdatlen <=
sizeof(datbuf0))
1541 #if defined(HAVE_ST_MSG_CONTROL)
1542 if (maxctllen <=
sizeof(ctlbuf0))
1543 ctlbuf = ctlbuf0.bytes;
1553 memset(&mh, 0,
sizeof(mh));
1555 memset(&namebuf, 0,
sizeof(namebuf));
1556 mh.
msg_name = (
struct sockaddr *)&namebuf;
1561 iov.iov_base = datbuf;
1562 iov.iov_len = maxdatlen;
1564 #if defined(HAVE_ST_MSG_CONTROL)
1576 ss = rb_recvmsg(fptr->
fd, &mh, flags);
1586 #if defined(HAVE_ST_MSG_CONTROL)
1605 #if defined(HAVE_ST_MSG_CONTROL)
1613 #define BIG_ENOUGH_SPACE 65536
1614 if (BIG_ENOUGH_SPACE < maxctllen &&
1619 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1629 #undef BIG_ENOUGH_SPACE
1632 if (
NIL_P(vmaxdatlen) && ss != -1 && ss == (ssize_t)iov.iov_len) {
1640 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1645 if (flags != orig_flags) {
1646 rsock_discard_cmsg_resource(&mh, (flags & MSG_PEEK) != 0);
1663 #
if defined(HAVE_ST_MSG_CONTROL)
1670 #if defined(HAVE_ST_MSG_CONTROL)
1674 for (cmh = CMSG_FIRSTHDR(&mh); cmh !=
NULL; cmh = CMSG_NXTHDR(&mh, cmh)) {
1678 if (cmh->cmsg_len == 0) {
1681 ctl_end = (
char*)cmh + cmh->cmsg_len;
1682 clen = (ctl_end <= msg_end ? ctl_end : msg_end) - (
char*)CMSG_DATA(cmh);
1683 ctl = ancdata_new(family, cmh->cmsg_level, cmh->cmsg_type,
rb_tainted_str_new((
char*)CMSG_DATA(cmh), clen));
1684 if (request_scm_rights)
1685 make_io_for_unix_rights(ctl, cmh, msg_end);
1687 discard_cmsg(cmh, msg_end, (flags & MSG_PEEK) != 0);
1697 #if defined(HAVE_RECVMSG)
1754 return bsock_recvmsg_internal(argc, argv, sock, 0);
1758 #if defined(HAVE_RECVMSG)
1773 return bsock_recvmsg_internal(argc, argv, sock, 1);
1780 #if defined(HAVE_ST_MSG_CONTROL)
1789 rb_define_method(rb_cAncillaryData,
"initialize", ancillary_initialize, 4);
1802 rb_define_method(rb_cAncillaryData,
"unix_rights", ancillary_unix_rights, 0);
1807 rb_define_method(rb_cAncillaryData,
"ip_pktinfo", ancillary_ip_pktinfo, 0);
1810 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo", ancillary_ipv6_pktinfo, 0);
1811 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_addr", ancillary_ipv6_pktinfo_addr, 0);
1812 rb_define_method(rb_cAncillaryData,
"ipv6_pktinfo_ifindex", ancillary_ipv6_pktinfo_ifindex, 0);
RUBY_EXTERN VALUE rb_cString
VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, rb_unblock_function_t *ubf, void *data2)
#define RSTRING_LEN(string)
static VALUE UINT2NUM(unsigned int v)
VALUE rb_ary_entry(VALUE ary, long offset)
void rb_update_max_fd(int fd)
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)
static VALUE INT2NUM(int v)
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
#define RSTRING_PTR(string)
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
#define RARRAY_LEN(ARRAY)
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)
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)
#define NEWOBJ(obj, type)
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)
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]
#define RARRAY_PTR(ARRAY)
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)
VALUE rb_hash_aref(VALUE hash, VALUE key)
VALUE rb_str_catf(VALUE str, const char *format,...)
#define rb_str_set_len(str, length)
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)
#define OBJSETUP(obj, c, t)
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)