First, some background info. What I'm trying to do is essentially a port sniff. I'm trying to connect to a host and determine if a port is open, closed or blocked. I used to do this using the fsockopen( ) function. It lets you set a timeout for initiating the connection, and life was good. But then I started running this website on it's own unique IP address, and so I have to bind the connection to this IP. You can't do this with fsockopen( ) but you can do it with socket_create( ) and related functions.

So I've switched to using these functions, but now I have a new problem. I seem to be able to create read and write timeouts, but no timeout for actually creating the connection. I've tried setting send and receive timeouts, and setting the default_socket_timeout value. I set both to timeout in 2 seconds, but it still takes 75 seconds to timeout.

Also to be clear, this code works fine for most hosts. The problem is running it on a host that has the port blocked via firewall. socket_connect( ) eventually returns an error #60, as it should, for a timed-out connection. The problem is how long that error takes (75 seconds).

ini_set("default_socket_timeout","2");
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($sock,OPERATING_IP);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 1, "usec" => 0));
socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 1, "usec" => 0));
$sock_status = @socket_connect($sock,$ip,$port);

In the above code: OPERATING_IP is a constant of the IP address I am binding to, $ip is the IP address I am connecting to. This will be any user anywhere on the internet. I do not control or know anything about it, $port is the specific port I am testing

So just to reiterate, how can I set a timeout for actually initiating the TCP connection using socket_connect( )? I tried (in lines 1, 4 & 5) to set it to a short timeout of 2 seconds, but it still takes 75 seconds to timeout, when connecting to hosts that block connections.

    I don't know anything about connection timeout as relating to the socket_ functions, but I do know you can specify connection timout using curl. Would that perhaps be viable for testing connectability?

    [man]curl_setopt[/man]

    CURLOPT_CONNECTTIMEOUT The number of seconds to wait while trying to connect. Use 0 to wait indefinitely.

      7 days later

      CURL doesn't really have anything to do with this. CURL is for making HTTP requests. I'm trying to open TCP connections to arbitrary ports that could be running any service, or no service at all.

        I haven't done any of this, and I'd expect timeout settings to set timeouts, but I think if you set the socket to be non-blocking before trying to connect, execution ought to go straight through the socket_connect call without pausing.

        While the connection attempt is in progress, socket_connect would return false and set socket_last_error to say the connection is in progress.

        I don't know whether this will affect the 75-second timeout, but at least you won't be completely held up (if you're testing multiple ports you could test them concurrently, for example).

        EDIT: I see there's a user note on the [man]socket_connect[/man] page describing non-blocking sockets and setting a timeout.

          Weedpacket;11035337 wrote:

          I haven't done any of this, and I'd expect timeout settings to set timeouts, but I think if you set the socket to be non-blocking before trying to connect, execution ought to go straight through the socket_connect call without pausing.

          While the connection attempt is in progress, socket_connect would return false and set socket_last_error to say the connection is in progress.

          I don't know whether this will affect the 75-second timeout, but at least you won't be completely held up (if you're testing multiple ports you could test them concurrently, for example).

          EDIT: I see there's a user note on the [man]socket_connect[/man] page describing non-blocking sockets and setting a timeout.

          If I did non-blocking sockets, how would I check the status of the socket? I wasn't able to find any sample code and I have no idea how you'd do this.

            There's some sample code in the user note I alluded to. Short answer is that you check [man]socket_last_error[/man].

              Write a Reply...