aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2019-06-12 19:14:40 -0400
committerDeterminant <tederminant@gmail.com>2019-06-12 19:14:40 -0400
commite27e529e589ef89fbe010ebf7c5635ec2873f64f (patch)
tree76e7d20589d11f3aabd255ca70201f1288d1d1bc /src
parent9f6460c7ab774d900f391345bbf3fac8617a3aa3 (diff)
WIP: error handling
Diffstat (limited to 'src')
-rw-r--r--src/conn.cpp114
-rw-r--r--src/network.cpp9
-rw-r--r--src/util.cpp26
3 files changed, 89 insertions, 60 deletions
diff --git a/src/conn.cpp b/src/conn.cpp
index 5fc59f3..7f485fd 100644
--- a/src/conn.cpp
+++ b/src/conn.cpp
@@ -170,34 +170,38 @@ void ConnPool::Conn::disp_terminate() {
void ConnPool::accept_client(int fd, int) {
int client_fd;
struct sockaddr client_addr;
- socklen_t addr_size = sizeof(struct sockaddr_in);
- if ((client_fd = accept(fd, &client_addr, &addr_size)) < 0)
- SALTICIDAE_LOG_ERROR("error while accepting the connection: %s",
- strerror(errno));
- else
- {
- int one = 1;
- if (setsockopt(client_fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
- throw ConnPoolError(std::string("setsockopt failed"));
- if (fcntl(client_fd, F_SETFL, O_NONBLOCK) == -1)
- throw ConnPoolError(std::string("unable to set nonblocking socket"));
+ try {
+ socklen_t addr_size = sizeof(struct sockaddr_in);
+ if ((client_fd = accept(fd, &client_addr, &addr_size)) < 0)
+ throw ConnPoolError(SALTI_ERROR_ACCEPT, errno);
+ else
+ {
+ int one = 1;
+ if (setsockopt(client_fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
+ throw ConnPoolError(SALTI_ERROR_ACCEPT, errno);
+ if (fcntl(client_fd, F_SETFL, O_NONBLOCK) == -1)
+ throw ConnPoolError(SALTI_ERROR_ACCEPT, errno);
- NetAddr addr((struct sockaddr_in *)&client_addr);
- conn_t conn = create_conn();
- conn->self_ref = conn;
- conn->send_buffer.set_capacity(queue_capacity);
- conn->seg_buff_size = seg_buff_size;
- conn->fd = client_fd;
- conn->cpool = this;
- conn->mode = Conn::PASSIVE;
- conn->addr = addr;
- add_conn(conn);
- SALTICIDAE_LOG_INFO("accepted %s", std::string(*conn).c_str());
- auto &worker = select_worker();
- conn->worker = &worker;
- conn->on_setup();
- update_conn(conn, true);
- worker.feed(conn, client_fd);
+ NetAddr addr((struct sockaddr_in *)&client_addr);
+ conn_t conn = create_conn();
+ conn->self_ref = conn;
+ conn->send_buffer.set_capacity(queue_capacity);
+ conn->seg_buff_size = seg_buff_size;
+ conn->fd = client_fd;
+ conn->cpool = this;
+ conn->mode = Conn::PASSIVE;
+ conn->addr = addr;
+ add_conn(conn);
+ SALTICIDAE_LOG_INFO("accepted %s", std::string(*conn).c_str());
+ auto &worker = select_worker();
+ conn->worker = &worker;
+ conn->on_setup();
+ update_conn(conn, true);
+ worker.feed(conn, client_fd);
+ }
+ } catch (ConnPoolError &e) {
+ SALTICIDAE_LOG_ERROR("%s", e.what());
+ throw e;
}
}
@@ -229,24 +233,29 @@ void ConnPool::_listen(NetAddr listen_addr) {
ev_listen.clear();
close(listen_fd);
}
- if ((listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
- throw ConnPoolError(std::string("cannot create socket for listening"));
- if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0 ||
- setsockopt(listen_fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
- throw ConnPoolError(std::string("setsockopt failed"));
- if (fcntl(listen_fd, F_SETFL, O_NONBLOCK) == -1)
- throw ConnPoolError(std::string("unable to set nonblocking socket"));
+ try {
+ if ((listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ throw ConnPoolError(SALTI_ERROR_LISTEN, errno);
+ if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0 ||
+ setsockopt(listen_fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
+ throw ConnPoolError(SALTI_ERROR_LISTEN, errno);
+ if (fcntl(listen_fd, F_SETFL, O_NONBLOCK) == -1)
+ throw ConnPoolError(SALTI_ERROR_LISTEN, errno);
- struct sockaddr_in sockin;
- memset(&sockin, 0, sizeof(struct sockaddr_in));
- sockin.sin_family = AF_INET;
- sockin.sin_addr.s_addr = INADDR_ANY;
- sockin.sin_port = listen_addr.port;
+ struct sockaddr_in sockin;
+ memset(&sockin, 0, sizeof(struct sockaddr_in));
+ sockin.sin_family = AF_INET;
+ sockin.sin_addr.s_addr = INADDR_ANY;
+ sockin.sin_port = listen_addr.port;
- if (bind(listen_fd, (struct sockaddr *)&sockin, sizeof(sockin)) < 0)
- throw ConnPoolError(std::string("binding error"));
- if (::listen(listen_fd, max_listen_backlog) < 0)
- throw ConnPoolError(std::string("listen error"));
+ if (bind(listen_fd, (struct sockaddr *)&sockin, sizeof(sockin)) < 0)
+ throw ConnPoolError(SALTI_ERROR_LISTEN, errno);
+ if (::listen(listen_fd, max_listen_backlog) < 0)
+ throw ConnPoolError(SALTI_ERROR_LISTEN, errno);
+ } catch (ConnPoolError &e) {
+ SALTICIDAE_LOG_ERROR("%s", e.what());
+ throw e;
+ }
ev_listen = FdEvent(disp_ec, listen_fd,
std::bind(&ConnPool::accept_client, this, _1, _2));
ev_listen.add(FdEvent::READ);
@@ -256,13 +265,18 @@ void ConnPool::_listen(NetAddr listen_addr) {
ConnPool::conn_t ConnPool::_connect(const NetAddr &addr) {
int fd;
int one = 1;
- if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
- throw ConnPoolError(std::string("cannot create socket for remote"));
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0 ||
- setsockopt(fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
- throw ConnPoolError(std::string("setsockopt failed"));
- if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
- throw ConnPoolError(std::string("unable to set nonblocking socket"));
+ try {
+ if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ throw ConnPoolError(SALTI_ERROR_CONNECT, errno);
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0 ||
+ setsockopt(fd, SOL_TCP, TCP_NODELAY, (const char *)&one, sizeof(one)) < 0)
+ throw ConnPoolError(SALTI_ERROR_CONNECT, errno);
+ if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
+ throw ConnPoolError(SALTI_ERROR_CONNECT, errno);
+ } catch (ConnPoolError &e) {
+ SALTICIDAE_LOG_ERROR("%s", e.what());
+ throw e;
+ }
conn_t conn = create_conn();
conn->self_ref = conn;
conn->send_buffer.set_capacity(queue_capacity);
diff --git a/src/network.cpp b/src/network.cpp
index 49bad48..30ef0eb 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -44,9 +44,10 @@ void msgnetwork_config_queue_capacity(msgnetwork_config_t *self, size_t cap) {
self->queue_capacity(cap);
}
-bool msgnetwork_send_msg(msgnetwork_t *self,
- const msg_t *msg, const msgnetwork_conn_t *conn) {
- return self->_send_msg(*msg, *conn);
+void msgnetwork_send_msg_by_move(msgnetwork_t *self,
+ msg_t *_moved_msg, const msgnetwork_conn_t *conn) {
+ self->_send_msg(std::move(*_moved_msg), *conn);
+ delete _moved_msg;
}
msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr) {
@@ -167,7 +168,7 @@ void peernetwork_send_msg_by_move(peernetwork_t *self,
void peernetwork_multicast_msg_by_move(peernetwork_t *self,
msg_t *_moved_msg,
const netaddr_array_t *paddrs) {
- self->multicast_msg(std::move(*_moved_msg), *paddrs);
+ self->_multicast_msg(std::move(*_moved_msg), *paddrs);
delete _moved_msg;
}
diff --git a/src/util.cpp b/src/util.cpp
index a0d5044..f762b4c 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -34,6 +34,22 @@
namespace salticidae {
+const char *SALTICIDAE_ERROR_STRINGS[] = {
+ "",
+ "generic",
+ "unable to accept",
+ "unable to listen",
+ "unable to connect",
+ "peer already exists",
+ "peer does not exist",
+ "invalid NetAddr format",
+ "invalid OptVal format",
+ "option name already exists",
+ "unknown action",
+ "configuration file line too long",
+ "invalid option format"
+};
+
const char *TTY_COLOR_RED = "\x1b[31m";
const char *TTY_COLOR_GREEN = "\x1b[32m";
const char *TTY_COLOR_YELLOW = "\x1b[33m";
@@ -91,8 +107,6 @@ const std::string get_current_datetime() {
return std::string(buf);
}
-SalticidaeError::SalticidaeError() : msg("unknown") {}
-
void Logger::set_color() {
if (is_tty())
{
@@ -182,7 +196,7 @@ void Config::add_opt(const std::string &optname, const optval_t &optval, Action
char short_opt,
const std::string &optdoc) {
if (conf.count(optname))
- throw SalticidaeError("option name already exists");
+ throw SalticidaeError(SALTI_ERROR_OPTNAME_ALREADY_EXISTS);
opts.push_back(new Opt(optname, optdoc,
optval, action, short_opt,
opts.size()));
@@ -199,7 +213,7 @@ void Config::update(Opt &p, const char *optval) {
case SET_VAL: p.optval->set_val(optval); break;
case APPEND: p.optval->append(optval); break;
default:
- throw SalticidaeError("unknown action");
+ throw SalticidaeError(SALTI_ERROR_OPT_UNKNOWN_ACTION);
}
}
@@ -220,7 +234,7 @@ bool Config::load(const std::string &fname) {
if (strlen(buff) == BUFF_SIZE - 1)
{
fclose(conf_f);
- throw SalticidaeError("configuration file line too long");
+ throw SalticidaeError(SALTI_ERROR_CONFIG_LINE_TOO_LONG);
}
std::string line(buff);
size_t pos = line.find("=");
@@ -269,7 +283,7 @@ size_t Config::parse(int argc, char **argv) {
if (id == -1)
break;
if (id == '?')
- throw SalticidaeError("invalid option format");
+ throw SalticidaeError(SALTI_ERROR_OPT_INVALID);
if (id >= 0x100)
update(*(opts[id - 0x100]), optarg);
else