not sure why accept never receives connect

master
JoYo 2017-07-28 17:24:37 -04:00
parent 6fd526ec2b
commit 1dcd4278ff
4 changed files with 237 additions and 180 deletions

View File

@ -1,123 +0,0 @@
/*
@file generation.c
*/
#include <arpa/inet.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX_LEN 1024
#define PORT 5000
int reproduce(void *pic_address, int pic_size)
{
int status = 0;
printf("{\"address\":\"%p\",\"size\":\"%d\"}\n", pic_address, pic_size);
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
int sock = socket(AF_INET, SOCK_STREAM, 0);
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
status = send(sock, pic_address, pic_size, 0);
status = 1;
CLONE_CLEANUP:
if (sock)
{
close(sock);
}
return status;
}
int generation(void)
{
int status = 0;
char reply[MAX_LEN];
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
int sock = socket(AF_INET, SOCK_STREAM, 0);
printf("connecting\n");
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
status = recv(sock, reply, MAX_LEN, 0);
int child_len = (int)reply;
int prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
int flags = (MAP_ANON | MAP_PRIVATE);
void *pic_buffer = mmap(NULL, child_len, prot, flags, -1, 0);
if (MAP_FAILED == pic_buffer)
{
status = errno;
goto GEN_CLEANUP;
}
int iter = child_len;
while (1)
{
status = recv(sock, reply, MAX_LEN, 0);
if (!status)
{
break;
}
if ((status + iter) > child_len)
{
break;
}
memcpy(&pic_buffer[iter - child_len], reply, status);
iter -= status;
}
int (*reproduce_function)(void *, int) = reproduce;
void (*pic_function)(void *, int, void *) = pic_buffer;
pic_function(pic_buffer, child_len, reproduce_function);
status = 1;
GEN_CLEANUP:
if (sock)
{
close(sock);
}
return status;
}
int main(int argc, const char **argv)
{
pid_t process_id;
int status = 0;
process_id = fork();
if (0 == process_id)
{
status = generation();
if (status)
{
return 1;
}
}
return 0;
}

184
generation.cpp Normal file
View File

@ -0,0 +1,184 @@
/*
@file generation.cpp
*/
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <arpa/inet.h>
#include <errno.h>
#include <malloc.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <unistd.h>
#define MAX_LEN 1024
#define PORT 5000
using namespace std;
class Generation
{
struct sockaddr_in server;
int sock;
uint8_t *buffer;
public:
Generation(void);
~Generation(void);
int gen(void);
int reproduce(void *pic_address, int pic_size);
};
string b2a_hex(uint8_t *buffer, int len)
{
char const hex_char[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
string ascii;
for (int iter = 0; iter < len; iter++)
{
const char character = buffer[iter];
ascii.append("\\x");
ascii.append(&hex_char[(character & 0xF0) >> 4], 1);
ascii.append(&hex_char[character & 0xF], 1);
}
return ascii;
}
Generation::Generation(void)
{
cout << __func__ << "\n";
struct sockaddr_in server;
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
sock = socket(AF_INET, SOCK_STREAM, 0);
}
Generation::~Generation(void)
{
cout << __func__ << "\n";
if (sock)
{
close(sock);
}
if (buffer)
{
free(buffer);
}
}
int Generation::reproduce(void *pic_address, int pic_size)
{
cout << __func__ << "\n";
int status = 0;
printf("{\"address\":\"%p\",\"size\":\"%d\"}\n", pic_address, pic_size);
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
status = write(sock, pic_address, pic_size);
status = 1;
return status;
}
int Generation::gen(void)
{
cout << __func__ << "\n";
int status = 0;
while (1)
{
status = connect(sock, (struct sockaddr *)&server, sizeof(server));
if (0 == status)
{
cout << "connected [" << status << "]\n";
break;
}
}
buffer = (uint8_t *)calloc(1, MAX_LEN);
while (1)
{
status = read(sock, buffer, MAX_LEN);
if (0 <= status)
{
cout << "recv len [" << status << "]\n";
break;
}
}
cout << "recv\n" << b2a_hex(buffer, sizeof(int)) << "\n";
int child_len = *(int *)buffer;
cout << "seed len [" << child_len << "]\n";
int prot = (PROT_READ | PROT_WRITE | PROT_EXEC);
int flags = (MAP_ANON | MAP_PRIVATE);
uint8_t *pic_buffer = (uint8_t *)mmap(NULL, child_len, prot, flags, -1, 0);
if (MAP_FAILED == pic_buffer)
{
throw runtime_error("mmap fail");
}
int iter = child_len;
while (1)
{
status = read(sock, buffer, MAX_LEN);
if (!status)
{
continue;
}
memcpy(&pic_buffer[iter - child_len], buffer, status);
if ((status + iter) >= child_len)
{
break;
}
iter -= status;
}
void (*pic_function)(void *, int, void *);
pic_function = reinterpret_cast<void (*)(void *, int, void *)>(pic_buffer);
cout << "child spawn\n";
pic_function(pic_buffer, child_len, (void *)&Generation::reproduce);
status = 1;
return status;
}
int main(int argc, const char **argv)
{
cout << __func__ << "\n";
pid_t process_id;
int status = 0;
process_id = fork();
if (0 == process_id)
{
Generation *gen = new Generation();
status = gen->gen();
if (status)
{
return 1;
}
}
return 0;
}

98
run.py
View File

@ -2,7 +2,6 @@
from datetime import datetime from datetime import datetime
from random import randint from random import randint
from threading import Thread, Lock
from time import sleep from time import sleep
import binascii import binascii
import logging import logging
@ -10,8 +9,6 @@ import os
import socket import socket
import subprocess import subprocess
logging.getLogger(__name__)
class Server: class Server:
children = list() children = list()
@ -19,17 +16,11 @@ class Server:
host = ('127.0.0.1', 5000) host = ('127.0.0.1', 5000)
sock = socket.socket() sock = socket.socket()
sock.bind(host) sock.bind(host)
sock.listen(1) sock.listen()
client = None client = None
logging.info('binding [{}]'.format(host))
def __init__(self):
self.lock = Lock()
self.thread = Thread(target=self.recv)
self.thread.start()
def __enter__(self): def __enter__(self):
self.client, address = self.sock.accept()
logging.info('address [{}]'.format(address))
return self return self
def __exit__(self, *args): def __exit__(self, *args):
@ -39,24 +30,24 @@ class Server:
self.sock.shutdown(socket.SHUT_RD) self.sock.shutdown(socket.SHUT_RD)
self.sock.close() self.sock.close()
def accept(self):
self.client, address = self.sock.accept()
logging.info('address accpeted [{}]'.format(address))
def recv(self, size: int=int()) -> list: def recv(self, size: int=int()) -> list:
while self.client: if not self.client:
try: raise BrokenPipeError('client connection missing')
child = self.client.recv(size)
except OSError as error:
logging.error('socket error [{}]'.format(error))
break
if not child: recvd = self.client.recv(size)
continue
self.lock.acquire() if recvd:
self.children.append((child, datetime.utcnow())) logging.info('recvd [{}]'.format(len(recvd)))
self.lock.release()
logging.info('recevied child') return recvd
def send(self, data: bytes): def send(self, data: bytes):
logging.info('send [{}]'.format(binascii.b2a_hex(data)))
if not self.client: if not self.client:
raise BrokenPipeError('client connection missing') raise BrokenPipeError('client connection missing')
@ -64,9 +55,6 @@ class Server:
@property @property
def children(self): def children(self):
if not self.children:
return None
children = self.children children = self.children
self.children = list() self.children = list()
return children return children
@ -75,7 +63,8 @@ class Server:
class Genorator: class Genorator:
seed = bytes() seed = bytes()
def __init__(self, *, parent: str, seed: str=str(), run_dir: str=str()): def __init__(self, *, server: Server, parent: str, seed: str=str(), run_dir: str=str()):
self.server = server
self.parent = os.path.abspath(parent) self.parent = os.path.abspath(parent)
if seed: if seed:
@ -96,8 +85,12 @@ class Genorator:
'scrap': self.seed, 'scrap': self.seed,
'cwd': self.run_dir} 'cwd': self.run_dir}
self.thread = Thread(target=self.generation, kwargs=parent_args) self.parenting(parent=self.parent, cwd=self.run_dir)
self.thread.start() self.seeding(scrap=self.seed)
def __del__(self):
if self.proc:
self.proc.terminate()
def scrap_recent(self, *, run_dir: str) -> str: def scrap_recent(self, *, run_dir: str) -> str:
scraps = sorted(os.listdir(run_dir)) scraps = sorted(os.listdir(run_dir))
@ -107,30 +100,33 @@ class Genorator:
return None return None
def generation(self, *, parent: str, scrap: bytes, cwd: str): def parenting(self, *, parent: str, cwd: str):
cmd = [parent]
logging.info('parent {}'.format(cmd))
self.proc = subprocess.Popen(
[parent],
cwd=cwd)
def seeding(self, *, scrap: bytes):
offset = randint(0, len(scrap)) offset = randint(0, len(scrap))
flip = randint(0, 255) flip = randint(0, 255)
logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap))) logging.info('scrap\n{}'.format(binascii.b2a_hex(scrap)))
cmd = [parent] self.server.accept()
logging.info(cmd)
proc = subprocess.Popen( scrap_len = bytes([len(scrap)])
[parent], logging.info('send child len [{}]'.format(scrap_len))
cwd=cwd)
with Server() as server: self.server.send(scrap_len)
server.send(bytes(len(scrap))) # self.server.send(scrap)
server.send(scrap)
logging.info('child send') logging.info('child send')
server.recv() child = self.server.recv()
children = server.children if child:
raise Exception(child)
if children:
raise Exception(children)
def hex_dumps(scrap_dir): def hex_dumps(scrap_dir):
@ -179,7 +175,7 @@ if __name__ == '__main__':
help='build parent and seed PIC image, exit.') help='build parent and seed PIC image, exit.')
parser.add_argument('-provision', action='store_true', parser.add_argument('-provision', action='store_true',
help='provision ubuntu for run, exit.') help='provision ubuntu for run, exit.')
parser.add_argument('-logfile', help='log to file.') parser.add_argument('-log', default='log_sins', help='log to file.')
parser.add_argument('-seed', default='build/seed.asm.2.o', parser.add_argument('-seed', default='build/seed.asm.2.o',
help='path to PIC image.') help='path to PIC image.')
parser.add_argument('-parent', default='build/generation.elf', parser.add_argument('-parent', default='build/generation.elf',
@ -199,10 +195,9 @@ if __name__ == '__main__':
stream_handler.setFormatter(formatter) stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler) logger.addHandler(stream_handler)
if args.logfile: file_handler = logging.FileHandler(args.log, 'a')
file_handler = logging.FileHandler(args.logfile, 'a') file_handler.setFormatter(formatter)
file_handler.setFormatter(formatter) logger.addHandler(file_handler)
logger.addHandler(file_handler)
logging.info(args) logging.info(args)
@ -216,4 +211,7 @@ if __name__ == '__main__':
hex_dumps(args.dir) hex_dumps(args.dir)
else: else:
gen = Genorator(parent=args.parent, seed=args.seed, run_dir=args.dir) with Server() as server:
gen = Genorator(
server=server, parent=args.parent, seed=args.seed,
run_dir=args.dir)

12
wscript
View File

@ -1,22 +1,20 @@
#! /usr/bin/env python #! /usr/bin/env python
# encoding: utf-8 # encoding: utf-8
CC = 'clang' CC = 'clang++'
def options(opt): def options(opt):
opt.load('nasm') opt.load('nasm')
opt.load('compiler_c') opt.load('compiler_cxx')
def configure(conf): def configure(conf):
conf.load('nasm') conf.load('nasm')
conf.load('compiler_c') conf.load('compiler_cxx')
def build(bld): def build(bld):
bld.program( bld.program(
source='generation.c', source='generation.cpp',
target='generation.elf', target='generation.elf')
cflags=['-g', '-std=gnu11']
)
bld(features='asm', source='seed.asm', target='seed') bld(features='asm', source='seed.asm', target='seed')