|
@@ -1206,182 +1206,3 @@ struct handle_ops udpsrv_ops = {
|
|
|
.attrquerybyhdl = &socket_attrquerybyhdl,
|
|
|
.attrsetbyhdl = &socket_attrsetbyhdl,
|
|
|
};
|
|
|
-
|
|
|
-PAL_HANDLE _DkBroadcastStreamOpen(void) {
|
|
|
- if (!pal_sec.mcast_port) {
|
|
|
- unsigned short mcast_port;
|
|
|
- _DkFastRandomBitsRead(&mcast_port, sizeof(unsigned short));
|
|
|
- pal_sec.mcast_port = mcast_port > 1024 ? mcast_port : mcast_port + 1024;
|
|
|
- }
|
|
|
-
|
|
|
- struct sockaddr_in addr;
|
|
|
- int ret = 0;
|
|
|
- addr.sin_family = AF_INET;
|
|
|
- addr.sin_addr.s_addr = INADDR_ANY;
|
|
|
- addr.sin_port = __htons(pal_sec.mcast_port);
|
|
|
-
|
|
|
- /* set up server (sender) side */
|
|
|
-
|
|
|
- int srv = INLINE_SYSCALL(socket, 3, AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
|
|
-
|
|
|
- if (IS_ERR(srv))
|
|
|
- goto err;
|
|
|
-
|
|
|
- ret = INLINE_SYSCALL(setsockopt, 5, srv, IPPROTO_IP, IP_MULTICAST_IF, &addr.sin_addr.s_addr,
|
|
|
- sizeof(addr.sin_addr.s_addr));
|
|
|
- if (IS_ERR(ret))
|
|
|
- goto err_srv;
|
|
|
-
|
|
|
- /* set up client (receiver) side */
|
|
|
-
|
|
|
- int cli = INLINE_SYSCALL(socket, 3, AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
|
|
-
|
|
|
- if (IS_ERR(cli))
|
|
|
- goto err_srv;
|
|
|
-
|
|
|
- int reuse = 1;
|
|
|
- INLINE_SYSCALL(setsockopt, 5, cli, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
|
|
-
|
|
|
- ret = INLINE_SYSCALL(bind, 3, cli, &addr, sizeof(addr));
|
|
|
- if (IS_ERR(ret))
|
|
|
- goto err_cli;
|
|
|
-
|
|
|
- ret = INLINE_SYSCALL(setsockopt, 5, cli, IPPROTO_IP, IP_MULTICAST_IF, &addr.sin_addr.s_addr,
|
|
|
- sizeof(addr.sin_addr.s_addr));
|
|
|
- if (IS_ERR(ret))
|
|
|
- goto err_cli;
|
|
|
-
|
|
|
- inet_pton4(GRAPHENE_MCAST_GROUP, sizeof(GRAPHENE_MCAST_GROUP) - 1, &addr.sin_addr.s_addr);
|
|
|
-
|
|
|
- struct ip_mreq group;
|
|
|
- group.imr_multiaddr.s_addr = addr.sin_addr.s_addr;
|
|
|
- group.imr_interface.s_addr = INADDR_ANY;
|
|
|
- ret = INLINE_SYSCALL(setsockopt, 5, cli, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));
|
|
|
- if (IS_ERR(ret))
|
|
|
- goto err_cli;
|
|
|
-
|
|
|
- PAL_HANDLE hdl = malloc(HANDLE_SIZE(mcast));
|
|
|
- SET_HANDLE_TYPE(hdl, mcast);
|
|
|
- HANDLE_HDR(hdl)->flags |= WFD(1);
|
|
|
- hdl->mcast.srv = srv;
|
|
|
- hdl->mcast.cli = cli;
|
|
|
- hdl->mcast.port = (PAL_NUM)pal_sec.mcast_port;
|
|
|
- hdl->mcast.nonblocking = PAL_FALSE;
|
|
|
- hdl->mcast.addr = (PAL_PTR)malloc_copy(&addr, sizeof(addr));
|
|
|
- return hdl;
|
|
|
-
|
|
|
-err_cli:
|
|
|
- INLINE_SYSCALL(close, 1, cli);
|
|
|
-err_srv:
|
|
|
- INLINE_SYSCALL(close, 1, srv);
|
|
|
-err:
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-static int64_t mcast_send(PAL_HANDLE handle, uint64_t offset, uint64_t size, const void* buf) {
|
|
|
- if (offset)
|
|
|
- return -PAL_ERROR_INVAL;
|
|
|
-
|
|
|
- if (handle->mcast.srv == PAL_IDX_POISON)
|
|
|
- return -PAL_ERROR_BADHANDLE;
|
|
|
-
|
|
|
- struct msghdr hdr;
|
|
|
- struct iovec iov;
|
|
|
- iov.iov_base = (void*)buf;
|
|
|
- iov.iov_len = size;
|
|
|
- hdr.msg_name = (char*)handle->mcast.addr;
|
|
|
- hdr.msg_namelen = sizeof(struct sockaddr_in);
|
|
|
- hdr.msg_iov = &iov;
|
|
|
- hdr.msg_iovlen = 1;
|
|
|
- hdr.msg_control = NULL;
|
|
|
- hdr.msg_controllen = 0;
|
|
|
- hdr.msg_flags = 0;
|
|
|
-
|
|
|
- int64_t bytes = INLINE_SYSCALL(sendmsg, 3, handle->mcast.srv, &hdr, MSG_NOSIGNAL);
|
|
|
-
|
|
|
- if (IS_ERR(bytes))
|
|
|
- switch (ERRNO(bytes)) {
|
|
|
- case ECONNRESET:
|
|
|
- case EPIPE:
|
|
|
- return -PAL_ERROR_CONNFAILED;
|
|
|
- default:
|
|
|
- return unix_to_pal_error(ERRNO(bytes));
|
|
|
- }
|
|
|
-
|
|
|
- assert(!IS_ERR(bytes));
|
|
|
- return bytes;
|
|
|
-}
|
|
|
-
|
|
|
-static int64_t mcast_receive(PAL_HANDLE handle, uint64_t offset, size_t size, void* buf) {
|
|
|
- if (offset)
|
|
|
- return -PAL_ERROR_INVAL;
|
|
|
-
|
|
|
- if (handle->mcast.cli == PAL_IDX_POISON)
|
|
|
- return -PAL_ERROR_BADHANDLE;
|
|
|
-
|
|
|
- struct msghdr hdr;
|
|
|
- struct iovec iov;
|
|
|
- iov.iov_base = buf;
|
|
|
- iov.iov_len = size;
|
|
|
- hdr.msg_name = NULL;
|
|
|
- hdr.msg_namelen = 0;
|
|
|
- hdr.msg_iov = &iov;
|
|
|
- hdr.msg_iovlen = 1;
|
|
|
- hdr.msg_control = NULL;
|
|
|
- hdr.msg_controllen = 0;
|
|
|
- hdr.msg_flags = 0;
|
|
|
-
|
|
|
- int64_t bytes = INLINE_SYSCALL(recvmsg, 3, handle->mcast.cli, &hdr, 0);
|
|
|
-
|
|
|
- if (IS_ERR(bytes))
|
|
|
- return -PAL_ERROR_DENIED;
|
|
|
-
|
|
|
- return bytes;
|
|
|
-}
|
|
|
-
|
|
|
-static int mcast_attrquerybyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
|
|
- int ret, val;
|
|
|
-
|
|
|
- if (handle->mcast.cli == PAL_IDX_POISON)
|
|
|
- return -PAL_ERROR_BADHANDLE;
|
|
|
-
|
|
|
- ret = INLINE_SYSCALL(ioctl, 3, handle->mcast.cli, FIONREAD, &val);
|
|
|
- if (IS_ERR(ret))
|
|
|
- return unix_to_pal_error(ERRNO(ret));
|
|
|
-
|
|
|
- attr->handle_type = pal_type_mcast;
|
|
|
- attr->disconnected = HANDLE_HDR(handle)->flags & (ERROR(0) | ERROR(1));
|
|
|
- attr->nonblocking = handle->mcast.nonblocking;
|
|
|
- attr->readable = !!val;
|
|
|
- attr->writable = PAL_TRUE;
|
|
|
- attr->runnable = PAL_FALSE;
|
|
|
- attr->pending_size = val;
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static int mcast_attrsetbyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
|
|
- if (handle->mcast.cli == PAL_IDX_POISON)
|
|
|
- return -PAL_ERROR_BADHANDLE;
|
|
|
-
|
|
|
- int ret;
|
|
|
- PAL_BOL* nonblocking = &handle->mcast.nonblocking;
|
|
|
-
|
|
|
- if (attr->nonblocking != *nonblocking) {
|
|
|
- ret = INLINE_SYSCALL(fcntl, 3, handle->mcast.cli, F_SETFL, *nonblocking ? O_NONBLOCK : 0);
|
|
|
-
|
|
|
- if (IS_ERR(ret))
|
|
|
- return unix_to_pal_error(ERRNO(ret));
|
|
|
-
|
|
|
- *nonblocking = attr->nonblocking;
|
|
|
- }
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-struct handle_ops mcast_ops = {
|
|
|
- .write = &mcast_send,
|
|
|
- .read = &mcast_receive,
|
|
|
- .attrquerybyhdl = &mcast_attrquerybyhdl,
|
|
|
- .attrsetbyhdl = &mcast_attrsetbyhdl,
|
|
|
-};
|