public static IObservable <TcpClientTermination> ServeTcp <TSource>(
     this IQbservable <TSource> source,
     IPEndPoint endPoint,
     IRemotingFormatter formatter,
     QbservableServiceOptions options)
 {
     return(QbservableTcpServer.CreateService <object, TSource>(endPoint, formatter, options, _ => source));
 }
Example #2
0
 public static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
     IPEndPoint endPoint,
     IRemotingFormatter formatter,
     QbservableServiceOptions options,
     Func <IObservable <TSource>, IQbservable <TResult> > service)
 {
     return(CreateService <TSource, TResult>(endPoint, () => formatter, options, service));
 }
 public TcpServerQbservableProvider(
     QbservableProtocol protocol,
     QbservableServiceOptions options,
     Func <object, IQbservable <TSource> > sourceSelector)
 {
     this.protocol       = protocol;
     this.options        = options;
     this.sourceSelector = sourceSelector;
 }
 public static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
     AppDomainSetup appDomainSetup,
     IPEndPoint endPoint,
     QbservableServiceOptions options,
     Func <IObservable <TSource>, IQbservable <TResult> > service,
     [CallerMemberName] string appDomainBaseName = null,
     params Assembly[] fullTrustAssemblies)
 {
     return(CreateService <TSource, TResult>(appDomainSetup, endPoint, CreateDefaultFormatter, options, service, appDomainBaseName, fullTrustAssemblies));
 }
 public static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
     AppDomainSetup appDomainSetup,
     IPEndPoint endPoint,
     Func <IRemotingFormatter> formatterFactory,
     QbservableServiceOptions options,
     Func <IObservable <TSource>, IObservable <TResult> > service,
     [CallerMemberName] string appDomainBaseName = null,
     params Assembly[] fullTrustAssemblies)
 {
     return(CreateService <TSource, TResult>(appDomainSetup, endPoint, formatterFactory, options, new QbservableServiceConverter <TSource, TResult>(service).Convert, appDomainBaseName, fullTrustAssemblies));
 }
        public static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
            AppDomainSetup appDomainSetup,
            PermissionSet permissions,
            IPEndPoint endPoint,
            Func <IRemotingFormatter> formatterFactory,
            QbservableServiceOptions options,
            Func <IObservable <TSource>, IQbservable <TResult> > service,
            [CallerMemberName] string appDomainBaseName = null,
            params Assembly[] fullTrustAssemblies)
        {
            var minimumPermissions = new PermissionSet(PermissionState.None);

            minimumPermissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
            minimumPermissions.AddPermission(new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, endPoint.Address.ToString(), endPoint.Port));

            var entryAssembly = Assembly.GetEntryAssembly();

            var domain = AppDomain.CreateDomain(
                Interlocked.Increment(ref appDomainNumber) + ':' + appDomainBaseName,
                null,
                appDomainSetup,
                minimumPermissions.Union(permissions),
                new[]
            {
                typeof(QbservableTcpServer).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(Rxx.Parsers.Linq.Parser).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(System.Reactive.Linq.Observable).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(System.Reactive.Linq.Qbservable).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(System.Reactive.Notification).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(System.Reactive.IEventPattern <,>).Assembly.Evidence.GetHostEvidence <StrongName>(),
                typeof(System.Reactive.Concurrency.TaskPoolScheduler).Assembly.Evidence.GetHostEvidence <StrongName>()
            }
                .Concat(entryAssembly == null ? new StrongName[0] : new[] { entryAssembly.Evidence.GetHostEvidence <StrongName>() })
                .Concat(fullTrustAssemblies.Select(assembly => assembly.Evidence.GetHostEvidence <StrongName>()))
                .ToArray());

            try
            {
                var handle = Activator.CreateInstanceFrom(
                    domain,
                    typeof(CreateServiceProxy <TSource, TResult>).Assembly.ManifestModule.FullyQualifiedName,
                    typeof(CreateServiceProxy <TSource, TResult>).FullName);

                var proxy = (CreateServiceProxy <TSource, TResult>)handle.Unwrap();

                return(proxy.CreateService(endPoint, options, new CreateServiceProxyDelegates <TSource, TResult>(formatterFactory, service))
                       .Finally(() => AppDomain.Unload(domain)));
            }
            catch
            {
                AppDomain.Unload(domain);
                throw;
            }
        }
        public static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
            AppDomainSetup appDomainSetup,
            IPEndPoint endPoint,
            Func <IRemotingFormatter> formatterFactory,
            QbservableServiceOptions options,
            Func <IObservable <TSource>, IQbservable <TResult> > service,
            [CallerMemberName] string appDomainBaseName = null,
            params Assembly[] fullTrustAssemblies)
        {
            var permissions = new PermissionSet(PermissionState.None);

            return(CreateService <TSource, TResult>(appDomainSetup, permissions, endPoint, formatterFactory, options, service, appDomainBaseName, fullTrustAssemblies));
        }
            public IObservable <TcpClientTermination> CreateService(
                IPEndPoint endPoint,
                QbservableServiceOptions options,
                CreateServiceProxyDelegates <TSource, TResult> delegates)
            {
                Func <IRemotingFormatter> formatterFactory;
                Func <IObservable <TSource>, IQbservable <TResult> > service;

                /* Retrieving a cross-domain delegate always fails with a SecurityException due to
                 * a Demand for ReflectionPermission, regardless of whether that permission is asserted
                 * here or even whether full trust is asserted (commented line).  It is unclear why the
                 * assertions don't work.  The only solution appears to be that the delegates must
                 * point to public members.
                 *
                 * (Alternatively, adding the ReflectionPermission to the minimum permission set of the
                 * AppDomain works as well, but it's more secure to disallow it entirely to prevent
                 * reflection from executing within clients' expression trees, just in case the host
                 * relaxes the service options to allow unrestricted expressions constrained only by
                 * the minimum AppDomain permissions; i.e., The Principle of Least Surprise.)
                 *
                 * new PermissionSet(PermissionState.Unrestricted).Assert();
                 */

                try
                {
                    formatterFactory = delegates.FormatterFactory;
                    service          = delegates.Service;
                }
                catch (SecurityException ex)
                {
                    throw new ArgumentException(Errors.CreateServiceDelegatesNotPublic, ex);
                }
                finally
                {
                    /* This line is unnecessary - see comments above.
                     * PermissionSet.RevertAssert();
                     */
                }

                return(QbservableTcpServer
                       .CreateService <TSource, TResult>(endPoint, formatterFactory, options, service)
                       .RemotableWithoutConfiguration());
            }
Example #9
0
        public SecurityExpressionVisitor(QbservableServiceOptions serviceOptions)
        {
            this.options = serviceOptions.ExpressionOptions;
            this.context = serviceOptions.EvaluationContext;

            if (options.HasFlag(ExpressionOptions.AllowTypeTests) &&
                options.HasFlag(ExpressionOptions.AllowExplicitConversions))
            {
                context.EnsureHasKnownOperator("Cast");
                context.EnsureHasKnownOperator("OfType");
            }

            if (options.HasFlag(ExpressionOptions.AllowCatchBlocks))
            {
                context.EnsureHasKnownOperator("Catch");
                context.EnsureHasKnownOperator("OnErrorResumeNext");
                context.EnsureHasKnownOperator("Retry");
            }
        }
        public static async Task <QbservableProtocol> NegotiateServerAsync(Stream stream, IRemotingFormatter formatter, QbservableServiceOptions serviceOptions, CancellationToken cancel)
        {
            // TODO: Enable protocol registration and implement actual protocol negotiation

            var protocol = new DefaultQbservableProtocol(stream, formatter, serviceOptions, cancel);

            var buffer = new byte[4];

            await protocol.ReceiveAsync(buffer, 0, 4).ConfigureAwait(false);

            await protocol.SendAsync(buffer, 0, 4).ConfigureAwait(false);

            return(protocol);
        }
 protected QbservableProtocol(Stream stream, IRemotingFormatter formatter, QbservableServiceOptions serviceOptions, CancellationToken cancel)
     : base(stream, formatter, serviceOptions, cancel)
 {
     Contract.Ensures(!IsClient);
 }
 public DefaultQbservableProtocol(Stream stream, IRemotingFormatter formatter, QbservableServiceOptions serviceOptions, CancellationToken cancel)
     : base(stream, formatter, serviceOptions, cancel)
 {
 }
Example #13
0
        private static IObservable <TcpClientTermination> CreateService <TSource, TResult>(
            IPEndPoint endPoint,
            Func <IRemotingFormatter> formatterFactory,
            QbservableServiceOptions options,
            Func <IObservable <TSource>, IQbservable <TResult> > service)
        {
            return(ObservableTcpListener
                   .Start(endPoint, maxConcurrent: 1)                           // maxConcurrent must be 1 to ensure thread-safety.  See the Start method's remarks for details.
                   .SelectMany(client => Observable
                               .StartAsync(async cancel =>
            {
                var watch = Stopwatch.StartNew();

                // disable Nagle algorithm so that observed events are sent as soon as they happen
                client.NoDelay = true;

                var localEndPoint = client.Client.LocalEndPoint;
                var remoteEndPoint = client.Client.RemoteEndPoint;

                var exceptions = new List <ExceptionDispatchInfo>();
                var shutDownReason = QbservableProtocolShutDownReason.None;

                try
                {
                    using (var stream = client.GetStream())
                        using (var protocol = await QbservableProtocol.NegotiateServerAsync(stream, formatterFactory(), options, cancel).ConfigureAwait(false))
                        {
                            var provider = new TcpServerQbservableProvider <TResult>(
                                protocol,
                                options,
                                argument =>
                            {
                                if (argument == null && typeof(TSource).IsValueType)
                                {
                                    return service(Observable.Return(default(TSource)));
                                }
                                else
                                {
                                    return service(Observable.Return((TSource)argument));
                                }
                            });

                            try
                            {
                                await protocol.ExecuteServerAsync(provider).ConfigureAwait(false);
                            }
                            catch (OperationCanceledException)
                            {
                            }
                            catch (Exception ex)
                            {
                                exceptions.Add(ExceptionDispatchInfo.Capture(ex));
                            }

                            var protocolExceptions = protocol.Exceptions;

                            if (protocolExceptions != null)
                            {
                                foreach (var exception in protocolExceptions)
                                {
                                    exceptions.Add(exception);
                                }
                            }

                            shutDownReason = protocol.ShutDownReason;
                        }
                }
                catch (OperationCanceledException)
                {
                    shutDownReason = QbservableProtocolShutDownReason.ProtocolNegotiationCancelled;
                }
                catch (Exception ex)
                {
                    shutDownReason = QbservableProtocolShutDownReason.ProtocolNegotiationError;

                    exceptions.Add(ExceptionDispatchInfo.Capture(ex));
                }

                return new TcpClientTermination(localEndPoint, remoteEndPoint, watch.Elapsed, shutDownReason, exceptions);
            })
                               .Finally(client.Close)));
        }