Fsockopen Power Plays (://URLFAN)
Discover what sites bloggers are referencing in real time.
Reading 1,398,702 feeds, parsing 95,631,598 posts, ranking 1,515,000 domains.

    HOME  CONTACT  ABOUT US  TOP 100 SITES  BUZZ POSTS
Search 95,631,598 blog posts
LOOKUP A DOMAIN

Feed
askapache.com

Post Category

Post Date
Jul 02, 2008 4:42 a.m.

Article Structure
15 paragraphs
27489 characters
6 images
3 outgoing links

Sites mentioned
(click for rank details):

php.net
snoopy.sourceforge.net
wordpress.org
askapache.com

ietf.org


Next Article
Göttingen: „Schwarze Witwe“ zu lebenslanger Haft verurteilt - FOCUS Online

Previous Article
predam sonyericsson P1i - 10 500

Fsockopen Power Plays

Source: http://feeds.askapache.com/~r/apache/htaccess/~3/3...

Displaying mentions in this article, for full text please visit source.

Fsockopen PowerPHP’s function fsockopen lets you open an Internet or Unix domain socket connection for connecting to a resource, and is one of the most powerful functions. fsockopen could be described as creating a direct link to the wire connected to a resource, which means you can send any information (EBCDIC, ASCII, Hex, C arrays, Raw) directly to the target server.

A Socket is like /dev/null

In unix you can send anything to the /dev/null device, for windoze think Recycle Bin, and likewise you can send anything to a socket created with fsockopen. I’ve seen fsockopen code that sends custom exploits to cisco routers, including being used by the metasploit framework. I’ve seen fsockopen telnet emulation, smtp/pop3 login, and a lot of other advanced raw networking that is exciting for me see.

Some Definitions for Fsockopen client A program that establishes connections for the purpose of sending requests. server An application program that accepts connections in order to service requests by sending back responses. Simple Socket Explantion

A web server host listens on TCP port 80. When a client host wishes to view a resource on the web server, it establishes a TCP connection with the server host by opening a socket to send the request for the resource. When the connection is established, the client and server exchange requests and responses (respectively) until the connection is closed or aborted.

HTTP and fsockopen

’SnoopyThe Snoopy class is bundled with WordPress distributions and uses fsockopen to achieve most of its cool features. WordPress core, plugins, and other included files and classes also use the fsockopen function to communicate via HTTP.

Fsockopen Examples

fsockopen warningNote the warning sign, fsockopen is dangerous in the sense that you can crash your server, perform a DOS against your own server or other site, use up all your servers available sockets and fd descriptors, use up your bandwidth, etc.. Shouldn’t be a problem unless you are being malicious or careless.

Here are some BOSS fsockopen functions I hacked together yesterday for use in my AskApache Crazy Cache WordPress Plugin. I’ve used code and ideas from 100’s of authors, projects, and docs to try to make this the very best I can.

Intro

This is a working example employing as many of the best-practices, tips, and tricks for using fsockopen on remote streams that I could find.

100megs */ function askapache_txrx($fp,$request,$chunk=1024){   $rec=$buf='';   if(!@fwrite($fp, $request, strlen($request)))die('fwrite error');   while ( !@feof($fp) && askapache_time_ok(askapache_time_passed())){     $buf = @fread($fp, $chunk);     $rec .= $buf;   }   if(!@fclose($fp))die('fclose error');   return $rec; }   /* initiates the socket and download for the passed url.    automatically handles gzip, chunked, both, and plain downloads.    uses the long2ip/ip2long for ip validation, uses gethostbyname to    get the ipv4 address which saves fsockopen from having to do the lookup    final data is saved to $rbody but currently only displays headers.*/ function aa_dl($url=NULL){   global $aa_time;   $ub = @parse_url($url);   if(!isset($ub['host'])||empty($ub['host'])) die("bad url $url");   $proto   = ($ub['scheme']=='https')?'ssl://':'';   $port   = (isset($ub['port'])&&!empty($ub['port'])) ? $ub['port']:($proto!='')?443:80;   $path   = (isset($ub['path'])&&!empty($ub['path'])) ? $ub['path']:'/';   $query   = (isset($ub['query'])&&!empty($ub['query'])) ? '?'.$ub['query'] : '';   $host   = $ub['host'];   $ipp     = @gethostbyname($host);   $ip     = ($ipp!=$host) ? long2ip(ip2long($ipp)) : $host;      $headers=array(    "GET {$path}{$query} HTTP/1.1",    "Host: {$host}",    'User-Agent: Mozilla/5.0 (AskApache/; +http://www.askapache.com/)',    'Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,*/*;q=0.5',    'Accept-Language: en-us,en;q=0.5',    'Accept-Encoding: gzip,deflate',    'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',    'Connection: close','Referer: http://www.askapache.com'   );   $request=join(AA_LF,$headers).AA_LF.AA_LF;      $fp=askapache_get_sock($proto.$ip, $port);   if($fp){     $rbody=$rec='';$resp_headers=array();     $rec=askapache_txrx($fp,$request);     list($resp_headers, $rbody) = explode(AA_LF.AA_LF, trim($rec), 2);   echo "n

$request

n

$resp_headers

n";     $gzip2=(stripos($resp_headers,'Content-Encoding')!==false &&         stripos($resp_headers,'gzip')!==false)?1:0;     $chunk=(stripos($resp_headers,'Transfer-Encoding')!==false &&         stripos($resp_headers,'chunked')!==false)?1:0;     $rbody=aa_decode_body($rbody,$chunk,$gzip2);     unset($rbody);   } }   /* based on http://us.php.net/manual/en/function.fsockopen.php#75175    ungzips and/or re-assembles transfer-encoded:chunked responses    returns the good response on success */ function aa_decode_body ($str, $chunked, $gzipped){   if($gzipped && !$chunked) return aa_gzdecode($str);   if(!$gzipped && !$chunked) return $str;   $tmp = $str; $str = '';   do {     $tmp = ltrim($tmp);     $pos = strpos($tmp,AA_LF);     $len = hexdec(substr($tmp, 0, $pos));     if($gzipped) $str .= gzinflate(substr($tmp,($pos+12),$len));     else $str .=substr($tmp,($pos+2),$len);     $tmp = substr($tmp,($len+$pos+2));   $chk=trim($tmp);   } while (!empty($chk));   return $str; }   /*  based on http://us2.php.net/manual/en/function.gzencode.php#82520   saves the gzipped data to a tempfile, then outputs the decoded   data to the output buffer using readgzfile, returning the decoded   buffer and deleting the tempfile on success */ function aa_gzdecode($data){   $g=tempnam('/tmp','ff');   @file_put_contents($g,$data);   ob_start(); readgzfile($g); $d=ob_get_clean(); @unlink($g);   return $d; }   /*  very cool!  this is run during socket reads and checks whether the script   execution time limit or the socket read time limit has been met, killing   the script if so, otherwise returns true.  Run with a cron-like process */ function askapache_time_ok($sock_time=0) {   global $aa_time;   if (time()-$aa_time>AA_MAX_TIME)     die('killed script.. time exceeded '.AA_MAX_TIME.' Total: '.$total);   if ($sock_time>AA_RECV_TIME)     die('Killed socket.. time exceeded '.AA_RECV_TIME.' Total: '.$sock_time);   return true; }   /* input for askapache_time_ok to keep track of each socket read time time. */ function askapache_time_passed() {   global $aa_time_start;   return (time() - $aa_time_start); }   /*  handles fsockopen errors, printing them out though you may want to die on err */ function askapache_sock_strerror($errno,$errstr){   switch($errno){     case -3:  $err="Socket creation failed"; break;     case -4:  $err="DNS lookup failure"; break;     case -5:  $err="Connection refused or timed out"; break;     case 111: $err="Connection refused"; break;     case 113: $err="No route to host"; break;     case 110: $err="Connection timed out"; break;     case 104: $err="Connection reset by client"; break;     default:  $err="Connection failed"; break;   }   echo '

Fsockopen failed!'."n[".$errno."] ".$err." (".$errstr.")

";   return false; } ?>
Debugging Fsockopen

If you really want to know more about fsockopen, you can do what I did and read all the relevant php source files, your OS sys, lib, and user files relevant to fsockopen, and of course you can always trace php using the fsockopen function to get an under-the-hood look at what in the world fsockopen is doing. Personally, I was trying to find more error codes and error strings to display when an fsockopen call failed, and I ended up finding over 50..

Tracing fsockopen using Strace

Once you save the above file on your site, you can use the strace tool to debug it. This is a tad overboard but way cool nevertheless!

strace -e trace=connect php -nef fsockopen-test.php

connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("66.33.216.129")}, 28) = 0 connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.87.106.226")}, 16) = -1 EINPROGRESS (Operation now in progress)

strace -e trace=network php -nef fsockopen-test.php

socket(PF_FILE, SOCK_STREAM, 0)         = 3 connect(3, {sa_family=AF_FILE, path="/var/run/.nscd_socket"}, 110) = -1 ENOENT (No such file or directory) socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("66.33.216.129")}, 28) = 0 send(3, "274221115httpd6apache3org1"..., 34, 0) = 34 recvfrom(3, "274221201200115httpd6apache3org"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("66.33.216.129")}, [16]) = 50 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = -1 EAFNOSUPPORT (Address family not supported by protocol) socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("192.87.106.226")}, 16) = -1 EINPROGRESS (Operation now in progress) getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 send(3, "GET / HTTP/1.1rnHost: httpd.apac"..., 356, MSG_DONTWAIT) = 356 recv(3, "HTTP/1.1 200 OKrnDate: Wed, 02 J"..., 8192, MSG_DONTWAIT) = 2609 recv(3, "", 8192, MSG_DONTWAIT)         = 0

strace -q -e trace=all php -nef fsockopen-test.php

mmap2(NULL, 266240, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb76ba000 munmap(0xb76ba000, 266240)              = 0 socket(PF_FILE, SOCK_STREAM, 0)         = 3 connect(3, {sa_family=AF_FILE, path="/var/run/.nscd_socket"}, 110) = -1 ENOENT (No such file or directory) close(3)                                = 0 open("/etc/hosts", O_RDONLY)            = 3 fcntl64(3, F_GETFD)                     = 0 fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=948, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f6e000 read(3, "# /etc/hosts - dh2 generatedn127"..., 4096) = 948 read(3, "", 4096)                       = 0 close(3)                                = 0 munmap(0xb7f6e000, 4096)                = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("66.33.216.129")}, 28) = 0 send(3, "X~112entwikipedia3org1"..., 34, 0) = 34 gettimeofday({1214998196, 656179}, NULL) = 0 poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1 ioctl(3, FIONREAD, [100])               = 0 recvfrom(3, "X~201200132entwikipedia3org1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("66.33.216.129")}, [16]) = 100 close(3)                                = 0 time(NULL)                              = 1214998196 gettimeofday({1214998196, 656754}, NULL) = 0 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 fcntl64(3, F_GETFL)                     = 0×2 (flags O_RDWR) fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0 connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("208.80.152.2")}, 16) = -1 EINPROGRESS (Operation now in progress) poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 10000) = 1 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 fcntl64(3, F_SETFL, O_RDWR)             = 0 send(3, "GET /wiki/Main_Page HTTP/1.1rnHo"..., 370, MSG_DONTWAIT) = 370 poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 time(NULL)                              = 1214998196 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 30000) = 1 recv(3, "HTTP/1.0 200 OKrnDate: Wed, 02 J"..., 8192, MSG_DONTWAIT) = 2896 time(NULL)                              = 1214998196 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 30000) = 1 recv(3, "214!337i30733623w253wy21526EL227;227253261"..., 8192, MSG_DONTWAIT) = 5792 time(NULL)                              = 1214998196 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 30000) = 1 recv(3, "420127321417yI347257371373344332330227245"..., 8192, MSG_DONTWAIT) = 7487 time(NULL)                              = 1214998197 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 30000) = 1 recv(3, "", 8192, MSG_DONTWAIT)         = 0 close(3)                                = 0 write(1, "n
GET /wiki/Main_Page HTTP/1"..., 1300


More Fsockopen Info TCP Multiplexing

RFC 793: To allow for many processes within a single Host to use TCP communication facilities simultaneously, the TCP provides a set of addresses or ports within each host. Concatenated with the network and host addresses from the internet communication layer, this forms a socket. A pair of sockets uniquely identifies each connection. That is, a socket may be simultaneously used in multiple connections.

The binding of ports to processes is handled independently by each Host. However, it proves useful to attach frequently used processes (e.g., a “logger” or timesharing service) to fixed sockets which are made known to the public. These services can then be accessed through the known addresses. Establishing and learning the port addresses of other processes may involve more dynamic mechanisms.

TCP Connections

The reliability and flow control mechanisms described above require that TCPs initialize and maintain certain status information for each data stream. The combination of this information, including sockets, sequence numbers, and window sizes, is called a connection. Each connection is uniquely specified by a pair of sockets identifying its two sides.

When two processes wish to communicate, their TCP’s must first establish a connection (initialize the status information on each side). When their communication is complete, the connection is terminated or closed to free the resources for other uses.

Since connections must be established between unreliable hosts and over the unreliable internet communication system, a handshake mechanism with clock-based sequence numbers is used to avoid erroneous initialization of connections.

Fsockopen Practical Uses Transfer-Encoding

RFC 2068

19.4.6 Introduction of Transfer-Encoding      HTTP/1.1 introduces the Transfer-Encoding header field (section    14.40).  Proxies/gateways MUST remove any transfer coding prior to    forwarding a message via a MIME-compliant protocol.      A process for decoding the "chunked" transfer coding (section 3.6)    can be represented in pseudo-code as:             length := 0           read chunk-size, chunk-ext (if any) and CRLF           while (chunk-size > 0) {              read chunk-data and CRLF              append chunk-data to entity-body              length := length + chunk-size              read chunk-size and CRLF           }           read entity-header           while (entity-header not empty) {              append entity-header to existing header fields              read entity-header           }           Content-Length := length           Remove "chunked" from Transfer-Encoding Socket-Related Man Pages DESCRIPTION This  manual  page  describes the Linux networking socket layer user interface. The BSD compatible sockets are the uniform interface between the user process and the network protocol stacks in the kernel.  The protocol modules are  grouped  into  protocol  families  like  PF_INET, PF_IPX, PF_PACKET and socket types like SOCK_STREAM or SOCK_DGRAM.  See socket(2) for more information on families and types.   SOCKET LAYER FUNCTIONS These  functions  are  used by the user process to send or receive packets and to do other socket operations. For more information see their respective manual pages.   socket(2) creates a socket, connect(2) connects a socket to a remote socket address, the bind(2) function binds a socket to a  local  socket address,  listen(2)  tells  the socket that new connections shall be accepted, and accept(2) is used to get a new socket with a new incoming connection.  socketpair(2) returns two connected anonymous sockets (only implemented for a few local families like PF_UNIX)   send(2), sendto(2), and sendmsg(2) send data over a socket, and recv(2), recvfrom(2), recvmsg(2) receive data from a  socket.   poll(2)  and select(2)  wait  for  arriving  data  or a readiness to send data.  In addition, the standard I/O operations like write(2), writev(2), send- file(2), read(2), and readv(2) can be used to read and write data.   getsockname(2) returns the local socket address and getpeername(2) returns the remote socket address.  getsockopt(2) and  setsockopt(2)  are used to set or get socket layer or protocol options.  ioctl(2) can be used to set or read some other options.   close(2) is used to close a socket.  shutdown(2) closes parts of a full duplex socket connection.   Seeking, or calling pread(2) or pwrite(2) with a non-zero position is not supported on sockets.   It  is possible to do non-blocking IO on sockets by setting the O_NONBLOCK flag on a socket file descriptor using fcntl(2).  Then all opera- tions that would block will (usually) return with EAGAIN (operation should be retried later); connect(2) will return EINPROGRESS error.  The user can then wait for various events via poll(2) or select(2).

From the FreeBSD man page for socket(2)

Sockets of type SOCK_STREAM are full-duplex byte streams, similar to pipes.  A stream socket must be in a connected state before any data may be sent or received on it.  A connection to another socket is created with a connect(2) system call.  Once connected, data may be transferred using read(2) and write(2) calls or some variant of the send(2) and recv(2) functions.  (Some protocol families, such as the Internet family, support the notion of an ``implied connect'', which permits data to be sent piggybacked onto a connect operation by using the sendto(2) system call.)  When a session has been completed a close(2) may be performed. Out-of-band data may also be transmitted as described in send(2) and received as described in recv(2).   The communications protocols used to implement a SOCK_STREAM insure that data is not lost or duplicated.  If a piece of data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length of time, then the connection is considered broken and calls will indicate an error with -1 returns and with ETIMEDOUT as the specific code in the global variable errno.  The protocols optionally keep sockets ``warm'' by forcing transmissions roughly every minute in the absence of other activity.  An error is then indicated if no response can be elicited on an otherwise idle connection for an extended period (e.g. 5 minutes).  A SIGPIPE signal is raised if a process sends on a broken stream; this causes naive processes, which do not handle the sig- nal, to exit. Random Posts

Feeds and posts are not affliated with ://URLFAN. They are displayed here simply for informational purposes, if you would like to remove your feed, posts, or domain from ranking and analysis, please contact us.

://URLFAN (.15)
Contact Us - About ://URLFAN - Notify me when my site is added or updated.