tags:

views:

361

answers:

12

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

A: 

The server might require a ident response. Also, I ran that script, it connected fine. Maybe its a firewall issue.

Petah
What server address did you manage to connect it to, if you don't mind me asking? I think it might be something wrong with my server.
Rob
+2  A: 

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.

Svisstack
While I appreciate your help, my script doesn't even get far enough to check what the IRC server is sending. It fails at the `if ($ircSocket)` conditional, due to timing out.
Rob
@Rob: Then problem with this is not in your script, because in my side this working good, then why you posting complete source code?
Svisstack
Because maybe someone would be able to figure out why it works on some servers and not others
Rob
@Rob: hmm, if your code works on some servers and not others and if you know 100% this is not your network, server network, route problem then my post solve your problems in your code, if your not sure about network problem, then ask on serverfault.com because source after my patches working well.
Svisstack
@Svisstack: Well I was thinking maybe something in php.ini would be disabling it that I'm overlooking.
Rob
@Rob: instead of checking if a PING or PONG is equal, see if it's returned in the response by using strstr() : http://ca2.php.net/manual/en/function.strstr.php
Geekster
@Geekster: Thanks, but again, that has nothing to do with the issue.
Rob
@Rob : I know. It's Ident, as I posted in my answer, but I thought I would give you something added. :)
Geekster
A: 

Sounds like you are being blocked because you don't have IDENT set up.

Listen on port 113 to see if there is an Ident request from the IRC server.

Also this is a good read for how Mirc handles ident requests so you can easily whip something up to make it work.

Geekster
I don't think it's ident, either. My friend has ran the exact same script to connect to the exact same server and it worked fine.
Rob
He is probably running with different PHP_INI settings then. I'd suggest taking a look at his settings in php_ini, and compare which ones are different to yours then.
Geekster
Also, many IRC servers will require Ident servers to block bots, so if you code one in... it's definitely an improvement to what you have.
Geekster
@Geekster: I don't have any IDENT listen and i connecting to this server and IDENT is checking after connection to server was established, because ident must know local-port of connection because in this way ident determinate connected user, before connection this is not IMPOSIBLE.
Svisstack
+1  A: 
  1. Install netcat
  2. Run on the same device nc hub.malvager.com 6667
  3. Analyze results.

If your result is:

sviss@sviss:~$ nc -v hub.malvager.com 6667
DNS fwd/rev mismatch: hub.malvager.com != li115-185.members.linode.com
hub.malvager.com [69.164.201.185] 6667 (ircd) open
:hub.malvager.com NOTICE AUTH :*** Looking up your hostname...
:hub.malvager.com NOTICE AUTH :*** Found your hostname (cached) 
  1. Install fresh PHP version from SOURCE FILES (this is important because in binary versions from apt or something versions is deprecated) from php.net
  2. Then you can modify default PHP.ini file to tune fsockopen settings if problem not has solved yet (i think with default .ini file your script will be working good).

If your result representing some connection error, some think like this example:

sviss@sviss:~$ nc -v hub.malvager.com 6668
DNS fwd/rev mismatch: hub.malvager.com != li115-185.members.linode.com
hub.malvager.com [69.164.201.185] 6668 (?) : Connection refused
  1. Do tracert hub.malvager.com and post results into your question, then i must read this and update my answer.

  2. If you are working on POSIX do dig hub.malvager.com and post results into your question, then i must read this and update my answer.

  3. If you are working on WINDOWS do nslookup hub.malvager.com and post results into your question, then i must read this and update my answer.

  4. If you want analyze this result alone, handy from your point is my results of this command then i post this.

Result of dig hub.malvager.com:

; <<>> DiG 9.5.1-P3 <<>> hub.malvager.com
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33134
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

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

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

;; Query time: 17 msec
;; SERVER: 62.179.1.62#53(62.179.1.62)
;; WHEN: Wed Sep 22 18:28:57 2010
;; MSG SIZE  rcvd: 50

Result of tracert hub.malvager.com on POSIX:

traceroute to hub.malvager.com (69.164.201.185), 30 hops max, 40 byte packets
 1  10.10.10.1 (10.10.10.1)  1.428 ms  1.861 ms  2.287 ms
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  *  (84.116.252.205)  145.057 ms  145.557 ms
 8  84.116.132.53 (84.116.132.53)  141.189 ms  142.263 ms  143.312 ms
 9  84.116.132.230 (84.116.132.230)  143.827 ms  169.115 ms *
10  us-nyc01b-rd1-pos-12-0.aorta.net (213.46.160.242)  141.656 ms  142.722 ms *
11  us-nyc01b-ri1-ge-0-1-0.aorta.net (213.46.190.178)  144.280 ms  146.999 ms  147.512 ms
12  be-20-203-pe01.111eighthave.ny.ibone.comcast.net (68.86.88.73)  148.066 ms  148.570 ms  133.769 ms
13  68.86.87.109 (68.86.87.109)  133.962 ms  137.222 ms  137.218 ms
14  pos-0-9-0-0-cr01.ashburn.va.ibone.comcast.net (68.86.87.61)  142.599 ms  142.608 ms  142.624 ms
15  pos-1-5-0-0-cr01.atlanta.ga.ibone.comcast.net (68.86.87.78)  144.131 ms  141.138 ms  144.306 ms
16  pos-1-10-0-0-cr01.dallas.tx.ibone.comcast.net (68.86.86.129)  165.506 ms  166.013 ms  169.184 ms
17  pos-0-3-0-0-pe01.1950stemmons.tx.ibone.comcast.net (68.86.86.154)  170.688 ms  171.203 ms  174.275 ms
18  theplanet-cr01.dallas.tx.ibone.comcast.net (75.149.228.2)  183.499 ms  184.011 ms  187.376 ms
19  te9-1.dsr02.dllstx3.theplanet.com (70.87.253.22)  187.883 ms  188.390 ms  174.093 ms
20  * * *
21  56.ff.5746.static.theplanet.com (70.87.255.86)  173.691 ms  174.396 ms  174.679 ms
22  li115-185.members.linode.com (69.164.201.185)  174.702 ms  175.541 ms  174.186 ms
Svisstack
I don't have shell access to these servers.
Rob
@Rob: then you can try use exec() to obitatin result of this commands if in php ini safe_mode is disabled, in other case you don't solve this problem because you don't have terms to get information about target environment who you need to get produce solution.
Svisstack
@Svisstack: thank you for your help thus far, I have appended the results of the dig and traceroute to my question
Rob
@Rob: with your result's is all ok, then with connection between your and the server is all ok, then problem can exist in your machine or irc server machine. For determinate what is wrong i need important information from second application for establishing connections like `nc` or `telnet` you can't try to get this infromation? Maybe netcat is instaled on your machine. But take a look on this, netcat will not exit if connection was establised, then hang up your `exec`, then you must in exec do command with redirection stdout to file (> operator) and read file.
Svisstack
@Svisstack: What would be the exact `exec` statement for this?
Rob
@Rob: exec('nc hub.malvager.com 6667') and if command not hang up then result of this exec is a your result, if command hang up then do exec('nc hub.malvager.com 6667 > ./x') and in other script get get_file_contents('x'), and give me data from x, this is a result.
Svisstack
I thought so, and I tried that earlier, but x was empty. (well, output.txt, but same thing) x is empty this time, too.
Rob
Svisstack
Alright that worked, and it timed out as well.
Rob
Your hosting provider could be blocking access to IRC (http://www.linode.com/faq.cfm#can-i-run-an-IRC-server-on-my-linode)...
wimvds
A: 

Telnet indicates it should be written this way for malvager.com, port 6667

"PASS *\n"
"NICK OrgyBot|" . rand() . "\n"
"USER Orgy orgy.test hfcoder :twBooter\n"


if($exData[0] == "PING :hub.malvager.com")
{ 
 fwrite($ircSocket, "PONG :hub.malvager.com".$exData[1]."\n"); 
} 
NiDeep
A: 

Are you running this bot from your local machine or your webserver? If it is from your webserver it could be that malvager.com has your webserver blocked while other irc servers have it unblocked.

I have had this issue on other IRC networks and it turns out, other people have used the same hosting provider I use to host botnets which required the IRC server to block the IP from my host.

I would ask a malvager.com admin if the IP address you are connecting from is blocked.

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

EDIT:

I use bluehost and it looks like you do too. I was having issues with my irc working on their servers and I spoke to them in Live Chat. They mentioned they don't allow irc bots on their network so they have most of the networks blocked. They mentioned however if one slips by and they catch it, they will suspend your account.

jostster
Who is the one that is very downvote happy?
jostster
A: 

1) If the server sends a ping with a message, you should reply with a pong followed by the same message.
2) From time to time (every 30 seconds or so) send a ping message to the server. If you don't get a reply in a couple of minutes, you can probably consider that the client has timed out from the server and should reconnect.

Tom
Yeah, that'd be a great idea to implement. **IF** I could get the server connected initially.
Rob
A: 

The end of message in the IRC protocol according to rfc1459 is ¨\r\n¨ not just ¨\n¨. Some server implementations might reject your messages because of that.

LarsV
A: 

Have you tried using telnet to simulate your bot's behavior and see what happens? Connect, type (or copy-paste) exactly what your bot would output and stare at the screen for a few minutes.

Tom
A: 

I remember doing some bots back in the mIRC era. The problem were always the line breaks i used to send after the message.

As far as i remember, the chars vere #30 and #32 or such. Why not try them instead of \n. Some servers are pretty sensitive to this issues.

Also the pong has to be replied with the text after the ping, thats very important.

Have fun!

Herr Kaleun
By voting -1 on comments, your problem won't solve by itself. I try to be nice but that is rude. Solve your problem on your own then.
Herr Kaleun
@Herr Kaleun, by not reading my question entirely, or at all, you won't solve my problem.
Rob
Not every person has plenty of time, at least i tried to be nice. Have fun
Herr Kaleun
A: 

bluehost.com hosting blocking IRC connections to this IRC server, this is checked information.

Svisstack
A: 

this

code has a perfect working IRC server. I would go this way.

PS: If you don't like it, be nice and don't wote it down. Thanks

Herr Kaleun