I have client and server in php communicating over shared memory, Now I would like to access this shred memory object using Boost.Interprocess how can I access it?
server.php:
function create_image($str){
// Create a blank image and add some text
$im = imagecreatetruecolor(300, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
$stringBanner=exec("date").$str;
imagestring($im, 1, 5, 5, $stringBanner , $text_color);
ob_start();
imagejpeg($im);
$i = ob_get_contents();
ob_get_clean();
imagedestroy($im);
return $i;
}
echo "\n".__FILE__."\n";
$shm_key = ftok(__FILE__, 't');
echo $shm_key."\n";
$shm_id = shmop_open($shm_key, "a", 0, 0);
if ($shm_id) {
//it is already created
shmop_delete($shm_id);
shmop_close($shm_id);
}
//you need to create it with shmop_open using "c" only
echo "try to create\n";
if(!$shm_id = shmop_open($shm_key, "c", 0777, 1024*4))exit(-1);
echo "ID ".$shm_id."\n";
$i=0;
for(;;){
sleep(1);
$s="i=".$i++;
$str=$i;
$im=serialize(create_image($str));
$data=serialize(strlen($im));
$shm_bytes_written = shmop_write($shm_id, $data, 0);
$shm_bytes_written = shmop_write($shm_id, $im, 32);
echo $shm_bytes_written." bytes is written: ".$s." ID = $shm_id\n";
}
client.php
<?php
$shm_key =1946222626;// ftok(__FILE__, 't');
$shm_id = shmop_open(
$shm_key, "a",
0644,1024*4
);
$s=shmop_size($shm_id);
$data = unserialize(
shmop_read( $shm_id, 0,
31)
);
$im = unserialize(
shmop_read( $shm_id, 32,
$data)
);
// Set the content type header - in this case image/jpeg
header('Content-Type: image/jpeg');
// Output the image
echo $im;
What kind of key I should provide to Boost to get this memory region?
boost_client.cpp
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
#include "sys/msg.h"
int main()
{
int msqid;
key_t key;
char f[]="??????";
int mid;
//key = ftok(, 't');
//msqid = msgget(key, 0666 | IPC_CREAT);
std::cout<<msqid<<std::endl;
boost::interprocess::shared_memory_object
shdmem(boost::interprocess::open_or_create,
f,//"shmem_server",
boost::interprocess::read_write);
shdmem.truncate(1024);
std::cout << shdmem.get_name() << std::endl;
boost::interprocess::offset_t size;
if (shdmem.get_size(size))
std::cout << size << std::endl;
}
EDIT:
Well I found the solution in Boost IPC library Docs:
XSI_KEY based example from boost Docs
I'm not an expert in what you're doing, but from what I read in your question and my knowledge, I would drop that pure IPC thing and wrap it into ZMQ (you'll find wrapper in every language you need). It's meant to solve those kind of problems and provide a single API that could run over IPC or more common TCP socket.
Related
Given the following inputs:
CLIENT RANDOM : 61fc160e0a6e96db43aebcca55da7fbccb97cc04d59fcc105490b4396a915ab9
SERVER RANDOM : f0ecb127db6e353a2985894c123532a8d092fafcf7cdce3a444f574e47524401
PREMASTER KEY : 0303ec4418e91f0abf9a012f524b61c0312008641ebce76d68b2417447e3d9a970d02fd65a20e5e3e98413dbd13b6536
First I use these input to calculate the following key buffers:
CLIENT MAC: 500c7c6e6101cb1693b4cee7db6fb0bc2725deca
SERVER MAC: 41e260280fe213bd5f2c0412c69389cac2e39e4f
CLIENT KEY: c17226212f6195c1515602a0c0864ec90e73e7bcd05ad90b196fd5a5cb2445f2
SERVER KEY: 6b07166b634a7e58e623b969eb0c024a1e866bc2719c054e1a05849b87ccf79b
CLIENT IV: dac71f7b3639cf4d4ec86ee51b9530f6
SERVER IV: c1212631365432c8d5a4c93f6f999a8e
I calculate these values using helper functions I found online:
function p_hash($algo, $secret, $seed, $size) {
$output = "";
$a = $seed;
while (strlen($output) < $size) {
$a = hash_hmac($algo, $a, $secret, true);
$output .= hash_hmac($algo, $a . $seed, $secret, true);
}
return substr($output, 0, $size);
}
function prf_tls12($secret, $label, $seed, $size) {
return p_hash("sha256", $secret, $label . $seed, $size);
}
function generate_master($pre_master_secret, $client_random, $server_random) {
return prf_tls12($pre_master_secret, 'master secret', $client_random . $server_random, 48);
}
$client_random = hex2bin('61fc160e0a6e96db43aebcca55da7fbccb97cc04d59fcc105490b4396a915ab9');
$server_random = hex2bin('f0ecb127db6e353a2985894c123532a8d092fafcf7cdce3a444f574e47524401');
$pre_master_secret = hex2bin('0303ec4418e91f0abf9a012f524b61c0312008641ebce76d68b2417447e3d9a970d02fd65a20e5e3e98413dbd13b6536');
$master_secret = generate_master($pre_master_secret, $client_random, $server_random);
$key_buffer = prf_tls12($master_secret, 'key expansion', $server_random . $client_random, 136);
$client_mac = substr($key_buffer, 0, 20);
$server_mac = substr($key_buffer, 20, 20);
$client_key = substr($key_buffer, 40, 32);
$server_key = substr($key_buffer, 72, 32);
$client_iv = substr($key_buffer, 104, 16);
$server_iv = substr($key_buffer, 120, 16);
Here I have an AES_256_CBC encrypted message sent from the CLIENT ---> SERVER in Hex format
$EncryptedMessage = 'f32da333a3416888d55c583c9796f8fc498895e386616a62aa364a41cd2bfc203c1f296b4afd9c4a9674c993bf0db558de0c0cb2b3dc4b083af3824e0b9a3327';
I run the following code using the PHPSECLIB v3.0 plugin:
$cipher = new AES('cbc');
$cipher->setIV($client_iv);
$cipher->setKey($client_key);
$cipher->disablePadding();
$DecryptedMessage = bin2hex($cipher->decrypt(hex2bin($EncryptedMessage)));
print($DecryptedMessage);
I get the following output in Hex:
f889ff0ce7cc744c2182363e7117ae74e34ccb0510099e7c11133c369f98468de9f20fa6e7207c8121484a9663929d1af4bffb5410da37029aa26b9298411e3b
Basically, I have no idea whether I'm doing this right or not. I dont seem to see anything in my decrypted message. Also, unless I specifically use the $cipher->disablePadding(); I will get a PHP Fatal Error saying that PHP Fatal error: Uncaught phpseclib3\Exception\BadDecryptionException: The ciphertext has an invalid padding length (81) compared to the block size (16)
Note: This is supposed to be an "Encrypted Handshake Message" sent as the first message from a client to server after the Key Exchange using TLS 1.2. I am unable to determine if my decryption is correct, since I cant find much on the structure of value anywhere. Any help is appreciated, thanks!
I have written a code to upload text file on server using c++ wininet.h api..
The code runs fine but the file is not recieved on server side...
Can you guys please have a look why my code is not working.....
I have written a code on client side and on server side there is a php file in which i have checked $_FILES variable and written the code...
My client code
#include <windows.h>
#include <wininet.h>
#include <iostream>
#include<stdio.h>
#define ERROR_OPEN_FILE 10
#define ERROR_MEMORY 11
#define ERROR_SIZE 12
#define ERROR_INTERNET_OPEN 13
#define ERROR_INTERNET_CONN 14
#define ERROR_INTERNET_REQ 15
#define ERROR_INTERNET_SEND 16
using namespace std;
int main()
{
// Local variables
static char *filename = "C:\\test.txt"; //Filename to be loaded
static char *type = "image/jpg";
static char boundary[] = "pippo"; //Header boundary
static char nameForm[] = "uploadedfile"; //Input form name
static char iaddr[] = "localhost"; //IP address
static char url[] = "C:\\xampp\\htdocs\\test.php"; //URL
char hdrs[255]; //Headers
char * buffer; //Buffer containing file + headers
char * content; //Buffer containing file
FILE * pFile; //File pointer
long lSize; //File size
size_t result;
// Open file
pFile = fopen ( filename , "rb" );
if (pFile==NULL) return ERROR_OPEN_FILE;
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
content = (char*) malloc (sizeof(char)*lSize);
if (content == NULL) return ERROR_MEMORY;
// copy the file into the buffer:
result = fread (content,1,lSize,pFile);
if (result != lSize) return ERROR_SIZE;
// terminate
fclose (pFile);
//allocate memory to contain the whole file + HEADER
buffer = (char*) malloc (sizeof(char)*lSize + 2048);
//print header
sprintf(hdrs,"Content-Type: multipart/form-data; boundary=%s",boundary);
sprintf(buffer,"--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",boundary,nameForm,filename);
sprintf(buffer,"%sContent-Type: %s\r\n\r\n",buffer,type);
sprintf(buffer,"%s%s\r\n",buffer,content);
sprintf(buffer,"%s--%s--\r\n",buffer,boundary);
//Open internet connection
HINTERNET hSession = InternetOpen("WinSock",INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if(hSession==NULL) return ERROR_INTERNET_OPEN;
HINTERNET hConnect = InternetConnect(hSession, iaddr,INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
if(hConnect==NULL) return ERROR_INTERNET_CONN;
HINTERNET hRequest = HttpOpenRequest(hConnect, (const char*)"POST",url, NULL, NULL, (const char**)"*/*\0", 0, 1);
if(hRequest==NULL) return ERROR_INTERNET_REQ;
BOOL sent= HttpSendRequest(hRequest, hdrs, strlen(hdrs), buffer, strlen(buffer));
if(!sent) return ERROR_INTERNET_SEND;
//close any valid internet-handles
InternetCloseHandle(hSession);
InternetCloseHandle(hConnect);
InternetCloseHandle(hRequest);
return 0;
}
My PHP code
<?php
$uploadfile = C:\xampp\htdocs\;
echo "<p>";
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $uploadfile)) {
echo "File is valid, and was successfully uploaded.\n";
} else {
echo "Upload failed";
}
echo "</p>";
echo '<pre>';
echo 'Here is some more debugging info: ';
print_r($_FILES);
print "</pre>";
?>
I am running this code on Code Blocks...
Actual: Code runs fine but the file is not recieved at server localhost...
EXPECTED: File to be recieved on server end localhost....
Please help this is my college project.
Reference = Upload file via POST
On a very busy PHP server, I am trying to get a global counter going and thought shared memory would be the way to go. Ideally I would use APC
apc_add('counter',1);
apc_inc('counter',1);
var_dump(apc_fetch('counter'));
except that it is not available on the servers and I am restricted to what is available. The servers do have shmop so tried to get that to work, however it seems to be session specific. Is there anything else that could be used?
The shmop code I tried:
$shm_key = ftok(__FILE__, 't');
$shm_id = shmop_open($shm_key, "c", 0644, 8);
$shm_data = shmop_read($shm_id, 0, 8);
$shm_data = shmop_read($shm_id, 0, 8);
var_dump($shm_data);
if (empty($shm_data)) {
//counter has not been set
$shm_bytes_written = shmop_write($shm_id, 0, 1);
} else {
$shm_bytes_written = shmop_write($shm_id, (int)$shm_data + 1, 0);
}
$shm_data = shmop_read($shm_id, 0, 8);
var_dump($shm_data);
So Chrome 14 has implemented hybi10 version of websockets. I have a in house program that our company uses via chrome that uses websockets which is broken with this change.
Has anyone been successful framing the data using a php server? I am able to get the new handshake to work but I can't seem to figure out the framing. There is a python example here https://github.com/kanaka/websockify/blob/master/websocket.py#L233 but I am having a difficult time converting this to php, anyone have a suggestion?
I should mention that the function in question on the python example is decode_hybi().
i just completed a class wich makes the PHP-Websocket-Server of Nico Kaiser (https://github.com/nicokaiser/php-websocket) capable of handling hybi-10 frames and handshake. You can download the new class here: http://lemmingzshadow.net/386/php-websocket-serverclient-nach-draft-hybi-10/ (Connection.php)
This code assumes no errors or malformed frames and is based on this answer - How to (de)construct data frames in WebSockets hybi 08+?.
This code is very basic and is far from a complete solution. It works for my purposes (which are pretty basic). Hopefully it is of use to others.
function handle_data($data){
$bytes = $data;
$data_length = "";
$mask = "";
$coded_data = "" ;
$decoded_data = "";
$data_length = $bytes[1] & 127;
if($data_length === 126){
$mask = substr($bytes, 4, 8);
$coded_data = substr($bytes, 8);
}else if($data_length === 127){
$mask = substr($bytes, 10, 14);
$coded_data = substr($bytes, 14);
}else{
$mask = substr($bytes, 2, 6);
$coded_data = substr($bytes, 6);
}
for($i=0;$i<strlen($coded_data);$i++){
$decoded_data .= $coded_data[$i] ^ $mask[$i%4];
}
$this->log("Server Received->".$decoded_data);
return true;
}
Here is the code to send data back. Again this is pretty basic, it assumes you are sending a single text frame. No continuation frames etc. No error checking either. Hopefully others find it useful.
public function send($data)
{
$frame = Array();
$encoded = "";
$frame[0] = 0x81;
$data_length = strlen($data);
if($data_length <= 125){
$frame[1] = $data_length;
}else{
$frame[1] = 126;
$frame[2] = $data_length >> 8;
$frame[3] = $data_length & 0xFF;
}
for($i=0;$i<sizeof($frame);$i++){
$encoded .= chr($frame[$i]);
}
$encoded .= $data;
write_to_socket($this->socket, $encoded);
return true;
}
I got a problem implementing a PHP programm in C++. It is about the PHP/Perl function unpack. I don't know how to do the follwing in C++ (no problem in reading a file... but how do i unpack("C*") the read contents).
<?php
$file = fopen("bitmaskt.dat", "rb");
//create the data stream
$matrix_x = unpack("C*", fread($file, 286));
$matrix_y = unpack("C*", fread($file, 286));
$mask_data = unpack("C*", fread($file, 286));
$reed_ecc_codewords = ord(fread($file, 1));
$reed_blockorder = unpack("C*", fread($file, 128));
fclose($file);
?>
Currently, I'm very hopeless solving this problem on my own - I'm searching for days, all I found are questions... Is there any free unpack() c++ implementation out there? :-(
Perl's documentation for pack covers the templates used for pack and unpack.
Say you generated bitmaskt.dat with
#! /usr/bin/perl
use warnings;
use strict;
open my $fh, ">", "bitmaskt.dat" or die "$0: open: $!";
my #data = (42) x 286;
print $fh pack("C*" => #data);
print $fh pack("C*" => #data);
print $fh pack("C*" => #data);
print $fh pack("C" => 7);
print $fh pack("C*" => (1) x 128);
close $fh or warn "$0: close";
You might read it with
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
typedef unsigned char datum_t;
typedef std::vector<datum_t> buf_t;
std::istream &read_data(std::istream &in, buf_t &buf, size_t n)
{
std::istreambuf_iterator<char> it(in.rdbuf()), eos;
while (it != eos && n-- != 0)
buf.push_back(static_cast<datum_t>(*it++));
return in;
}
For example:
int main()
{
std::ifstream bm("bitmaskt.dat", std::ifstream::binary | std::ifstream::in);
struct {
buf_t buf;
size_t len;
std::string name;
} sections[] = {
{ buf_t(), 286, "matrix_x" },
{ buf_t(), 286, "matrix_y" },
{ buf_t(), 286, "mask_data" },
{ buf_t(), 1, "reed_ecc_codewords" },
{ buf_t(), 128, "reed_blockorder" },
};
const int n = sizeof(sections) / sizeof(sections[0]);
for (int i = 0; n - i > 0; i++) {
if (!read_data(bm, sections[i].buf, sections[i].len)) {
std::cerr << "Read " << sections[i].name << " failed" << std::endl;
return 1;
}
}
const int codeword = 3;
std::cout << (unsigned int) sections[codeword].buf[0] << '\n';
return 0;
}
Output:
7
I don't know about any general implementation of unpack for C++, but that doesn't seem to be the thing you need anyway.
if matrix_x is defined somewhere as unsigned char matrix_x[286] and you have an opened input stream inFile
then what you need to do is inFile.get(matrix_x, 286). This reads 286 bytes from the input and places them in the array pointed to by matrix_x.