Fsockopen Magic
PHP'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 Windows think Recycle Bin, and likewise you can send anything to a socket created with fsockopen. Just like # cat file > /dev/null
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.
Why use fsockopen?
SPEED! Fsockopen is the lowest php helper function to create and use a socket. Once you have a socket opened you can read/write data over that socket using binary-safe php functions like fwrite and fread very quickly.
For example, the PHP function gethostbyaddr gets the reverse DNS associated with an IP address, and gethostbyname does the reverse getting the IP address associated with a DNS record/website. But like most PHP helper networking functions they are designed to be robust. This means they tie into your OS internals to check your resolver settings, have long timeouts to make sure they don't miss a slow host, and are really quite bloated in order to be so robust and work for every situation. By using fsockopen as I show here: PHP fsockopen for FAST DNS lookups over UDP, it's literally just opening a single socket to the DNS server over UDP, sending the request, and shows the response. The speed boost goes from upwards of 50 seconds the normal way, to a max of just 5 seconds in that example. When doing many many lookups or async lookups (such as looking up the reverse ips for thousands of addresses), the speed boost is 30-1000x faster using straight fsockopen.
HTTP and fsockopen
The Snoopy class is bundled with WordPress distributions and uses fsockopen to achieve most of its cool features, it's not used as much by WP now since WP has a newer and much better/complicated replacement, but it's an excellent small but of code that illustrates fsockopen use. Many WordPress core, plugins, and other included files and classes also use the fsockopen function to communicate via Sockets.
Fsockopen Examples
Note 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.
// max time for script execution !defined('AA_MAX_TIME') && define('AA_MAX_TIME', 60); // max time for socket reads !defined('AA_RECV_TIME') && define('AA_RECV_TIME', 30); // max time for socket connect !defined('AA_CONN_TIME') && define('AA_CONN_TIME', 5); // linebreak !defined('AA_LF') && define('AA_LF', chr(13).chr(10)); // ignore TCP RST i.e. browser stop button @ignore_user_abort(1); // set the script execution time @set_time_limit(AA_MAX_TIME); // set the default socket timeout value @ini_set("default_socket_timeout",AA_RECV_TIME); // output implicitly @ob_implicit_flush(1); // for binary freads @set_magic_quotes_runtime(0); // keep track of script execution time $aa_time=time(); // download each of these urls using fsockopen aa_dl('http://httpd.apache.org'); aa_dl('http://www.w3.org'); aa_dl('http://www.google.com'); aa_dl('http://www.freebsd.org/cgi/man.cgi?query=connect&sektion=2&apropos=0&manpath=FreeBSD+7.0-RELEASE'); aa_dl('https://www.askapache.com/htaccess/'); aa_dl('http://www.php.net'); aa_dl('http://en.wikipedia.org/wiki/Main_Page'); /* returns a socket pointer if valid or displays an error message sets stream timeout, starts the clock to check for socket read time */ function askapache_get_sock($target,$port){ global $aa_time_start; $aa_time_start=time(); if(false===($fp = @fsockopen($target,$port,$errno,$errstr,AA_CONN_TIME))||!is_resource($fp)) return askapache_sock_strerror($errno,$errstr); @stream_set_timeout($fp, AA_RECV_TIME); return $fp; } /* writes request, then reads response until EOF, script max, or socket max returns response on success. Uses buffer to allow size>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/; +https://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: https://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 104: $err="Connection reset by client"; break; case 110: $err="Connection timed out"; break; case 111: $err="Connection refused"; break; case 113: $err="No route to host"; 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..
fsockopen Errors
function fsockopen_err($errnum) { static $fsockopen_errors; if ( is_null($fsockopen_errors) ) { $fsockopen_errors = array( 0 => 'Success', 1 => 'Operation not permitted', 2 => 'No such file or directory', 3 => 'No such process', 4 => 'Interrupted system call - DNS lookup failure', 5 => 'Input/output error - Connection refused or timed out', 6 => 'No such device or address', 7 => 'Argument list too long', 8 => 'Exec format error', 9 => 'Bad file descriptor', 10 => 'No child processes', 11 => 'Resource temporarily unavailable', 12 => 'Cannot allocate memory', 13 => 'Permission denied', 14 => 'Bad address', 15 => 'Block device required', 16 => 'Device or resource busy', 17 => 'File exists', 18 => 'Invalid cross-device link', 19 => 'No such device', 20 => 'Not a directory', 21 => 'Is a directory', 22 => 'Invalid argument', 23 => 'Too many open files in system', 24 => 'Too many open files', 25 => 'Inappropriate ioctl for device', 26 => 'Text file busy', 27 => 'File too large', 28 => 'No space left on device', 29 => 'Illegal seek', 30 => 'Read-only file system', 31 => 'Too many links', 32 => 'Broken pipe', 33 => 'Numerical argument out of domain', 34 => 'Numerical result out of range', 35 => 'Resource deadlock avoided', 36 => 'File name too long', 37 => 'No locks available', 38 => 'Function not implemented', 39 => 'Directory not empty', 40 => 'Too many levels of symbolic links', 41 => 'Unknown error 41', 42 => 'No message of desired type', 43 => 'Identifier removed', 44 => 'Channel number out of range', 45 => 'Level 2 not synchronized', 46 => 'Level 3 halted', 47 => 'Level 3 reset', 48 => 'Link number out of range', 49 => 'Protocol driver not attached', 50 => 'No CSI structure available', 51 => 'Level 2 halted', 52 => 'Invalid exchange', 53 => 'Invalid request descriptor', 54 => 'Exchange full', 55 => 'No anode', 56 => 'Invalid request code', 57 => 'Invalid slot', 58 => 'Unknown error 58', 59 => 'Bad font file format', 60 => 'Device not a stream', 61 => 'No data available', 62 => 'Timer expired', 63 => 'Out of streams resources', 64 => 'Machine is not on the network', 65 => 'Package not installed', 66 => 'Object is remote', 67 => 'Link has been severed', 68 => 'Advertise error', 69 => 'Srmount error', 70 => 'Communication error on send', 71 => 'Protocol error', 72 => 'Multihop attempted', 73 => 'RFS specific error', 74 => 'Bad message', 75 => 'Value too large for defined data type', 76 => 'Name not unique on network', 77 => 'File descriptor in bad state', 78 => 'Remote address changed', 79 => 'Can not access a needed shared library', 80 => 'Accessing a corrupted shared library', 81 => '.lib section in a.out corrupted', 82 => 'Attempting to link in too many shared libraries', 83 => 'Cannot exec a shared library directly', 84 => 'Invalid or incomplete multibyte or wide character', 85 => 'Interrupted system call should be restarted', 86 => 'Streams pipe error', 87 => 'Too many users', 88 => 'Socket operation on non-socket', 89 => 'Destination address required', 90 => 'Message too long', 91 => 'Protocol wrong type for socket', 92 => 'Protocol not available', 93 => 'Protocol not supported', 94 => 'Socket type not supported', 95 => 'Operation not supported', 96 => 'Protocol family not supported', 97 => 'Address family not supported by protocol', 98 => 'Address already in use', 99 => 'Cannot assign requested address', 100 => 'Network is down', 101 => 'Network is unreachable', 102 => 'Network dropped connection on reset', 103 => 'Software caused connection abort', 104 => 'Connection reset by peer', 105 => 'No buffer space available', 106 => 'Transport endpoint is already connected', 107 => 'Transport endpoint is not connected', 108 => 'Cannot send after transport endpoint shutdown', 109 => 'Too many references: cannot splice', 110 => 'Connection timed out', 111 => 'Connection refused', 112 => 'Host is down', 113 => 'No route to host', 114 => 'Operation already in progress', 115 => 'Operation now in progress', 116 => 'Stale NFS file handle', 117 => 'Structure needs cleaning', 118 => 'Not a XENIX named type file', 119 => 'No XENIX semaphores available', 120 => 'Is a named type file', 121 => 'Remote I/O error', 122 => 'Disk quota exceeded', 123 => 'No medium found', 124 => 'Wrong medium type', 125 => 'Operation canceled', 126 => 'Required key not available', 127 => 'Key has expired', 128 => 'Key has been revoked', 129 => 'Key was rejected by service', 130 => 'Owner died', 131 => 'State not recoverable', 132 => 'Operation not possible due to RF-kill', 133 => 'Memory page has hardware error' ); } return ( isset( $fsockopen_errors[ $errnum ] ) ) ? $fsockopen_errors[ $errnum ] : $errnum; }
If you would like to see all the errors on your particular machine:
for ( $i=-50, $s=""; ( $i<250 && !!$s=socket_strerror($i) ); $i++ ) { !!! strpos( $s, 'nknown error' ) && print "$i => $s\n"; }
Which outputs:
0 => Success 1 => Operation not permitted 2 => No such file or directory 3 => No such process 4 => Interrupted system call 5 => Input/output error 6 => No such device or address 7 => Argument list too long 8 => Exec format error 9 => Bad file descriptor 10 => No child processes 11 => Resource temporarily unavailable 12 => Cannot allocate memory 13 => Permission denied 14 => Bad address 15 => Block device required 16 => Device or resource busy 17 => File exists 18 => Invalid cross-device link 19 => No such device 20 => Not a directory 21 => Is a directory 22 => Invalid argument 23 => Too many open files in system 24 => Too many open files 25 => Inappropriate ioctl for device 26 => Text file busy 27 => File too large 28 => No space left on device 29 => Illegal seek 30 => Read-only file system 31 => Too many links 32 => Broken pipe 33 => Numerical argument out of domain 34 => Numerical result out of range 35 => Resource deadlock avoided 36 => File name too long 37 => No locks available 38 => Function not implemented 39 => Directory not empty 40 => Too many levels of symbolic links 42 => No message of desired type 43 => Identifier removed 44 => Channel number out of range 45 => Level 2 not synchronized 46 => Level 3 halted 47 => Level 3 reset 48 => Link number out of range 49 => Protocol driver not attached 50 => No CSI structure available 51 => Level 2 halted 52 => Invalid exchange 53 => Invalid request descriptor 54 => Exchange full 55 => No anode 56 => Invalid request code 57 => Invalid slot 59 => Bad font file format 60 => Device not a stream 61 => No data available 62 => Timer expired 63 => Out of streams resources 64 => Machine is not on the network 65 => Package not installed 66 => Object is remote 67 => Link has been severed 68 => Advertise error 69 => Srmount error 70 => Communication error on send 71 => Protocol error 72 => Multihop attempted 73 => RFS specific error 74 => Bad message 75 => Value too large for defined data type 76 => Name not unique on network 77 => File descriptor in bad state 78 => Remote address changed 79 => Can not access a needed shared library 80 => Accessing a corrupted shared library 81 => .lib section in a.out corrupted 82 => Attempting to link in too many shared libraries 83 => Cannot exec a shared library directly 84 => Invalid or incomplete multibyte or wide character 85 => Interrupted system call should be restarted 86 => Streams pipe error 87 => Too many users 88 => Socket operation on non-socket 89 => Destination address required 90 => Message too long 91 => Protocol wrong type for socket 92 => Protocol not available 93 => Protocol not supported 94 => Socket type not supported 95 => Operation not supported 96 => Protocol family not supported 97 => Address family not supported by protocol 98 => Address already in use 99 => Cannot assign requested address 100 => Network is down 101 => Network is unreachable 102 => Network dropped connection on reset 103 => Software caused connection abort 104 => Connection reset by peer 105 => No buffer space available 106 => Transport endpoint is already connected 107 => Transport endpoint is not connected 108 => Cannot send after transport endpoint shutdown 109 => Too many references: cannot splice 110 => Connection timed out 111 => Connection refused 112 => Host is down 113 => No route to host 114 => Operation already in progress 115 => Operation now in progress 116 => Stale file handle 117 => Structure needs cleaning 118 => Not a XENIX named type file 119 => No XENIX semaphores available 120 => Is a named type file 121 => Remote I/O error 122 => Disk quota exceeded 123 => No medium found 124 => Wrong medium type 125 => Operation canceled 126 => Required key not available 127 => Key has expired 128 => Key has been revoked 129 => Key was rejected by service 130 => Owner died 131 => State not recoverable 132 => Operation not possible due to RF-kill 133 => Memory page has hardware error
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, "2742211??1??????5httpd6apache3org??1"..., 34, 0) = 34 recvfrom(3, "274221201200?1?1????5httpd6apache3org?"..., 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~1??1??????2entwikipedia3org??1"..., 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~201200?1?3????2entwikipedia3org??1"..., 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) = 0x2 (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, "nGET /wiki/Main_Page HTTP/1"..., 1300More Fsockopen Info
Fsockopen Related Links
- fsockopen tag page
- fsockopen search page
- PHP fsockopen for FAST DNS lookups over UDP
- Hypertext Transfer Protocol — HTTP/1.1, RFC 2616. R. Fielding et al.
- Hypertext ransport Protocol HTTP/1.1. J. Gettys. (slides)
- What's wrong with HTTP (and why it doesn't matter).J. C. Mogul. (PDF slides)
- Network Performance Effects of HTTP/1.1, CSS1, and PNG.H. F. Nielsen, J. Gettys et al.
- Mozilla's HTTP/1.1 Pipelining FAQ. D. Fisher.
- Wikipedia: HTTP proxy.
Fsockopen Practical Uses
- Download Web Pages, Files, etc.
- Upload a file
- Send POST data to a form
- Emulate cron
- Download plugin updates
- Scan sites for exploits
- Pass wp-nonces via cookie headers, and more
Socket Constants
define ('SOCKET_EPERM', 1); define ('SOCKET_ENOENT', 2); define ('SOCKET_EINTR', 4); define ('SOCKET_EIO', 5); define ('SOCKET_ENXIO', 6); define ('SOCKET_E2BIG', 7); define ('SOCKET_EBADF', 9); define ('SOCKET_EAGAIN', 11); define ('SOCKET_ENOMEM', 12); define ('SOCKET_EACCES', 13); define ('SOCKET_EFAULT', 14); define ('SOCKET_ENOTBLK', 15); define ('SOCKET_EBUSY', 16); define ('SOCKET_EEXIST', 17); define ('SOCKET_EXDEV', 18); define ('SOCKET_ENODEV', 19); define ('SOCKET_ENOTDIR', 20); define ('SOCKET_EISDIR', 21); define ('SOCKET_EINVAL', 22); define ('SOCKET_ENFILE', 23); define ('SOCKET_EMFILE', 24); define ('SOCKET_ENOTTY', 25); define ('SOCKET_ENOSPC', 28); define ('SOCKET_ESPIPE', 29); define ('SOCKET_EROFS', 30); define ('SOCKET_EMLINK', 31); define ('SOCKET_EPIPE', 32); define ('SOCKET_ENAMETOOLONG', 36); define ('SOCKET_ENOLCK', 37); define ('SOCKET_ENOSYS', 38); define ('SOCKET_ENOTEMPTY', 39); define ('SOCKET_ELOOP', 40); define ('SOCKET_EWOULDBLOCK', 11); define ('SOCKET_ENOMSG', 42); define ('SOCKET_EIDRM', 43); define ('SOCKET_ECHRNG', 44); define ('SOCKET_EL2NSYNC', 45); define ('SOCKET_EL3HLT', 46); define ('SOCKET_EL3RST', 47); define ('SOCKET_ELNRNG', 48); define ('SOCKET_EUNATCH', 49); define ('SOCKET_ENOCSI', 50); define ('SOCKET_EL2HLT', 51); define ('SOCKET_EBADE', 52); define ('SOCKET_EBADR', 53); define ('SOCKET_EXFULL', 54); define ('SOCKET_ENOANO', 55); define ('SOCKET_EBADRQC', 56); define ('SOCKET_EBADSLT', 57); define ('SOCKET_ENOSTR', 60); define ('SOCKET_ENODATA', 61); define ('SOCKET_ETIME', 62); define ('SOCKET_ENOSR', 63); define ('SOCKET_ENONET', 64); define ('SOCKET_EREMOTE', 66); define ('SOCKET_ENOLINK', 67); define ('SOCKET_EADV', 68); define ('SOCKET_ESRMNT', 69); define ('SOCKET_ECOMM', 70); define ('SOCKET_EPROTO', 71); define ('SOCKET_EMULTIHOP', 72); define ('SOCKET_EBADMSG', 74); define ('SOCKET_ENOTUNIQ', 76); define ('SOCKET_EBADFD', 77); define ('SOCKET_EREMCHG', 78); define ('SOCKET_ERESTART', 85); define ('SOCKET_ESTRPIPE', 86); define ('SOCKET_EUSERS', 87); define ('SOCKET_ENOTSOCK', 88); define ('SOCKET_EDESTADDRREQ', 89); define ('SOCKET_EMSGSIZE', 90); define ('SOCKET_EPROTOTYPE', 91); define ('SOCKET_ENOPROTOOPT', 92); define ('SOCKET_EPROTONOSUPPORT', 93); define ('SOCKET_ESOCKTNOSUPPORT', 94); define ('SOCKET_EOPNOTSUPP', 95); define ('SOCKET_EPFNOSUPPORT', 96); define ('SOCKET_EAFNOSUPPORT', 97); define ('SOCKET_EADDRINUSE', 98); define ('SOCKET_EADDRNOTAVAIL', 99); define ('SOCKET_ENETDOWN', 100); define ('SOCKET_ENETUNREACH', 101); define ('SOCKET_ENETRESET', 102); define ('SOCKET_ECONNABORTED', 103); define ('SOCKET_ECONNRESET', 104); define ('SOCKET_ENOBUFS', 105); define ('SOCKET_EISCONN', 106); define ('SOCKET_ENOTCONN', 107); define ('SOCKET_ESHUTDOWN', 108); define ('SOCKET_ETOOMANYREFS', 109); define ('SOCKET_ETIMEDOUT', 110); define ('SOCKET_ECONNREFUSED', 111); define ('SOCKET_EHOSTDOWN', 112); define ('SOCKET_EHOSTUNREACH', 113); define ('SOCKET_EALREADY', 114); define ('SOCKET_EINPROGRESS', 115); define ('SOCKET_EISNAM', 120); define ('SOCKET_EREMOTEIO', 121); define ('SOCKET_EDQUOT', 122); define ('SOCKET_ENOMEDIUM', 123); define ('SOCKET_EMEDIUMTYPE', 124);
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.
Transfer-Encoding
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.
Have Fun ;)
« Get Number of Running Proccesses with PHPBoosting Googles PageSpeed Module with TMPFS »
Comments