protected virtual bool PingHost(IPEndPoint target, Guid remote_session_id) { Logger.Debug("Ping requested. Try to ping: {0}({1})", target, remote_session_id); bool result = false; try { var client = new System.Net.Sockets.TcpClient(); client.Connect(target); client.ReceiveTimeout = 3000; client.SendTimeout = 3000; var stream = client.GetStream(); var conn = new Atom(Atom.PCP_CONNECT, 1); AtomWriter.Write(stream, conn); var helo = new AtomCollection(); helo.SetHeloSessionID(PeerCast.SessionID); AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); var res = AtomReader.Read(stream); if (res.Name == Atom.PCP_OLEH) { var session_id = res.Children.GetHeloSessionID(); if (session_id.HasValue && session_id.Value == remote_session_id) { Logger.Debug("Ping succeeded"); result = true; } else { Logger.Debug("Ping failed. Remote SessionID mismatched"); } } AtomWriter.Write(stream, new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); stream.Close(); client.Close(); } catch (InvalidDataException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.Net.Sockets.SocketException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (EndOfStreamException e) { Logger.Debug("Ping failed"); Logger.Debug(e); } catch (System.IO.IOException io_error) { Logger.Debug("Ping failed"); Logger.Debug(io_error); if (!(io_error.InnerException is System.Net.Sockets.SocketException)) { throw; } } return(result); }
protected override void DoPost(Host from, Atom packet) { if (uphost != from) { try { connection.Send(stream => { AtomWriter.Write(stream, packet); }); } catch (IOException e) { Logger.Info(e); Stop(StopReason.ConnectionError); } } }
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); }
/// <summary> /// Saves the <see cref="AtomEntry"/> to the specified <see cref="WebResponse"/>. /// </summary> /// <param name="response">The <see cref="HttpWebResponse"/> to write to.</param> public void Save(WebResponse response) { _writer = new AtomWriter(response.ResponseUri.ToString(), this.Encoding); _writer.Write(this); }
/// <summary> /// Saves the <see cref="AtomEntry"/> to the specified <see cref="TextWriter"/>. /// </summary> /// <param name="xw">The <see cref="XmlWriter"/> to write to.</param> public void Save(XmlWriter xw) { _writer = new AtomWriter(xw); _writer.Write(this); }
/// <summary> /// Saves the <see cref="AtomEntry"/> to the specified <see cref="TextWriter"/>. /// </summary> /// <param name="tw">The <see cref="TextWriter"/> to write to.</param> public void Save(TextWriter tw) { _writer = new AtomWriter(tw); _writer.Write(this); }
/// <summary> /// Saves the <see cref="AtomEntry"/> to the specified filename. /// </summary> /// <exception cref="ArgumentException">The encoding is not supported; the filename is empty, contains only white space, or contains one or more invalid characters.</exception> /// <exception cref="UnauthorizedAccessException">Access is denied.</exception> /// <exception cref="ArgumentNullException">The filename is a null reference.</exception> /// <exception cref="DirectoryNotFoundException">The directory to write to is not found.</exception> /// <exception cref="IOException">The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <param name="filename">The file name to write to.</param> public void Save(string filename) { _writer = new AtomWriter(filename, this.Encoding); _writer.Write(this); }
/// <summary> /// Saves the <see cref="AtomEntry"/> to the specified <see cref="Stream"/>. /// </summary> /// <param name="stream">The <see cref="Stream"/> to write to.</param> /// <exception cref="ArgumentException">The encoding is not supported or the stream cannot be written to.</exception> /// <exception cref="ArgumentNullException">stream is null.</exception> /// <exception cref="RequiredElementNotFoundException">A required element is not found.</exception> /// <exception cref="InvalidOperationException">The internal writ</exception> public void Save(Stream stream) { _writer = new AtomWriter(stream, this.Encoding); _writer.Write(this); }
private void AnnounceThreadProc() { Logger.Debug("Thread started"); var host = Uri.DnsSafeHost; var port = Uri.Port; if (port < 0) { port = DefaultPort; } while (!IsStopped) { int next_update = Environment.TickCount; posts.Clear(); try { Logger.Debug("Connecting to YP"); AnnouncingStatus = AnnouncingStatus.Connecting; using (var client = new TcpClient(host, port)) { using (var stream = client.GetStream()) { AtomWriter.Write(stream, new Atom(new ID4("pcp\n"), (int)1)); var helo = new AtomCollection(); Logger.Debug("Sending Handshake"); helo.SetHeloAgent(PeerCast.AgentName); helo.SetHeloVersion(1218); helo.SetHeloSessionID(PeerCast.SessionID); helo.SetHeloBCID(PeerCast.BroadcastID); if (PeerCast.IsFirewalled.HasValue) { if (PeerCast.IsFirewalled.Value) { //Do nothing } else { var listener = PeerCast.FindListener( ((IPEndPoint)client.Client.RemoteEndPoint).Address, OutputStreamType.Relay | OutputStreamType.Metadata); if (listener != null) { helo.SetHeloPort(listener.LocalEndPoint.Port); } } } else { var listener = PeerCast.FindListener( ((IPEndPoint)client.Client.RemoteEndPoint).Address, OutputStreamType.Relay | OutputStreamType.Metadata); if (listener != null) { helo.SetHeloPing(listener.LocalEndPoint.Port); } } AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); while (!IsStopped) { var atom = AtomReader.Read(stream); if (atom.Name == Atom.PCP_OLEH) { OnPCPOleh(atom); break; } else if (atom.Name == Atom.PCP_QUIT) { Logger.Debug("Handshake aborted by PCP_QUIT ({0})", atom.GetInt32()); throw new QuitException(); } if (restartEvent.WaitOne(10)) { throw new RestartException(); } } Logger.Debug("Handshake succeeded"); AnnouncingStatus = AnnouncingStatus.Connected; while (!IsStopped) { if (next_update - Environment.TickCount <= 0) { Logger.Debug("Sending channel info"); lock (announcingChannels) { foreach (var announcing in announcingChannels) { PostChannelBcst(announcing.Channel, true); } } next_update = Environment.TickCount + 30000; } if (stream.DataAvailable) { Atom atom = AtomReader.Read(stream); ProcessAtom(atom); } lock (posts) { foreach (var atom in posts) { AtomWriter.Write(stream, atom); } posts.Clear(); } if (restartEvent.WaitOne(10)) { throw new RestartException(); } } lock (posts) { foreach (var atom in posts) { AtomWriter.Write(stream, atom); } posts.Clear(); } Logger.Debug("Closing connection"); AtomWriter.Write(stream, new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); } } } catch (RestartException) { Logger.Debug("Connection retrying"); AnnouncingStatus = AnnouncingStatus.Connecting; } catch (BannedException) { AnnouncingStatus = AnnouncingStatus.Error; Logger.Error("Your BCID is banned"); break; } catch (QuitException) { AnnouncingStatus = AnnouncingStatus.Error; } catch (SocketException e) { AnnouncingStatus = AnnouncingStatus.Error; Logger.Info(e); } catch (IOException e) { AnnouncingStatus = AnnouncingStatus.Error; Logger.Info(e); } Logger.Debug("Connection closed"); if (!IsStopped) { restartEvent.WaitOne(10000); } else { AnnouncingStatus = AnnouncingStatus.Idle; } } Logger.Debug("Thread finished"); }
public Uri FindTracker(Guid channel_id) { Logger.Debug("Finding tracker {0} from {1}", channel_id.ToString("N"), Uri); var host = Uri.DnsSafeHost; var port = Uri.Port; Uri res = null; if (port < 0) { port = DefaultPort; } try { var client = new TcpClient(host, port); var stream = client.GetStream(); var request = System.Text.Encoding.UTF8.GetBytes( String.Format("GET /channel/{0} HTTP/1.0\r\n", channel_id.ToString("N")) + "x-peercast-pcp:1\r\n" + "\r\n"); stream.Write(request, 0, request.Length); var response = ReadResponse(stream); var md = System.Text.RegularExpressions.Regex.Match(response, @"^HTTP/1.\d (\d+) "); if (md.Success) { var status = md.Groups[1].Value; switch (status) { case "503": var helo = new AtomCollection(); helo.SetHeloAgent(PeerCast.AgentName); helo.SetHeloVersion(1218); helo.SetHeloSessionID(PeerCast.SessionID); helo.SetHeloPort(0); AtomWriter.Write(stream, new Atom(Atom.PCP_HELO, helo)); var hosts = ReadHosts(stream, channel_id); res = HostToUri(hosts.FirstOrDefault(h => h.IsTracker), channel_id); break; case "200": //なぜかリレー可能だったのでYP自体をトラッカーとみなしてしまうことにする AtomWriter.Write(stream, new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); res = Uri; break; default: //エラーだったのでトラッカーのアドレスを貰えず終了 break; } } AtomWriter.Write(stream, new Atom(Atom.PCP_QUIT, Atom.PCP_ERROR_QUIT)); client.Close(); } catch (SocketException) { } catch (IOException) { } if (res != null) { Logger.Debug("Tracker found: {0}", res); } else { Logger.Debug("Tracker no found"); } return(res); }