strange socket timeout on Azure App Services, but works fine locally - php

I'm having weird issues with sockets. I'm trying to connect to this IP with the port 25565 to figure out the ping of this particular IP/Server. I have a piece of code that works just fine locally and shows me the ping without fail, it also works just fine on an OVH Kimsufi box running nginx/PHP CGI. Yet on Microsoft Azure it does not, showing me the 10060 (timeout) errorcode and this message: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.. And only for this one IP. Another IP (37.59.51.122) works just fine. I have this app running in 3 different regions, EU West, US West and US East. It works in none of them.
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
function ping($host, $port)
{
$time_start = round(microtime(true) * 1000);
$fp = fsockopen("tcp://" . $host, $port, $errno, $errstr, 1);
if ($fp) {
$time_end = round(microtime(true) * 1000);
fclose($fp);
$time = $time_end - $time_start;
return $time;
} else {
return $errno . ":" . $errstr;
}
}
echo ping("149.56.81.67", 25565);
Does anyone have any idea what could possibly be causing this problem? Is there an azure-specific setting I need to change to fix this?
Or is there an easy way to debug this on Azure?
I'm quite new to Azure so I'm very unfamiliar with it.
EDIT: I have tried in many different regions (from japan to west US.) and couldn't find any settings about firewalls or IP blacklists. I'm really at a loss here.

If you change your last line to ping 8.8.8.8 on port 53 (Google's Public DNS Servers), it does work as expected as you already pointed out.
However, from Kudu's DebugConsole (https://{appname}.scm.azurewebsites.net/DebugConsole), if i do a tcpping host:port i see either your remote firewall acting up or packet loss.
D:\home\site\wwwroot>tcpping 149.56.81.67:25565
Connection attempt failed: Connection timed out.
Connection attempt failed: Connection timed out.
Connected to 149.56.81.67:25565, time taken: 78ms
Connected to 149.56.81.67:25565, time taken: 86ms
Complete: 2/4 successfull attempts (50%). Average success time: 82ms
This is why you see the timeout.
Try to run tcpdump on your remote server to see if it's really packet loss or the machine is simply not sending a SYN back (may send a RST instead).

I have found out the problem. I had this script running in a loop, pinging it 5 times in quick succession. I have since added a 500ms delay between requests and I no longer have timeouts.
I wouldn't have figured this out without the help of evilSnobu. I figured out that tcpping.exe did work more often than my php script, despite the raw connection being virtually the same. The only difference was the delay between the requests. It was OVH's ddos protection firewall blocking my connections.

Related

Need to check IP reachability via PHP or SSH (can't use ping though)

I need to check if my hosting server can reach certain IPs that I need to work with.
I have a shared hosting plan and, although I have access to SSH, the PING function is not available.
I've tried several php scripts but to no avail. Most of them relied on executing PING via shell.
Is there any way I can check this without using PING? I tried using the CURL function (in PHP) but it doesn't seem to work with IPs.
Any help would be very much appreciated.
Try this, it connects to port 22, which is the reserved port for ssh:
<?php
//
// By: Spicer Matthews <spicer#cloudmanic.com>
// Company: Cloudmanic Labs, LLC
// Date: 5/19/2011
// Description: This is a client to the echo server. It will send 10 test commands, and echo the server response.
// Run it from the command line "php client.php".
//
set_time_limit(0);
$address = '127.0.0.1';
$port = '22';
$fp = fsockopen($address, $port, $errno, $errstr, 300);
if(! $fp)
{
http_response_code(204);
}
else
{
http_response_code(404);
}
?>
The response codes may need to be changed, as necessary.

how to use php sockets to write string

So Im trying to get my head wrapped around this....
I open the port
$remip = $_SERVER['SERVER_ADDR']; //Grab my server address
$fp = fsockopen($remip, 80, $errno, $errstr, 10);//Godaddy hosting only 80 and 443 ports work
//fsockopen(ip address , port, IDK, IDK, timeout delay)
so now the ports open or if not maybe some error checking to be sure
if (!$fp) { echo "$errstr ($errno)<br>\n"; exit; } //Not sure what this echos out but its clear how it stops errors
So now that the port is open any ip/client can connect on this port????
Ill assume I can now connect....
So on my client I open a socket to my server ip address port tcp connection.....
The php file includes something like
else {$out = "hello, 80\r\n"; //out specifies the string to be written , bytes to write
fwrite($fp, $out); //$fp is the handle
fclose($fp)}//close the connection
at this point ill assume that my client gets the hello written to it ..
finish up by closing the connection
Im entirely new to this so Im attempting to understand some sample code here...
So how long is this socket open for? If i want to keep this port open do i need to do a cron job to launch this file periodically.
Im 100% sure that I have got something wrong here so please set me straight.
I think you have a misconception of what fsockopen does. In your example your fsockopen does not actually open port 80 (as in opening a server socket), but it opens a client socket that connects to port 80 on the server itself. It actually does open a (client) port which gets a (not completely) random number.
After you connected using fsockopen you can send HTTP commands to the webserver such as GET /index.php
What you need to use is socket_listen() and socket_bind(). There are a few places in the docs that show you how to get PHP listening on a socket: http://www.php.net/manual/en/function.socket-listen.php
I suggest you read and try them out by simply testing then with a unix tool called netcat (nc <ip_address> <port> command normally)

socket_accept seems to hang on the first connection

I'm trying to make a simple listener on port 8195. When I try the following code block in PHP CLI conditions, it only shows 'Test' once, then hangs. If I delete the file 'votifier.run', the file designed to be the on/off switch, it still continues to hang. It never shows 'Client connected'.
Furthermore, if I try to connect to the host via Telnet on port 8195 while the script is running, I simply get a connection failed message. It's like it's looking for one connection and just not giving up.
// Set the IP and port to listen to
$address = 'localhost';
$port = 8195;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port);
// Start listening for connections
socket_listen($sock);
// Loop continuously
while ( file_exists('votifier.run') ) {
echo 'Test';
$client = socket_accept($sock);
if( $client ) {
echo 'Client connected';
// Don't hang on slow connections
socket_set_timeout($client, 5);
// Send them our version
socket_write("VOTIFIER MCWEBLINK\n");
// Read the 256 byte block
$block = socket_read($client, 256);
...
The answer:
socket_accept() will usually hang until a connection is made. If a connection attempt was made, the script would continue, but because the socket was being created on localhost, it would only accept connections to it from localhost.
The fix is to use your external IP rather than 'localhost' or '127.0.0.1'. Then you can Telnet to it.
I'm just guessing here, but could it be that the address you are trying to bind to should not be a hostname?
If the socket is of the AF_INET family, the address is an IP in dotted-quad notation (e.g. 127.0.0.1).
EDIT
Ok, I've taken your script and tried to reproduce your error but couldn't. There are a couple of flaws in it but none that would cause a telnet client's connection attempt to fail.
Since none of the aforementioned applies, let's go thru the checklist one by one:
sockets module loaded/compiled
localhost does resolve to 127.0.0.1
the port isn't taken by any other application running
there's no rule of any sort of firewall that would prevent communication between the telnet client and your server
the machine which you connect from is allowed to connect to the server host (try the same host if it isn't)
the file that's being checked in the while-loop does exist
you are sure that there isn't another fatal error within your script that would prevent the snippet you posted from running
These are all the possible error sources I can think of, atm. Try fixing up the minor flaws first, then go thru the checklist.
if( $client ) {
echo 'Client connected';
// Don't hang on slow connections
socket_set_option(
$client,
SOL_SOCKET,
SO_RCVTIMEO | SO_SNDTIMEO,
array('sec' => 5, 'usec' => 0)
);
// Send them our version
socket_write($client, "VOTIFIER MCWEBLINK\n");
^^^^^^^
// Read the 256 byte block
$block = socket_read($client, 256);
You should be using threads. If the client never sends anything your code will block in the read() method. Each accepted socket should be completely handled in a new thread.
You may want to check this:
PHP Votifier example for Minecraft Topsites
It explains how the code works, it's the basic function that makes the encryption, fills up the 256 blank spaces and sends the packet too. You can work a little with it as you may want to improve it.
You can see a live demo of the running php for the plugin here: http://topg.org/test_votifier

Port checking from php

I'm trying to connect to gmail pop server from a phplist installation and it fails, but i'm not sure whether my webhost opened port 995 or not. They say they have opened it, but i'm in doubt. Is there a way i can check it from a php script? They are running php 5.2.0 on a windows server, though i'm not sure what OS is that. phpinfo() says "Windows NT DEDI514 5.2 build 3790"
You can put code in a php script to open a connection to a specific hostname (or IP address) and port.
If you know the expected response, you should be able to tell if you are getting a connection. If you get something like "Connection refused", then either you are being blocked, or the destination host is not accepting connections on that port.
This example uses IP address 192.0.2.0 and port 995. Replace these with whatever you want to test.
<?php
echo "\nOpening connection\n\n";
$fp = fsockopen("192.0.2.0", 995, $errno, $errstr);
if (!$fp) {
echo "ERROR: $errno - $errstr\n";
} else {
echo fread($fp, 1024);
fclose($fp);
}
?>
You can also send data to the server using
fwrite($fp, "blah blah blah\r\n");
There is more information about fsockopen here.
I think you'll need to ping or traceroute to a machine that will respond on that port.
This article should have much more than you want to know, but there's an example script at the bottom that you can modify to test.
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?lngWId=8&txtCodeId=1786
There are some other scripts here:
http://www.theworldsend.net/
I can't vouch for any of these personally, but they look like what you need.
And, of course, if you can ssh or telnet into your server, you can do all this much more easily using the ping and traceroute commands.
Maybe safe mode is active? This prevents calling services on other servers.
Edit:
All filesystem and stream functions are affected by the safe mode settings!
The open_basedir setting affects fopen()!

php fsockopen

I have a simple php script on a server that's using fsockopen to connect to a server.
<?php
$fp = fsockopen("smtp.gmail.com", 25, $errno, $errstr, 30);
if (!$fp) {
echo "$errstr ($errno)<br />\n";
} else {
echo fgets($fp, 1024);
fclose($fp);
}
?>
The problem is the the script times out and fails to connect. If i change the port from 25 to 80 for example it works without problems on any host. So the problem seems to be only the port 25 no matter what host i use, i tried a lot of them and all work for port 80 and others but for 25 fails.
Connections are not blocked form firewall as if i telnet from shell it successfully connects to any port on any host.
Any idea what could be the problem as it's really weird?
LE: If i run the same php script from the shell, php scriptname.php it works so only when i run it by http it fails. I have apache with SuPHP so the problem is around here somewhere
Interesting...
Some firewalls can block specific program's connections to specific ports.
Please check it again, try to stop firewall completely. Also try to stop any anti-spyware.
Like maxnk mentioned firewalling is the most likely issue, either on the server, or by your ISP. Port 25 is frequently firewalled as a method to prevent spam.
Just as a quick test, since you mentioned gmail, you might want to try connecting to port 587 instead. Gmail listens for smpt on this alternate port in addition to port 25 to help users bypass overly restrictive firewalls.
I've run into some strange issues with PHP's socket handling, too. It ended up being a problem with the system it was running on. Have you tried running your code on a different machine?
I think the connection problem is with your machine. I just copied your code into a script on my machine(linux suse) and ran it with php -f test_script. I got the following message
220 mx.google.com ESMTP j8sm1814228gvb.0
CentOS can have SELinux enabled which can cause connection weirdness. Have you checked your error logs?

Categories