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)); }
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)); }
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)); }
/// <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)); }
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); }
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); }
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); } }
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)); }