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, AUTHORIT开发者_如何学编程Y: 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
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.
- Install
netcat
- Run on the same device
nc hub.malvager.com 6667
- 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)
- Install fresh
PHP
version from SOURCE FILES (this is important because in binary versions from apt or something versions is deprecated) from php.net - Then you can modify default
PHP.ini
file to tunefsockopen
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
Do
tracert hub.malvager.com
and post results into your question, then i must read this and update my answer.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.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.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
The server might require a ident response. Also, I ran that script, it connected fine. Maybe its a firewall issue.
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.
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
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.
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.
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.
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");
}
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.
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!
bluehost.com
hosting blocking IRC connections to this IRC server, this is checked information.
精彩评论