Пример #1
0
        private Atom CreatePCPHelo()
        {
            var helo = new AtomCollection();

            helo.SetHeloAgent(PeerCast.AgentName);
            helo.SetHeloSessionID(PeerCast.SessionID);
            switch (PeerCast.GetPortStatus(Channel.NetworkAddressFamily))
            {
            case PortStatus.Open:
            {
                var listener = PeerCast.FindListener(
                    connection.RemoteEndPoint.Address,
                    OutputStreamType.Relay | OutputStreamType.Metadata);
                helo.SetHeloPort(listener.LocalEndPoint.Port);
            }
            break;

            case PortStatus.Firewalled:
                break;

            case PortStatus.Unknown:
            {
                var listener = PeerCast.FindListener(
                    connection.RemoteEndPoint.Address,
                    OutputStreamType.Relay | OutputStreamType.Metadata);
                if (listener != null)
                {
                    helo.SetHeloPing(listener.LocalEndPoint.Port);
                }
            }
            break;
            }
            PCPVersion.SetHeloVersion(helo);
            return(new Atom(Atom.PCP_HELO, helo));
        }
Пример #2
0
        private Atom CreateBroadcastPacket(BroadcastGroup group, Atom packet)
        {
            var bcst = new AtomCollection();

            bcst.SetBcstFrom(PeerCast.SessionID);
            bcst.SetBcstGroup(group);
            bcst.SetBcstHops(0);
            bcst.SetBcstTTL(11);
            PCPVersion.SetBcstVersion(bcst);
            bcst.SetBcstChannelID(Channel.ChannelID);
            bcst.Add(packet);
            return(new Atom(Atom.PCP_BCST, bcst));
        }
Пример #3
0
        private Atom CreateChannelBcst(Channel channel, bool playing)
        {
            var bcst = new AtomCollection();

            bcst.SetBcstTTL(1);
            bcst.SetBcstHops(0);
            bcst.SetBcstFrom(PeerCast.SessionID);
            PCPVersion.SetBcstVersion(bcst);
            bcst.SetBcstChannelID(channel.ChannelID);
            bcst.SetBcstGroup(BroadcastGroup.Root);
            PostChannelInfo(bcst, channel);
            PostHostInfo(bcst, channel, playing);
            return(new Atom(Atom.PCP_BCST, bcst));
        }
Пример #4
0
        /// <summary>
        /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります
        /// </summary>
        /// <returns>作ったPCP_HOSTパケット</returns>
        private Atom CreateHostPacket()
        {
            var host = new AtomCollection();

            host.SetHostChannelID(Channel.ChannelID);
            host.SetHostSessionID(PeerCast.SessionID);
            var globalendpoint =
                PeerCast.GetGlobalEndPoint(
                    RemoteEndPoint.AddressFamily,
                    OutputStreamType.Relay);

            if (globalendpoint != null)
            {
                host.AddHostIP(globalendpoint.Address);
                host.AddHostPort(globalendpoint.Port);
            }
            var localendpoint =
                PeerCast.GetLocalEndPoint(
                    RemoteEndPoint.AddressFamily,
                    OutputStreamType.Relay);

            if (localendpoint != null)
            {
                host.AddHostIP(localendpoint.Address);
                host.AddHostPort(localendpoint.Port);
            }
            host.SetHostNumListeners(Channel.LocalDirects);
            host.SetHostNumRelays(Channel.LocalRelays);
            host.SetHostUptime(Channel.Uptime);
            if (Channel.Contents.Count > 0)
            {
                host.SetHostOldPos((uint)(Channel.Contents.Oldest.Position & 0xFFFFFFFFU));
                host.SetHostNewPos((uint)(Channel.Contents.Newest.Position & 0xFFFFFFFFU));
            }
            PCPVersion.SetHostVersion(host);
            host.SetHostFlags1(
                (PeerCast.AccessController.IsChannelRelayable(Channel) ? PCPHostFlags1.Relay : 0) |
                (PeerCast.AccessController.IsChannelPlayable(Channel) ? PCPHostFlags1.Direct : 0) |
                ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) |
                (RecvRate > 0 ? PCPHostFlags1.Receiving : 0));
            host.SetHostUphostIP(RemoteEndPoint.Address);
            host.SetHostUphostPort(RemoteEndPoint.Port);
            return(new Atom(Atom.PCP_HOST, host));
        }
Пример #5
0
        private bool SendPCPHelo()
        {
            var helo = new AtomCollection();

            helo.SetHeloAgent(PeerCast.AgentName);
            helo.SetHeloSessionID(PeerCast.SessionID);
            if (PeerCast.IsFirewalled.HasValue)
            {
                if (PeerCast.IsFirewalled.Value)
                {
                    //Do nothing
                }
                else
                {
                    var listener = PeerCast.FindListener(
                        RemoteEndPoint.Address,
                        OutputStreamType.Relay | OutputStreamType.Metadata);
                    helo.SetHeloPort(listener.LocalEndPoint.Port);
                }
            }
            else
            {
                var listener = PeerCast.FindListener(
                    RemoteEndPoint.Address,
                    OutputStreamType.Relay | OutputStreamType.Metadata);
                if (listener != null)
                {
                    helo.SetHeloPing(listener.LocalEndPoint.Port);
                }
            }
            PCPVersion.SetHeloVersion(helo);
            try {
                connection.Send(stream => {
                    AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo));
                });
            }
            catch (IOException e) {
                Logger.Info(e);
                Stop(StopReason.ConnectionError);
                return(false);
            }
            return(true);
        }
Пример #6
0
        private void PostHostInfo(AtomCollection parent, Channel channel, bool playing)
        {
            var hostinfo = new AtomCollection();

            hostinfo.SetHostChannelID(channel.ChannelID);
            hostinfo.SetHostSessionID(PeerCast.SessionID);
            var globalendpoint = PeerCast.GetGlobalEndPoint(AddressFamily.InterNetwork, OutputStreamType.Relay);

            if (globalendpoint != null)
            {
                hostinfo.AddHostIP(globalendpoint.Address);
                hostinfo.AddHostPort(globalendpoint.Port);
            }
            var localendpoint = PeerCast.GetLocalEndPoint(AddressFamily.InterNetwork, OutputStreamType.Relay);

            if (localendpoint != null)
            {
                hostinfo.AddHostIP(localendpoint.Address);
                hostinfo.AddHostPort(localendpoint.Port);
            }
            hostinfo.SetHostNumListeners(channel.TotalDirects);
            hostinfo.SetHostNumRelays(channel.TotalRelays);
            hostinfo.SetHostUptime(channel.Uptime);
            if (channel.Contents.Count > 0)
            {
                hostinfo.SetHostOldPos((uint)(channel.Contents.Oldest.Position & 0xFFFFFFFFU));
                hostinfo.SetHostNewPos((uint)(channel.Contents.Newest.Position & 0xFFFFFFFFU));
            }
            PCPVersion.SetHostVersion(hostinfo);
            var relayable  = PeerCast.AccessController.IsChannelRelayable(channel);
            var playable   = PeerCast.AccessController.IsChannelPlayable(channel) && PeerCast.FindListener(remoteEndPoint.Address, OutputStreamType.Play) != null;
            var firewalled = !PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value || PeerCast.FindListener(remoteEndPoint.Address, OutputStreamType.Relay) == null;
            var receiving  = playing && channel.Status == SourceStreamStatus.Receiving;

            hostinfo.SetHostFlags1(
                (relayable  ? PCPHostFlags1.Relay      : 0) |
                (playable   ? PCPHostFlags1.Direct     : 0) |
                (firewalled ? PCPHostFlags1.Firewalled : 0) |
                PCPHostFlags1.Tracker |
                (receiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None));
            parent.SetHost(hostinfo);
        }
Пример #7
0
        private async Task OnPCPHelo(Atom atom, CancellationToken cancel_token)
        {
            if (Downhost != null)
            {
                return;
            }
            Logger.Debug("Helo received");
            var session_id  = atom.Children.GetHeloSessionID();
            int remote_port = 0;

            if (session_id != null)
            {
                var host = new HostBuilder();
                host.SessionID = session_id.Value;
                var port = atom.Children.GetHeloPort();
                var ping = atom.Children.GetHeloPing();
                if (port != null)
                {
                    remote_port = port.Value;
                }
                else if (ping != null)
                {
                    if (IsPingTarget(((IPEndPoint)RemoteEndPoint).Address) &&
                        await PingHost(new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, ping.Value), session_id.Value, cancel_token).ConfigureAwait(false))
                    {
                        remote_port = ping.Value;
                    }
                    else
                    {
                        remote_port = 0;
                    }
                }
                else
                {
                    remote_port = 0;
                }
                if (remote_port != 0)
                {
                    var ip = new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, remote_port);
                    if (host.GlobalEndPoint == null || !host.GlobalEndPoint.Equals(ip))
                    {
                        host.GlobalEndPoint = ip;
                    }
                }
                host.IsFirewalled = remote_port == 0;
                host.Extra.Update(atom.Children);
                Downhost = host.ToHost();
                var user_agent = atom.Children.GetHeloAgent();
                if (user_agent != null)
                {
                    UserAgent = user_agent;
                }
            }
            var oleh = new AtomCollection();

            if (RemoteEndPoint != null && RemoteEndPoint.AddressFamily == Channel.NetworkAddressFamily)
            {
                oleh.SetHeloRemoteIP(((IPEndPoint)RemoteEndPoint).Address);
            }
            oleh.SetHeloAgent(PeerCast.AgentName);
            oleh.SetHeloSessionID(PeerCast.SessionID);
            oleh.SetHeloRemotePort(remote_port);
            PCPVersion.SetHeloVersion(oleh);
            await Connection.WriteAsync(new Atom(Atom.PCP_OLEH, oleh), cancel_token).ConfigureAwait(false);

            if (Downhost == null)
            {
                Logger.Info("Helo has no SessionID");
                //セッションIDが無かった
                Stop(StopReason.NotIdentifiedError);
            }
            else if ((Downhost.Extra.GetHeloVersion() ?? 0) < 1200)
            {
                Logger.Info("Helo version {0} is too old", Downhost.Extra.GetHeloVersion() ?? 0);
                //クライアントバージョンが無かった、もしくは古すぎ
                Stop(StopReason.BadAgentError);
            }
            else if (IsRelayFull)
            {
                Logger.Debug("Handshake succeeded {0}({1}) but relay is full", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N"));
                Stop(StopReason.UnavailableError);
            }
            else
            {
                Logger.Debug("Handshake succeeded {0}({1})", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N"));
                await Connection.WriteAsync(new Atom(Atom.PCP_OK, (int)1), cancel_token).ConfigureAwait(false);
            }
        }
Пример #8
0
        protected virtual void OnPCPHelo(Atom atom)
        {
            if (Downhost != null)
            {
                return;
            }
            Logger.Debug("Helo received");
            var session_id  = atom.Children.GetHeloSessionID();
            int remote_port = 0;

            if (session_id != null)
            {
                var host = new HostBuilder();
                host.SessionID = session_id.Value;
                var port = atom.Children.GetHeloPort();
                var ping = atom.Children.GetHeloPing();
                if (port != null)
                {
                    remote_port = port.Value;
                }
                else if (ping != null)
                {
                    if (IsPingTarget(((IPEndPoint)RemoteEndPoint).Address) &&
                        PingHost(new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, ping.Value), session_id.Value))
                    {
                        remote_port = ping.Value;
                    }
                    else
                    {
                        remote_port = 0;
                    }
                }
                else
                {
                    remote_port = 0;
                }
                if (remote_port != 0)
                {
                    var ip = new IPEndPoint(((IPEndPoint)RemoteEndPoint).Address, remote_port);
                    if (host.GlobalEndPoint == null || !host.GlobalEndPoint.Equals(ip))
                    {
                        host.GlobalEndPoint = ip;
                    }
                }
                host.IsFirewalled = remote_port == 0;
                host.Extra.Update(atom.Children);
                Downhost  = host.ToHost();
                UserAgent = atom.Children.GetHeloAgent() ?? UserAgent;
            }
            var oleh = new AtomCollection();

            if (RemoteEndPoint != null && RemoteEndPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            {
                oleh.SetHeloRemoteIP(((IPEndPoint)RemoteEndPoint).Address);
            }
            oleh.SetHeloAgent(PeerCast.AgentName);
            oleh.SetHeloSessionID(PeerCast.SessionID);
            oleh.SetHeloRemotePort(remote_port);
            PCPVersion.SetHeloVersion(oleh);
            Send(new Atom(Atom.PCP_OLEH, oleh));
            if (Downhost == null)
            {
                Logger.Info("Helo has no SessionID");
                //セッションIDが無かった
                Stop(StopReason.NotIdentifiedError);
            }
            else if ((Downhost.Extra.GetHeloVersion() ?? 0) < 1200)
            {
                Logger.Info("Helo version {0} is too old", Downhost.Extra.GetHeloVersion() ?? 0);
                //クライアントバージョンが無かった、もしくは古すぎ
                Stop(StopReason.BadAgentError);
            }
            else if (IsRelayFull)
            {
                Logger.Debug("Handshake succeeded {0}({1}) but relay is full", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N"));
                Stop(StopReason.UnavailableError);
            }
            else
            {
                Logger.Debug("Handshake succeeded {0}({1})", Downhost.GlobalEndPoint, Downhost.SessionID.ToString("N"));
                Send(new Atom(Atom.PCP_OK, (int)1));
            }
        }
 public static int GetPCPVersion(this Channel channel)
 {
     return(PCPVersion.GetPCPVersionForNetworkType(channel.Network));
 }