├── .clang-format ├── .github └── workflows │ ├── docker-image.yml │ └── release.yml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── config.json ├── docker ├── Dockerfile └── docker-compose.yml ├── include ├── common │ ├── common.h │ ├── logger.h │ └── socks5_type.h ├── option │ └── parser.h ├── server │ └── socks5_server.h ├── session │ └── socks5_session.h ├── socks_server.h └── util │ └── io_context_pool.h ├── main.cpp ├── src ├── common │ ├── common.cpp │ └── logger.cpp ├── option │ └── parser.cpp ├── server │ └── socks5_server.cpp ├── session │ └── socks5_session.cpp └── util │ └── io_context_pool.cpp └── third-party ├── asio-1.24.0 └── include │ ├── asio.hpp │ └── asio │ ├── any_io_executor.hpp │ ├── append.hpp │ ├── as_tuple.hpp │ ├── associated_allocator.hpp │ ├── associated_cancellation_slot.hpp │ ├── associated_executor.hpp │ ├── associator.hpp │ ├── async_result.hpp │ ├── awaitable.hpp │ ├── basic_datagram_socket.hpp │ ├── basic_deadline_timer.hpp │ ├── basic_file.hpp │ ├── basic_io_object.hpp │ ├── basic_random_access_file.hpp │ ├── basic_raw_socket.hpp │ ├── basic_readable_pipe.hpp │ ├── basic_seq_packet_socket.hpp │ ├── basic_serial_port.hpp │ ├── basic_signal_set.hpp │ ├── basic_socket.hpp │ ├── basic_socket_acceptor.hpp │ ├── basic_socket_iostream.hpp │ ├── basic_socket_streambuf.hpp │ ├── basic_stream_file.hpp │ ├── basic_stream_socket.hpp │ ├── basic_streambuf.hpp │ ├── basic_streambuf_fwd.hpp │ ├── basic_waitable_timer.hpp │ ├── basic_writable_pipe.hpp │ ├── bind_allocator.hpp │ ├── bind_cancellation_slot.hpp │ ├── bind_executor.hpp │ ├── buffer.hpp │ ├── buffer_registration.hpp │ ├── buffered_read_stream.hpp │ ├── buffered_read_stream_fwd.hpp │ ├── buffered_stream.hpp │ ├── buffered_stream_fwd.hpp │ ├── buffered_write_stream.hpp │ ├── buffered_write_stream_fwd.hpp │ ├── buffers_iterator.hpp │ ├── cancellation_signal.hpp │ ├── cancellation_state.hpp │ ├── cancellation_type.hpp │ ├── co_spawn.hpp │ ├── completion_condition.hpp │ ├── compose.hpp │ ├── connect.hpp │ ├── connect_pipe.hpp │ ├── coroutine.hpp │ ├── deadline_timer.hpp │ ├── defer.hpp │ ├── deferred.hpp │ ├── detached.hpp │ ├── detail │ ├── array.hpp │ ├── array_fwd.hpp │ ├── assert.hpp │ ├── atomic_count.hpp │ ├── base_from_cancellation_state.hpp │ ├── base_from_completion_cond.hpp │ ├── bind_handler.hpp │ ├── blocking_executor_op.hpp │ ├── buffer_resize_guard.hpp │ ├── buffer_sequence_adapter.hpp │ ├── buffered_stream_storage.hpp │ ├── bulk_executor_op.hpp │ ├── call_stack.hpp │ ├── chrono.hpp │ ├── chrono_time_traits.hpp │ ├── completion_handler.hpp │ ├── concurrency_hint.hpp │ ├── conditionally_enabled_event.hpp │ ├── conditionally_enabled_mutex.hpp │ ├── config.hpp │ ├── consuming_buffers.hpp │ ├── cstddef.hpp │ ├── cstdint.hpp │ ├── date_time_fwd.hpp │ ├── deadline_timer_service.hpp │ ├── dependent_type.hpp │ ├── descriptor_ops.hpp │ ├── descriptor_read_op.hpp │ ├── descriptor_write_op.hpp │ ├── dev_poll_reactor.hpp │ ├── epoll_reactor.hpp │ ├── event.hpp │ ├── eventfd_select_interrupter.hpp │ ├── exception.hpp │ ├── executor_function.hpp │ ├── executor_op.hpp │ ├── fd_set_adapter.hpp │ ├── fenced_block.hpp │ ├── functional.hpp │ ├── future.hpp │ ├── gcc_arm_fenced_block.hpp │ ├── gcc_hppa_fenced_block.hpp │ ├── gcc_sync_fenced_block.hpp │ ├── gcc_x86_fenced_block.hpp │ ├── global.hpp │ ├── handler_alloc_helpers.hpp │ ├── handler_cont_helpers.hpp │ ├── handler_invoke_helpers.hpp │ ├── handler_tracking.hpp │ ├── handler_type_requirements.hpp │ ├── handler_work.hpp │ ├── hash_map.hpp │ ├── impl │ │ ├── buffer_sequence_adapter.ipp │ │ ├── descriptor_ops.ipp │ │ ├── dev_poll_reactor.hpp │ │ ├── dev_poll_reactor.ipp │ │ ├── epoll_reactor.hpp │ │ ├── epoll_reactor.ipp │ │ ├── eventfd_select_interrupter.ipp │ │ ├── handler_tracking.ipp │ │ ├── io_uring_descriptor_service.ipp │ │ ├── io_uring_file_service.ipp │ │ ├── io_uring_service.hpp │ │ ├── io_uring_service.ipp │ │ ├── io_uring_socket_service_base.ipp │ │ ├── kqueue_reactor.hpp │ │ ├── kqueue_reactor.ipp │ │ ├── null_event.ipp │ │ ├── pipe_select_interrupter.ipp │ │ ├── posix_event.ipp │ │ ├── posix_mutex.ipp │ │ ├── posix_serial_port_service.ipp │ │ ├── posix_thread.ipp │ │ ├── posix_tss_ptr.ipp │ │ ├── reactive_descriptor_service.ipp │ │ ├── reactive_socket_service_base.ipp │ │ ├── resolver_service_base.ipp │ │ ├── scheduler.ipp │ │ ├── select_reactor.hpp │ │ ├── select_reactor.ipp │ │ ├── service_registry.hpp │ │ ├── service_registry.ipp │ │ ├── signal_set_service.ipp │ │ ├── socket_ops.ipp │ │ ├── socket_select_interrupter.ipp │ │ ├── strand_executor_service.hpp │ │ ├── strand_executor_service.ipp │ │ ├── strand_service.hpp │ │ ├── strand_service.ipp │ │ ├── thread_context.ipp │ │ ├── throw_error.ipp │ │ ├── timer_queue_ptime.ipp │ │ ├── timer_queue_set.ipp │ │ ├── win_event.ipp │ │ ├── win_iocp_file_service.ipp │ │ ├── win_iocp_handle_service.ipp │ │ ├── win_iocp_io_context.hpp │ │ ├── win_iocp_io_context.ipp │ │ ├── win_iocp_serial_port_service.ipp │ │ ├── win_iocp_socket_service_base.ipp │ │ ├── win_mutex.ipp │ │ ├── win_object_handle_service.ipp │ │ ├── win_static_mutex.ipp │ │ ├── win_thread.ipp │ │ ├── win_tss_ptr.ipp │ │ ├── winrt_ssocket_service_base.ipp │ │ ├── winrt_timer_scheduler.hpp │ │ ├── winrt_timer_scheduler.ipp │ │ └── winsock_init.ipp │ ├── io_control.hpp │ ├── io_object_impl.hpp │ ├── io_uring_descriptor_read_at_op.hpp │ ├── io_uring_descriptor_read_op.hpp │ ├── io_uring_descriptor_service.hpp │ ├── io_uring_descriptor_write_at_op.hpp │ ├── io_uring_descriptor_write_op.hpp │ ├── io_uring_file_service.hpp │ ├── io_uring_null_buffers_op.hpp │ ├── io_uring_operation.hpp │ ├── io_uring_service.hpp │ ├── io_uring_socket_accept_op.hpp │ ├── io_uring_socket_connect_op.hpp │ ├── io_uring_socket_recv_op.hpp │ ├── io_uring_socket_recvfrom_op.hpp │ ├── io_uring_socket_recvmsg_op.hpp │ ├── io_uring_socket_send_op.hpp │ ├── io_uring_socket_sendto_op.hpp │ ├── io_uring_socket_service.hpp │ ├── io_uring_socket_service_base.hpp │ ├── io_uring_wait_op.hpp │ ├── is_buffer_sequence.hpp │ ├── is_executor.hpp │ ├── keyword_tss_ptr.hpp │ ├── kqueue_reactor.hpp │ ├── limits.hpp │ ├── local_free_on_block_exit.hpp │ ├── macos_fenced_block.hpp │ ├── memory.hpp │ ├── mutex.hpp │ ├── non_const_lvalue.hpp │ ├── noncopyable.hpp │ ├── null_event.hpp │ ├── null_fenced_block.hpp │ ├── null_global.hpp │ ├── null_mutex.hpp │ ├── null_reactor.hpp │ ├── null_signal_blocker.hpp │ ├── null_socket_service.hpp │ ├── null_static_mutex.hpp │ ├── null_thread.hpp │ ├── null_tss_ptr.hpp │ ├── object_pool.hpp │ ├── old_win_sdk_compat.hpp │ ├── op_queue.hpp │ ├── operation.hpp │ ├── pipe_select_interrupter.hpp │ ├── pop_options.hpp │ ├── posix_event.hpp │ ├── posix_fd_set_adapter.hpp │ ├── posix_global.hpp │ ├── posix_mutex.hpp │ ├── posix_serial_port_service.hpp │ ├── posix_signal_blocker.hpp │ ├── posix_static_mutex.hpp │ ├── posix_thread.hpp │ ├── posix_tss_ptr.hpp │ ├── push_options.hpp │ ├── reactive_descriptor_service.hpp │ ├── reactive_null_buffers_op.hpp │ ├── reactive_socket_accept_op.hpp │ ├── reactive_socket_connect_op.hpp │ ├── reactive_socket_recv_op.hpp │ ├── reactive_socket_recvfrom_op.hpp │ ├── reactive_socket_recvmsg_op.hpp │ ├── reactive_socket_send_op.hpp │ ├── reactive_socket_sendto_op.hpp │ ├── reactive_socket_service.hpp │ ├── reactive_socket_service_base.hpp │ ├── reactive_wait_op.hpp │ ├── reactor.hpp │ ├── reactor_op.hpp │ ├── reactor_op_queue.hpp │ ├── recycling_allocator.hpp │ ├── regex_fwd.hpp │ ├── resolve_endpoint_op.hpp │ ├── resolve_op.hpp │ ├── resolve_query_op.hpp │ ├── resolver_service.hpp │ ├── resolver_service_base.hpp │ ├── scheduler.hpp │ ├── scheduler_operation.hpp │ ├── scheduler_task.hpp │ ├── scheduler_thread_info.hpp │ ├── scoped_lock.hpp │ ├── scoped_ptr.hpp │ ├── select_interrupter.hpp │ ├── select_reactor.hpp │ ├── service_registry.hpp │ ├── signal_blocker.hpp │ ├── signal_handler.hpp │ ├── signal_init.hpp │ ├── signal_op.hpp │ ├── signal_set_service.hpp │ ├── socket_holder.hpp │ ├── socket_ops.hpp │ ├── socket_option.hpp │ ├── socket_select_interrupter.hpp │ ├── socket_types.hpp │ ├── solaris_fenced_block.hpp │ ├── source_location.hpp │ ├── static_mutex.hpp │ ├── std_event.hpp │ ├── std_fenced_block.hpp │ ├── std_global.hpp │ ├── std_mutex.hpp │ ├── std_static_mutex.hpp │ ├── std_thread.hpp │ ├── strand_executor_service.hpp │ ├── strand_service.hpp │ ├── string_view.hpp │ ├── thread.hpp │ ├── thread_context.hpp │ ├── thread_group.hpp │ ├── thread_info_base.hpp │ ├── throw_error.hpp │ ├── throw_exception.hpp │ ├── timer_queue.hpp │ ├── timer_queue_base.hpp │ ├── timer_queue_ptime.hpp │ ├── timer_queue_set.hpp │ ├── timer_scheduler.hpp │ ├── timer_scheduler_fwd.hpp │ ├── tss_ptr.hpp │ ├── type_traits.hpp │ ├── utility.hpp │ ├── variadic_templates.hpp │ ├── wait_handler.hpp │ ├── wait_op.hpp │ ├── win_event.hpp │ ├── win_fd_set_adapter.hpp │ ├── win_fenced_block.hpp │ ├── win_global.hpp │ ├── win_iocp_file_service.hpp │ ├── win_iocp_handle_read_op.hpp │ ├── win_iocp_handle_service.hpp │ ├── win_iocp_handle_write_op.hpp │ ├── win_iocp_io_context.hpp │ ├── win_iocp_null_buffers_op.hpp │ ├── win_iocp_operation.hpp │ ├── win_iocp_overlapped_op.hpp │ ├── win_iocp_overlapped_ptr.hpp │ ├── win_iocp_serial_port_service.hpp │ ├── win_iocp_socket_accept_op.hpp │ ├── win_iocp_socket_connect_op.hpp │ ├── win_iocp_socket_recv_op.hpp │ ├── win_iocp_socket_recvfrom_op.hpp │ ├── win_iocp_socket_recvmsg_op.hpp │ ├── win_iocp_socket_send_op.hpp │ ├── win_iocp_socket_service.hpp │ ├── win_iocp_socket_service_base.hpp │ ├── win_iocp_thread_info.hpp │ ├── win_iocp_wait_op.hpp │ ├── win_mutex.hpp │ ├── win_object_handle_service.hpp │ ├── win_static_mutex.hpp │ ├── win_thread.hpp │ ├── win_tss_ptr.hpp │ ├── winapp_thread.hpp │ ├── wince_thread.hpp │ ├── winrt_async_manager.hpp │ ├── winrt_async_op.hpp │ ├── winrt_resolve_op.hpp │ ├── winrt_resolver_service.hpp │ ├── winrt_socket_connect_op.hpp │ ├── winrt_socket_recv_op.hpp │ ├── winrt_socket_send_op.hpp │ ├── winrt_ssocket_service.hpp │ ├── winrt_ssocket_service_base.hpp │ ├── winrt_timer_scheduler.hpp │ ├── winrt_utils.hpp │ ├── winsock_init.hpp │ ├── work_dispatcher.hpp │ └── wrapped_handler.hpp │ ├── dispatch.hpp │ ├── error.hpp │ ├── error_code.hpp │ ├── execution.hpp │ ├── execution │ ├── allocator.hpp │ ├── any_executor.hpp │ ├── bad_executor.hpp │ ├── blocking.hpp │ ├── blocking_adaptation.hpp │ ├── bulk_execute.hpp │ ├── bulk_guarantee.hpp │ ├── connect.hpp │ ├── context.hpp │ ├── context_as.hpp │ ├── detail │ │ ├── as_invocable.hpp │ │ ├── as_operation.hpp │ │ ├── as_receiver.hpp │ │ ├── bulk_sender.hpp │ │ ├── submit_receiver.hpp │ │ └── void_receiver.hpp │ ├── execute.hpp │ ├── executor.hpp │ ├── impl │ │ ├── bad_executor.ipp │ │ └── receiver_invocation_error.ipp │ ├── invocable_archetype.hpp │ ├── mapping.hpp │ ├── occupancy.hpp │ ├── operation_state.hpp │ ├── outstanding_work.hpp │ ├── prefer_only.hpp │ ├── receiver.hpp │ ├── receiver_invocation_error.hpp │ ├── relationship.hpp │ ├── schedule.hpp │ ├── scheduler.hpp │ ├── sender.hpp │ ├── set_done.hpp │ ├── set_error.hpp │ ├── set_value.hpp │ ├── start.hpp │ └── submit.hpp │ ├── execution_context.hpp │ ├── executor.hpp │ ├── executor_work_guard.hpp │ ├── experimental │ ├── append.hpp │ ├── as_single.hpp │ ├── as_tuple.hpp │ ├── awaitable_operators.hpp │ ├── basic_channel.hpp │ ├── basic_concurrent_channel.hpp │ ├── cancellation_condition.hpp │ ├── channel.hpp │ ├── channel_error.hpp │ ├── channel_traits.hpp │ ├── co_spawn.hpp │ ├── concurrent_channel.hpp │ ├── coro.hpp │ ├── coro_traits.hpp │ ├── deferred.hpp │ ├── detail │ │ ├── channel_handler.hpp │ │ ├── channel_message.hpp │ │ ├── channel_operation.hpp │ │ ├── channel_payload.hpp │ │ ├── channel_receive_op.hpp │ │ ├── channel_send_functions.hpp │ │ ├── channel_send_op.hpp │ │ ├── channel_service.hpp │ │ ├── completion_handler_erasure.hpp │ │ ├── coro_promise_allocator.hpp │ │ ├── has_signature.hpp │ │ ├── impl │ │ │ └── channel_service.hpp │ │ └── partial_promise.hpp │ ├── impl │ │ ├── as_single.hpp │ │ ├── channel_error.ipp │ │ ├── coro.hpp │ │ ├── parallel_group.hpp │ │ ├── promise.hpp │ │ └── use_coro.hpp │ ├── parallel_group.hpp │ ├── prepend.hpp │ ├── promise.hpp │ └── use_coro.hpp │ ├── file_base.hpp │ ├── generic │ ├── basic_endpoint.hpp │ ├── datagram_protocol.hpp │ ├── detail │ │ ├── endpoint.hpp │ │ └── impl │ │ │ └── endpoint.ipp │ ├── raw_protocol.hpp │ ├── seq_packet_protocol.hpp │ └── stream_protocol.hpp │ ├── handler_alloc_hook.hpp │ ├── handler_continuation_hook.hpp │ ├── handler_invoke_hook.hpp │ ├── high_resolution_timer.hpp │ ├── impl │ ├── any_io_executor.ipp │ ├── append.hpp │ ├── as_tuple.hpp │ ├── awaitable.hpp │ ├── buffered_read_stream.hpp │ ├── buffered_write_stream.hpp │ ├── cancellation_signal.ipp │ ├── co_spawn.hpp │ ├── connect.hpp │ ├── connect_pipe.hpp │ ├── connect_pipe.ipp │ ├── defer.hpp │ ├── deferred.hpp │ ├── detached.hpp │ ├── dispatch.hpp │ ├── error.ipp │ ├── error_code.ipp │ ├── execution_context.hpp │ ├── execution_context.ipp │ ├── executor.hpp │ ├── executor.ipp │ ├── handler_alloc_hook.ipp │ ├── io_context.hpp │ ├── io_context.ipp │ ├── multiple_exceptions.ipp │ ├── post.hpp │ ├── prepend.hpp │ ├── read.hpp │ ├── read_at.hpp │ ├── read_until.hpp │ ├── redirect_error.hpp │ ├── serial_port_base.hpp │ ├── serial_port_base.ipp │ ├── spawn.hpp │ ├── src.hpp │ ├── system_context.hpp │ ├── system_context.ipp │ ├── system_executor.hpp │ ├── thread_pool.hpp │ ├── thread_pool.ipp │ ├── use_awaitable.hpp │ ├── use_future.hpp │ ├── write.hpp │ └── write_at.hpp │ ├── io_context.hpp │ ├── io_context_strand.hpp │ ├── io_service.hpp │ ├── io_service_strand.hpp │ ├── ip │ ├── address.hpp │ ├── address_v4.hpp │ ├── address_v4_iterator.hpp │ ├── address_v4_range.hpp │ ├── address_v6.hpp │ ├── address_v6_iterator.hpp │ ├── address_v6_range.hpp │ ├── bad_address_cast.hpp │ ├── basic_endpoint.hpp │ ├── basic_resolver.hpp │ ├── basic_resolver_entry.hpp │ ├── basic_resolver_iterator.hpp │ ├── basic_resolver_query.hpp │ ├── basic_resolver_results.hpp │ ├── detail │ │ ├── endpoint.hpp │ │ ├── impl │ │ │ └── endpoint.ipp │ │ └── socket_option.hpp │ ├── host_name.hpp │ ├── icmp.hpp │ ├── impl │ │ ├── address.hpp │ │ ├── address.ipp │ │ ├── address_v4.hpp │ │ ├── address_v4.ipp │ │ ├── address_v6.hpp │ │ ├── address_v6.ipp │ │ ├── basic_endpoint.hpp │ │ ├── host_name.ipp │ │ ├── network_v4.hpp │ │ ├── network_v4.ipp │ │ ├── network_v6.hpp │ │ └── network_v6.ipp │ ├── multicast.hpp │ ├── network_v4.hpp │ ├── network_v6.hpp │ ├── resolver_base.hpp │ ├── resolver_query_base.hpp │ ├── tcp.hpp │ ├── udp.hpp │ ├── unicast.hpp │ └── v6_only.hpp │ ├── is_applicable_property.hpp │ ├── is_contiguous_iterator.hpp │ ├── is_executor.hpp │ ├── is_read_buffered.hpp │ ├── is_write_buffered.hpp │ ├── local │ ├── basic_endpoint.hpp │ ├── connect_pair.hpp │ ├── datagram_protocol.hpp │ ├── detail │ │ ├── endpoint.hpp │ │ └── impl │ │ │ └── endpoint.ipp │ └── stream_protocol.hpp │ ├── multiple_exceptions.hpp │ ├── packaged_task.hpp │ ├── placeholders.hpp │ ├── posix │ ├── basic_descriptor.hpp │ ├── basic_stream_descriptor.hpp │ ├── descriptor.hpp │ ├── descriptor_base.hpp │ └── stream_descriptor.hpp │ ├── post.hpp │ ├── prefer.hpp │ ├── prepend.hpp │ ├── query.hpp │ ├── random_access_file.hpp │ ├── read.hpp │ ├── read_at.hpp │ ├── read_until.hpp │ ├── readable_pipe.hpp │ ├── recycling_allocator.hpp │ ├── redirect_error.hpp │ ├── registered_buffer.hpp │ ├── require.hpp │ ├── require_concept.hpp │ ├── serial_port.hpp │ ├── serial_port_base.hpp │ ├── signal_set.hpp │ ├── socket_base.hpp │ ├── spawn.hpp │ ├── ssl.hpp │ ├── ssl │ ├── context.hpp │ ├── context_base.hpp │ ├── detail │ │ ├── buffered_handshake_op.hpp │ │ ├── engine.hpp │ │ ├── handshake_op.hpp │ │ ├── impl │ │ │ ├── engine.ipp │ │ │ └── openssl_init.ipp │ │ ├── io.hpp │ │ ├── openssl_init.hpp │ │ ├── openssl_types.hpp │ │ ├── password_callback.hpp │ │ ├── read_op.hpp │ │ ├── shutdown_op.hpp │ │ ├── stream_core.hpp │ │ ├── verify_callback.hpp │ │ └── write_op.hpp │ ├── error.hpp │ ├── host_name_verification.hpp │ ├── impl │ │ ├── context.hpp │ │ ├── context.ipp │ │ ├── error.ipp │ │ ├── host_name_verification.ipp │ │ ├── rfc2818_verification.ipp │ │ └── src.hpp │ ├── rfc2818_verification.hpp │ ├── stream.hpp │ ├── stream_base.hpp │ ├── verify_context.hpp │ └── verify_mode.hpp │ ├── static_thread_pool.hpp │ ├── steady_timer.hpp │ ├── strand.hpp │ ├── stream_file.hpp │ ├── streambuf.hpp │ ├── system_context.hpp │ ├── system_error.hpp │ ├── system_executor.hpp │ ├── system_timer.hpp │ ├── this_coro.hpp │ ├── thread.hpp │ ├── thread_pool.hpp │ ├── time_traits.hpp │ ├── traits │ ├── bulk_execute_free.hpp │ ├── bulk_execute_member.hpp │ ├── connect_free.hpp │ ├── connect_member.hpp │ ├── equality_comparable.hpp │ ├── execute_free.hpp │ ├── execute_member.hpp │ ├── prefer_free.hpp │ ├── prefer_member.hpp │ ├── query_free.hpp │ ├── query_member.hpp │ ├── query_static_constexpr_member.hpp │ ├── require_concept_free.hpp │ ├── require_concept_member.hpp │ ├── require_free.hpp │ ├── require_member.hpp │ ├── schedule_free.hpp │ ├── schedule_member.hpp │ ├── set_done_free.hpp │ ├── set_done_member.hpp │ ├── set_error_free.hpp │ ├── set_error_member.hpp │ ├── set_value_free.hpp │ ├── set_value_member.hpp │ ├── start_free.hpp │ ├── start_member.hpp │ ├── static_query.hpp │ ├── static_require.hpp │ ├── static_require_concept.hpp │ ├── submit_free.hpp │ └── submit_member.hpp │ ├── ts │ ├── buffer.hpp │ ├── executor.hpp │ ├── internet.hpp │ ├── io_context.hpp │ ├── net.hpp │ ├── netfwd.hpp │ ├── socket.hpp │ └── timer.hpp │ ├── unyield.hpp │ ├── use_awaitable.hpp │ ├── use_future.hpp │ ├── uses_executor.hpp │ ├── version.hpp │ ├── wait_traits.hpp │ ├── windows │ ├── basic_object_handle.hpp │ ├── basic_overlapped_handle.hpp │ ├── basic_random_access_handle.hpp │ ├── basic_stream_handle.hpp │ ├── object_handle.hpp │ ├── overlapped_handle.hpp │ ├── overlapped_ptr.hpp │ ├── random_access_handle.hpp │ └── stream_handle.hpp │ ├── writable_pipe.hpp │ ├── write.hpp │ ├── write_at.hpp │ └── yield.hpp ├── nlohmann-3.11.2 └── single_include │ └── nlohmann │ ├── json.hpp │ └── json_fwd.hpp └── spdlog-1.9.0 ├── .clang-format ├── .clang-tidy ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── INSTALL ├── LICENSE ├── README.md ├── appveyor.yml ├── bench ├── CMakeLists.txt ├── async_bench.cpp ├── bench.cpp ├── formatter-bench.cpp ├── latency.cpp └── utils.h ├── cmake ├── ide.cmake ├── pch.h.in ├── spdlog.pc.in ├── spdlogCPack.cmake ├── spdlogConfig.cmake.in ├── utils.cmake └── version.rc.in ├── example ├── CMakeLists.txt └── example.cpp ├── include └── spdlog │ ├── async.h │ ├── async_logger-inl.h │ ├── async_logger.h │ ├── cfg │ ├── argv.h │ ├── env.h │ ├── helpers-inl.h │ └── helpers.h │ ├── common-inl.h │ ├── common.h │ ├── details │ ├── backtracer-inl.h │ ├── backtracer.h │ ├── circular_q.h │ ├── console_globals.h │ ├── file_helper-inl.h │ ├── file_helper.h │ ├── fmt_helper.h │ ├── log_msg-inl.h │ ├── log_msg.h │ ├── log_msg_buffer-inl.h │ ├── log_msg_buffer.h │ ├── mpmc_blocking_q.h │ ├── null_mutex.h │ ├── os-inl.h │ ├── os.h │ ├── periodic_worker-inl.h │ ├── periodic_worker.h │ ├── registry-inl.h │ ├── registry.h │ ├── synchronous_factory.h │ ├── tcp_client-windows.h │ ├── tcp_client.h │ ├── thread_pool-inl.h │ ├── thread_pool.h │ └── windows_include.h │ ├── fmt │ ├── bin_to_hex.h │ ├── bundled │ │ ├── args.h │ │ ├── chrono.h │ │ ├── color.h │ │ ├── compile.h │ │ ├── core.h │ │ ├── format-inl.h │ │ ├── format.h │ │ ├── locale.h │ │ ├── os.h │ │ ├── ostream.h │ │ ├── printf.h │ │ ├── ranges.h │ │ └── xchar.h │ ├── chrono.h │ ├── compile.h │ ├── fmt.h │ ├── ostr.h │ └── xchar.h │ ├── formatter.h │ ├── fwd.h │ ├── logger-inl.h │ ├── logger.h │ ├── pattern_formatter-inl.h │ ├── pattern_formatter.h │ ├── sinks │ ├── android_sink.h │ ├── ansicolor_sink-inl.h │ ├── ansicolor_sink.h │ ├── base_sink-inl.h │ ├── base_sink.h │ ├── basic_file_sink-inl.h │ ├── basic_file_sink.h │ ├── daily_file_sink.h │ ├── dist_sink.h │ ├── dup_filter_sink.h │ ├── hourly_file_sink.h │ ├── mongo_sink.h │ ├── msvc_sink.h │ ├── null_sink.h │ ├── ostream_sink.h │ ├── qt_sinks.h │ ├── ringbuffer_sink.h │ ├── rotating_file_sink-inl.h │ ├── rotating_file_sink.h │ ├── sink-inl.h │ ├── sink.h │ ├── stdout_color_sinks-inl.h │ ├── stdout_color_sinks.h │ ├── stdout_sinks-inl.h │ ├── stdout_sinks.h │ ├── syslog_sink.h │ ├── systemd_sink.h │ ├── tcp_sink.h │ ├── win_eventlog_sink.h │ ├── wincolor_sink-inl.h │ └── wincolor_sink.h │ ├── spdlog-inl.h │ ├── spdlog.h │ ├── stopwatch.h │ ├── tweakme.h │ └── version.h ├── logos └── jetbrains-variant-4.svg ├── scripts ├── extract_version.py └── format.sh ├── src ├── async.cpp ├── cfg.cpp ├── color_sinks.cpp ├── file_sinks.cpp ├── fmt.cpp ├── spdlog.cpp └── stdout_sinks.cpp └── tests ├── CMakeLists.txt ├── catch.hpp ├── catch.license ├── includes.h ├── main.cpp ├── test_async.cpp ├── test_backtrace.cpp ├── test_cfg.cpp ├── test_create_dir.cpp ├── test_daily_logger.cpp ├── test_dup_filter.cpp ├── test_errors.cpp ├── test_eventlog.cpp ├── test_file_helper.cpp ├── test_file_logging.cpp ├── test_fmt_helper.cpp ├── test_macros.cpp ├── test_misc.cpp ├── test_mpmc_q.cpp ├── test_pattern_formatter.cpp ├── test_registry.cpp ├── test_sink.h ├── test_stdout_api.cpp ├── test_stopwatch.cpp ├── test_systemd.cpp ├── test_time_point.cpp ├── utils.cpp └── utils.h /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | 11 | build-and-push-docker-image: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | 18 | - name: Log in to Docker Hub 19 | run: echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login --username "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin 20 | 21 | - name: Build Docker image 22 | run: docker build . -f docker/Dockerfile --tag ${{ secrets.DOCKERHUB_USERNAME }}/socks5-server:latest 23 | 24 | - name: Push Docker image to Docker Hub 25 | run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/socks5-server:latest -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore build dir 2 | build/ 3 | 4 | # ignore binary file 5 | bin/ 6 | 7 | # ignore .vscode 8 | .vscode/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 NumPy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "server" : { 3 | "host" : "0.0.0.0", 4 | "port" : 1080 5 | }, 6 | "log" : { 7 | "log_file" : "logs/server.log", 8 | "max_rotate_size" : 1048576, 9 | "max_rotate_count" : 10 10 | }, 11 | "auth" : { 12 | "username" : "socks-user", 13 | "password" : "socks-passwd" 14 | }, 15 | "supported-methods" : [0, 2], 16 | "timeout" : 60 17 | } -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:20.04 2 | 3 | COPY . /root/socks5-service 4 | 5 | WORKDIR /root/socks5-service 6 | 7 | RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list 8 | 9 | # Install Required Packages 10 | RUN apt-get update && apt-get install -y --no-install-recommends g++ cmake make 11 | 12 | # Clean up APT when done. 13 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 14 | 15 | RUN [ -d "./build" ] && rm ./build -r; echo '' 16 | RUN mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release .. && make 17 | 18 | CMD cd build && /bin/bash -c "../bin/socks_server" 19 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "2.0" 2 | 3 | networks: 4 | socks5_net: 5 | 6 | services: 7 | socks5-service: 8 | image: xukeawsl/socks5-server:latest 9 | container_name: socks5-server 10 | ports: 11 | - 1080:1080 12 | volumes: 13 | - /var/log/socks5:/root/socks5-service/build/logs 14 | networks: 15 | - socks5_net 16 | environment: 17 | - TZ=Asia/Shanghai 18 | restart: always 19 | logging: 20 | driver: "json-file" 21 | options: 22 | max-size: "10m" 23 | max-file: "5" 24 | privileged: true -------------------------------------------------------------------------------- /include/common/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "asio.hpp" 13 | #include "logger.h" 14 | 15 | /* SOCKS Protocol Version Field */ 16 | enum class SocksVersion : uint8_t { 17 | V4 = 0x04, 18 | V5 = 0x05, 19 | }; 20 | 21 | enum class ATyp : uint8_t { 22 | Ipv4 = 0x01, 23 | DoMainName = 0x03, 24 | Ipv6 = 0x04, 25 | }; 26 | 27 | class noncopyable { 28 | protected: 29 | noncopyable() {} 30 | ~noncopyable() {} 31 | noncopyable(const noncopyable&) = delete; 32 | const noncopyable& operator=(const noncopyable&) = delete; 33 | }; 34 | 35 | namespace convert { 36 | 37 | template 38 | std::string format_address( 39 | const asio::ip::basic_endpoint& endpoint) { 40 | if (endpoint.address().is_v6()) { 41 | return "[" + endpoint.address().to_string() + "]" + ":" + 42 | std::to_string(endpoint.port()); 43 | } 44 | return endpoint.address().to_string() + ":" + 45 | std::to_string(endpoint.port()); 46 | } 47 | 48 | std::string dst_to_string(const std::vector& dst_addr, ATyp addr_type); 49 | 50 | } // namespace convert -------------------------------------------------------------------------------- /include/common/logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "spdlog/async.h" 4 | #include "spdlog/sinks/basic_file_sink.h" 5 | #include "spdlog/sinks/rotating_file_sink.h" 6 | #include "spdlog/sinks/stdout_color_sinks.h" 7 | #include "spdlog/spdlog.h" 8 | 9 | class Logger { 10 | public: 11 | static Logger* getInstance(); 12 | 13 | bool Init(const std::string& log_file, long unsigned max_rotateSize, 14 | long unsigned max_rotateCount); 15 | 16 | private: 17 | Logger() = default; 18 | ~Logger() = default; 19 | Logger(const Logger&) = delete; 20 | Logger& operator=(const Logger&) = delete; 21 | Logger(Logger&&) = delete; 22 | Logger& operator=(Logger&&) = delete; 23 | }; -------------------------------------------------------------------------------- /include/server/socks5_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/common.h" 4 | #include "util/io_context_pool.h" 5 | 6 | class Socks5Session; 7 | 8 | class Socks5Server : public noncopyable { 9 | public: 10 | Socks5Server(const std::string& host, uint16_t port, size_t thread_num); 11 | 12 | ~Socks5Server(); 13 | 14 | void start() noexcept; 15 | 16 | private: 17 | void init(); 18 | 19 | void do_accept(); 20 | 21 | void stop(); 22 | 23 | protected: 24 | size_t pool_size; 25 | size_t conn_timeout; 26 | io_context_pool pool; 27 | asio::signal_set signals; 28 | asio::ip::tcp::acceptor acceptor; 29 | asio::ip::tcp::endpoint listen_endpoint; 30 | std::shared_ptr new_conn_ptr; 31 | }; -------------------------------------------------------------------------------- /include/socks_server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "option/parser.h" 4 | #include "server/socks5_server.h" -------------------------------------------------------------------------------- /include/util/io_context_pool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "common/common.h" 4 | 5 | class io_context_pool : private noncopyable { 6 | public: 7 | explicit io_context_pool(size_t pool_size); 8 | 9 | void run(); 10 | 11 | void stop(); 12 | 13 | asio::io_context& get_io_context(); 14 | 15 | private: 16 | using io_context_ptr = std::shared_ptr; 17 | using io_context_work = 18 | asio::executor_work_guard; 19 | 20 | std::vector io_contexts; 21 | std::list work; 22 | 23 | size_t next_io_context; 24 | }; -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "socks_server.h" 2 | 3 | int main(int argc, char* argv[]) { 4 | // parse command options 5 | if (ServerParser::global_config()->parse_config_file("../config.json") != 6 | true) { 7 | std::printf("bad configuration file !!!"); 8 | return EXIT_FAILURE; 9 | } 10 | 11 | // init log config 12 | if (Logger::getInstance()->Init( 13 | ServerParser::global_config()->get_log_file(), 14 | ServerParser::global_config()->get_max_rotate_size(), 15 | ServerParser::global_config()->get_max_rotate_count())) { 16 | SPDLOG_INFO("Log initialization succeeded"); 17 | SPDLOG_INFO("log_file : {}", 18 | ServerParser::global_config()->get_log_file()); 19 | SPDLOG_INFO("max_rotate_size : {} Bytes", 20 | ServerParser::global_config()->get_max_rotate_size()); 21 | SPDLOG_INFO("max_rotate_count : {}", 22 | ServerParser::global_config()->get_max_rotate_count()); 23 | } else { 24 | return EXIT_FAILURE; 25 | } 26 | 27 | Socks5Server server(ServerParser::global_config()->get_host(), 28 | ServerParser::global_config()->get_port(), 29 | ServerParser::global_config()->get_thread_num()); 30 | server.start(); 31 | 32 | return EXIT_SUCCESS; 33 | } -------------------------------------------------------------------------------- /src/common/common.cpp: -------------------------------------------------------------------------------- 1 | #include "common/common.h" 2 | 3 | namespace convert { 4 | 5 | std::string dst_to_string(const std::vector& dst_addr, 6 | ATyp addr_type) { 7 | char addr[UINT8_MAX]; 8 | std::memset(addr, 0, sizeof(addr)); 9 | 10 | switch (addr_type) { 11 | case ATyp::Ipv4: { 12 | std::snprintf(addr, sizeof(addr), "%d.%d.%d.%d", dst_addr[0], 13 | dst_addr[1], dst_addr[2], dst_addr[3]); 14 | } break; 15 | 16 | case ATyp::Ipv6: { 17 | std::snprintf(addr, sizeof(addr), 18 | "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%" 19 | "02x:%02x%02x:%" 20 | "02x%02x", 21 | dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3], 22 | dst_addr[4], dst_addr[5], dst_addr[6], dst_addr[7], 23 | dst_addr[8], dst_addr[9], dst_addr[10], dst_addr[11], 24 | dst_addr[12], dst_addr[13], dst_addr[14], 25 | dst_addr[15]); 26 | } break; 27 | 28 | case ATyp::DoMainName: { 29 | std::memcpy(addr, dst_addr.data(), dst_addr.size()); 30 | } break; 31 | } 32 | 33 | return std::string(addr); 34 | } 35 | 36 | } // namespace convert -------------------------------------------------------------------------------- /src/util/io_context_pool.cpp: -------------------------------------------------------------------------------- 1 | #include "util/io_context_pool.h" 2 | 3 | io_context_pool::io_context_pool(size_t pool_size) : next_io_context(0) { 4 | if (pool_size == 0) pool_size = 1; 5 | 6 | for (size_t i = 0; i < pool_size; ++i) { 7 | io_context_ptr io_context(std::make_shared()); 8 | io_contexts.emplace_back(io_context); 9 | work.emplace_back(asio::make_work_guard(*io_context)); 10 | } 11 | } 12 | 13 | void io_context_pool::run() { 14 | std::vector> threads; 15 | for (size_t i = 0; i < io_contexts.size(); ++i) { 16 | threads.emplace_back(std::make_shared( 17 | [](io_context_ptr ptr) { ptr->run(); }, io_contexts[i])); 18 | } 19 | 20 | for (size_t i = 0; i < io_contexts.size(); ++i) { 21 | threads[i]->join(); 22 | } 23 | } 24 | 25 | void io_context_pool::stop() { 26 | work.clear(); 27 | 28 | for (size_t i = 0; i < io_contexts.size(); ++i) { 29 | io_contexts[i]->stop(); 30 | } 31 | } 32 | 33 | asio::io_context& io_context_pool::get_io_context() { 34 | asio::io_context& io_context = *io_contexts[next_io_context]; 35 | ++next_io_context; 36 | if (next_io_context == io_contexts.size()) { 37 | next_io_context = 0; 38 | } 39 | return io_context; 40 | } -------------------------------------------------------------------------------- /third-party/asio-1.24.0/include/asio/associator.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // associator.hpp 3 | // ~~~~~~~~~~~~~~ 4 | // 5 | // Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 | // 7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 | // 10 | 11 | #ifndef ASIO_ASSOCIATOR_HPP 12 | #define ASIO_ASSOCIATOR_HPP 13 | 14 | #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 | # pragma once 16 | #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 | 18 | #include "asio/detail/config.hpp" 19 | 20 | #include "asio/detail/push_options.hpp" 21 | 22 | namespace asio { 23 | 24 | /// Used to generically specialise associators for a type. 25 | template