Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection timing out when connecting to an IRC server with PHP

Tags:

php

irc

I'm trying to connect my PHP script to IRC, but it keeps timing out. I'm on the server, so I know it's up and running, I can't tell what the problem is.

Could it be an error in my code?

<?php

/**
 * Configuration.
 * Pretty self-explanatory
 */

$ircServer = "hub.malvager.com";
$ircPort = "6667";
$ircChannel = "#hackforums";

set_time_limit(0);

$ircSocket = fsockopen($ircServer, $ircPort, $eN, $eS);

if ($ircSocket)
{

    fwrite($ircSocket, "USER Orgy orgy.test hfcoder :twBooter\n");
    fwrite($ircSocket, "NICK OrgyBot|" . rand() . "\n");
    fwrite($ircSocket, "JOIN " . $ircChannel . "\n");

    while(1)
    {
        while($data = fgets($ircSocket, 128))
        {
            echo nl2br($data);
            flush();

            // Separate all data
            $exData = explode(' ', $data);

            // Send PONG back to the server
            if($exData[0] == "PING")
            {
                fwrite($ircSocket, "PONG ".$exData[1]."\n");
            }
        }
    }
}
else
{
    echo $eS . ": " . $eN;
}

?>

UPDATE: Apparently, it's successfully working on SOME servers, but not others. fsockopen is allowed, as is set_time_limit. I can't figure out what the problem is.

UPDATE: Here's a trace route:

traceroute to hub.malvager.com (69.164.201.185), 30 hops max, 40 byte packets
1  rtr-1.bluehost.com (69.89.16.1)  0.406 ms  0.418 ms  0.438 ms
2  ge-6-8.car2.SaltLakeCity1.Level3.net (4.53.42.5)  1.484 ms  1.515 ms  1.590 ms
3  ae-5-5.ebr1.Denver1.Level3.net (4.69.133.126)  35.117 ms  35.119 ms  35.270 ms
4  ae-2-2.ebr2.Dallas1.Level3.net (4.69.132.106)  39.978 ms  39.938 ms  39.939 ms
5  ae-3-80.edge4.Dallas3.Level3.net (4.69.145.141)  40.070 ms  40.046 ms ae-4-90.edge4.Dallas3.Level3.net (4.69.145.205)  40.040 ms
6  THE-PLANET.edge4.Dallas3.Level3.net (4.59.32.30)  40.171 ms  41.407 ms  40.698 ms
7  te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26)  40.653 ms te9-2.dsr02.dllstx3.theplanet.com (70.87.253.30)  40.454 ms te7-2.dsr02.dllstx3.theplanet.com (70.87.253.26)  40.593 ms
8  * * 6e.ff.5746.static.theplanet.com (70.87.255.110)  40.537 ms
9  52.ff.5746.static.theplanet.com (70.87.255.82)  40.481 ms  40.472 ms  40.459 ms
10  li115-185.members.linode.com (69.164.201.185)  40.450 ms  40.171 ms  40.582 ms

And the dig:

; <<>> DiG 9.6.2-RedHat-9.6.2-0.BH <<>> hub.malvager.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34815
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5

;; QUESTION SECTION:
;hub.malvager.com.      IN  A

;; ANSWER SECTION:
hub.malvager.com.   85419   IN  A   69.164.201.185

;; AUTHORITY SECTION:
malvager.com.       85419   IN  NS  ns1.linode.com.
malvager.com.       85419   IN  NS  ns3.linode.com.
malvager.com.       85419   IN  NS  ns2.linode.com.
malvager.com.       85419   IN  NS  ns4.linode.com.
malvager.com.       85419   IN  NS  ns5.linode.com.

;; ADDITIONAL SECTION:
ns1.linode.com.     54252   IN  A   69.93.127.10
ns2.linode.com.     51679   IN  A   65.19.178.10
ns3.linode.com.     41439   IN  A   75.127.96.10
ns4.linode.com.     26259   IN  A   207.192.70.10
ns5.linode.com.     54441   IN  A   109.74.194.10

;; Query time: 4 msec
;; SERVER: 74.220.195.27#53(74.220.195.27)
;; WHEN: Thu Sep 23 16:32:21 2010
;; MSG SIZE  rcvd: 227

NETCAT:

nc: connect to hub.malvager.com port 6667 (tcp) failed: Connection timed out

like image 977
Rob Avatar asked Sep 16 '10 14:09

Rob


1 Answers

You have some errors.

Is buggy, because checking strictly first explode result, you exploding by space character and in IRC implementation protocol all commands must be terminated by newline character then server send to you "PING\n" not "PING" then your $exData array is in this state.

array(1) {
  [0]=>
  string(5) "PING
"
}

Then your $exData[0] == "PING" is false because "PING" is not equal to "PING\n". Good solution is not add "\n" to the end of command in parser because "\n" is not only newline marker (for poor IRC Protocol implementation i recommend this, you never know what newline marker IRC protocol developer may use, think about Delphi INDY Buggy IRC Server Control), better solution is not checking her.

if (strstr(strtolower($exData[0]), "ping"))
{ 
    $cmd = "PONG";
    if (sizeof($exData) == 1)
    {
        $cmd .= "\n";
    }
    else for ($Index=1; $Index < sizeof($exData); $Index++)
    {
        $cmd .= " " . $exData[$Index];
    }
    /*
     * Not adding newline marker, because is.
     * already exists in last element of $exData
     * array at last position if for was executed
     */
    fwrite($ircSocket, $cmd);
}

I will change the while($data = fgets($ircSocket, 128)), to the while ($data = fgets($ircSocket)), because in long server names you can simply overflow 128 bytes.


And your fwrite($ircSocket, "JOIN " . $ircChannel . "\n"); line don't doing exactly what you want, because your JOIN command was sended after the USER and NICK command then server parse your request before user was registered and if user is not registered you can JOIN to channel, IRC servers don't QUEUE failed command because this don't have any sense. The best practice of this is send JOIN command after the MOTD command was received from the server and after the left from channel command was received too if you want implement some functionality like AUTOJOIN.

// End of /MOTD command.
if (sizeof($exData) > 1) if (strstr($exData[1], "376"))
{
    fwrite($ircSocket, "JOIN " . $ircChannel . "\n");
}

About your script design, if you writing simple bot then i don't have any thing to say in this topic, but if you plan write some big piece of code you should design your script in other way. You must separate some layers like IRC Protocol implementation and your IRC Bot actions. You should use some class to move responsibility of IRC Protocol into her, because in bigger piece of code mixing IRC Protocol control with your bot actions code is nice Technical debt.

like image 137
Svisstack Avatar answered Nov 01 '22 20:11

Svisstack