|
|
|
@ -48,8 +48,12 @@ struct reality_relay { |
|
|
|
int closed; |
|
|
|
int closed; |
|
|
|
|
|
|
|
|
|
|
|
size_t bytes_c2d, bytes_d2c; |
|
|
|
size_t bytes_c2d, bytes_d2c; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct reality_relay *next; // цепочка активных релеев (для shutdown)
|
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct reality_relay *g_relays = NULL; // активные релеи
|
|
|
|
|
|
|
|
|
|
|
|
static void relay_free(struct reality_relay *r); |
|
|
|
static void relay_free(struct reality_relay *r); |
|
|
|
static void relay_flush_c2d(struct reality_relay *r); |
|
|
|
static void relay_flush_c2d(struct reality_relay *r); |
|
|
|
static void relay_flush_d2c(struct reality_relay *r); |
|
|
|
static void relay_flush_d2c(struct reality_relay *r); |
|
|
|
@ -65,6 +69,12 @@ static void relay_free_cb(void *arg) { |
|
|
|
static void relay_free(struct reality_relay *r) { |
|
|
|
static void relay_free(struct reality_relay *r) { |
|
|
|
if (!r || r->closed) return; |
|
|
|
if (!r || r->closed) return; |
|
|
|
r->closed = 1; |
|
|
|
r->closed = 1; |
|
|
|
|
|
|
|
{ // вынуть из реестра активных релеев
|
|
|
|
|
|
|
|
struct reality_relay **pp = &g_relays; |
|
|
|
|
|
|
|
while (*pp && *pp != r) pp = &(*pp)->next; |
|
|
|
|
|
|
|
if (*pp) *pp = r->next; |
|
|
|
|
|
|
|
r->next = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
if (r->dns_q) { adns_cancel(r->dns_q); r->dns_q = NULL; } |
|
|
|
if (r->dns_q) { adns_cancel(r->dns_q); r->dns_q = NULL; } |
|
|
|
if (r->client_sid) { uasync_remove_socket_t(r->ua, r->client_sock); r->client_sid = NULL; } |
|
|
|
if (r->client_sid) { uasync_remove_socket_t(r->ua, r->client_sock); r->client_sid = NULL; } |
|
|
|
if (r->dest_sid) { uasync_remove_socket_t(r->ua, r->dest_sock); r->dest_sid = NULL; } |
|
|
|
if (r->dest_sid) { uasync_remove_socket_t(r->ua, r->dest_sock); r->dest_sid = NULL; } |
|
|
|
@ -265,6 +275,7 @@ int reality_relay_start(struct UASYNC *ua, socket_t client_sock, |
|
|
|
r->client_sock = client_sock; |
|
|
|
r->client_sock = client_sock; |
|
|
|
r->dest_sock = SOCKET_INVALID; |
|
|
|
r->dest_sock = SOCKET_INVALID; |
|
|
|
r->connecting = 1; |
|
|
|
r->connecting = 1; |
|
|
|
|
|
|
|
r->next = g_relays; g_relays = r; |
|
|
|
|
|
|
|
|
|
|
|
// берём владение client_sock сразу (снимаем старую регистрацию) — до парсинга,
|
|
|
|
// берём владение client_sock сразу (снимаем старую регистрацию) — до парсинга,
|
|
|
|
// чтобы любая ошибка ниже не оставила сокет зарегистрированным в uasync.
|
|
|
|
// чтобы любая ошибка ниже не оставила сокет зарегистрированным в uasync.
|
|
|
|
@ -315,3 +326,14 @@ int reality_relay_start(struct UASYNC *ua, socket_t client_sock, |
|
|
|
r->host, r->port, initial_len); |
|
|
|
r->host, r->port, initial_len); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void reality_relay_shutdown(void) { |
|
|
|
|
|
|
|
int count = 0; |
|
|
|
|
|
|
|
while (g_relays) { |
|
|
|
|
|
|
|
struct reality_relay *r = g_relays; |
|
|
|
|
|
|
|
relay_free(r); // сам вынимает r из g_relays и откладывает u_free через call_soon
|
|
|
|
|
|
|
|
count++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (count > 0) |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_REALITY, "reality_relay_shutdown: closed %d active relays", count); |
|
|
|
|
|
|
|
} |
|
|
|
|