From 36e723658811dd12a2244edc178dc8dddabe15a2 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 21 Jul 2016 18:48:44 +1000 Subject: [PATCH] Introduce (possible) fix for issue with using ipv6 instead of ipv4 address when POSTing a heartbeat to classicube.net. --- MCGalaxy_.csproj | 2 +- Network/ClassiCube.cs | 47 +++++++++++++++++--- {Server/Extra => Network}/Heart.cs | 23 +++++----- Network/IBeat.cs | 69 ++++++++++++++++-------------- 4 files changed, 88 insertions(+), 53 deletions(-) rename {Server/Extra => Network}/Heart.cs (82%) diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 5639261e3..7255369a9 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -514,6 +514,7 @@ + @@ -566,7 +567,6 @@ - diff --git a/Network/ClassiCube.cs b/Network/ClassiCube.cs index 3b9c11697..5c6871a25 100644 --- a/Network/ClassiCube.cs +++ b/Network/ClassiCube.cs @@ -1,7 +1,7 @@ /* Copyright 2012 MCForge - Dual-licensed under the Educational Community License, Version 2.0 and + Dual-licensed under the Educational Community License, Version 2.0 and the GNU General Public License, Version 3 (the "Licenses"); you may not use this file except in compliance with the Licenses. You may obtain a copy of the Licenses at @@ -17,17 +17,48 @@ */ using System; using System.IO; +using System.Net; +using System.Net.Sockets; using Newtonsoft.Json; namespace MCGalaxy { public sealed class ClassiCubeBeat : IBeat { - public string URL { get { return "http://www.classicube.net/heartbeat.jsp"; } } + string url = "http://www.classicube.net/heartbeat.jsp"; + public string URL { get { return url; } } public bool Persistance { get { return true; } } + + public void Init() { + try { + IPAddress[] addresses = Dns.GetHostAddresses("www.classicube.net"); + EnsureIPv4Url(addresses); + } catch (Exception ex) { + Server.s.Log("Error while trying to retrieve DNS information for classicube.net"); + Server.ErrorLog(ex); + } + } + + // classicube.net only supports ipv4 servers, so we need to make + // sure we are using its ipv4 address when POSTing heartbeats + void EnsureIPv4Url(IPAddress[] addresses) { + bool useIPv6 = false; + IPAddress firstIPv4 = null; + + foreach (IPAddress ip in addresses) { + AddressFamily family = ip.AddressFamily; + if (family == AddressFamily.InterNetworkV6) + useIPv6 = true; + if (family == AddressFamily.InterNetwork && firstIPv4 == null) + firstIPv4 = ip; + } + + if (!useIPv6 || firstIPv4 == null) return; + url = "http://" + firstIPv4 + ":80/heartbeat.jsp"; + } - public string Prepare() { + public string PrepareBeat() { string name = Server.name; Server.zombie.OnHeartbeat(ref name); Server.lava.OnHeartbeat(ref name); @@ -51,6 +82,10 @@ namespace MCGalaxy { return count; } + public void OnRequest(HttpWebRequest request) { + request.Host = "www.classicube.net"; + } + bool foundUrl = false; public void OnResponse(string line) { if (String.IsNullOrEmpty(line.Trim())) return; @@ -80,9 +115,9 @@ namespace MCGalaxy { } class Response { - public string[][] errors; - public string response; - public string status; + public string[][] errors; + public string response; + public string status; } } } diff --git a/Server/Extra/Heart.cs b/Network/Heart.cs similarity index 82% rename from Server/Extra/Heart.cs rename to Network/Heart.cs index 1f1e899b4..3248ccd75 100644 --- a/Server/Extra/Heart.cs +++ b/Network/Heart.cs @@ -1,7 +1,7 @@ /* Copyright 2012 MCForge - Dual-licensed under the Educational Community License, Version 2.0 and + Dual-licensed under the Educational Community License, Version 2.0 and the GNU General Public License, Version 3 (the "Licenses"); you may not use this file except in compliance with the Licenses. You may obtain a copy of the Licenses at @@ -63,16 +63,16 @@ namespace MCGalaxy { } CanBeat = true; - for (int i = 0; i < Beats.Length; i++) + for (int i = 0; i < Beats.Length; i++) { + Beats[i].Init(); Pump(Beats[i]); + } } /// Pumps the specified beat. - /// The beat. - /// public static void Pump(IBeat beat) { - if(!CanBeat) return; - byte[] data = Encoding.ASCII.GetBytes(beat.Prepare()); + if (!CanBeat) return; + byte[] data = Encoding.ASCII.GetBytes(beat.PrepareBeat()); for (int i = 0; i < MAX_RETRIES; i++) { try { @@ -82,20 +82,18 @@ namespace MCGalaxy { req.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore); req.Timeout = 15000; req.ContentLength = data.Length; + beat.OnRequest(req); using (var w = req.GetRequestStream()) { w.Write(data, 0, data.Length); - - if (Server.logbeat) - Server.s.Log("Beat " + beat.ToString() + " was sent"); + if (Server.logbeat) Server.s.Log("Beat " + beat + " was sent"); } using (var r = new StreamReader(req.GetResponse().GetResponseStream())) { string read = r.ReadToEnd().Trim(); beat.OnResponse(read); - if (Server.logbeat) - Server.s.Log("Beat: \"" + read + "\" was recieved"); + if (Server.logbeat) Server.s.Log("Beat: \"" + read + "\" was recieved"); } return; } catch { @@ -103,8 +101,7 @@ namespace MCGalaxy { } } - if (Server.logbeat) - Server.s.Log("Beat: " + beat.ToString() + " failed."); + if (Server.logbeat) Server.s.Log("Beat: " + beat + " failed."); } } } diff --git a/Network/IBeat.cs b/Network/IBeat.cs index f70edb3da..3f806689c 100644 --- a/Network/IBeat.cs +++ b/Network/IBeat.cs @@ -1,38 +1,41 @@ /* - Copyright 2012 MCForge + Copyright 2012 MCForge - Dual-licensed under the Educational Community License, Version 2.0 and - the GNU General Public License, Version 3 (the "Licenses"); you may - not use this file except in compliance with the Licenses. You may - obtain a copy of the Licenses at - - http://www.opensource.org/licenses/ecl2.php - http://www.gnu.org/licenses/gpl-3.0.html - - Unless required by applicable law or agreed to in writing, - software distributed under the Licenses are distributed on an "AS IS" - BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - or implied. See the Licenses for the specific language governing - permissions and limitations under the Licenses. + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. */ -namespace MCGalaxy -{ - public interface IBeat - { - /// Gets or sets the URL. - /// The URL. - string URL {get; } +using System.Net; - /// Prepares this instance. - /// - string Prepare(); - - /// Gets a value indicating whether this is persistance. - /// true if persistance; otherwise, false. - bool Persistance {get; } - - /// Called when a response is recieved. - /// The resonse. - void OnResponse(string resonse); - } +namespace MCGalaxy { + public interface IBeat { + + /// Gets the URL. + string URL { get; } + + /// Gets whether this IBeat has periodically repeating beats. + bool Persistance { get; } + + /// Initialises persistent data for this beat instance. + void Init(); + + /// Prepares the data for the next beat of this this instance. + string PrepareBeat(); + + /// Called when a response is recieved. + void OnRequest(HttpWebRequest request); + + /// Called when a response is recieved. + void OnResponse(string resonse); + } }