From 71d17c50d6a316311d59bbfe48b91f3e5258ebd4 Mon Sep 17 00:00:00 2001 From: Dylan T Date: Tue, 29 Jan 2019 12:51:53 +0000 Subject: [PATCH] Fixed internal IP detection (#2711), closes #2702 --- src/pocketmine/network/upnp/UPnP.php | 4 +--- src/pocketmine/utils/Internet.php | 31 +++++++++++++++++++++++++++ src/pocketmine/wizard/SetupWizard.php | 8 +++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/pocketmine/network/upnp/UPnP.php b/src/pocketmine/network/upnp/UPnP.php index aa9c3a733..305cd1746 100644 --- a/src/pocketmine/network/upnp/UPnP.php +++ b/src/pocketmine/network/upnp/UPnP.php @@ -29,9 +29,7 @@ namespace pocketmine\network\upnp; use pocketmine\utils\Internet; use pocketmine\utils\Utils; use function class_exists; -use function gethostbyname; use function is_object; -use function trim; abstract class UPnP{ @@ -46,7 +44,7 @@ abstract class UPnP{ throw new \RuntimeException("UPnP requires the com_dotnet extension"); } - $myLocalIP = gethostbyname(trim(`hostname`)); + $myLocalIP = Internet::getInternalIP(); /** @noinspection PhpUndefinedClassInspection */ $com = new \COM("HNetCfg.NATUPnP"); diff --git a/src/pocketmine/utils/Internet.php b/src/pocketmine/utils/Internet.php index 268e2784d..ebd704bda 100644 --- a/src/pocketmine/utils/Internet.php +++ b/src/pocketmine/utils/Internet.php @@ -32,10 +32,17 @@ use function curl_init; use function curl_setopt_array; use function explode; use function preg_match; +use function socket_close; +use function socket_connect; +use function socket_create; +use function socket_getsockname; +use function socket_last_error; +use function socket_strerror; use function strip_tags; use function strtolower; use function substr; use function trim; +use const AF_INET; use const CURLINFO_HEADER_SIZE; use const CURLINFO_HTTP_CODE; use const CURLOPT_AUTOREFERER; @@ -51,6 +58,8 @@ use const CURLOPT_RETURNTRANSFER; use const CURLOPT_SSL_VERIFYHOST; use const CURLOPT_SSL_VERIFYPEER; use const CURLOPT_TIMEOUT_MS; +use const SOCK_DGRAM; +use const SOL_UDP; class Internet{ public static $ip = false; @@ -98,6 +107,28 @@ class Internet{ return false; } + /** + * Returns the machine's internal network IP address. If the machine is not behind a router, this may be the same + * as the external IP. + * + * @return string + * @throws InternetException + */ + public static function getInternalIP() : string{ + $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); + try{ + if(!@socket_connect($sock, "8.8.8.8", 65534)){ + throw new InternetException("Failed to get internal IP: " . trim(socket_strerror(socket_last_error($sock)))); + } + if(!@socket_getsockname($sock, $name)){ + throw new InternetException("Failed to get internal IP: " . trim(socket_strerror(socket_last_error($sock)))); + } + return $name; + }finally{ + socket_close($sock); + } + } + /** * GETs an URL using cURL * NOTE: This is a blocking operation and can take a significant amount of time. It is inadvisable to use this method on the main thread. diff --git a/src/pocketmine/wizard/SetupWizard.php b/src/pocketmine/wizard/SetupWizard.php index 398d25358..0cd3f1d1e 100644 --- a/src/pocketmine/wizard/SetupWizard.php +++ b/src/pocketmine/wizard/SetupWizard.php @@ -30,9 +30,9 @@ namespace pocketmine\wizard; use pocketmine\lang\BaseLang; use pocketmine\utils\Config; use pocketmine\utils\Internet; +use pocketmine\utils\InternetException; use function base64_encode; use function fgets; -use function gethostbyname; use function random_bytes; use function sleep; use function strtolower; @@ -223,7 +223,11 @@ LICENSE; if($externalIP === false){ $externalIP = "unknown (server offline)"; } - $internalIP = gethostbyname(trim(`hostname`)); + try{ + $internalIP = Internet::getInternalIP(); + }catch(InternetException $e){ + $internalIP = "unknown (" . $e->getMessage() . ")"; + } $this->error($this->lang->translateString("ip_warning", ["EXTERNAL_IP" => $externalIP, "INTERNAL_IP" => $internalIP])); $this->error($this->lang->get("ip_confirm"));