mirror of https://github.com/agdsn/xerxes.git
boodt::program_options works, dut there are
other todos like fix a little crash on disconnect or do some error handling.
This commit is contained in:
parent
12fbe224af
commit
28e4ceb2e1
129
socket.cxx
129
socket.cxx
|
|
@ -7,7 +7,12 @@
|
|||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include "socket.hxx"
|
||||
#include <iostream>
|
||||
|
||||
namespace xerxes
|
||||
{
|
||||
|
|
@ -16,8 +21,10 @@ namespace xerxes
|
|||
int domain)
|
||||
: fd(socket(protocol, type, domain))
|
||||
{
|
||||
std::cerr << "new socket" << std::endl;
|
||||
if(fd < 0)
|
||||
{
|
||||
perror("--");
|
||||
throw std::runtime_error("could not create socket.");
|
||||
}
|
||||
}
|
||||
|
|
@ -35,6 +42,60 @@ namespace xerxes
|
|||
}
|
||||
}
|
||||
|
||||
SocketOption::SocketOption(std::string new_file)
|
||||
: type(UNIX), file(new_file)
|
||||
{
|
||||
}
|
||||
|
||||
SocketOption::SocketOption(std::string new_hostname, std::string new_port)
|
||||
: type(TCP), hostname(new_hostname), port(new_port)
|
||||
{
|
||||
}
|
||||
|
||||
Socket*
|
||||
SocketOption::gen_socket()
|
||||
{
|
||||
if(type == TCP)
|
||||
{
|
||||
return new Socket(PF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void validate(boost::any& v,
|
||||
const std::vector<std::string>& values,
|
||||
SocketOption* target_type, int)
|
||||
{
|
||||
static boost::regex r("(tcp|unix):(([\\d\\w_-]|\\.|/)+)(:(\\d+))?");
|
||||
|
||||
using namespace boost::program_options;
|
||||
using namespace std;
|
||||
|
||||
validators::check_first_occurrence(v);
|
||||
const std::string& s = validators::get_single_string(values);
|
||||
|
||||
boost::smatch match;
|
||||
if(regex_match(s, match, r))
|
||||
{
|
||||
if(match[1] == "tcp")
|
||||
{
|
||||
v = boost::any(SocketOption(match[2], match[5]));
|
||||
}
|
||||
else
|
||||
{
|
||||
v = boost::any(SocketOption(match[2]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw validation_error("invalid value");
|
||||
}
|
||||
}
|
||||
|
||||
MysqlData
|
||||
makeData(int len)
|
||||
{
|
||||
|
|
@ -69,6 +130,37 @@ namespace xerxes
|
|||
return ::connect(socket.fd, serv_addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
connect_inet(Socket& socket,
|
||||
SocketOption& opt)
|
||||
{
|
||||
addrinfo hints;
|
||||
addrinfo* res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
getaddrinfo(opt.hostname.c_str(), opt.port.c_str(), &hints, &res);
|
||||
int ret = connect(socket, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
connect_unix(Socket& socket,
|
||||
SocketOption& opt)
|
||||
{
|
||||
struct sockaddr_un adr;
|
||||
|
||||
memset(&adr, 0, sizeof(adr));
|
||||
adr.sun_family = AF_UNIX;
|
||||
strncpy(adr.sun_path, opt.file.c_str(), sizeof(adr.sun_path));
|
||||
return connect(socket, (struct sockaddr *) &adr, SUN_LEN(&adr));
|
||||
}
|
||||
|
||||
int
|
||||
recv(Socket& socket,
|
||||
MysqlData& data,
|
||||
|
|
@ -111,4 +203,41 @@ namespace xerxes
|
|||
{
|
||||
return ::bind(socket.fd, bind_address, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
bind_inet(Socket& socket,
|
||||
SocketOption& opt)
|
||||
{
|
||||
addrinfo hints;
|
||||
addrinfo* res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
|
||||
getaddrinfo(opt.hostname.c_str(), opt.port.c_str(), &hints, &res);
|
||||
|
||||
int ret = bind(socket, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
freeaddrinfo(res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bind_unix(Socket& socket,
|
||||
SocketOption& opt)
|
||||
{
|
||||
unlink(opt.file.c_str());
|
||||
|
||||
struct sockaddr_un adr;
|
||||
|
||||
memset(&adr, 0, sizeof(adr));
|
||||
adr.sun_family = AF_UNIX;
|
||||
strncpy(adr.sun_path, opt.file.c_str(), sizeof(adr.sun_path));
|
||||
return bind(socket, (struct sockaddr *) &adr, SUN_LEN(&adr));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
socket.hxx
43
socket.hxx
|
|
@ -15,6 +15,9 @@
|
|||
#include <boost/utility.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/shared_array.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/epoll.h>
|
||||
|
|
@ -41,6 +44,31 @@ namespace xerxes
|
|||
MysqlData
|
||||
makeData(int len);
|
||||
|
||||
enum sock_opt_types
|
||||
{
|
||||
TCP,
|
||||
UNIX
|
||||
};
|
||||
|
||||
class SocketOption
|
||||
{
|
||||
public:
|
||||
|
||||
SocketOption(std::string new_file);
|
||||
SocketOption(std::string new_hostname, std::string new_port);
|
||||
|
||||
Socket* gen_socket();
|
||||
|
||||
int type;
|
||||
std::string file;
|
||||
std::string hostname;
|
||||
std::string port;
|
||||
};
|
||||
|
||||
void validate(boost::any& v,
|
||||
const std::vector<std::string>& values,
|
||||
SocketOption* target_type, int);
|
||||
|
||||
boost::shared_ptr<Socket>
|
||||
accept(Socket& socket,
|
||||
sockaddr* address,
|
||||
|
|
@ -54,6 +82,14 @@ namespace xerxes
|
|||
sockaddr const* const serv_address,
|
||||
socklen_t address_len);
|
||||
|
||||
int
|
||||
connect_inet(Socket& socket,
|
||||
SocketOption& opt);
|
||||
|
||||
int
|
||||
connect_unix(Socket& socket,
|
||||
SocketOption& opt);
|
||||
|
||||
int
|
||||
recv(Socket& socket,
|
||||
MysqlData& data,
|
||||
|
|
@ -70,6 +106,13 @@ namespace xerxes
|
|||
sockaddr const* const bind_address,
|
||||
socklen_t addrlen);
|
||||
|
||||
int
|
||||
bind_inet(Socket& socket,
|
||||
SocketOption& opt);
|
||||
|
||||
int
|
||||
bind_unix(Socket& socket,
|
||||
SocketOption& opt);
|
||||
|
||||
class SocketErr{};
|
||||
class ConResetErr: public SocketErr{};
|
||||
|
|
|
|||
146
xerxes.cxx
146
xerxes.cxx
|
|
@ -6,6 +6,10 @@
|
|||
* Maximilian Marx <mmarx@wh2.tu-dresden.de>
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO : Fix crash on disconnect
|
||||
* TODO : Do some Error handling
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -14,75 +18,8 @@
|
|||
#include "socket.hxx"
|
||||
#include "epoll.hxx"
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/program_options.hpp>
|
||||
#include <vector>
|
||||
|
||||
enum sock_opt_types{
|
||||
TCP,
|
||||
UNIX
|
||||
};
|
||||
|
||||
class SocketOption {
|
||||
public:
|
||||
|
||||
SocketOption(std::string new_file)
|
||||
: type(UNIX), file(new_file)
|
||||
{
|
||||
}
|
||||
SocketOption(std::string new_hostname, std::string new_port)
|
||||
: type(TCP), hostname(new_hostname), port(new_port)
|
||||
{
|
||||
}
|
||||
|
||||
int type;
|
||||
std::string file;
|
||||
std::string hostname;
|
||||
std::string port;
|
||||
};
|
||||
|
||||
|
||||
void validate(boost::any& v,
|
||||
const std::vector<std::string>& values,
|
||||
SocketOption* target_type, int)
|
||||
{
|
||||
//static boost::regex r("(tcp|unix):([\\d\\w_-/.]+)(:(\\d+))?");
|
||||
static boost::regex r("(tcp|unix):(([\\d\\w_-]|\\.|/)+)(:(\\d+))?");
|
||||
|
||||
using namespace boost::program_options;
|
||||
using namespace std;
|
||||
|
||||
// Make sure no previous assignment to 'a' was made.
|
||||
validators::check_first_occurrence(v);
|
||||
// Extract the first string from 'values'. If there is more than
|
||||
// one string, it's an error, and exception will be thrown.
|
||||
const std::string& s = validators::get_single_string(values);
|
||||
|
||||
// Do regex match and convert the interesting part to
|
||||
// int.
|
||||
boost::smatch match;
|
||||
if(regex_match(s, match, r))
|
||||
{
|
||||
cout << "1: " << match[1] << endl; // Type
|
||||
cout << "2: " << match[2] << endl; // File-/Hostname
|
||||
cout << "5: " << match[5] << endl; // Port
|
||||
if(match[1] == "tcp")
|
||||
{
|
||||
cout << "TCP" << endl;
|
||||
v = boost::any(SocketOption(match[2], match[5]));
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "UNIX" << endl;
|
||||
v = boost::any(SocketOption(match[2]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw validation_error("invalid value");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -110,48 +47,47 @@ po::variables_map vm;
|
|||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||
po::notify(vm);
|
||||
|
||||
if (vm.count("help")) {
|
||||
if (vm.count("help"))
|
||||
{
|
||||
cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vm.count("src")) {
|
||||
|
||||
if (vm.count("src"))
|
||||
{
|
||||
SocketOption sock = vm["src"].as<SocketOption>();
|
||||
}
|
||||
if (vm.count("dst"))
|
||||
{
|
||||
SocketOption sock = vm["dst"].as<SocketOption>();
|
||||
if(sock.type == TCP)
|
||||
{
|
||||
cout << "TCP Source is " << sock.hostname << "," << sock.port << ".\n";
|
||||
cout << "TCP Destination is " << sock.hostname << "," << sock.port << ".\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "UNIX Source is " << sock.file << ".\n";
|
||||
cout << "UNIX Destination is " << sock.file << ".\n";
|
||||
}
|
||||
} else {
|
||||
cout << "Source was not set.\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
else
|
||||
{
|
||||
cout << "Destination was not set.\n";
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
Socket lstn(PF_INET, SOCK_STREAM, 0);
|
||||
|
||||
addrinfo hints;
|
||||
addrinfo* res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
|
||||
getaddrinfo("127.0.0.1", "13337", &hints, &res);
|
||||
|
||||
bind(lstn, res->ai_addr, res->ai_addrlen);
|
||||
|
||||
freeaddrinfo(res);
|
||||
SocketOption src = vm["src"].as<SocketOption>();
|
||||
Socket &lstn = *(src.gen_socket());
|
||||
if(src.type == TCP)
|
||||
{
|
||||
cout << "TCP Source is " << src.hostname << "," << src.port << ".\n";
|
||||
bind_inet(lstn, src);
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "UNIX Source is " << src.file << ".\n";
|
||||
bind_unix(lstn, src);
|
||||
}
|
||||
|
||||
int ret = listen(lstn, 3);
|
||||
if( ret != 0)
|
||||
|
|
@ -177,23 +113,9 @@ exit(0);
|
|||
if((events[i].data.fd == -1)
|
||||
&& (events[i].events & EPOLLIN))
|
||||
{
|
||||
//close(accept(lstn, 0, 0));
|
||||
//cout << "hollo!" << endl;
|
||||
boost::shared_ptr<Socket> target(new Socket(PF_INET, SOCK_STREAM, 0));
|
||||
addrinfo hints;
|
||||
addrinfo* res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
getaddrinfo("127.0.0.1", "3306", &hints, &res);
|
||||
//getaddrinfo("127.0.0.1", "25", &hints, &res);
|
||||
connect(*target, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
|
||||
SocketOption dst = vm["dst"].as<SocketOption>();
|
||||
boost::shared_ptr<Socket> target(dst.gen_socket());
|
||||
connect_inet(*target, dst);
|
||||
sockets[target->fd] = target;
|
||||
|
||||
boost::shared_ptr<Socket> source(accept(lstn, 0, 0));
|
||||
|
|
|
|||
Loading…
Reference in New Issue