From 95257d41d0b946197093ad67657fb3d4f7f9030f Mon Sep 17 00:00:00 2001 From: Determinant Date: Sat, 22 Jun 2019 01:04:36 -0400 Subject: update C API; fix bugs --- include/salticidae/event.h | 20 ++++++-------- include/salticidae/network.h | 3 ++- include/salticidae/stream.h | 4 +++ include/salticidae/util.h | 1 + src/conn.cpp | 63 ++++++++++++++++++-------------------------- src/network.cpp | 8 ++++-- src/stream.cpp | 43 +++++++++++++++++++++++++++--- src/util.cpp | 1 + test/test_msgnet_c.c | 6 ++--- 9 files changed, 89 insertions(+), 60 deletions(-) diff --git a/include/salticidae/event.h b/include/salticidae/event.h index d3625d5..b243865 100644 --- a/include/salticidae/event.h +++ b/include/salticidae/event.h @@ -528,13 +528,11 @@ class MPSCQueueEventDriven: public MPSCQueue { public: MPSCQueueEventDriven(): - wait_sig(true), - fd(eventfd(0, EFD_NONBLOCK)) {} - - ~MPSCQueueEventDriven() { - ev.clear(); - close(fd); + wait_sig(true), + fd(eventfd(0, EFD_NONBLOCK)) { + if (fd == -1) throw SalticidaeError(SALTI_ERROR_FD); } + ~MPSCQueueEventDriven() { close(fd); } template void reg_handler(const EventContext &ec, Func &&func) { @@ -585,13 +583,11 @@ class MPMCQueueEventDriven: public MPMCQueue { public: MPMCQueueEventDriven(): - wait_sig(true), - fd(eventfd(0, EFD_NONBLOCK)) {} - - ~MPMCQueueEventDriven() { - evs.clear(); - close(fd); + wait_sig(true), + fd(eventfd(0, EFD_NONBLOCK)) { + if (fd == -1) throw SalticidaeError(SALTI_ERROR_FD); } + ~MPMCQueueEventDriven() { close(fd); } // this function is *NOT* thread-safe template diff --git a/include/salticidae/network.h b/include/salticidae/network.h index 6c8b7fd..0bae6c5 100644 --- a/include/salticidae/network.h +++ b/include/salticidae/network.h @@ -992,7 +992,7 @@ msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t void msgnetwork_free(const msgnetwork_t *self); void msgnetwork_send_msg(msgnetwork_t *self, const msg_t *msg, const msgnetwork_conn_t *conn); void msgnetwork_send_msg_deferred_by_move(msgnetwork_t *self, msg_t *_moved_msg, const msgnetwork_conn_t *conn); -msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr, SalticidaeCError *err); +msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr, bool blocking, SalticidaeCError *err); msgnetwork_conn_t *msgnetwork_conn_copy(const msgnetwork_conn_t *self); void msgnetwork_conn_free(const msgnetwork_conn_t *self); void msgnetwork_listen(msgnetwork_t *self, const netaddr_t *listen_addr, SalticidaeCError *err); @@ -1013,6 +1013,7 @@ void msgnetwork_reg_error_handler(msgnetwork_t *self, msgnetwork_error_callback_ msgnetwork_t *msgnetwork_conn_get_net(const msgnetwork_conn_t *conn); msgnetwork_conn_mode_t msgnetwork_conn_get_mode(const msgnetwork_conn_t *conn); const netaddr_t *msgnetwork_conn_get_addr(const msgnetwork_conn_t *conn); +const x509_t *msgnetwork_conn_get_peer_cert(const msgnetwork_conn_t *conn); /* PeerNetwork */ diff --git a/include/salticidae/stream.h b/include/salticidae/stream.h index 50a67dd..7d1456e 100644 --- a/include/salticidae/stream.h +++ b/include/salticidae/stream.h @@ -494,6 +494,7 @@ extern "C" { uint256_t *uint256_new(); uint256_t *uint256_new_from_bytes(const uint8_t *arr); +uint256_t *uint256_new_from_bytearray(const bytearray_t *bytes); void uint256_free(const uint256_t *self); bool uint256_is_null(const uint256_t *self); @@ -503,6 +504,8 @@ void uint256_unserialize(uint256_t *self, datastream_t *s); datastream_t *datastream_new(); datastream_t *datastream_new_from_bytes(const uint8_t *base, size_t size); +datastream_t *datastream_new_from_bytearray(const bytearray_t *bytes); +datastream_t *datastream_new_moved_from_bytearray(bytearray_t *bytes); void datastream_free(const datastream_t *self); datastream_t *datastream_copy(const datastream_t *self); @@ -534,6 +537,7 @@ int64_t datastream_get_i64(datastream_t *self, bool *succ); const uint8_t *datastream_get_data_inplace(datastream_t *self, size_t len); uint256_t *datastream_get_hash(const datastream_t *self); bytearray_t *bytearray_new_moved_from_datastream(datastream_t *_moved_self); +bytearray_t *bytearray_new_from_hex(const char *hex_str); char *datastream_get_hex(datastream_t *self); diff --git a/include/salticidae/util.h b/include/salticidae/util.h index 9102842..952b18b 100644 --- a/include/salticidae/util.h +++ b/include/salticidae/util.h @@ -98,6 +98,7 @@ enum SalticidaeErrorCode { SALTI_ERROR_TLS_KEY, SALTI_ERROR_TLS_KEY_NOT_MATCH, SALTI_ERROR_TLS_NO_PEER_CERT, + SALTI_ERROR_FD, SALTI_ERROR_UNKNOWN }; diff --git a/src/conn.cpp b/src/conn.cpp index 535803b..931e915 100644 --- a/src/conn.cpp +++ b/src/conn.cpp @@ -305,10 +305,7 @@ void ConnPool::accept_client(int fd, int) { conn->on_setup(); worker.feed(conn, client_fd); } - } catch (ConnPoolError &e) { - SALTICIDAE_LOG_ERROR("%s", e.what()); - throw e; - } + } catch (...) { recoverable_error(std::current_exception()); } } void ConnPool::Conn::conn_server(int fd, int events) { @@ -338,31 +335,26 @@ void ConnPool::_listen(NetAddr listen_addr) { ev_listen.clear(); close(listen_fd); } - 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); + 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(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; - } + 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); ev_listen = FdEvent(disp_ec, listen_fd, - std::bind(&ConnPool::accept_client, this, _1, _2)); + std::bind(&ConnPool::accept_client, this, _1, _2)); ev_listen.add(FdEvent::READ); SALTICIDAE_LOG_INFO("listening to %u", ntohs(listen_addr.port)); } @@ -370,18 +362,13 @@ void ConnPool::_listen(NetAddr listen_addr) { ConnPool::conn_t ConnPool::_connect(const NetAddr &addr) { int fd; int one = 1; - 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; - } + 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); 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 bc539f4..2f84f25 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -76,9 +76,9 @@ void msgnetwork_send_msg_deferred_by_move(msgnetwork_t *self, self->_send_msg_deferred(std::move(*_moved_msg), *conn); } -msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr, SalticidaeCError *cerror) { +msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr, bool blocking, SalticidaeCError *cerror) { SALTICIDAE_CERROR_TRY(cerror) - return new msgnetwork_conn_t(self->connect(*addr)); + return new msgnetwork_conn_t(self->connect(*addr, blocking)); SALTICIDAE_CERROR_CATCH(cerror) return nullptr; } @@ -151,6 +151,10 @@ const netaddr_t *msgnetwork_conn_get_addr(const msgnetwork_conn_t *conn) { return &(*conn)->get_addr(); } +const x509_t *msgnetwork_conn_get_peer_cert(const msgnetwork_conn_t *conn) { + return (*conn)->get_peer_cert(); +} + // PeerNetwork peernetwork_config_t *peernetwork_config_new() { diff --git a/src/stream.cpp b/src/stream.cpp index 71a5b27..f5d4ac9 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -6,8 +6,21 @@ extern "C" { uint256_t *uint256_new() { return new uint256_t(); } uint256_t *uint256_new_from_bytes(const uint8_t *arr) { - return new uint256_t(arr); + try { + return new uint256_t(arr); + } catch (...) { + return nullptr; + } } + +uint256_t *uint256_new_from_bytearray(const bytearray_t *bytes) { + try { + return new uint256_t(*bytes); + } catch (...) { + return nullptr; + } +} + void uint256_free(const uint256_t *self) { delete self; } bool uint256_is_null(const uint256_t *self) { return self->is_null(); } @@ -39,6 +52,22 @@ datastream_t *datastream_new_from_bytes(const uint8_t *base, size_t size) { } } +datastream_t *datastream_new_from_bytearray(const bytearray_t *bytes) { + try { + return new datastream_t(*bytes); + } catch (...) { + return nullptr; + } +} + +datastream_t *datastream_new_moved_from_bytearray(bytearray_t *bytes) { + try { + return new datastream_t(std::move(*bytes)); + } catch (...) { + return nullptr; + } +} + void datastream_free(const datastream_t *self) { delete self; } datastream_t *datastream_copy(const datastream_t *self) { @@ -98,9 +127,15 @@ uint256_t *datastream_get_hash(const datastream_t *self) { bytearray_t *bytearray_new_moved_from_datastream(datastream_t *_moved_src) { try { - auto res = new bytearray_t(std::move(*_moved_src)); - //delete _moved_src; - return res; + return new bytearray_t(std::move(*_moved_src)); + } catch (...) { + return nullptr; + } +} + +bytearray_t *bytearray_new_from_hex(const char *hex_str) { + try { + return new bytearray_t(salticidae::from_hex(hex_str)); } catch (...) { return nullptr; } diff --git a/src/util.cpp b/src/util.cpp index 1493b20..f70cb32 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -55,6 +55,7 @@ const char *SALTICIDAE_ERROR_STRINGS[] = { "EVP_PKEY error", "tls key does not match the cert", "tls fail to get peer cert", + "fd error", "unknown error" }; diff --git a/test/test_msgnet_c.c b/test/test_msgnet_c.c index f938c82..753c70f 100644 --- a/test/test_msgnet_c.c +++ b/test/test_msgnet_c.c @@ -139,7 +139,7 @@ bool conn_handler(const msgnetwork_conn_t *conn, bool connected, void *userdata) printf("[%s] Disconnected, retrying.\n", name); /* try to reconnect to the same address */ const netaddr_t *addr = msgnetwork_conn_get_addr(conn); - msgnetwork_connect(net, addr, &err); check_err(&err); + msgnetwork_connect(net, addr, false, &err); check_err(&err); } return true; } @@ -194,8 +194,8 @@ int main() { msgnetwork_listen(bob.net, bob_addr, &err); check_err(&err); /* try to connect once */ - msgnetwork_conn_free(msgnetwork_connect(alice.net, bob_addr, &err)); check_err(&err); - msgnetwork_conn_free(msgnetwork_connect(bob.net, alice_addr, &err)); check_err(&err); + msgnetwork_conn_free(msgnetwork_connect(alice.net, bob_addr, false, &err)); check_err(&err); + msgnetwork_conn_free(msgnetwork_connect(bob.net, alice_addr, false, &err)); check_err(&err); netaddr_free(alice_addr); netaddr_free(bob_addr); -- cgit v1.2.3