Electroneum
Loading...
Searching...
No Matches
net.cpp File Reference
#include <atomic>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/write.hpp>
#include <boost/endian/conversion.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/scoped_thread.hpp>
#include <boost/thread/thread.hpp>
#include <cstring>
#include <functional>
#include <gtest/gtest.h>
#include <memory>
#include "net/error.h"
#include "net/net_utils_base.h"
#include "net/socks.h"
#include "net/socks_connect.h"
#include "net/parse.h"
#include "net/tor_address.h"
#include "net/zmq.h"
#include "p2p/net_peerlist_boost_serialization.h"
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage.h"
Include dependency graph for net.cpp:

Go to the source code of this file.

Functions

 TEST (tor_address, constants)
 TEST (tor_address, invalid)
 TEST (tor_address, unblockable_types)
 TEST (tor_address, valid)
 TEST (tor_address, generic_network_address)
 TEST (tor_address, epee_serializev_v2)
 TEST (tor_address, epee_serializev_v3)
 TEST (tor_address, epee_serialize_unknown)
 TEST (tor_address, boost_serialize_v2)
 TEST (tor_address, boost_serialize_v3)
 TEST (tor_address, boost_serialize_unknown)
 TEST (get_network_address, onion)
 TEST (get_network_address, ipv4)
 TEST (socks_client, unsupported_command)
 TEST (socks_client, no_command)
 TEST (socks_client, connect_command)
 TEST (socks_client, connect_command_failed)
 TEST (socks_client, resolve_command)
 TEST (socks_connector, host)
 TEST (socks_connector, ipv4)
 TEST (socks_connector, error)
 TEST (socks_connector, timeout)
 TEST (zmq, error_codes)
 TEST (zmq, read_write)
 TEST (zmq, read_write_multipart)
 TEST (zmq, read_write_termination)

Function Documentation

◆ TEST() [1/26]

TEST ( get_network_address ,
ipv4  )

Definition at line 507 of file net.cpp.

508{
510 net::get_network_address("0.0.0.", 0);
512
513 address = net::get_network_address("0.0.0.257", 0);
515
516 address = net::get_network_address("0.0.0.254", 1000);
517 ASSERT_TRUE(bool(address));
519 EXPECT_STREQ("0.0.0.254", address->host_str().c_str());
520 EXPECT_STREQ("0.0.0.254:1000", address->str().c_str());
521
522 address = net::get_network_address("23.0.0.254:2000", 1000);
523 ASSERT_TRUE(bool(address));
525 EXPECT_STREQ("23.0.0.254", address->host_str().c_str());
526 EXPECT_STREQ("23.0.0.254:2000", address->str().c_str());
527}
#define EXPECT_EQ(val1, val2)
Definition gtest.h:1922
#define EXPECT_STREQ(s1, s2)
Definition gtest.h:1995
#define ASSERT_TRUE(condition)
Definition gtest.h:1865
expect< epee::net_utils::network_address > get_network_address(const boost::string_ref address, const std::uint16_t default_port)
Definition parse.cpp:38
@ unsupported_address
Type not supported by get_network_address.
Definition error.h:45
const char * address
Definition multisig.cpp:37
Here is the call graph for this function:

◆ TEST() [2/26]

TEST ( get_network_address ,
onion  )

Definition at line 481 of file net.cpp.

482{
484 net::get_network_address("onion", 0);
486
487 address = net::get_network_address(".onion", 0);
489
490 address = net::get_network_address(v3_onion, 1000);
491 ASSERT_TRUE(bool(address));
493 EXPECT_STREQ(v3_onion, address->host_str().c_str());
494 EXPECT_EQ(std::string{v3_onion} + ":1000", address->str());
495
496 address = net::get_network_address(std::string{v3_onion} + ":2000", 1000);
497 ASSERT_TRUE(bool(address));
499 EXPECT_STREQ(v3_onion, address->host_str().c_str());
500 EXPECT_EQ(std::string{v3_onion} + ":2000", address->str());
501
502 address = net::get_network_address(std::string{v3_onion} + ":65536", 1000);
504}
@ invalid_port
Outside of 0-65535 range.
Definition error.h:43
@ invalid_tor_address
Invalid base32 or length.
Definition error.h:44
Here is the call graph for this function:

◆ TEST() [3/26]

TEST ( socks_client ,
connect_command  )

Definition at line 612 of file net.cpp.

613{
614 io_thread io{};
615 stream_type::socket client{io.io_service};
616
617 std::atomic<bool> called{false};
618 auto test_client = net::socks::make_connect_client(
619 std::move(client), net::socks::version::v4a, checked_client{std::addressof(called), false}
620 );
621 ASSERT_TRUE(bool(test_client));
622
623 ASSERT_TRUE(test_client->set_connect_command("example.com", 8080));
624 EXPECT_FALSE(test_client->buffer().empty());
625 ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint()));
626 while (!io.connected)
627 ASSERT_FALSE(called);
628
629 const std::uint8_t expected_bytes[] = {
630 4, 1, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00,
631 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00
632 };
633
634 std::uint8_t actual_bytes[sizeof(expected_bytes)];
635 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
636 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
637
638 const std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0, 0, 0, 0};
639 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
640
641 // yikes!
642 while (!called);
643}
static bool connect_and_send(std::shared_ptr< client > self, const stream_type::endpoint &proxy_address)
Definition socks.cpp:294
#define ASSERT_FALSE(condition)
Definition gtest.h:1868
#define EXPECT_TRUE(condition)
Definition gtest.h:1859
#define EXPECT_FALSE(condition)
Definition gtest.h:1862
std::shared_ptr< client > make_connect_client(client::stream_type::socket &&proxy, socks::version ver, Handler handler)
Definition socks.h:226
Here is the call graph for this function:

◆ TEST() [4/26]

TEST ( socks_client ,
connect_command_failed  )

Definition at line 645 of file net.cpp.

646{
647 io_thread io{};
648 stream_type::socket client{io.io_service};
649
650 std::atomic<bool> called{false};
651 auto test_client = net::socks::make_connect_client(
652 std::move(client), net::socks::version::v4, checked_client{std::addressof(called), true}
653 );
654 ASSERT_TRUE(bool(test_client));
655
657 test_client->set_connect_command(
658 epee::net_utils::ipv4_network_address{boost::endian::native_to_big(std::uint32_t(5000)), 3000}
659 )
660 );
661 EXPECT_FALSE(test_client->buffer().empty());
662 ASSERT_TRUE(net::socks::client::connect_and_send(std::move(test_client), io.acceptor.local_endpoint()));
663 while (!io.connected)
664 ASSERT_FALSE(called);
665
666 const std::uint8_t expected_bytes[] = {
667 4, 1, 0x0b, 0xb8, 0x00, 0x00, 0x13, 0x88, 0x00
668 };
669
670 std::uint8_t actual_bytes[sizeof(expected_bytes)];
671 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
672 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
673
674 const std::uint8_t reply_bytes[] = {0, 91, 0, 0, 0, 0, 0, 0};
675 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
676
677 // yikes!
678 while (!called);
679}
Here is the call graph for this function:

◆ TEST() [5/26]

TEST ( socks_client ,
no_command  )

Definition at line 600 of file net.cpp.

601{
602 boost::asio::io_service io_service{};
603 stream_type::socket client{io_service};
604
605 auto test_client = net::socks::make_connect_client(
606 std::move(client), net::socks::version::v4a, std::bind( [] {} )
607 );
608 ASSERT_TRUE(bool(test_client));
609 EXPECT_FALSE(net::socks::client::send(std::move(test_client)));
610}
static bool send(std::shared_ptr< client > self)
Definition socks.cpp:305
Here is the call graph for this function:

◆ TEST() [6/26]

TEST ( socks_client ,
resolve_command  )

Definition at line 681 of file net.cpp.

682{
683 static std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0xff, 0, 0xad, 0};
684
685 struct resolve_client : net::socks::client
686 {
687 std::atomic<unsigned> called_;
688 bool expected_;
689
690 resolve_client(stream_type::socket&& proxy)
691 : net::socks::client(std::move(proxy), net::socks::version::v4a_tor)
692 , called_(0)
693 , expected_(false)
694 {};
695
696 virtual void done(boost::system::error_code error, std::shared_ptr<client> self) override
697 {
698 EXPECT_EQ(this, self.get());
699 EXPECT_EQ(expected_, bool(error)) << "Resolve failure: " << error.message();
700
701 if (!error)
702 {
703 ASSERT_EQ(sizeof(reply_bytes), buffer().size());
704 EXPECT_EQ(0u, std::memcmp(buffer().data(), reply_bytes, sizeof(reply_bytes)));
705 }
706
707 ++called_;
708 }
709 };
710
711 io_thread io{};
712 stream_type::socket client{io.io_service};
713
714 auto test_client = std::make_shared<resolve_client>(std::move(client));
715 ASSERT_TRUE(bool(test_client));
716
717 ASSERT_TRUE(test_client->set_resolve_command("example.com"));
718 EXPECT_FALSE(test_client->buffer().empty());
719 ASSERT_TRUE(net::socks::client::connect_and_send(test_client, io.acceptor.local_endpoint()));
720 while (!io.connected)
721 ASSERT_EQ(0u, test_client->called_);
722
723 const std::uint8_t expected_bytes[] = {
724 4, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
725 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00
726 };
727
728 std::uint8_t actual_bytes[sizeof(expected_bytes)];
729 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
730 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
731
732 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
733
734 // yikes!
735 while (test_client->called_ == 0);
736
737 test_client->expected_ = true;
738 ASSERT_TRUE(test_client->set_resolve_command("example.com"));
739 EXPECT_FALSE(test_client->buffer().empty());
741
742 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
743 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
744
745 reply_bytes[1] = 91;
746 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
747
748 // yikes!
749 while (test_client->called_ == 1);
750}
uint8_t version
Client support for socks connect and resolve commands.
Definition socks.h:94
epee::span< const std::uint8_t > buffer() const noexcept
Definition socks.h:143
#define ASSERT_EQ(val1, val2)
Definition gtest.h:1956
error
Tracks LMDB error codes.
Definition error.h:45
@ v4a_tor
Extensions defined in Tor codebase.
Definition socks.h:61
const T & move(const T &t)
#define false
Here is the call graph for this function:

◆ TEST() [7/26]

TEST ( socks_client ,
unsupported_command  )

Definition at line 582 of file net.cpp.

583{
584 boost::asio::io_service io_service{};
585 stream_type::socket client{io_service};
586
587 auto test_client = net::socks::make_connect_client(
588 std::move(client), net::socks::version::v4, std::bind( [] {} )
589 );
590 ASSERT_TRUE(bool(test_client));
591 EXPECT_TRUE(test_client->buffer().empty());
592
593 EXPECT_FALSE(test_client->set_connect_command("example.com", 8080));
594 EXPECT_TRUE(test_client->buffer().empty());
595
596 EXPECT_FALSE(test_client->set_resolve_command("example.com"));
597 EXPECT_TRUE(test_client->buffer().empty());
598}
Here is the call graph for this function:

◆ TEST() [8/26]

TEST ( socks_connector ,
error  )

Definition at line 805 of file net.cpp.

806{
807 io_thread io{};
808 boost::asio::steady_timer timeout{io.io_service};
809 timeout.expires_from_now(std::chrono::seconds{5});
810
811 boost::unique_future<boost::asio::ip::tcp::socket> sock =
812 net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout);
813
814 while (!io.connected)
815 ASSERT_FALSE(sock.is_ready());
816 const std::uint8_t expected_bytes[] = {
817 4, 1, 0x1f, 0x90, 0xfa, 0x58, 0x7d, 0x63, 0x00
818 };
819
820 std::uint8_t actual_bytes[sizeof(expected_bytes)];
821 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
822 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
823
824 const std::uint8_t reply_bytes[] = {0, 91, 0, 0, 0, 0, 0, 0};
825 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
826
827 ASSERT_EQ(boost::future_status::ready, sock.wait_for(boost::chrono::seconds{3}));
828 EXPECT_THROW(sock.get().is_open(), boost::system::system_error);
829}
#define EXPECT_THROW(statement, expected_exception)
Definition gtest.h:1843
Primarily for use with epee::net_utils::http_client.

◆ TEST() [9/26]

TEST ( socks_connector ,
host  )

Definition at line 752 of file net.cpp.

753{
754 io_thread io{};
755 boost::asio::steady_timer timeout{io.io_service};
756 timeout.expires_from_now(std::chrono::seconds{5});
757
758 boost::unique_future<boost::asio::ip::tcp::socket> sock =
759 net::socks::connector{io.acceptor.local_endpoint()}("example.com", "8080", timeout);
760
761 while (!io.connected)
762 ASSERT_FALSE(sock.is_ready());
763 const std::uint8_t expected_bytes[] = {
764 4, 1, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00,
765 'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm', 0x00
766 };
767
768 std::uint8_t actual_bytes[sizeof(expected_bytes)];
769 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
770 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
771
772 const std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0, 0, 0, 0};
773 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
774
775 ASSERT_EQ(boost::future_status::ready, sock.wait_for(boost::chrono::seconds{3}));
776 EXPECT_TRUE(sock.get().is_open());
777}

◆ TEST() [10/26]

TEST ( socks_connector ,
ipv4  )

Definition at line 779 of file net.cpp.

780{
781 io_thread io{};
782 boost::asio::steady_timer timeout{io.io_service};
783 timeout.expires_from_now(std::chrono::seconds{5});
784
785 boost::unique_future<boost::asio::ip::tcp::socket> sock =
786 net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout);
787
788 while (!io.connected)
789 ASSERT_FALSE(sock.is_ready());
790 const std::uint8_t expected_bytes[] = {
791 4, 1, 0x1f, 0x90, 0xfa, 0x58, 0x7d, 0x63, 0x00
792 };
793
794 std::uint8_t actual_bytes[sizeof(expected_bytes)];
795 boost::asio::read(io.server, boost::asio::buffer(actual_bytes));
796 EXPECT_TRUE(std::memcmp(expected_bytes, actual_bytes, sizeof(actual_bytes)) == 0);
797
798 const std::uint8_t reply_bytes[] = {0, 90, 0, 0, 0, 0, 0, 0};
799 boost::asio::write(io.server, boost::asio::buffer(reply_bytes));
800
801 ASSERT_EQ(boost::future_status::ready, sock.wait_for(boost::chrono::seconds{3}));
802 EXPECT_TRUE(sock.get().is_open());
803}

◆ TEST() [11/26]

TEST ( socks_connector ,
timeout  )

Definition at line 831 of file net.cpp.

832{
833 io_thread io{};
834 boost::asio::steady_timer timeout{io.io_service};
835 timeout.expires_from_now(std::chrono::milliseconds{10});
836
837 boost::unique_future<boost::asio::ip::tcp::socket> sock =
838 net::socks::connector{io.acceptor.local_endpoint()}("250.88.125.99", "8080", timeout);
839
840 ASSERT_EQ(boost::future_status::ready, sock.wait_for(boost::chrono::seconds{3}));
841 EXPECT_THROW(sock.get().is_open(), boost::system::system_error);
842}

◆ TEST() [12/26]

TEST ( tor_address ,
boost_serialize_unknown  )

Definition at line 446 of file net.cpp.

447{
448 std::string buffer{};
449 {
450 const net::tor_address tor{};
451 EXPECT_TRUE(tor.is_unknown());
454 EXPECT_EQ(0u, tor.port());
455
456 std::ostringstream stream{};
457 {
459 archive << tor;
460 }
461 buffer = stream.str();
462 }
463
465 {
466 EXPECT_TRUE(tor.is_unknown());
469 EXPECT_EQ(0u, tor.port());
470
471 std::istringstream stream{buffer};
473 archive >> tor;
474 }
475 EXPECT_TRUE(tor.is_unknown());
478 EXPECT_EQ(0u, tor.port());
479}
Tor onion address; internal format not condensed/decoded.
Definition tor_address.h:52
static const char * unknown_str() noexcept
static tor_address unknown() noexcept
Definition tor_address.h:70
Here is the call graph for this function:

◆ TEST() [13/26]

TEST ( tor_address ,
boost_serialize_v2  )

Definition at line 376 of file net.cpp.

377{
378 std::string buffer{};
379 {
381 EXPECT_FALSE(tor.is_unknown());
383 EXPECT_STREQ(v2_onion, tor.host_str());
384 EXPECT_EQ(10u, tor.port());
385
386 std::ostringstream stream{};
387 {
389 archive << tor;
390 }
391 buffer = stream.str();
392 }
393
395 {
396 EXPECT_TRUE(tor.is_unknown());
399 EXPECT_EQ(0u, tor.port());
400
401 std::istringstream stream{buffer};
403 archive >> tor;
404 }
405 EXPECT_FALSE(tor.is_unknown());
407 EXPECT_STREQ(v2_onion, tor.host_str());
408 EXPECT_EQ(10u, tor.port());
409}
static expect< tor_address > make(boost::string_ref address, std::uint16_t default_port=0)
#define ELECTRONEUM_UNWRAP(...)
Definition expect.h:60
#define EXPECT_NE(val1, val2)
Definition gtest.h:1926
Here is the call graph for this function:

◆ TEST() [14/26]

TEST ( tor_address ,
boost_serialize_v3  )

Definition at line 411 of file net.cpp.

412{
413 std::string buffer{};
414 {
416 EXPECT_FALSE(tor.is_unknown());
418 EXPECT_STREQ(v3_onion, tor.host_str());
419 EXPECT_EQ(10u, tor.port());
420
421 std::ostringstream stream{};
422 {
424 archive << tor;
425 }
426 buffer = stream.str();
427 }
428
430 {
431 EXPECT_TRUE(tor.is_unknown());
434 EXPECT_EQ(0u, tor.port());
435
436 std::istringstream stream{buffer};
438 archive >> tor;
439 }
440 EXPECT_FALSE(tor.is_unknown());
442 EXPECT_STREQ(v3_onion, tor.host_str());
443 EXPECT_EQ(10u, tor.port());
444}
Here is the call graph for this function:

◆ TEST() [15/26]

TEST ( tor_address ,
constants  )

Definition at line 66 of file net.cpp.

67{
68 static_assert(!net::tor_address::is_local(), "bad is_local() response");
69 static_assert(!net::tor_address::is_loopback(), "bad is_loopback() response");
70 static_assert(net::tor_address::get_type_id() == epee::net_utils::address_type::tor, "bad get_type_id() response");
71
76}
static constexpr bool is_local() noexcept
static constexpr epee::net_utils::address_type get_type_id() noexcept
static constexpr bool is_loopback() noexcept
Here is the call graph for this function:

◆ TEST() [16/26]

TEST ( tor_address ,
epee_serialize_unknown  )

Definition at line 325 of file net.cpp.

326{
327 std::string buffer{};
328 {
329 test_command command{net::tor_address::unknown()};
330 EXPECT_TRUE(command.tor.is_unknown());
331 EXPECT_EQ(net::tor_address{}, command.tor);
333 EXPECT_EQ(0u, command.tor.port());
334
336 EXPECT_TRUE(command.store(stg));
337 EXPECT_TRUE(stg.store_to_binary(buffer));
338 }
339
340 test_command command{};
341 {
342 EXPECT_TRUE(command.tor.is_unknown());
343 EXPECT_EQ(net::tor_address{}, command.tor);
344 EXPECT_STRNE(v3_onion, command.tor.host_str());
345 EXPECT_EQ(0u, command.tor.port());
346
348 EXPECT_TRUE(stg.load_from_binary(buffer));
349 EXPECT_TRUE(command.load(stg));
350 }
351 EXPECT_TRUE(command.tor.is_unknown());
352 EXPECT_EQ(net::tor_address{}, command.tor);
354 EXPECT_EQ(0u, command.tor.port());
355
356 // make sure that exceeding max buffer doesn't destroy tor_address::_load
357 {
359 stg.load_from_binary(buffer);
360
361 std::string host{};
362 ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
363 EXPECT_EQ(std::strlen(net::tor_address::unknown_str()), host.size());
364
365 host.push_back('k');
366 EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
367 EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
368 }
369
370 EXPECT_TRUE(command.tor.is_unknown());
371 EXPECT_EQ(net::tor_address{}, command.tor);
372 EXPECT_STRNE(v3_onion, command.tor.host_str());
373 EXPECT_EQ(0u, command.tor.port());
374}
bool get_value(const std::string &value_name, t_value &val, hsection hparent_section)
hsection open_section(const std::string &section_name, hsection hparent_section, bool create_if_notexist=false)
bool store_to_binary(binarybuffer &target)
bool set_value(const std::string &value_name, const t_value &target, hsection hparent_section)
bool load_from_binary(const epee::span< const uint8_t > target)
bool is_unknown() const noexcept
const char * host_str() const noexcept
std::uint16_t port() const noexcept
#define EXPECT_STRNE(s1, s2)
Definition gtest.h:1997
Here is the call graph for this function:

◆ TEST() [17/26]

TEST ( tor_address ,
epee_serializev_v2  )

Definition at line 223 of file net.cpp.

224{
225 std::string buffer{};
226 {
227 test_command command{ELECTRONEUM_UNWRAP(net::tor_address::make(v2_onion, 10))};
228 EXPECT_FALSE(command.tor.is_unknown());
229 EXPECT_NE(net::tor_address{}, command.tor);
230 EXPECT_STREQ(v2_onion, command.tor.host_str());
231 EXPECT_EQ(10u, command.tor.port());
232
234 EXPECT_TRUE(command.store(stg));
235 EXPECT_TRUE(stg.store_to_binary(buffer));
236 }
237
238 test_command command{};
239 {
240 EXPECT_TRUE(command.tor.is_unknown());
241 EXPECT_EQ(net::tor_address{}, command.tor);
243 EXPECT_EQ(0u, command.tor.port());
244
246 EXPECT_TRUE(stg.load_from_binary(buffer));
247 EXPECT_TRUE(command.load(stg));
248 }
249 EXPECT_FALSE(command.tor.is_unknown());
250 EXPECT_NE(net::tor_address{}, command.tor);
251 EXPECT_STREQ(v2_onion, command.tor.host_str());
252 EXPECT_EQ(10u, command.tor.port());
253
254 // make sure that exceeding max buffer doesn't destroy tor_address::_load
255 {
257 stg.load_from_binary(buffer);
258
259 std::string host{};
260 ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
261 EXPECT_EQ(std::strlen(v2_onion), host.size());
262
263 host.push_back('k');
264 EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
265 EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
266 }
267
268 EXPECT_TRUE(command.tor.is_unknown());
269 EXPECT_EQ(net::tor_address{}, command.tor);
271 EXPECT_EQ(0u, command.tor.port());
272}
Here is the call graph for this function:

◆ TEST() [18/26]

TEST ( tor_address ,
epee_serializev_v3  )

Definition at line 274 of file net.cpp.

275{
276 std::string buffer{};
277 {
278 test_command command{ELECTRONEUM_UNWRAP(net::tor_address::make(v3_onion, 10))};
279 EXPECT_FALSE(command.tor.is_unknown());
280 EXPECT_NE(net::tor_address{}, command.tor);
281 EXPECT_STREQ(v3_onion, command.tor.host_str());
282 EXPECT_EQ(10u, command.tor.port());
283
285 EXPECT_TRUE(command.store(stg));
286 EXPECT_TRUE(stg.store_to_binary(buffer));
287 }
288
289 test_command command{};
290 {
291 EXPECT_TRUE(command.tor.is_unknown());
292 EXPECT_EQ(net::tor_address{}, command.tor);
294 EXPECT_EQ(0u, command.tor.port());
295
297 EXPECT_TRUE(stg.load_from_binary(buffer));
298 EXPECT_TRUE(command.load(stg));
299 }
300 EXPECT_FALSE(command.tor.is_unknown());
301 EXPECT_NE(net::tor_address{}, command.tor);
302 EXPECT_STREQ(v3_onion, command.tor.host_str());
303 EXPECT_EQ(10u, command.tor.port());
304
305 // make sure that exceeding max buffer doesn't destroy tor_address::_load
306 {
308 stg.load_from_binary(buffer);
309
310 std::string host{};
311 ASSERT_TRUE(stg.get_value("host", host, stg.open_section("tor", nullptr, false)));
312 EXPECT_EQ(std::strlen(v3_onion), host.size());
313
314 host.push_back('k');
315 EXPECT_TRUE(stg.set_value("host", host, stg.open_section("tor", nullptr, false)));
316 EXPECT_TRUE(command.load(stg)); // poor error reporting from `KV_SERIALIZE`
317 }
318
319 EXPECT_TRUE(command.tor.is_unknown());
320 EXPECT_EQ(net::tor_address{}, command.tor);
321 EXPECT_STRNE(v3_onion, command.tor.host_str());
322 EXPECT_EQ(0u, command.tor.port());
323}
Here is the call graph for this function:

◆ TEST() [19/26]

TEST ( tor_address ,
generic_network_address  )

Definition at line 188 of file net.cpp.

189{
193
194 EXPECT_EQ(tor1, tor2);
195 EXPECT_NE(ip, tor1);
196 EXPECT_LT(ip, tor1);
197
198 EXPECT_STREQ(v3_onion, tor1.host_str().c_str());
199 EXPECT_EQ(std::string{v3_onion} + ":8080", tor1.str());
209}
#define EXPECT_LT(val1, val2)
Definition gtest.h:1930
Here is the call graph for this function:

◆ TEST() [20/26]

TEST ( tor_address ,
invalid  )

Definition at line 78 of file net.cpp.

79{
80 EXPECT_TRUE(net::tor_address::make("").has_error());
81 EXPECT_TRUE(net::tor_address::make(":").has_error());
82 EXPECT_TRUE(net::tor_address::make(".onion").has_error());
83 EXPECT_TRUE(net::tor_address::make(".onion:").has_error());
84 EXPECT_TRUE(net::tor_address::make(v2_onion + 1).has_error());
85 EXPECT_TRUE(net::tor_address::make(v3_onion + 1).has_error());
86 EXPECT_TRUE(net::tor_address::make(boost::string_ref{v2_onion, sizeof(v2_onion) - 2}).has_error());
87 EXPECT_TRUE(net::tor_address::make(boost::string_ref{v3_onion, sizeof(v3_onion) - 2}).has_error());
88 EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":-").has_error());
89 EXPECT_TRUE(net::tor_address::make(std::string{v2_onion} + ":900a").has_error());
90 EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":65536").has_error());
91 EXPECT_TRUE(net::tor_address::make(std::string{v3_onion} + ":-1").has_error());
92
93 std::string onion{v3_onion};
94 onion.at(10) = 1;
95 EXPECT_TRUE(net::tor_address::make(onion).has_error());
96}
Here is the call graph for this function:

◆ TEST() [21/26]

TEST ( tor_address ,
unblockable_types  )

Definition at line 98 of file net.cpp.

99{
101
102 ASSERT_NE(nullptr, tor.host_str());
103 EXPECT_STREQ("<unknown tor host>", tor.host_str());
104 EXPECT_STREQ("<unknown tor host>", tor.str().c_str());
105 EXPECT_EQ(0u, tor.port());
106 EXPECT_TRUE(tor.is_unknown());
107 EXPECT_FALSE(tor.is_local());
108 EXPECT_FALSE(tor.is_loopback());
111
113 ASSERT_NE(nullptr, tor.host_str());
114 EXPECT_STREQ("<unknown tor host>", tor.host_str());
115 EXPECT_STREQ("<unknown tor host>", tor.str().c_str());
116 EXPECT_EQ(0u, tor.port());
117 EXPECT_TRUE(tor.is_unknown());
118 EXPECT_FALSE(tor.is_local());
119 EXPECT_FALSE(tor.is_loopback());
122
124}
#define ASSERT_NE(val1, val2)
Definition gtest.h:1960
Here is the call graph for this function:

◆ TEST() [22/26]

TEST ( tor_address ,
valid  )

Definition at line 126 of file net.cpp.

127{
128 const auto address1 = net::tor_address::make(v3_onion);
129
130 ASSERT_TRUE(address1.has_value());
131 EXPECT_EQ(0u, address1->port());
132 EXPECT_STREQ(v3_onion, address1->host_str());
133 EXPECT_STREQ(v3_onion, address1->str().c_str());
134 EXPECT_TRUE(address1->is_blockable());
135
136 net::tor_address address2{*address1};
137
138 EXPECT_EQ(0u, address2.port());
139 EXPECT_STREQ(v3_onion, address2.host_str());
140 EXPECT_STREQ(v3_onion, address2.str().c_str());
141 EXPECT_TRUE(address2.is_blockable());
142 EXPECT_TRUE(address2.equal(*address1));
143 EXPECT_TRUE(address1->equal(address2));
144 EXPECT_TRUE(address2 == *address1);
145 EXPECT_TRUE(*address1 == address2);
146 EXPECT_FALSE(address2 != *address1);
147 EXPECT_FALSE(*address1 != address2);
148 EXPECT_TRUE(address2.is_same_host(*address1));
149 EXPECT_TRUE(address1->is_same_host(address2));
150 EXPECT_FALSE(address2.less(*address1));
151 EXPECT_FALSE(address1->less(address2));
152
153 address2 = ELECTRONEUM_UNWRAP(net::tor_address::make(std::string{v2_onion} + ":6545"));
154
155 EXPECT_EQ(6545, address2.port());
156 EXPECT_STREQ(v2_onion, address2.host_str());
157 EXPECT_EQ(std::string{v2_onion} + ":6545", address2.str().c_str());
158 EXPECT_TRUE(address2.is_blockable());
159 EXPECT_FALSE(address2.equal(*address1));
160 EXPECT_FALSE(address1->equal(address2));
161 EXPECT_FALSE(address2 == *address1);
162 EXPECT_FALSE(*address1 == address2);
163 EXPECT_TRUE(address2 != *address1);
164 EXPECT_TRUE(*address1 != address2);
165 EXPECT_FALSE(address2.is_same_host(*address1));
166 EXPECT_FALSE(address1->is_same_host(address2));
167 EXPECT_FALSE(address2.less(*address1));
168 EXPECT_TRUE(address1->less(address2));
169
170 address2 = ELECTRONEUM_UNWRAP(net::tor_address::make(std::string{v3_onion} + ":", 65535));
171
172 EXPECT_EQ(65535, address2.port());
173 EXPECT_STREQ(v3_onion, address2.host_str());
174 EXPECT_EQ(std::string{v3_onion} + ":65535", address2.str().c_str());
175 EXPECT_TRUE(address2.is_blockable());
176 EXPECT_FALSE(address2.equal(*address1));
177 EXPECT_FALSE(address1->equal(address2));
178 EXPECT_FALSE(address2 == *address1);
179 EXPECT_FALSE(*address1 == address2);
180 EXPECT_TRUE(address2 != *address1);
181 EXPECT_TRUE(*address1 != address2);
182 EXPECT_TRUE(address2.is_same_host(*address1));
183 EXPECT_TRUE(address1->is_same_host(address2));
184 EXPECT_FALSE(address2.less(*address1));
185 EXPECT_TRUE(address1->less(address2));
186}
bool less(const tor_address &rhs) const noexcept
bool equal(const tor_address &rhs) const noexcept
std::string str() const
bool is_blockable() const noexcept
bool is_same_host(const tor_address &rhs) const noexcept
Here is the call graph for this function:

◆ TEST() [23/26]

TEST ( zmq ,
error_codes  )

Definition at line 844 of file net.cpp.

845{
847 std::addressof(net::zmq::error_category()),
848 std::addressof(net::zmq::make_error_code(0).category())
849);
851 std::make_error_condition(std::errc::not_a_socket),
853);
854
856[]() -> expect<void>
857{
858ELECTRONEUM_ZMQ_CHECK(zmq_msg_send(nullptr, nullptr, 0));
859return success();
860}().matches(std::errc::not_a_socket)
861);
862
863bool thrown = false;
864try
865{
866ELECTRONEUM_ZMQ_THROW("stuff");
867}
868catch (const std::system_error& e)
869{
870thrown = true;
871EXPECT_EQ(std::make_error_condition(std::errc::not_a_socket), e.code());
872}
873EXPECT_TRUE(thrown);
874}
const std::error_category & error_category() noexcept
Definition zmq.cpp:40
std::error_code make_error_code(int code) noexcept
Definition zmq.h:64
#define ELECTRONEUM_ZMQ_THROW(msg)
Throw an exception with a custom msg, current ZMQ error code, filename, and line number.
Definition zmq.h:53
#define ELECTRONEUM_ZMQ_CHECK(...)
If the expression is less than 0, return the current ZMQ error code.
Definition zmq.h:38
Here is the call graph for this function:

◆ TEST() [24/26]

TEST ( zmq ,
read_write  )

Definition at line 876 of file net.cpp.

877{
878net::zmq::context context{zmq_init(1)};
879ASSERT_NE(nullptr, context);
880
881net::zmq::socket send_socket{zmq_socket(context.get(), ZMQ_REQ)};
882net::zmq::socket recv_socket{zmq_socket(context.get(), ZMQ_REP)};
883ASSERT_NE(nullptr, send_socket);
884ASSERT_NE(nullptr, recv_socket);
885
886ASSERT_EQ(0u, zmq_bind(recv_socket.get(), "inproc://testing"));
887ASSERT_EQ(0u, zmq_connect(send_socket.get(), "inproc://testing"));
888
889std::string message;
890message.resize(1024);
891crypto::rand(message.size(), reinterpret_cast<std::uint8_t*>(std::addressof(message[0])));
892
894
895const expect<std::string> received = net::zmq::receive(recv_socket.get());
896ASSERT_TRUE(bool(received));
897EXPECT_EQ(message, *received);
898}
std::string message("Message requiring signing")
std::enable_if< std::is_pod< T >::value, T >::type rand()
Definition crypto.h:216
span< const T > strspan(const std::string &s) noexcept
make a span from a std::string
Definition span.h:171
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
Definition zmq.h:98
expect< void > send(const epee::span< const std::uint8_t > payload, void *const socket, const int flags) noexcept
Definition zmq.cpp:182
expect< std::string > receive(void *const socket, const int flags)
Definition zmq.cpp:175
std::unique_ptr< void, close > socket
Unique ZMQ socket handle, calls zmq_close on destruction.
Definition zmq.h:101
Here is the call graph for this function:

◆ TEST() [25/26]

TEST ( zmq ,
read_write_multipart  )

Definition at line 900 of file net.cpp.

901{
902net::zmq::context context{zmq_init(1)};
903ASSERT_NE(nullptr, context);
904
905net::zmq::socket send_socket{zmq_socket(context.get(), ZMQ_REQ)};
906net::zmq::socket recv_socket{zmq_socket(context.get(), ZMQ_REP)};
907ASSERT_NE(nullptr, send_socket);
908ASSERT_NE(nullptr, recv_socket);
909
910ASSERT_EQ(0u, zmq_bind(recv_socket.get(), "inproc://testing"));
911ASSERT_EQ(0u, zmq_connect(send_socket.get(), "inproc://testing"));
912
913std::string message;
914message.resize(999);
915crypto::rand(message.size(), reinterpret_cast<std::uint8_t*>(std::addressof(message[0])));
916
917for (unsigned i = 0; i < 3; ++i)
918{
919const expect<std::string> received = net::zmq::receive(recv_socket.get(), ZMQ_DONTWAIT);
920ASSERT_FALSE(bool(received));
921EXPECT_EQ(net::zmq::make_error_code(EAGAIN), received.error());
922
924 reinterpret_cast<const std::uint8_t*>(std::addressof(message[0])) + (i * 333), 333
925};
926ASSERT_TRUE(bool(net::zmq::send(bytes, send_socket.get(), (i == 2 ? 0 : ZMQ_SNDMORE))));
927}
928
929const expect<std::string> received = net::zmq::receive(recv_socket.get(), ZMQ_DONTWAIT);
930ASSERT_TRUE(bool(received));
931EXPECT_EQ(message, *received);
932}
Non-owning sequence of data. Does not deep copy.
Definition span.h:57
*return False if otherwise error()
Here is the call graph for this function:

◆ TEST() [26/26]

TEST ( zmq ,
read_write_termination  )

Definition at line 934 of file net.cpp.

935{
936net::zmq::context context{zmq_init(1)};
937ASSERT_NE(nullptr, context);
938
939// must be declared before sockets and after context
940boost::scoped_thread<> thread{};
941
942net::zmq::socket send_socket{zmq_socket(context.get(), ZMQ_REQ)};
943net::zmq::socket recv_socket{zmq_socket(context.get(), ZMQ_REP)};
944ASSERT_NE(nullptr, send_socket);
945ASSERT_NE(nullptr, recv_socket);
946
947ASSERT_EQ(0u, zmq_bind(recv_socket.get(), "inproc://testing"));
948ASSERT_EQ(0u, zmq_connect(send_socket.get(), "inproc://testing"));
949
950std::string message;
951message.resize(1024);
952crypto::rand(message.size(), reinterpret_cast<std::uint8_t*>(std::addressof(message[0])));
953
954ASSERT_TRUE(bool(net::zmq::send(epee::strspan<std::uint8_t>(message), send_socket.get(), ZMQ_SNDMORE)));
955
956expect<std::string> received = net::zmq::receive(recv_socket.get(), ZMQ_DONTWAIT);
957ASSERT_FALSE(bool(received));
958EXPECT_EQ(net::zmq::make_error_code(EAGAIN), received.error());
959
960thread = boost::scoped_thread<>{
961 boost::thread{
962 [&context] () { context.reset(); }
963 }
964};
965
966received = net::zmq::receive(recv_socket.get());
967ASSERT_FALSE(bool(received));
968EXPECT_EQ(net::zmq::make_error_code(ETERM), received.error());
969}
Here is the call graph for this function: