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
133
socket.cxx
133
socket.cxx
|
|
@ -7,17 +7,24 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include "socket.hxx"
|
#include "socket.hxx"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace xerxes
|
namespace xerxes
|
||||||
{
|
{
|
||||||
Socket::Socket(int protocol,
|
Socket::Socket(int protocol,
|
||||||
int type,
|
int type,
|
||||||
int domain)
|
int domain)
|
||||||
: fd(socket(protocol, type, domain))
|
: fd(socket(protocol, type, domain))
|
||||||
{
|
{
|
||||||
|
std::cerr << "new socket" << std::endl;
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
{
|
{
|
||||||
|
perror("--");
|
||||||
throw std::runtime_error("could not create socket.");
|
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
|
MysqlData
|
||||||
makeData(int len)
|
makeData(int len)
|
||||||
{
|
{
|
||||||
|
|
@ -68,6 +129,37 @@ namespace xerxes
|
||||||
{
|
{
|
||||||
return ::connect(socket.fd, serv_addr, addrlen);
|
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
|
int
|
||||||
recv(Socket& socket,
|
recv(Socket& socket,
|
||||||
|
|
@ -111,4 +203,41 @@ namespace xerxes
|
||||||
{
|
{
|
||||||
return ::bind(socket.fd, bind_address, addrlen);
|
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/utility.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/shared_array.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/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
@ -41,6 +44,31 @@ namespace xerxes
|
||||||
MysqlData
|
MysqlData
|
||||||
makeData(int len);
|
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>
|
boost::shared_ptr<Socket>
|
||||||
accept(Socket& socket,
|
accept(Socket& socket,
|
||||||
sockaddr* address,
|
sockaddr* address,
|
||||||
|
|
@ -54,6 +82,14 @@ namespace xerxes
|
||||||
sockaddr const* const serv_address,
|
sockaddr const* const serv_address,
|
||||||
socklen_t address_len);
|
socklen_t address_len);
|
||||||
|
|
||||||
|
int
|
||||||
|
connect_inet(Socket& socket,
|
||||||
|
SocketOption& opt);
|
||||||
|
|
||||||
|
int
|
||||||
|
connect_unix(Socket& socket,
|
||||||
|
SocketOption& opt);
|
||||||
|
|
||||||
int
|
int
|
||||||
recv(Socket& socket,
|
recv(Socket& socket,
|
||||||
MysqlData& data,
|
MysqlData& data,
|
||||||
|
|
@ -70,6 +106,13 @@ namespace xerxes
|
||||||
sockaddr const* const bind_address,
|
sockaddr const* const bind_address,
|
||||||
socklen_t addrlen);
|
socklen_t addrlen);
|
||||||
|
|
||||||
|
int
|
||||||
|
bind_inet(Socket& socket,
|
||||||
|
SocketOption& opt);
|
||||||
|
|
||||||
|
int
|
||||||
|
bind_unix(Socket& socket,
|
||||||
|
SocketOption& opt);
|
||||||
|
|
||||||
class SocketErr{};
|
class SocketErr{};
|
||||||
class ConResetErr: public SocketErr{};
|
class ConResetErr: public SocketErr{};
|
||||||
|
|
|
||||||
180
xerxes.cxx
180
xerxes.cxx
|
|
@ -6,6 +6,10 @@
|
||||||
* Maximilian Marx <mmarx@wh2.tu-dresden.de>
|
* Maximilian Marx <mmarx@wh2.tu-dresden.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO : Fix crash on disconnect
|
||||||
|
* TODO : Do some Error handling
|
||||||
|
*/
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
@ -14,75 +18,8 @@
|
||||||
#include "socket.hxx"
|
#include "socket.hxx"
|
||||||
#include "epoll.hxx"
|
#include "epoll.hxx"
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <boost/any.hpp>
|
|
||||||
#include <boost/regex.hpp>
|
|
||||||
#include <boost/program_options.hpp>
|
|
||||||
#include <vector>
|
#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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -98,60 +35,59 @@ main(int argc, char* argv[])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Declare the supported options.
|
// Declare the supported options.
|
||||||
po::options_description desc("Allowed options");
|
po::options_description desc("Allowed options");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help", "produce help message")
|
("help", "produce help message")
|
||||||
("src", po::value<SocketOption>(), "Source")
|
("src", po::value<SocketOption>(), "Source")
|
||||||
("dst", po::value<SocketOption>(), "Destination")
|
("dst", po::value<SocketOption>(), "Destination")
|
||||||
;
|
;
|
||||||
|
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
po::store(po::parse_command_line(argc, argv, desc), vm);
|
po::store(po::parse_command_line(argc, argv, desc), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
if (vm.count("help")) {
|
if (vm.count("help"))
|
||||||
cout << desc << "\n";
|
{
|
||||||
return 1;
|
cout << desc << "\n";
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (vm.count("src")) {
|
|
||||||
SocketOption sock = vm["src"].as<SocketOption>();
|
if (vm.count("src"))
|
||||||
if(sock.type == TCP)
|
{
|
||||||
|
SocketOption sock = vm["src"].as<SocketOption>();
|
||||||
|
}
|
||||||
|
if (vm.count("dst"))
|
||||||
|
{
|
||||||
|
SocketOption sock = vm["dst"].as<SocketOption>();
|
||||||
|
if(sock.type == TCP)
|
||||||
|
{
|
||||||
|
cout << "TCP Destination is " << sock.hostname << "," << sock.port << ".\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cout << "UNIX Destination is " << sock.file << ".\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
cout << "TCP Source is " << sock.hostname << "," << sock.port << ".\n";
|
cout << "Destination was not set.\n";
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
cout << "UNIX Source is " << sock.file << ".\n";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cout << "Source was not set.\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SocketOption src = vm["src"].as<SocketOption>();
|
||||||
|
Socket &lstn = *(src.gen_socket());
|
||||||
|
if(src.type == TCP)
|
||||||
exit(0);
|
{
|
||||||
|
cout << "TCP Source is " << src.hostname << "," << src.port << ".\n";
|
||||||
|
bind_inet(lstn, src);
|
||||||
Socket lstn(PF_INET, SOCK_STREAM, 0);
|
}
|
||||||
|
else
|
||||||
addrinfo hints;
|
{
|
||||||
addrinfo* res;
|
cout << "UNIX Source is " << src.file << ".\n";
|
||||||
|
bind_unix(lstn, src);
|
||||||
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);
|
|
||||||
|
|
||||||
int ret = listen(lstn, 3);
|
int ret = listen(lstn, 3);
|
||||||
if( ret != 0)
|
if( ret != 0)
|
||||||
|
|
@ -177,23 +113,9 @@ exit(0);
|
||||||
if((events[i].data.fd == -1)
|
if((events[i].data.fd == -1)
|
||||||
&& (events[i].events & EPOLLIN))
|
&& (events[i].events & EPOLLIN))
|
||||||
{
|
{
|
||||||
//close(accept(lstn, 0, 0));
|
SocketOption dst = vm["dst"].as<SocketOption>();
|
||||||
//cout << "hollo!" << endl;
|
boost::shared_ptr<Socket> target(dst.gen_socket());
|
||||||
boost::shared_ptr<Socket> target(new Socket(PF_INET, SOCK_STREAM, 0));
|
connect_inet(*target, dst);
|
||||||
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);
|
|
||||||
|
|
||||||
sockets[target->fd] = target;
|
sockets[target->fd] = target;
|
||||||
|
|
||||||
boost::shared_ptr<Socket> source(accept(lstn, 0, 0));
|
boost::shared_ptr<Socket> source(accept(lstn, 0, 0));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue