Skip to content

Commit

Permalink
Remove privoxy component.
Browse files Browse the repository at this point in the history
  • Loading branch information
ssrlive committed Feb 7, 2024
1 parent 2e242d3 commit bd1ded6
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 112 deletions.
4 changes: 0 additions & 4 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
[submodule "depends/privoxy"]
path = depends/privoxy
url = https://github.com/ShadowsocksR-Live/Privoxy.git
branch = master
[submodule "depends/ssr-native"]
path = depends/ssr-native
url = https://github.com/ShadowsocksR-Live/shadowsocksr-native.git
Expand Down
1 change: 0 additions & 1 deletion depends/privoxy
Submodule privoxy deleted from 70acc0
2 changes: 0 additions & 2 deletions src/overtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ bool overtls_run_loop_begin(const struct server_config* cf,

overtls_set_log_callback(NULL, NULL);

overtls_lib_unload();

return true;
}

Expand Down
144 changes: 76 additions & 68 deletions src/run_ssr_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,31 @@
#pragma comment(lib, "Shlwapi.lib")
#include <assert.h>
#include <stdio.h>
#include <privoxyexports.h>
#include "socks_hub.h"
#include <ssr_client_api.h>
#include "run_ssr_client.h"
#include "proxy_settings.h"
#include "server_connectivity.h"
#include "utf8_to_wchar.h"
#include "overtls.h"

#define PRIVOXY_CONFIG_CONTENT_FMT \
"listen-address %s:%d\r\n" \
"forward-socks5 / 127.0.0.1:%d .\r\n"

static DWORD WINAPI SsrClientThread(LPVOID lpParam);
static uint16_t retrieve_socket_port(SOCKET socket);
static DWORD WINAPI PrivoxyThread(LPVOID lpParam);
static DWORD WINAPI HttpProxyThread(LPVOID lpParam);

struct ssr_client_ctx {
HANDLE hSsrClient;
HANDLE hPrivoxySvr;
HANDLE hOrderKeeper;
bool bOverTlsDll;
HANDLE hHttpProxySvr;
HANDLE hEvtS5Port;
struct server_config* config;
struct ssr_client_state* state;
int delay_ms;
uint16_t real_listen_port;
char privoxy_listen_host[MAX_PATH];
uint16_t privoxy_listen_port;
uint16_t real_s5_listen_port;
HANDLE hEvtHttpPort;
uint16_t real_http_proxy_listen_port;
char http_proxy_listen_host[MAX_PATH];
uint16_t http_proxy_listen_port;
const struct main_wnd_data* wnd_data;
};

Expand All @@ -51,8 +50,8 @@ struct ssr_client_ctx* ssr_client_begin_run(struct server_config* config, const

const char* ssr_listen_host = get_ssr_listen_host(data);
int ssr_listen_port = get_ssr_listen_port(data);
const char* proxy_listen_host = get_privoxy_listen_host(data);
int proxy_listen_port = get_privoxy_listen_port(data);
const char* http_proxy_listen_host = get_http_proxy_listen_host(data);
int http_proxy_listen_port = get_http_proxy_listen_port(data);
int delay_quit_ms = get_delay_quit_ms(data);
int change_inet_opts = get_change_inet_opts(data);

Expand All @@ -67,18 +66,13 @@ struct ssr_client_ctx* ssr_client_begin_run(struct server_config* config, const
}
}

if (proxy_listen_port != 0) {
if (tcp_port_is_occupied("0.0.0.0", proxy_listen_port) ||
tcp_port_is_occupied("127.0.0.1", proxy_listen_port))
if (http_proxy_listen_port != 0) {
if (tcp_port_is_occupied("0.0.0.0", http_proxy_listen_port) ||
tcp_port_is_occupied("127.0.0.1", http_proxy_listen_port))
{
wnsprintfA(error_info, ARRAYSIZE(error_info), "tcp_port_is_occupied for proxy_listen_port: %d\n", proxy_listen_port);
wnsprintfA(error_info, ARRAYSIZE(error_info), "tcp_port_is_occupied for proxy_listen_port: %d\n", http_proxy_listen_port);
return NULL;
}
} else {
// TODO: Privoxy not allow listen port is ZERO recently.
DebugBreak();
wnsprintfA(error_info, ARRAYSIZE(error_info), "tcp_port_is_occupied for proxy_listen_port: %d\n", proxy_listen_port);
return NULL;
}

ctx = (struct ssr_client_ctx*)calloc(1, sizeof(*ctx));
Expand All @@ -90,33 +84,51 @@ struct ssr_client_ctx* ssr_client_begin_run(struct server_config* config, const
ctx->config->listen_port = (unsigned short)ssr_listen_port;
string_safe_assign(&ctx->config->listen_host, ssr_listen_host);

strcpy(ctx->privoxy_listen_host, proxy_listen_host);
ctx->privoxy_listen_port = (uint16_t)proxy_listen_port;
strcpy(ctx->http_proxy_listen_host, http_proxy_listen_host);
ctx->http_proxy_listen_port = (uint16_t)http_proxy_listen_port;
ctx->delay_ms = (delay_quit_ms < SSR_DELAY_QUIT_MIN) ? SSR_DELAY_QUIT_MIN : delay_quit_ms;

ctx->hOrderKeeper = CreateEvent(NULL, TRUE, FALSE, NULL);
if (overtls_lib_initialize()) {
ctx->bOverTlsDll = true;
}
ctx->hEvtS5Port = CreateEvent(NULL, TRUE, FALSE, NULL);
ctx->hSsrClient = CreateThread(NULL, 0, SsrClientThread, ctx, 0, &threadId);
WaitForSingleObject(ctx->hOrderKeeper, INFINITE);
CloseHandle(ctx->hOrderKeeper);
WaitForSingleObject(ctx->hEvtS5Port, INFINITE);
CloseHandle(ctx->hEvtS5Port);
ctx->hEvtS5Port = NULL;

if (overtls_lib_initialize() && config_is_overtls(ctx->config)) {
if (ctx->bOverTlsDll && config_is_overtls(ctx->config)) {
error_code = 0;
}
else {
error_code = ssr_get_client_error_code(ctx->state);
}
if (error_code == 0) {
ctx->hPrivoxySvr = CreateThread(NULL, 0, PrivoxyThread, ctx, 0, &threadId);
if (change_inet_opts != 0) {
wchar_t*p = utf8_to_wchar_string(ctx->privoxy_listen_host, &malloc);
enable_system_proxy(p, ctx->privoxy_listen_port);
if (false == socks_hub_lib_initialize()) {
DebugBreak();
wnsprintfA(error_info, ARRAYSIZE(error_info), "missing dll file \"%s\"\n", "socks_hub.dll");
// FIXME: resource leak here.
return NULL;
}
ctx->hEvtHttpPort = CreateEvent(NULL, TRUE, FALSE, NULL);
ctx->hHttpProxySvr = CreateThread(NULL, 0, HttpProxyThread, ctx, 0, &threadId);
WaitForSingleObject(ctx->hEvtHttpPort, INFINITE);
CloseHandle(ctx->hEvtHttpPort);
ctx->hEvtHttpPort = NULL;
if (change_inet_opts != 0 && ctx->real_http_proxy_listen_port != 0) {
wchar_t*p = utf8_to_wchar_string(ctx->http_proxy_listen_host, &malloc);
enable_system_proxy(p, ctx->real_http_proxy_listen_port);
free(p);
} else {
disable_system_proxy();
}
} else {
WaitForSingleObject(ctx->hSsrClient, INFINITE);
CloseHandle(ctx->hSsrClient);
ctx->hSsrClient = NULL;
if (ctx->bOverTlsDll) {
overtls_lib_unload();
}
config_release(ctx->config);
free(ctx);
ctx = NULL;
Expand All @@ -128,19 +140,25 @@ struct ssr_client_ctx* ssr_client_begin_run(struct server_config* config, const

void ssr_client_terminate(struct ssr_client_ctx* ctx) {
if (ctx) {
if (overtls_lib_initialize() && config_is_overtls(ctx->config)) {
if (ctx->bOverTlsDll && config_is_overtls(ctx->config)) {
assert(ctx->state == NULL);
overtls_client_stop();
}else {
ssr_run_loop_shutdown(ctx->state);
}
WaitForSingleObject(ctx->hSsrClient, INFINITE);
CloseHandle(ctx->hSsrClient);
ctx->hSsrClient = NULL;
if (ctx->bOverTlsDll) {
overtls_lib_unload();
}
config_release(ctx->config);

privoxy_shutdown();
WaitForSingleObject(ctx->hPrivoxySvr, INFINITE);
CloseHandle(ctx->hPrivoxySvr);
socks_hub_stop();
WaitForSingleObject(ctx->hHttpProxySvr, INFINITE);
CloseHandle(ctx->hHttpProxySvr);
ctx->hHttpProxySvr = NULL;
socks_hub_lib_unload();

free(ctx);

Expand All @@ -153,23 +171,23 @@ static void ssr_feedback_state(struct ssr_client_state* state, void* p) {
SOCKET socket;
state_set_force_quit(state, true, ctx->delay_ms); // force_quit flag
socket = (SOCKET)ssr_get_listen_socket_fd(state);
ctx->real_listen_port = retrieve_socket_port(socket);
ctx->real_s5_listen_port = retrieve_socket_port(socket);
ctx->state = state;
SetEvent(ctx->hOrderKeeper);
SetEvent(ctx->hEvtS5Port);
}

static void listen_port_callback(int listen_port, void* p) {
static void s5_port_cb(int listen_port, void* p) {
struct ssr_client_ctx* ctx = (struct ssr_client_ctx*)p;
ctx->real_listen_port = listen_port;
SetEvent(ctx->hOrderKeeper);
ctx->real_s5_listen_port = listen_port;
SetEvent(ctx->hEvtS5Port);
}

static DWORD WINAPI SsrClientThread(LPVOID lpParam) {
struct ssr_client_ctx* ctx = (struct ssr_client_ctx*)lpParam;
if (overtls_lib_initialize() && config_is_overtls(ctx->config)) {
if (ctx->bOverTlsDll && config_is_overtls(ctx->config)) {
// run overtls thread
if (false == overtls_run_loop_begin(ctx->config, &listen_port_callback, ctx)) {
listen_port_callback(0, ctx);
if (false == overtls_run_loop_begin(ctx->config, &s5_port_cb, ctx)) {
s5_port_cb(0, ctx);
}
}
else {
Expand All @@ -191,34 +209,24 @@ static uint16_t retrieve_socket_port(SOCKET socket) {
}
}

static DWORD WINAPI PrivoxyThread(LPVOID lpParam) {
static void http_port_cb(int listen_port, void* p) {
struct ssr_client_ctx* ctx = (struct ssr_client_ctx*)p;
ctx->real_http_proxy_listen_port = listen_port;
SetEvent(ctx->hEvtHttpPort);
}

static DWORD WINAPI HttpProxyThread(LPVOID lpParam) {
struct ssr_client_ctx* ctx = (struct ssr_client_ctx*)lpParam;
char privoxy_config_file[MAX_PATH] = { 0 };
char content[MAX_PATH * 2] = { 0 };
HANDLE hFile;
DWORD dwBytesToWrite = 0, dwBytesWritten = 0;
char* p, * tmp = exe_file_path(&malloc);
if (tmp && (p = strrchr(tmp, '\\'))) {
*p = '\0';
sprintf(privoxy_config_file, "%s/privoxy_config.txt", tmp);
free(tmp);
}
else {
assert(0);
}
char http_proxy_addr[MAX_PATH] = { 0 };
char socks5_proxy_addr[MAX_PATH] = { 0 };

assert(ctx->real_listen_port != 0);
sprintf(content, PRIVOXY_CONFIG_CONTENT_FMT, ctx->privoxy_listen_host, ctx->privoxy_listen_port, ctx->real_listen_port);
assert(ctx->real_s5_listen_port != 0);
sprintf(http_proxy_addr, "%s:%d", ctx->http_proxy_listen_host, ctx->http_proxy_listen_port);
sprintf(socks5_proxy_addr, "127.0.0.1:%d", ctx->real_s5_listen_port);

hFile = CreateFileA(privoxy_config_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
assert(!"Terminal failure: Unable to open file for write.\n");
if (false == socks_hub_run_loop_begin(http_proxy_addr, socks5_proxy_addr, http_port_cb, ctx)) {
http_port_cb(0, ctx);
}
dwBytesToWrite = lstrlenA(content);
WriteFile(hFile, content, dwBytesToWrite, &dwBytesWritten, NULL);
CloseHandle(hFile);

privoxy_main_entry(privoxy_config_file, NULL, NULL);

return 0;
}
8 changes: 4 additions & 4 deletions src/run_ssr_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ extern "C" {

#define SSR_DELAY_QUIT_MIN 500

#define PRIVOXY_LISTEN_ADDR "127.0.0.1"
#define PRIVOXY_LISTEN_PORT 8118
#define HTTP_PROXY_LISTEN_ADDR "127.0.0.1"
#define HTTP_PROXY_LISTEN_PORT 8118

struct ssr_client_ctx;
struct server_config;
Expand All @@ -27,8 +27,8 @@ p_log_callback get_log_callback_ptr(const struct main_wnd_data* data);

const char* get_ssr_listen_host(const struct main_wnd_data* data);
int get_ssr_listen_port(const struct main_wnd_data* data);
const char* get_privoxy_listen_host(const struct main_wnd_data* data);
int get_privoxy_listen_port(const struct main_wnd_data* data);
const char* get_http_proxy_listen_host(const struct main_wnd_data* data);
int get_http_proxy_listen_port(const struct main_wnd_data* data);
int get_delay_quit_ms(const struct main_wnd_data* data);
int get_change_inet_opts(const struct main_wnd_data* data);

Expand Down
92 changes: 92 additions & 0 deletions src/socks_hub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <Windows.h>
#include <stdio.h>
#include <ssr_client_api.h>
#include <assert.h>
#include "run_ssr_client.h"

//
// https://github.com/ssrlive/socks-hub/releases
//

HINSTANCE hSocksHub = NULL;

bool socks_hub_lib_initialize(void) {
if (hSocksHub != NULL) {
return true;
}
hSocksHub = LoadLibraryW(L"socks_hub.dll");
return (hSocksHub != NULL) ? true : false;
}

void socks_hub_lib_unload(void) {
if (hSocksHub != NULL) {
FreeLibrary(hSocksHub);
hSocksHub = NULL;
}
}

typedef enum ArgVerbosity {
Off = 0,
Error,
Warn,
Info,
Debug,
Trace,
} ArgVerbosity;

typedef enum SourceType {
Http = 0,
Socks5,
} SourceType;

typedef void (*p_sock_hub_log_callback)(enum ArgVerbosity, const char*, void*);
typedef void (*p_socks_hub_set_log_callback)(p_sock_hub_log_callback callback, void* ctx);

typedef int (*p_socks_hub_run)(enum SourceType type, const char* local_addr, const char* server_addr,
enum ArgVerbosity verbosity,
void (*callback)(int, void*),
void* ctx);

typedef int (*p_socks_hub_stop)(void);

bool socks_hub_run_loop_begin(
const char* local_addr,
const char* server_addr,
void(*listen_port_callback)(int listen_port, void* ctx),
void* ctx)
{
struct ssr_client_ctx* _ctx = (struct ssr_client_ctx*)ctx;
const struct main_wnd_data* data = get_main_wnd_data_from_ctx(_ctx);
p_log_callback callback = get_log_callback_ptr(data);
int res = 0;
p_socks_hub_run _socks_hub_run;
p_socks_hub_set_log_callback _socks_hub_set_log_callback;

_socks_hub_set_log_callback = (p_socks_hub_set_log_callback)GetProcAddress(hSocksHub, "socks_hub_set_log_callback");
if (_socks_hub_set_log_callback == NULL) {
return false;
}
// enable socks-tub log dumping
_socks_hub_set_log_callback((p_sock_hub_log_callback)callback, (void*)data);

_socks_hub_run = (p_socks_hub_run)GetProcAddress(hSocksHub, "socks_hub_run");
if (_socks_hub_run == NULL) {
return false;
}
// the socks-tub dead loop
res = _socks_hub_run(Http, local_addr, server_addr, Info, listen_port_callback, ctx);
assert(res == 0);

_socks_hub_set_log_callback(NULL, NULL);

return true;
}

void socks_hub_stop(void) {
p_socks_hub_stop _socks_hub_stop;
_socks_hub_stop = (p_socks_hub_stop)GetProcAddress(hSocksHub, "socks_hub_stop");
if (_socks_hub_stop != NULL) {
// stop socks-hub stop dead loop
_socks_hub_stop();
}
}
Loading

0 comments on commit bd1ded6

Please sign in to comment.