protected void OnPCPOleh(Atom atom) { var rip = atom.Children.GetHeloRemoteIP(); if (rip!=null) { switch (rip.AddressFamily) { case AddressFamily.InterNetwork: if (PeerCast.GlobalAddress==null || PeerCast.GlobalAddress.GetAddressLocality()<=rip.GetAddressLocality()) { PeerCast.GlobalAddress = rip; } break; case AddressFamily.InterNetworkV6: if (PeerCast.GlobalAddress6==null || PeerCast.GlobalAddress6.GetAddressLocality()<=rip.GetAddressLocality()) { PeerCast.GlobalAddress6 = rip; } break; } } var port = atom.Children.GetHeloPort(); if (port.HasValue) { PeerCast.IsFirewalled = port.Value==0; } var sid = atom.Children.GetHeloSessionID(); if (sid.HasValue) { var host = new HostBuilder(); host.SessionID = sid.Value; host.GlobalEndPoint = RemoteEndPoint; uphost = host.ToHost(); } }
private void OnPCPHost(Atom atom) { var session_id = atom.Children.GetHostSessionID(); if (session_id!=null) { var node = Channel.SourceNodes.FirstOrDefault(x => x.SessionID.Equals(session_id)); var host = new HostBuilder(node); if (node==null) { host.SessionID = (Guid)session_id; } host.Extra.Update(atom.Children); host.DirectCount = atom.Children.GetHostNumListeners() ?? 0; host.RelayCount = atom.Children.GetHostNumRelays() ?? 0; var flags1 = atom.Children.GetHostFlags1(); if (flags1 != null) { host.IsFirewalled = (flags1.Value & PCPHostFlags1.Firewalled) != 0; host.IsTracker = (flags1.Value & PCPHostFlags1.Tracker) != 0; host.IsRelayFull = (flags1.Value & PCPHostFlags1.Relay) == 0; host.IsDirectFull = (flags1.Value & PCPHostFlags1.Direct) == 0; host.IsReceiving = (flags1.Value & PCPHostFlags1.Receiving) != 0; host.IsControlFull = (flags1.Value & PCPHostFlags1.ControlIn) == 0; } var endpoints = atom.Children.GetHostEndPoints(); if (endpoints.Length>0 && (host.GlobalEndPoint==null || !host.GlobalEndPoint.Equals(endpoints[0]))) { host.GlobalEndPoint = endpoints[0]; } if (endpoints.Length>1 && (host.LocalEndPoint==null || !host.LocalEndPoint.Equals(endpoints[1]))) { host.LocalEndPoint = endpoints[1]; } Channel.AddSourceNode(host.ToHost()); } }
protected virtual void OnPCPHost(Atom atom) { var session_id = atom.Children.GetHostSessionID(); if (session_id!=null) { var node = Channel.Nodes.FirstOrDefault(x => x.SessionID.Equals(session_id)); HostBuilder host = new HostBuilder(node); if (node==null) { host.SessionID = (Guid)session_id; } host.Extra.Update(atom.Children); host.DirectCount = atom.Children.GetHostNumListeners() ?? 0; host.RelayCount = atom.Children.GetHostNumRelays() ?? 0; var flags1 = atom.Children.GetHostFlags1(); if (flags1 != null) { host.IsFirewalled = (flags1.Value & PCPHostFlags1.Firewalled) != 0; host.IsTracker = (flags1.Value & PCPHostFlags1.Tracker) != 0; host.IsRelayFull = (flags1.Value & PCPHostFlags1.Relay) == 0; host.IsDirectFull = (flags1.Value & PCPHostFlags1.Direct) == 0; host.IsReceiving = (flags1.Value & PCPHostFlags1.Receiving) != 0; host.IsControlFull = (flags1.Value & PCPHostFlags1.ControlIn) == 0; } var endpoints = atom.Children.GetHostEndPoints(); if (endpoints.Length>0 && (host.GlobalEndPoint==null || !host.GlobalEndPoint.Equals(endpoints[0]))) { host.GlobalEndPoint = endpoints[0]; } if (endpoints.Length>1 && (host.LocalEndPoint==null || !host.LocalEndPoint.Equals(endpoints[1]))) { host.LocalEndPoint = endpoints[1]; } Logger.Debug("Updating Node: {0}/{1}({2})", host.GlobalEndPoint, host.LocalEndPoint, host.SessionID.ToString("N")); Channel.AddNode(host.ToHost()); if (Downhost.SessionID==host.SessionID) Downhost = host.ToHost(); } }
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)); } }
/// <summary> /// 指定されたHostBuilderの値でHostBuilderを初期化します /// </summary> /// <param name="host">初期化元のHostBuilder</param> public HostBuilder(HostBuilder host) { if (host!=null) { SessionID = host.SessionID; BroadcastID = host.BroadcastID; LocalEndPoint = host.LocalEndPoint; GlobalEndPoint = host.GlobalEndPoint; RelayCount = host.RelayCount; DirectCount = host.DirectCount; IsFirewalled = host.IsFirewalled; IsTracker = host.IsTracker; IsRelayFull = host.IsRelayFull; IsDirectFull = host.IsDirectFull; IsReceiving = host.IsReceiving; IsControlFull = host.IsControlFull; Extensions = new List<string>(host.Extensions); Extra = new AtomCollection(host.Extra); } else { SessionID = Guid.Empty; BroadcastID = Guid.Empty; LocalEndPoint = null; GlobalEndPoint = null; RelayCount = 0; DirectCount = 0; IsFirewalled = false; IsTracker = false; IsRelayFull = false; IsDirectFull = false; IsReceiving = false; IsControlFull = false; Extensions = new List<string>(); Extra = new AtomCollection(); } }
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 List<Host> ReadHosts(Stream s, Guid channel_id) { var res = new List<Host>(); bool quit = false; while (!quit) { var atom = AtomReader.Read(s); if (atom.Name==Atom.PCP_HOST) { if (atom.Children.GetHostChannelID()==channel_id) { var host = new HostBuilder(); var endpoints = atom.Children.GetHostEndPoints(); if (endpoints.Length>0) host.GlobalEndPoint = endpoints[0]; if (endpoints.Length>1) host.LocalEndPoint = endpoints[1]; host.DirectCount = atom.Children.GetHostNumListeners() ?? 0; host.RelayCount = atom.Children.GetHostNumRelays() ?? 0; host.SessionID = atom.Children.GetHostSessionID() ?? Guid.Empty; if (atom.Children.GetHostFlags1().HasValue) { var flags = atom.Children.GetHostFlags1().Value; host.IsControlFull = (flags & PCPHostFlags1.ControlIn)!=0; host.IsFirewalled = (flags & PCPHostFlags1.Firewalled)!=0; host.IsDirectFull = (flags & PCPHostFlags1.Direct)==0; host.IsRelayFull = (flags & PCPHostFlags1.Relay)==0; host.IsReceiving = (flags & PCPHostFlags1.Receiving)!=0; host.IsTracker = (flags & PCPHostFlags1.Tracker)!=0; } res.Add(host.ToHost()); } } if (atom.Name==Atom.PCP_QUIT) { quit = true; } } return res; }