| 
					
				 | 
			
			
				@@ -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, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}; 
			 |