/// <summary> /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります /// </summary> /// <returns>作ったPCP_HOSTパケット</returns> public virtual 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)); } host.SetHostVersion(PCP_VERSION); host.SetHostVersionVP(PCP_VERSION_VP); 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)); }
/// <summary> /// 現在のチャンネルとPeerCastの状態からHostパケットを作ります /// </summary> /// <returns>作ったPCP_HOSTパケット</returns> private Atom CreatePCPHOST() { var host = new AtomCollection(); host.SetHostChannelID(Channel.ChannelID); host.SetHostSessionID(PeerCast.SessionID); var globalendpoint = PeerCast.GetGlobalEndPoint( connection.RemoteEndPoint.AddressFamily, OutputStreamType.Relay); if (globalendpoint != null) { host.AddHostIP(globalendpoint.Address); host.AddHostPort(globalendpoint.Port); } var localendpoint = PeerCast.GetLocalEndPoint( connection.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.GetPortStatus(connection.RemoteEndPoint.AddressFamily) != PortStatus.Open) ? PCPHostFlags1.Firewalled : 0) | (RecvRate > 0 ? PCPHostFlags1.Receiving : 0)); host.SetHostUphostIP(connection.RemoteEndPoint.Address); host.SetHostUphostPort(connection.RemoteEndPoint.Port); return(new Atom(Atom.PCP_HOST, host)); }
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 void PostHostInfo(AtomCollection parent, Channel channel, bool playing) { var host = channel.SelfNode; var hostinfo = new AtomCollection(); hostinfo.SetHostChannelID(channel.ChannelID); hostinfo.SetHostSessionID(PeerCast.SessionID); var globalendpoint = host.GlobalEndPoint; if (globalendpoint != null) { hostinfo.AddHostIP(globalendpoint.Address); hostinfo.AddHostPort(globalendpoint.Port); } var localendpoint = host.LocalEndPoint; 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)); } hostinfo.SetHostVersion(PCP_VERSION); hostinfo.SetHostVersionVP(PCP_VERSION_VP); hostinfo.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(channel) ? PCPHostFlags1.Direct : 0) | ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) | PCPHostFlags1.Tracker | (playing ? PCPHostFlags1.Receiving : PCPHostFlags1.None)); parent.SetHost(hostinfo); }
/// <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); }
protected override Task OnStopped(CancellationToken cancel_token) { switch (StoppedReason) { case StopReason.None: break; case StopReason.Any: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); break; case StopReason.SendTimeoutError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SKIP)); break; case StopReason.BadAgentError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_BADAGENT)); break; case StopReason.ConnectionError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_READ)); break; case StopReason.NotIdentifiedError: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_NOTIDENTIFIED)); break; case StopReason.UnavailableError: { //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { if (Downhost != null && Downhost.SessionID == node.SessionID) { continue; } var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip != null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port != null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Connection.WriteAsync(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.SessionID.ToString("N")); } } Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_UNAVAILABLE)); break; case StopReason.OffAir: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_OFFAIR)); break; case StopReason.UserShutdown: Connection.WriteAsync(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SHUTDOWN)); break; } if (Channel != null) { Channel.ContentChanged -= Channel_ContentChanged; Channel.ChannelInfoChanged -= Channel_ChannelPropertyChanged; Channel.ChannelTrackChanged -= Channel_ChannelPropertyChanged; } return(base.OnStopped(cancel_token)); }
protected override void DoStop(StopReason reason) { switch (reason) { case StopReason.None: break; case StopReason.Any: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); break; case StopReason.SendTimeoutError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SKIP)); break; case StopReason.BadAgentError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_BADAGENT)); break; case StopReason.ConnectionError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_READ)); break; case StopReason.NotIdentifiedError: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_NOTIDENTIFIED)); break; case StopReason.UnavailableError: { //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { if (Downhost!=null && Downhost.SessionID==node.SessionID) continue; var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip!=null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port!=null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Send(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.SessionID.ToString("N")); } } Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_UNAVAILABLE)); break; case StopReason.OffAir: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_OFFAIR)); break; case StopReason.UserShutdown: Send(new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT + Atom.PCP_ERROR_SHUTDOWN)); break; } base.DoStop(reason); }
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(); } 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); oleh.SetHeloVersion(PCP_VERSION); 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")); //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip!=null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port!=null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Send(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.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)); } }
private void PostHostInfo(AtomCollection parent, Channel channel, bool playing) { var host = channel.SelfNode; var hostinfo = new AtomCollection(); hostinfo.SetHostChannelID(channel.ChannelID); hostinfo.SetHostSessionID(PeerCast.SessionID); var globalendpoint = host.GlobalEndPoint; if (globalendpoint!=null) { hostinfo.AddHostIP(globalendpoint.Address); hostinfo.AddHostPort(globalendpoint.Port); } var localendpoint = host.LocalEndPoint; 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); hostinfo.SetHostFlags1( (PeerCast.AccessController.IsChannelRelayable(channel) ? PCPHostFlags1.Relay : 0) | (PeerCast.AccessController.IsChannelPlayable(channel) ? PCPHostFlags1.Direct : 0) | ((!PeerCast.IsFirewalled.HasValue || PeerCast.IsFirewalled.Value) ? PCPHostFlags1.Firewalled : 0) | PCPHostFlags1.Tracker | (playing ? PCPHostFlags1.Receiving : PCPHostFlags1.None)); parent.SetHost(hostinfo); }
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(); } 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); oleh.SetHeloVersion(PCP_VERSION); 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")); //次に接続するホストを送ってQUIT foreach (var node in SelectSourceHosts((IPEndPoint)RemoteEndPoint)) { var host_atom = new AtomCollection(node.Extra); Atom ip = host_atom.FindByName(Atom.PCP_HOST_IP); while (ip != null) { host_atom.Remove(ip); ip = host_atom.FindByName(Atom.PCP_HOST_IP); } Atom port = host_atom.FindByName(Atom.PCP_HOST_PORT); while (port != null) { host_atom.Remove(port); port = host_atom.FindByName(Atom.PCP_HOST_PORT); } host_atom.SetHostSessionID(node.SessionID); var globalendpoint = node.GlobalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(globalendpoint.Address); host_atom.AddHostPort(globalendpoint.Port); var localendpoint = node.LocalEndPoint ?? new IPEndPoint(IPAddress.Any, 0); host_atom.AddHostIP(localendpoint.Address); host_atom.AddHostPort(localendpoint.Port); host_atom.SetHostNumRelays(node.RelayCount); host_atom.SetHostNumListeners(node.DirectCount); host_atom.SetHostChannelID(Channel.ChannelID); host_atom.SetHostFlags1( (node.IsFirewalled ? PCPHostFlags1.Firewalled : PCPHostFlags1.None) | (node.IsTracker ? PCPHostFlags1.Tracker : PCPHostFlags1.None) | (node.IsRelayFull ? PCPHostFlags1.None : PCPHostFlags1.Relay) | (node.IsDirectFull ? PCPHostFlags1.None : PCPHostFlags1.Direct) | (node.IsReceiving ? PCPHostFlags1.Receiving : PCPHostFlags1.None) | (node.IsControlFull ? PCPHostFlags1.None : PCPHostFlags1.ControlIn)); Send(new Atom(Atom.PCP_HOST, host_atom)); Logger.Debug("Sending Node: {0}({1})", globalendpoint, node.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)); } }
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; hostinfo.SetHostFlags1( (relayable ? PCPHostFlags1.Relay : 0) | (playable ? PCPHostFlags1.Direct : 0) | (firewalled ? PCPHostFlags1.Firewalled : 0) | PCPHostFlags1.Tracker | (playing ? PCPHostFlags1.Receiving : PCPHostFlags1.None)); parent.SetHost(hostinfo); }