public OutputStreamBase( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, byte[] header) { this.PeerCast = peercast; this.Connection = new StreamConnection(input_stream, output_stream, header); this.Connection.SendTimeout = 10000; this.RemoteEndPoint = remote_endpoint; this.AccessControl = access_control; this.Channel = channel; var ip = remote_endpoint as IPEndPoint; this.IsLocal = ip != null?ip.Address.IsSiteLocal() : true; this.IsStopped = false; this.mainThread = new Thread(MainProc); this.mainThread.Name = String.Format("{0}:{1}", this.GetType().Name, remote_endpoint); this.SyncContext = new QueuedSynchronizationContext(); this.Logger = new Logger(this.GetType()); }
public OutputStreamBase( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, byte[] header) { this.PeerCast = peercast; this.InputStream = input_stream; this.OutputStream = output_stream; this.RemoteEndPoint = remote_endpoint; this.AccessControl = access_control; this.Channel = channel; var ip = remote_endpoint as IPEndPoint; this.IsLocal = ip!=null ? Utils.IsSiteLocal(ip.Address) : true; this.IsStopped = false; this.mainThread = new Thread(MainProc); this.mainThread.Name = String.Format("{0}:{1}", this.GetType().Name, remote_endpoint); this.SyncContext = new QueuedSynchronizationContext(); this.Logger = new Logger(this.GetType()); if (header!=null) { this.recvStream.Write(header, 0, header.Length); } this.SendTimeout = 10000; }
public virtual Guid?ParseChannelID(byte[] header, AccessControlInfo acinfo) { if ((acinfo.Accepts & OutputStreamType) == 0) { return(null); } return(ParseChannelID(header)); }
public async Task HandleClient( IPEndPoint localEndPoint, TcpClient client, AccessControlInfo acinfo, CancellationToken cancellationToken) { logger.Debug("Output thread started"); client.ReceiveBufferSize = 256 * 1024; client.SendBufferSize = 256 * 1024; client.NoDelay = true; var stream = client.GetStream(); int trying = 0; try { retry: stream.WriteTimeout = 3000; stream.ReadTimeout = 3000; (var clientOrNull, var handler) = await CreateMatchedHandler( client, stream, acinfo, cancellationToken).ConfigureAwait(false); client = clientOrNull; if (handler != null) { logger.Debug("Output stream started {0}", trying); var result = await handler.Start(cancellationToken).ConfigureAwait(false); switch (result) { case HandlerResult.Continue: trying++; goto retry; case HandlerResult.Close: case HandlerResult.Error: default: break; } } else { logger.Debug("No protocol handler matched"); } } catch (OperationCanceledException) { } finally { if (client != null) { client.Client.Shutdown(SocketShutdown.Send); logger.Debug("Closing client connection"); stream.Close(); client.Close(); } } }
public PCPPongOutputStream( PeerCast peercast, Stream input_stream, Stream output_stream, IPEndPoint endpoint, AccessControlInfo access_control, byte[] header) : base(peercast, input_stream, output_stream, endpoint, access_control, null, header) { Logger.Debug("Initialized: Remote {0}", endpoint); }
private void OutputThreadFunc(object arg) { logger.Debug("Output thread started"); var client = (TcpClient)arg; client.ReceiveBufferSize = 64 * 1024; client.SendBufferSize = 64 * 1024; var stream = client.GetStream(); stream.WriteTimeout = 3000; stream.ReadTimeout = 3000; IOutputStream output_stream = null; Channel channel = null; try { var remote_endpoint = (IPEndPoint)client.Client.RemoteEndPoint; List <byte> header; Guid channel_id; AuthenticationKey auth_key; var factory = FindMatchedFactory(GetRemoteType(remote_endpoint), stream, out header, out channel_id, out auth_key); if (factory != null) { var access_control = new AccessControlInfo(auth_key); output_stream = factory.Create(stream, stream, remote_endpoint, access_control, channel_id, header.ToArray()); channel = PeerCast.Channels.FirstOrDefault(c => c.ChannelID == channel_id); if (channel != null) { channel.AddOutputStream(output_stream); } logger.Debug("Output stream started"); var wait_stopped = new EventWaitHandle(false, EventResetMode.ManualReset); output_stream.Stopped += (sender, args) => { wait_stopped.Set(); }; output_stream.Start(); wait_stopped.WaitOne(); } else { logger.Debug("No protocol matched"); } } finally { logger.Debug("Closing client connection"); if (output_stream != null && channel != null) { channel.RemoveOutputStream(output_stream); } stream.Close(); client.Close(); lock (outputThreads) { outputThreads.Remove(Thread.CurrentThread); } logger.Debug("Output thread finished"); } }
public HTTPDummyOutputStream( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, HTTPRequest req) : base(peercast, input_stream, output_stream, remote_endpoint, access_control, null, null) { Logger.Debug("Initialized: Remote {0}", remote_endpoint); this.request = req; }
private async Task <(TcpClient, IOutputStream)> CreateMatchedHandler( TcpClient client, NetworkStream stream, AccessControlInfo acinfo, CancellationToken cancellationToken) { var output_factories = PeerCast.OutputStreamFactories.OrderBy(factory => factory.Priority); var header = new byte[4096]; int offset = 0; using (var cancel_source = new CancellationTokenSource(TimeSpan.FromMilliseconds(3000))) using (cancellationToken.Register(() => stream.Close(), false)) using (cancel_source.Token.Register(() => stream.Close(), false)) { try { while (offset < header.Length) { var len = await stream.ReadAsync(header, offset, header.Length - offset, cancellationToken).ConfigureAwait(false); if (len == 0) { break; } offset += len; var header_ary = header.Take(offset).ToArray(); foreach (var factory in output_factories) { var channel_id = factory.ParseChannelID(header_ary, acinfo); if (channel_id.HasValue) { if (factory.Name == "PCPGiv") { PeerCast.AddGivSocket(channel_id.Value, client.Client.AddressFamily, client.Client); return(null, factory.Create(null, acinfo, channel_id.Value)); } else { var connection = new ConnectionStream(client.Client, stream, header_ary); return(client, factory.Create(connection, acinfo, channel_id.Value)); } } } } } catch (ObjectDisposedException) { } catch (IOException) { } } logger.Debug("CreateMatchedHandle returning null"); return(client, null); }
private async Task <IOutputStream> CreateMatchedHandler( IPEndPoint remote_endpoint, NetworkStream stream, AccessControlInfo acinfo) { var output_factories = PeerCast.OutputStreamFactories.OrderBy(factory => factory.Priority); var header = new byte[4096]; int offset = 0; using (var cancel_source = new CancellationTokenSource(TimeSpan.FromMilliseconds(3000))) { var cancel_token = cancel_source.Token; cancel_token.Register(() => stream.Close()); try { while (offset < header.Length) { var len = await stream.ReadAsync(header, offset, header.Length - offset).ConfigureAwait(false); if (len == 0) { break; } offset += len; var header_ary = header.Take(offset).ToArray(); foreach (var factory in output_factories) { if ((acinfo.Accepts & factory.OutputStreamType) == 0) { continue; } var channel_id = factory.ParseChannelID(header_ary); if (channel_id.HasValue) { return(factory.Create( stream, stream, remote_endpoint, acinfo, channel_id.Value, header_ary)); } } } } catch (System.ObjectDisposedException) { } catch (System.IO.IOException) { } } return(null); }
public AdminHostOutputStream( AdminHost owner, PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, HTTPRequest request) : base(peercast, input_stream, output_stream, remote_endpoint, access_control, null, null) { this.owner = owner; this.request = request; Logger.Debug("Initialized: Remote {0}", remote_endpoint); }
/// <summary> /// 元になるストリーム、チャンネル、リクエストからHTTPOutputStreamを初期化します /// </summary> /// <param name="peercast">所属するPeerCast</param> /// <param name="connection">元になるストリーム</param> /// <param name="access_control">接続可否および認証の情報</param> /// <param name="channel">所属するチャンネル。無い場合はnull</param> public OutputStreamBase( PeerCast peercast, ConnectionStream connection, AccessControlInfo access_control, Channel channel) { this.Logger = new Logger(this.GetType(), connection.RemoteEndPoint?.ToString() ?? ""); this.Connection = connection; this.Connection.ReadTimeout = 10000; this.Connection.WriteTimeout = 10000; this.PeerCast = peercast; this.AccessControlInfo = access_control; this.Channel = channel; this.IsLocal = (RemoteEndPoint as IPEndPoint)?.Address?.IsSiteLocal() ?? true; }
/// <summary> /// 元になるストリーム、チャンネル、リクエストからHTTPOutputStreamを初期化します /// </summary> /// <param name="peercast">所属するPeerCast</param> /// <param name="input_stream">元になる受信ストリーム</param> /// <param name="output_stream">元になる送信ストリーム</param> /// <param name="remote_endpoint">接続先のアドレス</param> /// <param name="access_control">接続可否および認証の情報</param> /// <param name="channel">所属するチャンネル。無い場合はnull</param> /// <param name="request">クライアントからのリクエスト</param> public HTTPOutputStream( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, HTTPRequest request) : base(peercast, input_stream, output_stream, remote_endpoint, access_control, channel, null) { Logger.Debug("Initialized: Channel {0}, Remote {1}, Request {2} {3}", channel!=null ? channel.ChannelID.ToString("N") : "(null)", remote_endpoint, request.Method, request.Uri); this.request = request; }
public async Task HandleClient(TcpClient client, AccessControlInfo acinfo) { logger.Debug("Output thread started"); client.ReceiveBufferSize = 256 * 1024; client.SendBufferSize = 256 * 1024; client.NoDelay = true; var stream = client.GetStream(); int trying = 0; try { retry: stream.WriteTimeout = 3000; stream.ReadTimeout = 3000; var remote_endpoint = (IPEndPoint)client.Client.RemoteEndPoint; var handler = await CreateMatchedHandler(remote_endpoint, stream, acinfo).ConfigureAwait(false); if (handler != null) { logger.Debug("Output stream started {0}", trying); var result = await handler.Start().ConfigureAwait(false); switch (result) { case HandlerResult.Continue: trying++; goto retry; case HandlerResult.Close: case HandlerResult.Error: default: break; } } else { logger.Debug("No protocol handler matched"); } } finally { logger.Debug("Closing client connection"); stream.Close(); client.Close(); } }
public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { using (var stream = new MemoryStream(header)) { var req = HTTPRequestReader.Read(stream); return new HTTPDummyOutputStream( PeerCast, input_stream, output_stream, remote_endpoint, access_control, req); } }
/// <summary> /// 元になるストリーム、チャンネル、リクエストからHTTPOutputStreamを初期化します /// </summary> /// <param name="peercast">所属するPeerCast</param> /// <param name="input_stream">元になる受信ストリーム</param> /// <param name="output_stream">元になる送信ストリーム</param> /// <param name="remote_endpoint">接続先のアドレス</param> /// <param name="access_control">接続可否および認証の情報</param> /// <param name="channel">所属するチャンネル。無い場合はnull</param> /// <param name="request">クライアントからのリクエスト</param> public OutputStreamBase( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, byte[] header) { this.Logger = new Logger(this.GetType()); this.connection = new ConnectionStream( header!=null && header.Length>0 ? new PrependedStream(header, input_stream) : input_stream, output_stream); this.connection.ReadTimeout = 10000; this.connection.WriteTimeout = 10000; this.PeerCast = peercast; this.RemoteEndPoint = remote_endpoint; this.AccessControlInfo = access_control; this.Channel = channel; var ip = remote_endpoint as IPEndPoint; this.IsLocal = ip!=null ? ip.Address.IsSiteLocal() : true; }
public PCPOutputStream( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, RelayRequest request) : base(peercast, input_stream, output_stream, remote_endpoint, access_control, channel, null) { Logger.Debug("Initialized: Channel {0}, Remote {1}, Request {2} {3} ({4} {5})", channel!=null ? channel.ChannelID.ToString("N") : "(null)", remote_endpoint, request.Uri, request.StreamPos, request.PCPVersion, request.UserAgent); this.Downhost = null; this.UserAgent = request.UserAgent; this.IsChannelFound = channel!=null && channel.Status==SourceStreamStatus.Receiving; this.IsRelayFull = channel!=null ? !channel.MakeRelayable(this) : false; this.relayRequest = request; }
/// <summary> /// 元になるストリーム、チャンネル、リクエストからHTTPOutputStreamを初期化します /// </summary> /// <param name="peercast">所属するPeerCast</param> /// <param name="input_stream">元になる受信ストリーム</param> /// <param name="output_stream">元になる送信ストリーム</param> /// <param name="remote_endpoint">接続先のアドレス</param> /// <param name="access_control">接続可否および認証の情報</param> /// <param name="channel">所属するチャンネル。無い場合はnull</param> /// <param name="request">クライアントからのリクエスト</param> public OutputStreamBase( PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Channel channel, byte[] header) { this.Logger = new Logger(this.GetType(), remote_endpoint != null ? remote_endpoint.ToString() : ""); this.connection = new ConnectionStream( header != null && header.Length > 0 ? new PrependedStream(header, input_stream) : input_stream, output_stream); this.connection.ReadTimeout = 10000; this.connection.WriteTimeout = 10000; this.PeerCast = peercast; this.RemoteEndPoint = remote_endpoint; this.AccessControlInfo = access_control; this.Channel = channel; var ip = remote_endpoint as IPEndPoint; this.IsLocal = ip != null?ip.Address.IsSiteLocal() : true; }
private void OutputThreadFunc(object arg) { logger.Debug("Output thread started"); var client = (TcpClient)arg; client.ReceiveBufferSize = 64*1024; client.SendBufferSize = 64*1024; var stream = client.GetStream(); stream.WriteTimeout = 3000; stream.ReadTimeout = 3000; IOutputStream output_stream = null; Channel channel = null; try { var remote_endpoint = (IPEndPoint)client.Client.RemoteEndPoint; List<byte> header; Guid channel_id; AuthenticationKey auth_key; var factory = FindMatchedFactory(GetRemoteType(remote_endpoint), stream, out header, out channel_id, out auth_key); if (factory!=null) { var access_control = new AccessControlInfo(auth_key); output_stream = factory.Create(stream, stream, remote_endpoint, access_control, channel_id, header.ToArray()); channel = PeerCast.Channels.FirstOrDefault(c => c.ChannelID==channel_id); if (channel!=null) { channel.AddOutputStream(output_stream); } logger.Debug("Output stream started"); var wait_stopped = new EventWaitHandle(false, EventResetMode.ManualReset); output_stream.Stopped += (sender, args) => { wait_stopped.Set(); }; output_stream.Start(); wait_stopped.WaitOne(); } else { logger.Debug("No protocol matched"); } } finally { logger.Debug("Closing client connection"); if (output_stream!=null && channel!=null) { channel.RemoveOutputStream(output_stream); } stream.Close(); client.Close(); lock (outputThreads) { outputThreads.Remove(Thread.CurrentThread); } logger.Debug("Output thread finished"); } }
public async Task HandleClient(TcpClient client, AccessControlInfo acinfo) { logger.Debug("Output thread started"); client.ReceiveBufferSize = 16*1024; client.SendBufferSize = 16*1024; client.NoDelay = true; var stream = client.GetStream(); int trying = 0; try { retry: stream.WriteTimeout = 3000; stream.ReadTimeout = 3000; var remote_endpoint = (IPEndPoint)client.Client.RemoteEndPoint; var handler = await CreateMatchedHandler(remote_endpoint, stream, acinfo); if (handler!=null) { logger.Debug("Output stream started {0}", trying); var result = await handler.Start(); switch (result) { case HandlerResult.Continue: trying++; goto retry; case HandlerResult.Close: case HandlerResult.Error: default: break; } } else { logger.Debug("No protocol handler matched"); } } finally { logger.Debug("Closing client connection"); stream.Close(); client.Close(); } }
/// <summary> /// 出力ストリームを作成します /// </summary> /// <param name="input_stream">元になる受信ストリーム</param> /// <param name="output_stream">元になる送信ストリーム</param> /// <param name="remote_endpoint">接続先。無ければnull</param> /// <param name="channel_id">所属するチャンネルのチャンネルID</param> /// <param name="header">クライアントからのリクエスト</param> /// <returns> /// 作成できた場合はHTTPOutputStreamのインスタンス。 /// headerが正しく解析できなかった場合はnull /// </returns> public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { var request = ParseRequest(header); if (request!=null) { Channel channel = null; Uri tracker = CreateTrackerUri(channel_id, request.Uri); channel = PeerCast.RequestChannel(channel_id, tracker, true); return new HTTPOutputStream(PeerCast, input_stream, output_stream, remote_endpoint, access_control, channel, request); } else { return null; } }
public APIContext( APIHost owner, PeerCast peercast, AccessControlInfo access_control) { this.owner = owner; this.PeerCast = peercast; this.AccessControlInfo = access_control; }
public abstract IOutputStream Create(Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header);
public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { HTTPRequest request = null; using (var stream = new MemoryStream(header)) { try { request = HTTPRequestReader.Read(stream); } catch (EndOfStreamException) { } } return new AdminHostOutputStream(owner, PeerCast, input_stream, output_stream, remote_endpoint, access_control, request); }
public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { HTTPRequest request = null; long bytes = 0; using (var stream = new MemoryStream(header)) { try { request = HTTPRequestReader.Read(stream); bytes = stream.Position; } catch (EndOfStreamException) { } catch (InvalidDataException) { } } return new APIHostOutputStream( owner, PeerCast, input_stream, output_stream, remote_endpoint, access_control, request, header.Skip((int)bytes).ToArray()); }
public RTMPOutputStream( PeerCast peercast, System.IO.Stream input_stream, System.IO.Stream output_stream, System.Net.EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { input_stream.ReadTimeout = System.Threading.Timeout.Infinite; this.peerCast = peercast; this.inputStream = new RateCountedStream(new BufferedReadStream(input_stream, 8192, header), TimeSpan.FromMilliseconds(1000)); this.outputStream = new RateCountedStream(output_stream, TimeSpan.FromMilliseconds(1000)); this.remoteEndPoint = remote_endpoint; this.accessControl = access_control; this.connection = new RTMPPlayConnection(this, this.inputStream, this.outputStream); }
public RTMPOutputStream( PeerCast peercast, System.IO.Stream input_stream, System.IO.Stream output_stream, System.Net.EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { input_stream.ReadTimeout = System.Threading.Timeout.Infinite; this.peerCast = peercast; var stream = new ConnectionStream(new BufferedReadStream(input_stream, 8192, header), output_stream); this.inputStream = stream; this.outputStream = stream; stream.WriteTimeout = 10000; this.remoteEndPoint = remote_endpoint; this.accessControl = access_control; this.connection = new RTMPPlayConnection(this, this.inputStream, this.outputStream); }
public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { return new PCPPongOutputStream(PeerCast, input_stream, output_stream, (IPEndPoint)remote_endpoint, access_control, header); }
public override IOutputStream Create( System.IO.Stream input_stream, System.IO.Stream output_stream, System.Net.EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { return new RTMPOutputStream( PeerCast, input_stream, output_stream, remote_endpoint, access_control, channel_id, header); }
public APIHostOutputStream( APIHost owner, PeerCast peercast, Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, HTTPRequest request, byte[] header) : base(peercast, input_stream, output_stream, remote_endpoint, access_control, null, header) { this.owner = owner; this.request = request; this.rpcHost = new JSONRPCHost(this); Logger.Debug("Initialized: Remote {0}", remote_endpoint); }
/// <summary> /// 出力ストリームを作成します /// </summary> /// <param name="input_stream">元になる受信ストリーム</param> /// <param name="output_stream">元になる送信ストリーム</param> /// <param name="remote_endpoint">接続先。無ければnull</param> /// <param name="channel_id">所属するチャンネルID。</param> /// <param name="header">クライアントからのリクエスト</param> /// <returns> /// 作成できた場合はPCPOutputStreamのインスタンス。 /// headerが正しく解析できなかった場合はnull /// </returns> public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { var request = ParseRequest(header); if (request!=null) { var channel = this.PeerCast.RequestChannel(channel_id, null, false); return new PCPOutputStream(this.PeerCast, input_stream, output_stream, remote_endpoint, access_control, channel, request); } else { return null; } }
private async Task<IOutputStream> CreateMatchedHandler( IPEndPoint remote_endpoint, NetworkStream stream, AccessControlInfo acinfo) { var output_factories = PeerCast.OutputStreamFactories.OrderBy(factory => factory.Priority); var header = new byte[4096]; int offset = 0; using (var cancel_source=new CancellationTokenSource(TimeSpan.FromMilliseconds(3000))) { var cancel_token = cancel_source.Token; cancel_token.Register(() => stream.Close()); try { while (offset<header.Length) { var len = await stream.ReadAsync(header, offset, header.Length-offset); if (len==0) break; offset += len; var header_ary = header.Take(offset).ToArray(); foreach (var factory in output_factories) { if ((acinfo.Accepts & factory.OutputStreamType) == 0) continue; var channel_id = factory.ParseChannelID(header_ary); if (channel_id.HasValue) { return factory.Create( stream, stream, remote_endpoint, acinfo, channel_id.Value, header_ary); } } } } catch (System.ObjectDisposedException) { } catch (System.IO.IOException) { } } return null; }
public abstract IOutputStream Create( ConnectionStream connection, AccessControlInfo access_control, Guid channel_id);
public override IOutputStream Create( Stream input_stream, Stream output_stream, EndPoint remote_endpoint, AccessControlInfo access_control, Guid channel_id, byte[] header) { HTTPRequest req = null; var stream = new MemoryStream(header); try { req = HTTPRequestReader.Read(stream); } catch (EndOfStreamException) { } return new HTTPDummyOutputStream( PeerCast, input_stream, output_stream, remote_endpoint, access_control, req); }