diff --git a/src/core/network-proxy-http.c b/src/core/network-proxy-http.c index 61d49208..2eb504b5 100644 --- a/src/core/network-proxy-http.c +++ b/src/core/network-proxy-http.c @@ -29,27 +29,35 @@ static void network_proxy_http_destroy(struct network_proxy *proxy) { - struct _network_proxy_http *self = container_of(proxy, struct _network_proxy_http, proxy); + struct network_proxy_http *self = (struct network_proxy_http *)proxy->privdata; g_free(self->password); - _network_proxy_destroy(proxy); g_free(self); + + _network_proxy_destroy(proxy); + + g_free(proxy); } static struct network_proxy *network_proxy_http_clone(const struct network_proxy *proxy) { - struct _network_proxy_http *self = container_of(proxy, struct _network_proxy_http, proxy); - struct _network_proxy_http *res; + struct network_proxy_http *self = (struct network_proxy_http *)proxy->privdata; + struct network_proxy_http *priv; + struct network_proxy *res; - res = g_malloc0(sizeof *res); + res = g_malloc0(sizeof(struct network_proxy)); - _network_proxy_clone(&res->proxy, &self->proxy); - res->password = g_strdup(self->password); - return &res->proxy; + _network_proxy_clone(res, proxy); + + priv = g_malloc0(sizeof(struct network_proxy_http)); + res->privdata = (void *)priv; + + priv->password = g_strdup(self->password); + return res; } -static bool send_connect(struct _network_proxy_http *proxy, GIOChannel *ch, +static bool send_connect(struct network_proxy_http *proxy, GIOChannel *ch, const char *address, uint16_t port) { char port_str[6]; @@ -68,7 +76,7 @@ static bool send_connect(struct _network_proxy_http *proxy, GIOChannel *ch, return true; } -static int read_response(struct _network_proxy_http *proxy, GIOChannel *ch) +static int read_response(struct network_proxy_http *proxy, GIOChannel *ch) { GIOStatus status; GString line = { .str = NULL }; @@ -127,7 +135,7 @@ err: static GIOChannel *network_proxy_http_connect(const struct network_proxy *proxy, const IPADDR *hint_ip, const char *address, int port) { - struct _network_proxy_http *self = container_of(proxy, struct _network_proxy_http, proxy); + struct network_proxy_http *self = (struct network_proxy_http *)proxy->privdata; GIOChannel *ch; GIOFlags old_flags; GError *err = NULL; @@ -135,9 +143,9 @@ static GIOChannel *network_proxy_http_connect(const struct network_proxy *proxy, gint line_term_sz; if (hint_ip) - ch = net_connect_ip(hint_ip, self->proxy.port, NULL); + ch = net_connect_ip(hint_ip, proxy->port, NULL); else - ch = net_connect(self->proxy.host, self->proxy.port, NULL); + ch = net_connect(proxy->host, proxy->port, NULL); if (!ch) return NULL; @@ -171,18 +179,23 @@ err: return NULL; } -struct network_proxy *_network_proxy_http_create(void) +struct network_proxy *network_proxy_http_create(void) { - struct _network_proxy_http *res; + struct network_proxy *res; + struct network_proxy_http *priv; - res = g_malloc0(sizeof *res); + res = g_malloc0(sizeof(struct network_proxy)); - _network_proxy_create(&res->proxy); - res->password = g_strdup(settings_get_str("proxy_password")); + _network_proxy_create(res); - res->proxy.destroy = network_proxy_http_destroy; - res->proxy.connect = network_proxy_http_connect; - res->proxy.clone = network_proxy_http_clone; + priv = g_malloc0(sizeof(struct network_proxy_http)); + res->privdata = (void *)priv; - return &res->proxy; + priv->password = g_strdup(settings_get_str("proxy_password")); + + res->destroy = network_proxy_http_destroy; + res->connect = network_proxy_http_connect; + res->clone = network_proxy_http_clone; + + return res; } diff --git a/src/core/network-proxy-http.h b/src/core/network-proxy-http.h index 1f63d5e3..723aae43 100644 --- a/src/core/network-proxy-http.h +++ b/src/core/network-proxy-http.h @@ -3,11 +3,10 @@ #include "network-proxy.h" -struct _network_proxy_http { - struct network_proxy proxy; +struct network_proxy_http { char *password; }; -struct network_proxy *_network_proxy_http_create(void); +struct network_proxy *network_proxy_http_create(void); #endif diff --git a/src/core/network-proxy-priv.h b/src/core/network-proxy-priv.h index 76d40f27..d7b8050a 100644 --- a/src/core/network-proxy-priv.h +++ b/src/core/network-proxy-priv.h @@ -4,14 +4,10 @@ #include "settings.h" #include -/* stolen from linux kernel */ -#define container_of(ptr, type, member) __extension__ ({ \ - const __typeof__( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - - inline static void _network_proxy_create(struct network_proxy *dst) { + // TODO: Initialize all fields, to bring the struct to a known state + dst->privdata = NULL; dst->port = settings_get_int("proxy_port"); dst->host = g_strdup(settings_get_str("proxy_address")); } @@ -31,8 +27,6 @@ inline static void _network_proxy_destroy(struct network_proxy *proxy) g_free(proxy->host); } - - inline static bool _network_proxy_send_all(GIOChannel *ch, const void *buf, ssize_t len) { GError *err = NULL; diff --git a/src/core/network-proxy-simple.c b/src/core/network-proxy-simple.c index 289bb6ba..980215b5 100644 --- a/src/core/network-proxy-simple.c +++ b/src/core/network-proxy-simple.c @@ -24,49 +24,54 @@ static void network_proxy_simple_destroy(struct network_proxy *proxy) { - struct _network_proxy_simple *self = container_of(proxy, struct _network_proxy_simple, proxy); + struct network_proxy_simple *self = (struct network_proxy_simple *)proxy->privdata; g_free(self->password); g_free(self->string_after); g_free(self->string); + g_free(self); + _network_proxy_destroy(proxy); - g_free(self); + // We are responsible for the whole proxy struct + g_free(proxy); } static struct network_proxy *network_proxy_simple_clone(const struct network_proxy *proxy) { - struct _network_proxy_simple *self = container_of(proxy, struct _network_proxy_simple, proxy); - struct _network_proxy_simple *res; + struct network_proxy_simple *self = (struct network_proxy_simple *)proxy->privdata; + struct network_proxy *res; + struct network_proxy_simple *newself; - res = g_malloc0(sizeof *res); + // First make and set the parent struct + res = g_malloc0(sizeof(struct network_proxy)); + _network_proxy_clone(res, proxy); - _network_proxy_clone(&res->proxy, &self->proxy); + // Then allocate and set the private data + newself = g_malloc0(sizeof(struct network_proxy_simple)); + res->privdata = (void *)newself; - res->string = g_strdup(self->string); - res->string_after = g_strdup(self->string_after); - res->password = g_strdup(self->password); - return &res->proxy; + newself->string = g_strdup(self->string); + newself->string_after = g_strdup(self->string_after); + newself->password = g_strdup(self->password); + + return res; } -static GIOChannel *network_proxy_simple_connect(const struct network_proxy *proxy, const IPADDR *hint_ip, - char const *address, int port) +static GIOChannel *network_proxy_simple_connect(const struct network_proxy *proxy, + const IPADDR *hint_ip, char const *address, int port) { - struct _network_proxy_simple *self = container_of(proxy, struct _network_proxy_simple, proxy); - - (void)address; - (void)port; if (hint_ip) - return net_connect_ip(hint_ip, self->proxy.port, NULL); + return net_connect_ip(hint_ip, proxy->port, NULL); else - return net_connect(self->proxy.host, self->proxy.port, NULL); + return net_connect(proxy->host, proxy->port, NULL); } static void network_proxy_simple_send_string(const struct network_proxy *proxy, const struct network_proxy_send_string_info *info) { - struct _network_proxy_simple *self = container_of(proxy, struct _network_proxy_simple, proxy); + struct network_proxy_simple *self = (struct network_proxy_simple *)proxy->privdata; char *cmd; if (self->password && self->password[0]) { @@ -85,7 +90,7 @@ static void network_proxy_simple_send_string(const struct network_proxy *proxy, static void network_proxy_simple_send_string_after(const struct network_proxy *proxy, const struct network_proxy_send_string_info *info) { - struct _network_proxy_simple *self = container_of(proxy, struct _network_proxy_simple, proxy); + struct network_proxy_simple *self = (struct network_proxy_simple *)proxy->privdata; char *cmd; if (self->string_after && self->string_after[0]) { @@ -95,23 +100,29 @@ static void network_proxy_simple_send_string_after(const struct network_proxy *p } } -struct network_proxy *_network_proxy_simple_create(void) +struct network_proxy *network_proxy_simple_create(void) { - struct _network_proxy_simple *res; + struct network_proxy *proxy; + struct network_proxy_simple *self; - res = g_malloc0(sizeof *res); + proxy = g_malloc0(sizeof(struct network_proxy)); - _network_proxy_create(&res->proxy); - res->string = g_strdup(settings_get_str("proxy_string")); - res->string_after = g_strdup(settings_get_str("proxy_string_after")); - res->password = g_strdup(settings_get_str("proxy_password")); + // assume it could reset every variable to a known state + _network_proxy_create(proxy); - res->proxy.destroy = network_proxy_simple_destroy; - res->proxy.connect = network_proxy_simple_connect; - res->proxy.clone = network_proxy_simple_clone; + self = g_malloc0(sizeof(struct network_proxy_simple)); + proxy->privdata = (void *)self; - res->proxy.send_string = network_proxy_simple_send_string; - res->proxy.send_string_after = network_proxy_simple_send_string_after; + self->string = g_strdup(settings_get_str("proxy_string")); + self->string_after = g_strdup(settings_get_str("proxy_string_after")); + self->password = g_strdup(settings_get_str("proxy_password")); - return &res->proxy; + proxy->destroy = network_proxy_simple_destroy; + proxy->connect = network_proxy_simple_connect; + proxy->clone = network_proxy_simple_clone; + + proxy->send_string = network_proxy_simple_send_string; + proxy->send_string_after = network_proxy_simple_send_string_after; + + return proxy; } diff --git a/src/core/network-proxy-simple.h b/src/core/network-proxy-simple.h index 6c3c8281..010d8e4a 100644 --- a/src/core/network-proxy-simple.h +++ b/src/core/network-proxy-simple.h @@ -3,14 +3,12 @@ #include "network-proxy.h" -struct _network_proxy_simple { - struct network_proxy proxy; - +struct network_proxy_simple { char *string_after; char *string; char *password; }; -struct network_proxy *_network_proxy_simple_create(void); +struct network_proxy *network_proxy_simple_create(void); #endif diff --git a/src/core/network-proxy-socks5.c b/src/core/network-proxy-socks5.c index 8c4eeaf7..c3dc1e4c 100644 --- a/src/core/network-proxy-socks5.c +++ b/src/core/network-proxy-socks5.c @@ -65,25 +65,30 @@ struct server_response static void network_proxy_socks5_destroy(struct network_proxy *proxy) { - struct _network_proxy_socks5 *self = container_of(proxy, struct _network_proxy_socks5, proxy); + struct network_proxy_socks5 *self = (struct network_proxy_socks5 *)proxy->privdata; g_free(self->password); g_free(self->username); - _network_proxy_destroy(proxy); g_free(self); + _network_proxy_destroy(proxy); + g_free(proxy); } static struct network_proxy *network_proxy_socks5_clone(const struct network_proxy *proxy) { - struct _network_proxy_socks5 *self = container_of(proxy, struct _network_proxy_socks5, proxy); - struct _network_proxy_socks5 *res; + struct network_proxy_socks5 *self = (struct network_proxy_socks5 *)proxy->privdata; + struct network_proxy_socks5 *priv; + struct network_proxy *res; - res = g_malloc0(sizeof *res); + res = g_malloc0(sizeof(struct network_proxy)); + _network_proxy_clone(res, proxy); - _network_proxy_clone(&res->proxy, &self->proxy); - res->username = g_strdup(self->username); - res->password = g_strdup(self->password); - return &res->proxy; + priv = g_malloc0(sizeof(struct network_proxy_socks5)); + res->privdata = (void *)priv; + + priv->username = g_strdup(self->username); + priv->password = g_strdup(self->password); + return res; } static bool socks5_connect_unauthorized(GIOChannel *ch) @@ -94,9 +99,9 @@ static bool socks5_connect_unauthorized(GIOChannel *ch) } /* TODO: test this method! */ -static bool socks5_connect_plain(const struct _network_proxy_socks5 *proxy, GIOChannel *ch) +static bool socks5_connect_plain(const struct network_proxy_socks5 *proxy, GIOChannel *ch) { - uint8_t ver = 0x01; + uint8_t ver = 0x01; uint8_t ulen = strlen(proxy->username); uint8_t plen = proxy->password ? strlen(proxy->password) : 0; struct server_response_plain resp; @@ -124,7 +129,7 @@ static bool socks5_connect_plain(const struct _network_proxy_socks5 *proxy, GIOC return true; } -static bool socks5_connect(const struct _network_proxy_socks5 *proxy, GIOChannel *ch, +static bool socks5_connect(const struct network_proxy_socks5 *proxy, GIOChannel *ch, const char *address, uint16_t port) { bool rc; @@ -267,7 +272,7 @@ err: static GIOChannel *network_proxy_socks5_connect(const struct network_proxy *proxy, const IPADDR *hint_ip, const char *address, int port) { - struct _network_proxy_socks5 *self = container_of(proxy, struct _network_proxy_socks5, proxy); + struct network_proxy_socks5 *self = (struct network_proxy_socks5 *)proxy->privdata; GIOChannel *ch; GIOFlags old_flags; @@ -276,9 +281,9 @@ static GIOChannel *network_proxy_socks5_connect(const struct network_proxy *prox GError *err = NULL; if (hint_ip) - ch = net_connect_ip(hint_ip, self->proxy.port, NULL); + ch = net_connect_ip(hint_ip, proxy->port, NULL); else - ch = net_connect(self->proxy.host, self->proxy.port, NULL); + ch = net_connect(proxy->host, proxy->port, NULL); if (!ch) return NULL; @@ -315,19 +320,24 @@ err: return NULL; } -struct network_proxy *_network_proxy_socks5_create(void) +struct network_proxy *network_proxy_socks5_create(void) { - struct _network_proxy_socks5 *res; + struct network_proxy *res; + struct network_proxy_socks5 *priv; - res = g_malloc0(sizeof *res); + res = g_malloc0(sizeof(struct network_proxy)); - _network_proxy_create(&res->proxy); - res->username = g_strdup(settings_get_str("proxy_username")); - res->password = g_strdup(settings_get_str("proxy_password")); + _network_proxy_create(res); - res->proxy.destroy = network_proxy_socks5_destroy; - res->proxy.connect = network_proxy_socks5_connect; - res->proxy.clone = network_proxy_socks5_clone; + priv = g_malloc0(sizeof(struct network_proxy_socks5)); + res->privdata = (void *)priv; - return &res->proxy; + priv->username = g_strdup(settings_get_str("proxy_username")); + priv->password = g_strdup(settings_get_str("proxy_password")); + + res->destroy = network_proxy_socks5_destroy; + res->connect = network_proxy_socks5_connect; + res->clone = network_proxy_socks5_clone; + + return res; } diff --git a/src/core/network-proxy-socks5.h b/src/core/network-proxy-socks5.h index 058edaf5..45431d3a 100644 --- a/src/core/network-proxy-socks5.h +++ b/src/core/network-proxy-socks5.h @@ -3,13 +3,11 @@ #include "network-proxy.h" -struct _network_proxy_socks5 { - struct network_proxy proxy; - +struct network_proxy_socks5 { char *username; char *password; }; -struct network_proxy *_network_proxy_socks5_create(void); +struct network_proxy *network_proxy_socks5_create(void); #endif diff --git a/src/core/network-proxy.c b/src/core/network-proxy.c index 0deff1ee..f056da6b 100644 --- a/src/core/network-proxy.c +++ b/src/core/network-proxy.c @@ -30,13 +30,13 @@ struct network_proxy *network_proxy_create(const char *type) return NULL; if (strcmp(type, "simple")==0 || type[0]=='\0') - return _network_proxy_simple_create(); + return network_proxy_simple_create(); if (strcmp(type, "http")==0) - return _network_proxy_http_create(); + return network_proxy_http_create(); if (strcmp(type, "socks5")==0) - return _network_proxy_socks5_create(); + return network_proxy_socks5_create(); g_error("unsupported proxy type '%s'", type); return NULL; diff --git a/src/core/network-proxy.h b/src/core/network-proxy.h index edd1a655..a9fbf936 100644 --- a/src/core/network-proxy.h +++ b/src/core/network-proxy.h @@ -18,6 +18,9 @@ struct network_proxy_send_string_info { }; struct network_proxy { + /* Contains private data for the chosen proxy type */ + void *privdata; + /* destroys the network_proxy structure which must not be used anymore * after; this memberfunction is mandatory */ void (*destroy)(struct network_proxy *);