Skip to content

Commit b96cfae

Browse files
committed
change source port even if hopping test fails
1 parent b806002 commit b96cfae

File tree

3 files changed

+115
-133
lines changed

3 files changed

+115
-133
lines changed

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
int main(int argc, char *argv[])
1717
{
1818
#ifdef __cpp_lib_format
19-
std::cout << std::format("{} version 20241021\n", app_name);
19+
std::cout << std::format("{} version 20241026\n", app_name);
2020
if (argc <= 1)
2121
{
2222
std::cout << std::format("Usage: {} config1.conf\n", app_name);
2323
std::cout << std::format(" {} config1.conf config2.conf...\n", (int)app_name.length(), app_name.data());
2424
return 0;
2525
}
2626
#else
27-
std::cout << app_name << " version 20241021\n";
27+
std::cout << app_name << " version 20241026\n";
2828
if (argc <= 1)
2929
{
3030
std::cout << "Usage: " << app_name << " config1.conf\n";

src/networks/client.cpp

Lines changed: 57 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,12 @@ void client_mode::cleanup_expiring_forwarders()
498498

499499
int64_t time_elapsed = calculate_difference(time_right_now, expire_time);
500500

501-
if (time_elapsed > CLEANUP_WAITS / 2 &&
501+
if (time_elapsed > CLEANUP_WAITS / 3 &&
502+
time_elapsed <= CLEANUP_WAITS / 3 * 2 &&
503+
forwarder_ptr != nullptr)
504+
forwarder_ptr->pause(true);
505+
506+
if (time_elapsed > CLEANUP_WAITS / 3 * 2 &&
502507
forwarder_ptr != nullptr)
503508
forwarder_ptr->stop();
504509

@@ -556,7 +561,7 @@ void client_mode::loop_timeout_sessions()
556561

557562
std::shared_ptr<forwarder> egress_forwarder = std::atomic_load(&(udp_session_ptr->egress_forwarder));
558563
old_forwarders.push_back(egress_forwarder);
559-
egress_forwarder->stop();
564+
egress_forwarder->pause(true);
560565
#if __GNUC__ == 12 && __GNUC_MINOR__ < 3
561566
udp_session_ptr->egress_forwarder.store(nullptr);
562567
#else
@@ -691,84 +696,69 @@ void client_mode::test_before_change(std::shared_ptr<udp_mappings> udp_mappings_
691696
uint16_t destination_port_end = current_settings.destination_port_end;
692697
asio::error_code ec;
693698

694-
if (std::shared_ptr<forwarder> egress_hopping_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
695-
egress_hopping_forwarder == nullptr || destination_port_start == destination_port_end)
699+
std::shared_ptr<forwarder> udp_forwarder = nullptr;
700+
try
696701
{
697-
std::shared_ptr<forwarder> udp_forwarder = nullptr;
698-
try
699-
{
700-
auto bind_push_func = std::bind(&ttp::task_group_pool::push_task_peer, &sequence_task_pool, _1, _2, _3);
701-
auto bind_check_limit_func = [this](size_t number) -> bool {return sequence_task_pool.get_peer_network_task_count(number) > TASK_COUNT_LIMIT; };
702-
auto udp_func = std::bind(&client_mode::udp_forwarder_incoming_to_udp, this, _1, _2, _3, _4, _5);
703-
udp_forwarder = std::make_shared<forwarder>(io_context, bind_push_func, bind_check_limit_func, udp_mappings_ptr, udp_func, current_settings.ip_version_only);
704-
if (udp_forwarder == nullptr)
705-
{
706-
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
707-
return;
708-
}
709-
}
710-
catch (std::exception &ex)
711-
{
712-
std::string error_message = time_to_string_with_square_brackets() + "Cannot switch to new port, error: " + ex.what() + "\n";
713-
std::cerr << error_message;
714-
print_message_to_file(error_message, current_settings.log_messages);
715-
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
716-
return;
717-
}
718-
719-
std::shared_ptr<udp::endpoint> egress_target_endpoint = std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint));
720-
if (destination_port_start == destination_port_end)
721-
{
722-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*egress_target_endpoint));
723-
}
724-
else
725-
{
726-
uint16_t current_port_number = egress_target_endpoint->port();
727-
uint16_t new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
728-
for (size_t retry_times = 0; new_port_numer == current_port_number && retry_times < RETRY_TIMES; retry_times++)
729-
{
730-
new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
731-
}
732-
std::shared_ptr<asio::ip::address> target = std::atomic_load(&(target_address));
733-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*target, new_port_numer));
734-
}
735-
736-
std::shared_ptr<forwarder> new_forwarder = udp_forwarder;
737-
std::vector<uint8_t> keep_alive_packet = create_empty_data(current_settings.encryption_password, current_settings.encryption, EMPTY_PACKET_SIZE);
738-
udp_mappings_ptr->wrapper_ptr->write_iden(keep_alive_packet.data());
739-
740-
if (current_settings.ip_version_only == ip_only_options::ipv4)
741-
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v4, ec);
742-
else
743-
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v6, ec);
744-
745-
if (ec)
702+
auto bind_push_func = std::bind(&ttp::task_group_pool::push_task_peer, &sequence_task_pool, _1, _2, _3);
703+
auto bind_check_limit_func = [this](size_t number) -> bool {return sequence_task_pool.get_peer_network_task_count(number) > TASK_COUNT_LIMIT; };
704+
auto udp_func = std::bind(&client_mode::udp_forwarder_incoming_to_udp, this, _1, _2, _3, _4, _5);
705+
udp_forwarder = std::make_shared<forwarder>(io_context, bind_push_func, bind_check_limit_func, udp_mappings_ptr, udp_func, current_settings.ip_version_only);
706+
if (udp_forwarder == nullptr)
746707
{
747708
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
748709
return;
749710
}
711+
}
712+
catch (std::exception &ex)
713+
{
714+
std::string error_message = time_to_string_with_square_brackets() + "Cannot switch to new port, error: " + ex.what() + "\n";
715+
std::cerr << error_message;
716+
print_message_to_file(error_message, current_settings.log_messages);
717+
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
718+
return;
719+
}
750720

751-
new_forwarder->async_receive();
752-
if (egress_hopping_forwarder != nullptr)
753-
{
754-
egress_hopping_forwarder->pause(true);
755-
std::scoped_lock lock_expiring_forwarders{ mutex_expiring_forwarders };
756-
expiring_forwarders[egress_hopping_forwarder] = right_now();
757-
}
758-
std::atomic_store(&(udp_mappings_ptr->egress_hopping_forwarder), new_forwarder);
721+
std::shared_ptr<udp::endpoint> egress_target_endpoint = std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint));
722+
if (destination_port_start == destination_port_end)
723+
{
724+
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*egress_target_endpoint));
759725
}
760726
else
761727
{
762-
std::shared_ptr<udp::endpoint> hopping_endpoint = std::atomic_load(&(udp_mappings_ptr->hopping_endpoint));
763-
uint16_t current_port_number = hopping_endpoint->port();
728+
uint16_t current_port_number = egress_target_endpoint->port();
764729
uint16_t new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
765730
for (size_t retry_times = 0; new_port_numer == current_port_number && retry_times < RETRY_TIMES; retry_times++)
766731
{
767732
new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
768733
}
769-
hopping_endpoint->port(new_port_numer);
770-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), hopping_endpoint);
734+
std::shared_ptr<asio::ip::address> target = std::atomic_load(&(target_address));
735+
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*target, new_port_numer));
736+
}
737+
738+
std::shared_ptr<forwarder> new_forwarder = udp_forwarder;
739+
std::vector<uint8_t> keep_alive_packet = create_empty_data(current_settings.encryption_password, current_settings.encryption, EMPTY_PACKET_SIZE);
740+
udp_mappings_ptr->wrapper_ptr->write_iden(keep_alive_packet.data());
741+
742+
if (current_settings.ip_version_only == ip_only_options::ipv4)
743+
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v4, ec);
744+
else
745+
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v6, ec);
746+
747+
if (ec)
748+
{
749+
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
750+
return;
751+
}
752+
753+
new_forwarder->async_receive();
754+
if (std::shared_ptr<forwarder> egress_hopping_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
755+
egress_hopping_forwarder != nullptr)
756+
{
757+
egress_hopping_forwarder->pause(true);
758+
std::scoped_lock lock_expiring_forwarders{ mutex_expiring_forwarders };
759+
expiring_forwarders[egress_hopping_forwarder] = right_now();
771760
}
761+
std::atomic_store(&(udp_mappings_ptr->egress_hopping_forwarder), new_forwarder);
772762

773763
udp_mappings_ptr->hopping_available.store(hop_status::testing);
774764
udp_mappings *udp_session_ptr = udp_mappings_ptr.get();
@@ -788,8 +778,9 @@ void client_mode::switch_new_port(std::shared_ptr<udp_mappings> udp_mappings_ptr
788778
udp_mappings_ptr->hopping_timestamp.store(right_now() + current_settings.dynamic_port_refresh);
789779
udp_mappings_ptr->hopping_available.store(hop_status::pending);
790780

781+
std::shared_ptr<udp::endpoint> hopping_endpoint = std::atomic_load(&(udp_mappings_ptr->hopping_endpoint));
791782
std::atomic_store(&(udp_mappings_ptr->egress_previous_target_endpoint), std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint)));
792-
std::atomic_store(&(udp_mappings_ptr->egress_target_endpoint), std::make_shared<udp::endpoint>(*std::atomic_load(&(udp_mappings_ptr->hopping_endpoint))));
783+
std::atomic_store(&(udp_mappings_ptr->egress_target_endpoint), std::make_shared<udp::endpoint>(*hopping_endpoint));
793784

794785
std::shared_ptr<forwarder> new_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
795786
std::shared_ptr<forwarder> old_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_forwarder));

src/networks/relay.cpp

Lines changed: 56 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,12 @@ void relay_mode::cleanup_expiring_data_connections()
747747
int64_t time_elapsed = calculate_difference(time_right_now, expire_time);
748748
std::shared_ptr<forwarder> egress_forwarder = std::atomic_load(&udp_session_ptr->egress_forwarder);
749749

750-
if (time_elapsed > CLEANUP_WAITS / 2 &&
750+
if (time_elapsed > CLEANUP_WAITS / 3 &&
751+
time_elapsed <= CLEANUP_WAITS / 3 * 2 &&
752+
egress_forwarder != nullptr)
753+
egress_forwarder->pause(true);
754+
755+
if (time_elapsed > CLEANUP_WAITS / 3 * 2 &&
751756
egress_forwarder != nullptr)
752757
egress_forwarder->stop();
753758

@@ -984,84 +989,69 @@ void relay_mode::test_before_change(std::shared_ptr<udp_mappings> udp_mappings_p
984989
uint16_t destination_port_end = current_settings.egress->destination_port_end;
985990
asio::error_code ec;
986991

987-
if (std::shared_ptr<forwarder> egress_hopping_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
988-
egress_hopping_forwarder == nullptr || destination_port_start == destination_port_end)
992+
std::shared_ptr<forwarder> udp_forwarder = nullptr;
993+
try
989994
{
990-
std::shared_ptr<forwarder> udp_forwarder = nullptr;
991-
try
992-
{
993-
auto bind_push_func = std::bind(&ttp::task_group_pool::push_task_peer, &sequence_task_pool, _1, _2, _3);
994-
auto bind_check_limit_func = [this](size_t number) -> bool {return sequence_task_pool.get_peer_network_task_count(number) > TASK_COUNT_LIMIT; };
995-
auto udp_func = std::bind(&relay_mode::udp_forwarder_incoming_to_udp, this, _1, _2, _3, _4, _5);
996-
udp_forwarder = std::make_shared<forwarder>(io_context, bind_push_func, bind_check_limit_func, udp_mappings_ptr, udp_func, current_settings.egress->ip_version_only);
997-
if (udp_forwarder == nullptr)
998-
{
999-
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
1000-
return;
1001-
}
1002-
}
1003-
catch (std::exception &ex)
1004-
{
1005-
std::string error_message = time_to_string_with_square_brackets() + "Cannot switch to new port, error: " + ex.what() + "\n";
1006-
std::cerr << error_message;
1007-
print_message_to_file(error_message, current_settings.log_messages);
1008-
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
1009-
return;
1010-
}
1011-
1012-
std::shared_ptr<udp::endpoint> egress_target_endpoint = std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint));
1013-
if (destination_port_start == destination_port_end)
1014-
{
1015-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*egress_target_endpoint));
1016-
}
1017-
else
1018-
{
1019-
uint16_t current_port_number = egress_target_endpoint->port();
1020-
uint16_t new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
1021-
for (size_t retry_times = 0; new_port_numer == current_port_number && retry_times < RETRY_TIMES; retry_times++)
1022-
{
1023-
new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
1024-
}
1025-
std::shared_ptr<asio::ip::address> target = std::atomic_load(&(target_address));
1026-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*target, new_port_numer));
1027-
}
1028-
1029-
std::shared_ptr<forwarder> new_forwarder = udp_forwarder;
1030-
std::vector<uint8_t> keep_alive_packet = create_empty_data(current_settings.egress->encryption_password, current_settings.egress->encryption, EMPTY_PACKET_SIZE);
1031-
udp_mappings_ptr->wrapper_ptr->write_iden(keep_alive_packet.data());
1032-
1033-
if (current_settings.egress->ip_version_only == ip_only_options::ipv4)
1034-
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v4, ec);
1035-
else
1036-
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v6, ec);
1037-
1038-
if (ec)
995+
auto bind_push_func = std::bind(&ttp::task_group_pool::push_task_peer, &sequence_task_pool, _1, _2, _3);
996+
auto bind_check_limit_func = [this](size_t number) -> bool {return sequence_task_pool.get_peer_network_task_count(number) > TASK_COUNT_LIMIT; };
997+
auto udp_func = std::bind(&relay_mode::udp_forwarder_incoming_to_udp, this, _1, _2, _3, _4, _5);
998+
udp_forwarder = std::make_shared<forwarder>(io_context, bind_push_func, bind_check_limit_func, udp_mappings_ptr, udp_func, current_settings.egress->ip_version_only);
999+
if (udp_forwarder == nullptr)
10391000
{
10401001
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
10411002
return;
10421003
}
1004+
}
1005+
catch (std::exception &ex)
1006+
{
1007+
std::string error_message = time_to_string_with_square_brackets() + "Cannot switch to new port, error: " + ex.what() + "\n";
1008+
std::cerr << error_message;
1009+
print_message_to_file(error_message, current_settings.log_messages);
1010+
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
1011+
return;
1012+
}
10431013

1044-
new_forwarder->async_receive();
1045-
if (egress_hopping_forwarder != nullptr)
1046-
{
1047-
egress_hopping_forwarder->pause(true);
1048-
std::scoped_lock lock_expiring_forwarders{ mutex_expiring_forwarders };
1049-
expiring_forwarders[egress_hopping_forwarder] = right_now();
1050-
}
1051-
std::atomic_store(&(udp_mappings_ptr->egress_hopping_forwarder), new_forwarder);
1014+
std::shared_ptr<udp::endpoint> egress_target_endpoint = std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint));
1015+
if (destination_port_start == destination_port_end)
1016+
{
1017+
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*egress_target_endpoint));
10521018
}
10531019
else
10541020
{
1055-
std::shared_ptr<udp::endpoint> hopping_endpoint = std::atomic_load(&(udp_mappings_ptr->hopping_endpoint));
1056-
uint16_t current_port_number = hopping_endpoint->port();
1021+
uint16_t current_port_number = egress_target_endpoint->port();
10571022
uint16_t new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
10581023
for (size_t retry_times = 0; new_port_numer == current_port_number && retry_times < RETRY_TIMES; retry_times++)
10591024
{
10601025
new_port_numer = generate_new_port_number(destination_port_start, destination_port_end);
10611026
}
1062-
hopping_endpoint->port(new_port_numer);
1063-
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), hopping_endpoint);
1027+
std::shared_ptr<asio::ip::address> target = std::atomic_load(&(target_address));
1028+
std::atomic_store(&(udp_mappings_ptr->hopping_endpoint), std::make_shared<udp::endpoint>(*target, new_port_numer));
1029+
}
1030+
1031+
std::shared_ptr<forwarder> new_forwarder = udp_forwarder;
1032+
std::vector<uint8_t> keep_alive_packet = create_empty_data(current_settings.egress->encryption_password, current_settings.egress->encryption, EMPTY_PACKET_SIZE);
1033+
udp_mappings_ptr->wrapper_ptr->write_iden(keep_alive_packet.data());
1034+
1035+
if (current_settings.egress->ip_version_only == ip_only_options::ipv4)
1036+
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v4, ec);
1037+
else
1038+
new_forwarder->send_out(std::move(keep_alive_packet), local_empty_target_v6, ec);
1039+
1040+
if (ec)
1041+
{
1042+
udp_mappings_ptr->hopping_timestamp.store(time_right_now + current_settings.dynamic_port_refresh);
1043+
return;
1044+
}
1045+
1046+
new_forwarder->async_receive();
1047+
if (std::shared_ptr<forwarder> egress_hopping_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
1048+
egress_hopping_forwarder != nullptr)
1049+
{
1050+
egress_hopping_forwarder->pause(true);
1051+
std::scoped_lock lock_expiring_forwarders{ mutex_expiring_forwarders };
1052+
expiring_forwarders[egress_hopping_forwarder] = right_now();
10641053
}
1054+
std::atomic_store(&(udp_mappings_ptr->egress_hopping_forwarder), new_forwarder);
10651055

10661056
udp_mappings_ptr->hopping_available.store(hop_status::testing);
10671057

@@ -1082,8 +1072,9 @@ void relay_mode::switch_new_port(std::shared_ptr<udp_mappings> udp_mappings_ptr)
10821072
udp_mappings_ptr->hopping_timestamp.store(right_now() + current_settings.dynamic_port_refresh);
10831073
udp_mappings_ptr->hopping_available.store(hop_status::pending);
10841074

1075+
std::shared_ptr<udp::endpoint> hopping_endpoint = std::atomic_load(&(udp_mappings_ptr->hopping_endpoint));
10851076
std::atomic_store(&(udp_mappings_ptr->egress_previous_target_endpoint), std::atomic_load(&(udp_mappings_ptr->egress_target_endpoint)));
1086-
std::atomic_store(&(udp_mappings_ptr->egress_target_endpoint), std::make_shared<udp::endpoint>(*std::atomic_load(&(udp_mappings_ptr->hopping_endpoint))));
1077+
std::atomic_store(&(udp_mappings_ptr->egress_target_endpoint), std::make_shared<udp::endpoint>(*hopping_endpoint));
10871078

10881079
std::shared_ptr<forwarder> new_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_hopping_forwarder));
10891080
std::shared_ptr<forwarder> old_forwarder = std::atomic_load(&(udp_mappings_ptr->egress_forwarder));

0 commit comments

Comments
 (0)